Dialog

uistable

Dialog — extracted 1:1 from WEM-App.

npx shadcn add @krawma/dialog

npm: lucide-react@^1.22.0, radix-ui@^1.6.1 · registry: @krawma/button, @krawma/utils

Preview

States
openclosed
Keyboard
EscapeTab
Depends on
utilsbutton

Purpose

A modal overlay for focused tasks or content that requires the user's attention before returning to the page (forms, details, confirmations-with-input). For a yes/no confirmation of a destructive action use alert-dialog; for side panels / mobile off-canvas use sheet.

Anatomy

Dialog (root, controls open state) › DialogTriggerDialogPortalDialogOverlay + DialogContent (contains DialogHeader [DialogTitle, DialogDescription], body, DialogFooter, and a DialogClose).

Style

  • No variants — one modal treatment. DialogContent is centered, width-capped, and token-styled (bg-background, border, elevation). Layout inside is the consumer's job (use DialogHeader/DialogFooter).

Behavior & functionality

  • Controlled (open + onOpenChange) or uncontrolled (via DialogTrigger).
  • Opening renders a portal + overlay and traps focus; closing returns focus to the trigger.
  • Closes on: DialogClose, overlay click, and Escape.

Accessibility

  • Role dialog, modal; DialogTitle is required as the accessible name (use a visually-hidden title if the design has none). DialogDescription provides aria-describedby.
  • Focus is trapped while open and cycles with Tab; Escape closes.
  • Background content is inert while open.

Do / Don't

  • ✅ Always include a DialogTitle (visually hidden if needed).
  • ✅ Use for tasks the user must complete or dismiss deliberately.
  • ❌ Don't nest a dialog inside a dialog; prefer a single flow or a step pattern.
  • ❌ Don't use a dialog for simple confirmations — that's alert-dialog.