Overlays
Dialog
A centered modal over a scrim, with a title bar and close button, a body and a footer. Three widths, built on Radix Dialog.
- Source
- src/components/ui/dialog.tsx
- Figma
- Modal · size (sm, md, lg) × type (default, destructive).
Usage
Included in the GliaKit boilerplate. Import it where you need it:
import { Dialog, DialogTrigger, DialogClose, DialogContent, DialogBody, DialogFooter,} from "@/components/ui/dialog";When to use
- Confirming an action that needs a deliberate decision, such as deleting a project or revoking a key.
- Short, focused tasks that should not lose the page behind them: renaming, inviting a teammate, creating an item.
- Use sm for confirmations, md for short forms and lg for richer content like a settings panel or a preview.
- For long forms or detail views that people compare against the page, use a Sheet.
- For a passing status message, use a Toast. Do not interrupt people for something they do not need to act on.
- For a list of actions on an item, use a Dropdown menu.
Examples
Sizes
sm (384px) for confirmations, md (448px) for short forms, lg (672px) for richer content.
Destructive confirmation
The destructive type in Figma is a sm dialog with a destructive Button. Say exactly what will be lost.
Controlled, with a form
Control open with onOpenChange and close the dialog yourself when the form submits.
API reference
Dialog
Radix Dialog.Root. Holds the open state; uncontrolled by default.
| Prop | Type | Default | Description |
|---|---|---|---|
| open | boolean | - | Controlled open state. |
| defaultOpen | boolean | false | Initial open state when uncontrolled. |
| onOpenChange | (open: boolean) => void | - | Called when the dialog opens or closes, including Escape, a scrim click and the close button. |
| modal | boolean | true | When true, the rest of the page is inert and focus is trapped inside. |
DialogTrigger
Radix Dialog.Trigger. Opens the dialog. Use asChild to render your own Button.
| Prop | Type | Default | Description |
|---|---|---|---|
| asChild | boolean | false | Merge trigger behavior into the child element instead of rendering a <button>. |
DialogClose
Radix Dialog.Close. Closes the dialog when clicked. The title bar already includes one (the X button).
| Prop | Type | Default | Description |
|---|---|---|---|
| asChild | boolean | false | Merge close behavior into the child element, e.g. a Cancel Button. |
DialogContent
Renders the portal, the scrim and the surface with a title bar and X close button. Extends Radix Dialog.Content props (onEscapeKeyDown, onPointerDownOutside, onOpenAutoFocus, aria-describedby, className).
| Prop | Type | Default | Description |
|---|---|---|---|
| title | string | - | Required. Rendered as the Radix Dialog.Title, so it labels the dialog for screen readers. |
| size | "sm" | "md" | "lg" | "md" | Max width: sm 384px, md 448px, lg 672px, matching the Figma Modal variants. |
| children | React.ReactNode | - | Usually a DialogBody followed by a DialogFooter. |
DialogBody
Padded content area with muted small text. Extends native div attributes.
| Prop | Type | Default | Description |
|---|---|---|---|
| className | string | - | Extra classes, merged with the defaults. |
DialogFooter
Right-aligned row of actions. Extends native div attributes.
| Prop | Type | Default | Description |
|---|---|---|---|
| className | string | - | Extra classes, merged with the defaults. |
Accessibility
- Built on Radix Dialog: focus moves into the dialog on open, is trapped while it is open and returns to the trigger on close.
- Escape and a click on the scrim close the dialog. The rest of the page is hidden from assistive technology while it is open.
- The required title prop is wired to Dialog.Title, so the dialog has an accessible name.
- No Dialog.Description is rendered. Point aria-describedby on DialogContent at the id of your body text, or pass aria-describedby={undefined} to opt out and silence the Radix dev warning.
- The X button has aria-label="Close".