Skip to main content

Dialog

Blocks the page with one focused task the user must finish or dismiss.

import { Dialog } from "@/fragments/ui";Source

Preview

<Dialog>
  <Dialog.Trigger asChild>
    <Button>Open dialog</Button>
  </Dialog.Trigger>
  <Dialog.Content>
    <Dialog.Close />

Installation

npx @usefragments/cli add dialog

Writes src/fragments/ui/components/Dialog plus what it imports, the globals stylesheet, and .fragments/registry-lock.json, then prints the packages to add. No account, no key.

Your own registry: publish from Fragments Cloud and add --registry org/name. Connect a workspace.

Anatomy

Dialog is a compound: import the root and reach its parts through dot notation.

  • Dialog.Trigger
  • Dialog.Content
  • Dialog.Close
  • Dialog.Header
  • Dialog.Title
  • Dialog.Description
  • Dialog.Body
  • Dialog.Footer

Header, body, and footer in the standard layout.

<Dialog>
  <Dialog.Trigger asChild>
    <Button>Open dialog</Button>
  </Dialog.Trigger>
  <Dialog.Content>
    <Dialog.Close />
    <Dialog.Header>
      <Dialog.Title>Dialog title</Dialog.Title>
      <Dialog.Description>Focused supporting content.</Dialog.Description>
    </Dialog.Header>
    <Dialog.Body>Dialog body</Dialog.Body>
    <Dialog.Footer>
      <Dialog.Close asChild>
        <Button variant="soft">Close</Button>
      </Dialog.Close>
    </Dialog.Footer>
  </Dialog.Content>
</Dialog>

Examples

Confirmation

Names the consequence before an irreversible action.

<Dialog>
  <Dialog.Trigger asChild>
    <Button variant="solid" tone="danger">Delete item</Button>
  </Dialog.Trigger>
  <Dialog.Content>
    <Dialog.Header>

Large

Wider surface for denser content.

<Dialog>
  <Dialog.Trigger asChild>
    <Button>Open large dialog</Button>
  </Dialog.Trigger>
  <Dialog.Content width="lg">
    <Dialog.Close />

No Initial Focus

Skips autofocus when you place focus yourself.

<Dialog>
  <Dialog.Trigger asChild>
    <Button variant="soft">Open settings</Button>
  </Dialog.Trigger>
  <Dialog.Content initialFocus={false}>
    <Dialog.Header>

Long Title

A wrapping title keeps the close control reachable.

<Dialog>
  <Dialog.Trigger asChild>
    <Button>Open long title dialog</Button>
  </Dialog.Trigger>
  <Dialog.Content>
    <Dialog.Close />

API

Component props
Prop
Type
Default
Description
childrenRequirednodeNot set
defaultOpenbooleanNot setDefault open state
modalbooleantrueWhether the dialog blocks interaction with the rest of the page.
onOpenChangefunctionNot setCalled when open state changes
openbooleanNot setControlled open state

Accessibility

  • Traps focus while open
  • Escape closes
  • Focus returns to the trigger on close
  • role="dialog" with title and description wired to aria attributes

Guidance

Use when

  • Confirming something irreversible
  • Collecting input the user must finish in one pass
  • Content that needs acknowledgment before continuing
  • Isolating a step in a longer workflow

Avoid when

  • A short hint (use Tooltip)
  • A list of actions (use Menu)
  • Contextual content that should not block (use Popover)
  • Feedback the user does not act on (use Toast or Alert)

Do not use a Dialog for a non-blocking notification.

Don’t

<Dialog>Saved</Dialog>

Do

<Alert tone="success">
  <Alert.Icon />
  <Alert.Body>
    <Alert.Title>Changes saved</Alert.Title>
    <Alert.Content>Your settings are up to date.</Alert.Content>
  </Alert.Body>
</Alert>

Do not omit an accessible title and explicit close action from a Dialog.

Don’t

<Dialog><Dialog.Content>Focused task</Dialog.Content></Dialog>

Do

<Dialog defaultOpen>
  <Dialog.Content>
    <Dialog.Title>Account settings</Dialog.Title>
    <Dialog.Body>Update your workspace preferences.</Dialog.Body>
    <Dialog.Close>Close</Dialog.Close>
  </Dialog.Content>
</Dialog>
  • PopoveralternativeUse Popover for non-modal contextual content
  • MenualternativeUse Menu for action lists
  • AlertsiblingUse Alert for inline notifications

Next steps