Overlays
Dialog
Modal dialog in three sizes with title, description and a footer of actions. Fills the width on phones and scrolls inside.
Installation
Install the package (React 19):
terminal
terminal
terminal
Import the styles once, in your app entry or root layout:
/src/main.tsx
Use it anywhere inside your app's <Theme> (see Installation):
/src/DialogExample.tsx
Examples
Form dialog
Controlled, long content
size="lg"; the body scrolls inside the panel.
Static surface
Static dialog
The dialog card without overlay or focus handling.
Composition
anatomy.tsx
Dialog.Contentrenders the overlay and the portal for you.DialogSurface/DialogOverlayare the static look for previews.
API Reference
Dialog.Root
Holds the open state.
| Prop | Type | Default |
|---|---|---|
open | boolean | |
defaultOpen | boolean | false |
onOpenChange | (open: boolean) => void | |
modal | boolean | true |
Dialog.Trigger
Opens the dialog.
| Prop | Type | Default |
|---|---|---|
asChild | boolean | false |
Dialog.Content
The panel, with the overlay and portal. Padding 24 (20 on phones), flex column with 8px gaps.
| Prop | Type | Default |
|---|---|---|
size | "sm""md""lg" | "md" |
width | number | |
height | number | |
top | number | |
radius | "md""xl" | "md" |
onOpenAutoFocus | (event: Event) => void | |
onCloseAutoFocus | (event: Event) => void | |
onEscapeKeyDown | (event: KeyboardEvent) => void | |
onPointerDownOutside | (event: PointerDownOutsideEvent) => void |
Dialog.Title / Description / Footer
Accessible name (16/600), description (14 secondary) and the action row (right-aligned, stacked on phones).
| Prop | Type | Default |
|---|---|---|
className | string |
Dialog.Close
Closes the dialog.
| Prop | Type | Default |
|---|---|---|
asChild | boolean | false |
DialogOverlay
The dimmed underlay on its own (no portal or behavior), for static renders behind a DialogSurface. A <div>: all its props pass through.
| Prop | Type | Default |
|---|---|---|
className | string |
DialogSurface
Static dialog card (never wider than its container).
| Prop | Type | Default |
|---|---|---|
size | "sm""md""lg" | |
width | number | |
height | number | |
radius | "md""xl" | "md" |
Accessibility
- Follows the WAI-ARIA modal dialog pattern:
role="dialog",aria-modal, named byDialog.Titleand described byDialog.Description. - A
Dialog.Titleis required (a development warning names a dialog without one). Without a description passaria-describedby={undefined}to Content. - Focus moves into the dialog on open and is trapped there; Tab / Shift+Tab cycle through its controls.
- Escape or an overlay click closes it; focus returns to the element that opened it.
- The page behind is inert and does not scroll while open.
- Under 640px the panel fills the width minus 8px margins; content taller than the screen scrolls inside the panel. Opens and closes with the shared motion layer (
styles/motion.css); withprefers-reduced-motion: reduceit only fades.
Usage
- Use for a focused task that blocks the page: editing a record, a short form, a decision.
- Use ConfirmDialog for a yes/no decision about a consequential action.
- Use Popover for small inline edits, Sheet for side panels and long forms.
- Keep the primary action last in
Dialog.Footer(it is on top on phones).
© 2026 Motion. Internal documentation.