Skip to content
Alea0.1
Pro
  1. Alea
  2. Components
  3. Overlays
  4. Modal

Overlays

Modal

A modal that holds anything: a form, a gallery, a video, a wizard. Optional header and footer, seven sizes, centered or at the top, the body or the whole modal scrolling, edge-to-edge media and three backdrops.

import { Modal } from '@alea/ui';

Examples

Any content

A trigger, a title and whatever goes inside: here a small gallery with a caption. The footer is a function that gets close.

Long content and scrolling

scrollBehavior="inside" keeps the header and footer in place while the body scrolls (forms, terms, lists); "outside" lets the whole modal scroll with the page, for long reading.

Edge-to-edge media

padding="none" lets an image or a video touch the edges; without a title the modal needs an aria-label, and the close button floats over the media. size="auto" fits the content.

Sizes, placement and backdrops

size from xs (320 px) to xl (960 px), full or auto; placement="top" stays put while the content grows (a search); backdrop is dim, blur or transparent. On phones, fullscreenBelow="sm" takes the whole screen.

A flow inside one modal

Change the content instead of stacking modals: a header with Steps, the body for each step, and the footer moving back and forth.

Tokens

The design tokens this component reads, with their value in the current theme. Override any of them to restyle it.

Color

  • --alea-bg…
  • --alea-border…
  • --alea-surface…
  • --alea-surface-overlay…

Space

  • --alea-space-2…
  • --alea-space-3…
  • --alea-space-4…

Radius

  • --alea-radius-lg…

Type

  • --alea-font-family-display…
  • --alea-font-leading-tight…
  • --alea-font-size-2xl…
  • --alea-font-tracking-display…
  • --alea-font-weight-light…

Shadow

  • --alea-shadow-card…
  • --alea-shadow-pop…

Layer

  • --alea-z-modal…

Component

  • --alea-glass-blur…
  • --alea-glass-rim…
  • --alea-glass-saturate…
  • --alea-glass-tint…

Props

Modal props

A modal with any content: a header and footer if you want them, seven sizes, centered or at the top, the body or the whole modal scrolling, edge-to-edge media, three backdrops. Traps focus, closes on Escape and outside click, and returns focus to what opened it. For a title, text and two buttons, Dialog is quicker; to confirm something destructive, AlertDialog.

PropTypeDefaultDescription
childrenrequiredRender-Anything: a form, a gallery, a video, a wizard, a whole page. A function gets close.
aria-labelstring-Name for screen readers when there is no title.
backdrop"blur" | "dim" | "transparent"'dim'What is behind it: dim (default), blur (dim and blur) or transparent (only for modals that already stand out).
classNamestring-Extra class names for the modal surface.
footerRender-Content pinned at the bottom: actions, a summary. A function gets close.
fullscreenBelow"sm" | "md"-Takes the whole screen below this breakpoint (phones): sm (640 px) or md (768 px).
headerReactNode-Your own header instead of the title row (it still gets the close button).
motionMotionProp-How it enters and leaves (default rise): a preset, false, or options.
padding"none" | "normal"'normal'normal (default) or none, for media that should touch the edges (an image, a video, a map).
placement"center" | "top"'center'center (default) or top (stays put while its content grows, good for search and long forms).
scrollBehavior"inside" | "outside"'inside'inside: the header and footer stay, the body scrolls (default). outside: the whole modal scrolls with the page, for long reading.
showClosebooleantrueShows the close button. Default true.
size"sm" | "md" | "lg" | "xl" | "xs" | "auto" | "full"'md'xs 320, sm 400, md 560 (default), lg 760, xl 960, full (the whole window less a margin), or auto (as wide as its content).
titleReactNode-A title in the header, read when it opens. Without one, give the modal an aria-label.
triggerReactNode-The button (or any pressable) that opens it. Leave it out and control isOpen yourself.

Specs

Generated from the source: the variants in the types, the states and tokens in the CSS, and the motion patterns that apply. The grids render the real component in both themes; the numbers are measured from the page.

Variants
backdropblurdimtransparent
fullscreenBelowsmmd
paddingnonenormal
placementcentertop
scrollBehaviorinsideoutside
sizesmmdlgxlxsautofull
Motion
riseTakes a motion prop for its entrance and exit.
Dark and light
Every color comes from theme tokens, so it follows data-theme (and presets like Graphite) on the page or any wrapper. Contrast is checked in both themes.
Styling hooks
.alea-modal-overlay.alea-xmodal-overlay.alea-modal.alea-xmodal.alea-xmodal-dialog.alea-xmodal-head.alea-dialog-title.alea-dialog-x.alea-xmodal-x.alea-xmodal-body.alea-xmodal-footer
Data attributes
data-size=smdata-size=lgdata-size=fulldata-fullscreen-below=smdata-fullscreen-below=mddata-size=xsdata-size=mddata-size=xldata-size=autodata-placement=topdata-backdrop=transparentdata-backdrop=dimdata-backdrop=blurdata-scroll=insidedata-padding=nonedata-scroll=outside

Accessibility

  • Focus moves into the modal and stays there; on close it goes back to what opened it.
  • The page behind is hidden from screen readers and can't be scrolled.
  • It is named by its title, or by aria-label when there is no title (required then).
  • The close button is always reachable, also when the content scrolls or is edge-to-edge media.
  • Escape and a click on the backdrop close it; set isDismissable={false} or isKeyboardDismissDisabled for work that must not be lost.

Keyboard

KeyDoes
TabCycles inside the modal
Shift+TabCycles backwards
EscapeCloses it

Do and don't

Do

  • Use a title, or an aria-label, so screen readers say what opened.
  • Use scrollBehavior="inside" for forms and lists so the actions in the footer stay visible.
  • Use placement="top" for content that grows while people type (search, filters).
  • Make it full screen on phones (fullscreenBelow="sm") when the content is long.

Don't

  • Don't open a modal on page load.
  • Don't stack modals: replace the content, or use steps inside one.
  • Don't use it for a quick yes or no: AlertDialog is made for that.
  • Don't use backdrop="transparent" for content people must focus on.

In Figma

Modal with Size, Placement and Padding, and slots for header, body and footer.

Tested with axe, keyboard and screen reader roles