A modal is an overlay element which blocks interaction with elements outside it.
Vanilla CSS theme
--tint CSS variable used by the Vanilla CSS examples.Sheet
Overlays such as trays, drawers, and sheets can be built using a Modal with custom entry and exit animations.
import {DialogTrigger, Heading} from 'react-aria-components';
import {Sheet} from './Sheet';
import {Button} from './Button';
<DialogTrigger>
<Button>Open sheet</Button>
<Sheet>
<Heading slot="title">Notice</Heading>
<p>This is a modal with a custom modal overlay.</p>
<Button slot="close">Close</Button>
</Sheet>
</DialogTrigger>
Controlled
Use the isOpen prop to show a modal programmatically or mount in a different part of the JSX tree (e.g. outside a menu).
import {useState} from 'react';
import {Heading} from 'react-aria-components';
import {MenuTrigger, Menu, MenuItem} from './Menu';
import {Modal} from './Modal';
import {Dialog} from './Dialog';
import {Button} from './Button';
function Example() {
let [isOpen, setOpen] = useState(false);
return (
<>
<MenuTrigger>
<Button>Menu</Button>
<Menu>
<MenuItem onAction={() => setOpen(true)}>Open dialog…</MenuItem>
</Menu>
</MenuTrigger>
<Modal isDismissable isOpen={isOpen} onOpenChange={setOpen}>
<Dialog>
<Heading slot="title">Notice</Heading>
<p>Click outside or press Escape to close this dialog.</p>
</Dialog>
</Modal>
</>
);
}
Custom trigger
DialogTrigger works with any pressable React Aria component (e.g. Button, Link, etc.). Use the <Pressable> component or usePress hook to wrap a custom trigger element such as a third party component or DOM element.
import {Pressable, DialogTrigger, Heading} from 'react-aria-components';
import {Modal} from './Modal';
import {Dialog} from './Dialog';
import {Button} from './Button';
<DialogTrigger>
<Pressable>
<span role="button">Custom trigger</span>
</Pressable>
<Modal>
<Dialog>
<Heading slot="title">Dialog</Heading>
<p>This dialog was triggered by a custom button.</p>
<Button slot="close">Close</Button>
</Dialog>
</Modal>
</DialogTrigger>
Accessibility
<Pressable> child must have an interactive ARIA role or use an appropriate semantic HTML element so that screen readers can announce the trigger. Trigger components must forward their ref and spread all props to a DOM element.const CustomTrigger = React.forwardRef((props, ref) => (
<button {...props} ref={ref} />
));
Examples
API
<DialogTrigger>
<Button />
<ModalOverlay>
<Modal>
<Dialog />
</Modal>
</ModalOverlay>
</DialogTrigger>
DialogTrigger
A DialogTrigger opens a dialog when a trigger element is pressed.
| Name | Type | |
|---|---|---|
children | ReactNode | |
Modal
A modal is an overlay element which blocks interaction with elements outside it.
| Name | Type | Default |
|---|---|---|
isEntering | boolean | Default: — |
| Whether the modal is currently performing an entry animation. | ||
isExiting | boolean | Default: — |
| Whether the modal is currently performing an exit animation. | ||
isDismissable | boolean | Default: false
|
| Whether to close the modal when the user interacts outside it. | ||
isKeyboardDismissDisabled | boolean | Default: false
|
| Whether pressing the escape key to close the modal should be disabled. | ||
shouldCloseOnInteractOutside | | Default: — |
| When user interacts with the argument element outside of the overlay ref, return true if onClose should be called. This gives you a chance to filter out interaction with elements that should not dismiss the overlay. By default, onClose will always be called on interaction outside the overlay ref. | ||
children | ChildrenOrFunction | Default: — |
| The children of the component. A function may be provided to alter the children based on component state. | ||
Default className: react-aria-ModalOverlay
| Render Prop | CSS Selector |
|---|---|
isEntering | CSS Selector: [data-entering]
|
| Whether the modal is currently entering. Use this to apply animations. | |
isExiting | CSS Selector: [data-exiting]
|
| Whether the modal is currently exiting. Use this to apply animations. | |
state | CSS Selector: — |
| State of the modal. | |
ModalOverlay
A ModalOverlay is a wrapper for a Modal which allows customizing the backdrop element.
| Name | Type | Default |
|---|---|---|
isEntering | boolean | Default: — |
| Whether the modal is currently performing an entry animation. | ||
isExiting | boolean | Default: — |
| Whether the modal is currently performing an exit animation. | ||
isDismissable | boolean | Default: false
|
| Whether to close the modal when the user interacts outside it. | ||
isKeyboardDismissDisabled | boolean | Default: false
|
| Whether pressing the escape key to close the modal should be disabled. | ||
shouldCloseOnInteractOutside | | Default: — |
| When user interacts with the argument element outside of the overlay ref, return true if onClose should be called. This gives you a chance to filter out interaction with elements that should not dismiss the overlay. By default, onClose will always be called on interaction outside the overlay ref. | ||
children | ChildrenOrFunction | Default: — |
| The children of the component. A function may be provided to alter the children based on component state. | ||
Default className: react-aria-ModalOverlay
| Render Prop | CSS Selector |
|---|---|
isEntering | CSS Selector: [data-entering]
|
| Whether the modal is currently entering. Use this to apply animations. | |
isExiting | CSS Selector: [data-exiting]
|
| Whether the modal is currently exiting. Use this to apply animations. | |
state | CSS Selector: — |
| State of the modal. | |
| CSS Variable |
|---|
--visual-viewport-height |
| The height of the Visual Viewport, i.e. space above the software keyboard. |
--page-height |
The height of the <body> element. Useful for sizing the modal backdrop. |
Dialog
A dialog is an overlay shown above other content in an application.
| Name | Type | |
|---|---|---|
children | ReactNode | | |
| Children of the dialog. A function may be provided to access a function to close the dialog. | ||
Default className: react-aria-Dialog