Modal

A modal is an overlay element which blocks interaction with elements outside it.

Theme 
isDismissable 
isKeyboardDismissDisabled 
Example
Modal.tsx
Modal.css
import {DialogTrigger} from 'react-aria-components/Modal';
import {Modal} from './Modal';
import {Dialog, Heading} from './Dialog';
import {Form} from './Form';
import {TextField} from './TextField';
import {Button} from './Button';

function Example(props) {
  return (
    <DialogTrigger>
      <Button>Sign up…</Button>
      <Modal {...props}>
        <Dialog>
          <Heading slot="title">Subscribe to our newsletter</Heading>
          <p>Enter your information to subscribe to our newsletter and receive updates about new features and announcements.</p>
          <Form>
            <TextField autoFocus label="Name" placeholder="Enter your full name" />
            <TextField label="Email" placeholder="Enter your email" />
            <div style={{display: 'flex', gap: 8, alignSelf: 'end'}}>
              <Button slot="close" variant="secondary">Cancel</Button>
              <Button slot="close">Subscribe</Button>
            </div>
          </Form>
        </Dialog>
      </Modal>
    </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 {MenuTrigger, Menu, MenuItem} from './Menu';
import {Modal} from './Modal';
import {Dialog, Heading} 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} from 'react-aria-components/Modal';
import {Modal} from './Modal';
import {Dialog, Heading} 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>
const CustomTrigger = React.forwardRef((props, ref) => (
  <button {...props} ref={ref} />
));

API

UnderlayModal
<DialogTrigger>
  <Button />
  <ModalOverlay>
    <Modal>
      <Dialog>
        <Heading slot="title" />
        <Text slot="description" />
        <Button slot="close" />
      </Dialog>
    </Modal>
  </ModalOverlay>
</DialogTrigger>

DialogTrigger

A DialogTrigger opens a dialog when a trigger element is pressed.

NameType
childrenReactNode

A modal is an overlay element which blocks interaction with elements outside it.

NameTypeDefault
isEnteringbooleanDefault: —

Whether the modal is currently performing an entry animation.

isExitingbooleanDefault: —

Whether the modal is currently performing an exit animation.

isDismissablebooleanDefault: false

Whether to close the modal when the user interacts outside it.

isKeyboardDismissDisabledbooleanDefault: false

Whether pressing the escape key to close the modal should be disabled.

shouldCloseOnInteractOutside(element: Element) => booleanDefault: —

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<>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 PropCSS Selector
isEnteringCSS Selector: [data-entering]
Whether the modal is currently entering. Use this to apply animations.
isExitingCSS Selector: [data-exiting]
Whether the modal is currently exiting. Use this to apply animations.
stateCSS Selector: —
State of the modal.

ModalOverlay

A ModalOverlay is a wrapper for a Modal which allows customizing the backdrop element.

NameTypeDefault
isEnteringbooleanDefault: —

Whether the modal is currently performing an entry animation.

isExitingbooleanDefault: —

Whether the modal is currently performing an exit animation.

isDismissablebooleanDefault: false

Whether to close the modal when the user interacts outside it.

isKeyboardDismissDisabledbooleanDefault: false

Whether pressing the escape key to close the modal should be disabled.

shouldCloseOnInteractOutside(element: Element) => booleanDefault: —

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<>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 PropCSS Selector
isEnteringCSS Selector: [data-entering]
Whether the modal is currently entering. Use this to apply animations.
isExitingCSS Selector: [data-exiting]
Whether the modal is currently exiting. Use this to apply animations.
stateCSS Selector: —
State of the modal.
CSS Variable
--visual-viewport-height
The height of the Visual Viewport, i.e. space above the software keyboard.
--visual-viewport-width
The width of the Visual Viewport.
--page-height
The height of the <body> element. Useful for sizing and positioning the modal backdrop.
--page-width
The width of the <body> element. Useful for sizing and positioning the modal backdrop.

Dialog

A dialog is an overlay shown above other content in an application.

NameType
childrenReactNode | (opts: ) => ReactNode

Children of the dialog. A function may be provided to access a function to close the dialog.

isEnteringboolean

Whether the dialog is currently performing an entry animation. Focus is not moved into the dialog until the animation completes, since moving the screen reader cursor may cause scrolling that interrupts the animation.

Default className: react-aria-Dialog