skrewww

Containers & Overlays

Dialog

Dialog is a modal overlay that interrupts workflow for focused attention, information, or a decision.

Single component

stableReact AvailableFigma AvailableDocs Partial
React last updated
2026-07-11
Documentation last updated
2026-06-01
Accessibility target
WCAG 2.2 AA (target)
Version
1.0.0

Known open questions

  • Destructive alertdialog variant not confirmed as a separate Figma pattern — use Dialog with danger actions for now.
  • Full-screen mobile Dialog layout not confirmed — viewport padding and max-height cap used instead.
  • No canonical Figma Dialog COMPONENT_SET — a future Figma build should follow React DialogBody/DialogFooter composition, not instructional placeholders.

Live preview

Modal dialog with background inert, focus trap, and backdrop dismissal.

Informational

Long content

Purpose

A modal window that interrupts the current flow, requiring the user's attention or a decision before returning to the page.

Anatomy

Dialog = scrim + dialog surface + title + optional description + body + optional footer + close control.

Variants and states

modal

When to use

Destructive action confirmation, a focused task, collecting required information before proceeding.

When not to use

Non-critical supplementary information — use Popover.

Accessibility

Must trap focus while open, return focus to trigger on close, support Escape-to-close, role="dialog" with aria-modal="true".

Keyboard behavior

Escape closes the topmost overlay. Tab cycles within Dialog. Background content is inert while open. Focus returns to trigger or finalFocusRef on close.

Common mistakes

Not trapping focus, allowing Tab to escape to obscured page content behind the scrim.

Properties

Compound React API: DialogHeader/Title/Description/Close stay structured; DialogBody and DialogFooter accept arbitrary ReactNode. No canonical Figma Dialog COMPONENT_SET — React composition is the source of truth. Portal content unmounts when closed.

What is the difference between Dialog and Popover?

Dialog is modal, inerts the background, and traps focus. Popover is non-blocking supplementary content attached to a trigger.

Should clicking the overlay close a Dialog?

Yes when closeOnOverlayClick is enabled and the pointer down occurs on the backdrop, not when dragging out of content.

Why does a Dialog require an accessible title?

Modal dialogs must expose an accessible name through DialogTitle or aria-label so screen-reader users know what interrupted the page.

How does nested overlay Escape work?

Escape closes only the topmost overlay. Tooltip inside Popover inside Dialog closes in that order.

Does Dialog body/footer accept arbitrary composition?

Yes. DialogBody and DialogFooter take ReactNode children — forms, alerts, multiple buttons, or custom layout. There is no Figma instructional placeholder in React. Closed Dialogs unmount portal content by design (focus trap / portal lifecycle), unlike Accordion’s CSS-hidden panels.

Tokens used

component/card/surfacecomponent/radius/container

Component API

PropTypeDefaultDescription
openbooleanControlled open state.
defaultOpenbooleanInitial open state.
onOpenChange(open: boolean, reason?: DialogCloseReason) => voidClosure requests always emit false with a reason.
closeOnOverlayClickbooleantrueBackdrop dismissal.
DialogBody childrenReact.ReactNodeArbitrary body composition.
DialogFooter childrenReact.ReactNodeArbitrary action/footer composition.
initialFocusRefRefObject<HTMLElement>Preferred initial focus target on DialogContent.
finalFocusRefRefObject<HTMLElement>Preferred focus restoration target on close.

React example

Copy React example
"use client";

import {
  Dialog,
  DialogBody,
  DialogClose,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@/components/ui/Dialog";
import { Button } from "@/components/ui/Button";

export function Example() {
  return (
    <Dialog>
      <DialogTrigger>
        <Button type="button">Open dialog</Button>
      </DialogTrigger>
      <DialogContent>
        <DialogHeader>
          <DialogTitle>Save changes?</DialogTitle>
          <DialogClose />
        </DialogHeader>
        <DialogDescription>Review updates before publishing documentation.</DialogDescription>
        <DialogBody>
          <p>Dialog body content.</p>
        </DialogBody>
        <DialogFooter>
          <Button type="button" variant="secondary">Cancel</Button>
          <Button type="button">Save</Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}