Skip to content

Latest commit

 

History

History
198 lines (164 loc) · 6.19 KB

File metadata and controls

198 lines (164 loc) · 6.19 KB

import {Layout} from '../../src/Layout'; export default Layout;

import docs from 'docs:react-aria-components'; import vanillaDocs from 'docs:vanilla-starter/Modal'; import '../../tailwind/tailwind.css'; import Anatomy from '@react-aria/overlays/docs/modal-anatomy.svg'; import {InlineAlert, Heading, Content} from '@react-spectrum/s2'

export const tags = ['dialog', 'popup', 'overlay'];

Modal

{docs.exports.Modal.description}

```tsx render docs={vanillaDocs.exports.Modal} links={vanillaDocs.links} props={['isDismissable', 'isKeyboardDismissDisabled']} type="vanilla" files={["starters/docs/src/Modal.tsx", "starters/docs/src/Modal.css"]} "use client"; import {DialogTrigger, Heading} from 'react-aria-components'; import {Modal} from 'vanilla-starter/Modal'; import {Dialog} from 'vanilla-starter/Dialog'; import {Button} from 'vanilla-starter/Button'; import {TextField} from 'vanilla-starter/TextField';

function Example(props) { return ( Sign up… <Modal {...props}/* PROPS */>

Sign up Submit ); }


```tsx render docs={vanillaDocs.exports.Modal} links={vanillaDocs.links} props={['isDismissable', 'isKeyboardDismissDisabled']} type="tailwind" files={["starters/docs/src/Modal.tsx"]}
"use client";
import {DialogTrigger, Heading} from 'react-aria-components';
import {Modal} from 'tailwind-starter/Modal';
import {Dialog} from 'tailwind-starter/Dialog';
import {Button} from 'tailwind-starter/Button';
import {TextField} from 'tailwind-starter/TextField';

function Example(props) {
  return (
    <DialogTrigger>
      <Button>Sign up…</Button>
      <Modal {...props}/* PROPS */>
        <Dialog>
          <form>
            <Heading slot="title">Sign up</Heading>
            <TextField autoFocus label="First Name" />
            <TextField label="Last Name" />
            <Button slot="close">Submit</Button>
          </form>
        </Dialog>
      </Modal>
    </DialogTrigger>
  );
}

Sheet

Overlays such as trays, drawers, and sheets can be built using a Modal with custom entry and exit animations.

"use client";
import {DialogTrigger, Heading} from 'react-aria-components';
import {Sheet} from 'vanilla-starter/Sheet';
import {Button} from 'vanilla-starter/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).

"use client";
import {useState} from 'react';
import {Heading} from 'react-aria-components';
import {MenuButton, MenuItem} from 'vanilla-starter/Menu';
import {Modal} from 'vanilla-starter/Modal';
import {Dialog} from 'vanilla-starter/Dialog';
import {Button} from 'vanilla-starter/Button';

function Example() {
  let [isOpen, setOpen] = useState(false);

  return (
    <>
      <MenuButton label="Menu">
        <MenuItem onAction={() => setOpen(true)}>Open dialog…</MenuItem>
      </MenuButton>
      <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.

"use client"
import {Pressable, DialogTrigger, Heading} from 'react-aria-components';
import {Modal} from 'vanilla-starter/Modal';
import {Dialog} from 'vanilla-starter/Dialog';
import {Button} from 'vanilla-starter/Button';

<DialogTrigger>
  {/*- begin highlight -*/}
  <Pressable>
    <span role="button">Custom trigger</span>
  </Pressable>
  {/*- end highlight -*/}
  <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 Any `` child must have an [interactive ARIA role](https://www.w3.org/TR/wai-aria-1.2/#widget_roles) 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} />
));

API

<DialogTrigger>
  <Button />
  <ModalOverlay>
    <Modal>
      <Dialog />
    </Modal>
  </ModalOverlay>
</DialogTrigger>

DialogTrigger

Modal

ModalOverlay

<PropTable component={docs.exports.ModalOverlay} links={docs.links} showDescription cssVariables={{ '--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