Dialog
Basic
function DeployDialog() {
const [open, setOpen] = useState(false);
return (
<Dialog
title="DEPLOY UNIT"
description="Confirm deployment to the selected theater."
trigger={<Button variant="primary">DEPLOY</Button>}
open={open}
onOpenChange={setOpen}
footer={
<>
<Button variant="secondary" onClick={() => setOpen(false)}>
CANCEL
</Button>
<Button
variant="primary"
onClick={() => {
deploy();
setOpen(false);
}}
>
CONFIRM
</Button>
</>
}
>
<p>This action cannot be undone.</p>
</Dialog>
);
}
Footer buttons are ordinary buttons: to close the dialog from one, control open and set it to false in the button's handler. Escape, the Close button and a click outside the dialog close it through onOpenChange.
trigger takes one focusable element that forwards its ref, such as a Button; plain text renders as a Button.
Long content
When the content is taller than the screen, the title, Close and the footer stay in view and only the body scrolls. The dialog fits the visible screen less a margin, including the space above an on-screen keyboard. While the body scrolls it is a named region that Tab reaches and the arrow keys scroll. Long titles, identifiers and descriptions wrap, and footer actions wrap onto a new line when they do not fit side by side.
Sizes
Without a footer
Props
| PROP | TYPE | DEFAULT | REQUIRED |
|---|---|---|---|
motionTactile pointer/touch feedback. None disables motion; keyboard and system reduced motion are always immediate. | enumauto | none | "auto" | no |
title | string | — | yes |
description | string | — | no |
size | enumsm | md | lg | "md" | no |
open | boolean | — | no |
defaultOpen | boolean | — | no |
onOpenChange | function | — | no |
Accessibility
- Focus stays inside while open and returns to the trigger on close.
role="dialog", named by the title and described by the description; the rest of the page is hidden from assistive technology while it is open.- Escape, the overlay, or the named Close button dismisses. Close has a visible focus ring.
- The focused dialog shows the focus border, and a system-colored outline in forced colors.
- Other attributes and handlers you pass (keyboard, focus,
aria-*) reach the dialog element. The forwarded ref receives that element, a<section>, typedHTMLElement.
Manifest entry
<Dialog
title="DEPLOY UNIT"
description="Confirm deployment to the selected theater."
trigger={<Button variant="primary">DEPLOY</Button>}
footer={
<>
<Button variant="secondary">CANCEL</Button>
<Button variant="primary">CONFIRM</Button>
</>
}
>
<p>This action cannot be undone.</p>
</Dialog>View agent manifest
{
"description": "Modal dialog with a flat API: pass title, optional description, trigger, footer, and body children. Portal'd overlay + content built on React Aria Components (ModalOverlay + Modal + Dialog).",
"props": {
"motion": {
"type": "enum",
"values": [
"auto",
"none"
],
"default": "auto",
"description": "Tactile pointer/touch feedback. None disables motion; keyboard and system reduced motion are always immediate."
},
"title": {
"type": "string",
"required": true
},
"description": {
"type": "string"
},
"size": {
"type": "enum",
"values": [
"sm",
"md",
"lg"
],
"default": "md"
},
"open": {
"type": "boolean"
},
"defaultOpen": {
"type": "boolean"
},
"onOpenChange": {
"type": "function"
}
},
"slots": {
"trigger": {
"type": "focusable element | text (text renders a Button)"
},
"children": {
"type": "any",
"required": true
},
"footer": {
"type": "Button | ButtonGroup"
}
},
"composable_with": [
"Button",
"ButtonGroup"
],
"never_inside": [
"Button",
"Badge"
],
"example": "<Dialog\n title=\"DEPLOY UNIT\"\n description=\"Confirm deployment to the selected theater.\"\n trigger={<Button variant=\"primary\">DEPLOY</Button>}\n footer={\n <>\n <Button variant=\"secondary\">CANCEL</Button>\n <Button variant=\"primary\">CONFIRM</Button>\n </>\n }\n>\n <p>This action cannot be undone.</p>\n</Dialog>"
}Motion
The modal surface and backdrop enter together in 200ms and leave in 150ms. The surface begins at scale 0.98. Close callbacks run immediately; React Aria retains the backdrop and focus handling through the visual exit. Escape closes immediately.
Use motion="none" for frequently operated controls. The default motion="auto" respects system reduced motion, skips keyboard and assistive activation, and starts from the supplied resting state. See Motion for the interactive playground.