Skip to content

Component · 11

Dialog

A modal panel on a flat veil, with a hard shadow and a stamp-like drop in. Built on Base UI, so focus is trapped, Escape closes it, and focus returns to the trigger.

Confirm

Always give it a title and a description: they name it for screen readers.

tsx
<Dialog>
  <DialogTrigger render={<Button />}>Delete project</DialogTrigger>
  <DialogContent>
    <DialogHeader>
      <DialogTitle>Delete project?</DialogTitle>
      <DialogDescription>
        This permanently removes the project and its files. This cannot be undone.
      </DialogDescription>
    </DialogHeader>
    <DialogFooter>
      <DialogClose render={<Button variant="ghost" />}>Cancel</DialogClose>
      <DialogClose render={<Button variant="primary" />}>Delete</DialogClose>
    </DialogFooter>
  </DialogContent>
</Dialog>

With a form

Focus lands on the first field. Any content works inside.

tsx
<Dialog>
  <DialogTrigger render={<Button variant="primary" />}>Invite</DialogTrigger>
  <DialogContent>
    <DialogHeader>
      <DialogTitle>Invite a teammate</DialogTitle>
      <DialogDescription>They will get an email with a link to join.</DialogDescription>
    </DialogHeader>
    <label>
      Email
      <Input type="email" placeholder="name@company.com" />
    </label>
    <DialogFooter>
      <DialogClose render={<Button variant="ghost" />}>Cancel</DialogClose>
      <Button variant="primary">Send invite</Button>
    </DialogFooter>
  </DialogContent>
</Dialog>

Props

PropTypeDefaultDescription
Dialog open / defaultOpen / onOpenChange-closedOpen it uncontrolled, or control it from state.
Dialog modalboolean | "trap-focus"trueModal blocks the page behind it and traps focus.
Dialog disablePointerDismissalbooleanfalseStop clicks on the veil from closing it.
DialogTrigger renderReactElement<button>Use your own button: render={<Button />}.
DialogContent showClosebooleantrueThe corner × button. Keep it for touch screen reader users.
DialogContent initialFocus / finalFocus--Choose which element gets focus on open / on close.
DialogTitle-requiredThe dialog's accessible name.
DialogDescription-recommendedThe dialog's accessible description.

Dialogs render in a portal at the end of <body>. If your app root creates its own stacking context, add isolation: isolate to it so the dialog always sits on top. The layers use --gu-z-overlay and --gu-z-popup.