ACTIONS & SURFACES

Dialog

Modal dialog wrapping Radix Dialog. Two semantic modes via severity: default (informational, overlay closes) and alert (destructive confirmation, overlay does NOT close). A separate tone prop flips the offset shadow to the destructive token.

Import

1import {
2  Dialog,
3  DialogTrigger,
4  DialogContent,
5  DialogHeader,
6  DialogTitle,
7  DialogDescription,
8  DialogFooter,
9  DialogClose,
10} from 'damo-ui'

Default — informational

Standard modal. Click on the overlay or press Esc to dismiss.

1<Dialog>
2  <DialogTrigger asChild>
3    <Button variant="primary">Open dialog</Button>
4  </DialogTrigger>
5  <DialogContent>
6    <DialogHeader>
7      <DialogTitle>Confirm action</DialogTitle>
8      <DialogDescription>
9        This dialog is built on Radix Primitives, so focus is trapped while open
10        and Esc closes it.
11      </DialogDescription>
12    </DialogHeader>
13    <DialogFooter>
14      <DialogClose asChild>
15        <Button variant="ghost">Cancel</Button>
16      </DialogClose>
17      <DialogClose asChild>
18        <Button variant="primary">Confirm</Button>
19      </DialogClose>
20    </DialogFooter>
21  </DialogContent>
22</Dialog>

severity="alert" — destructive confirmation

Flip the role to alertdialog, block overlay-click dismissal, and remove the X button — the user must explicitly choose an action. Pair with tone="danger" to recolour the Memphis shadow.

1<Dialog>
2  <DialogTrigger asChild>
3    <Button variant="destructive">Delete account</Button>
4  </DialogTrigger>
5  <DialogContent severity="alert" tone="danger">
6    <DialogHeader>
7      <DialogTitle>Delete account?</DialogTitle>
8      <DialogDescription>
9        This action cannot be undone. Your data will be permanently removed.
10      </DialogDescription>
11    </DialogHeader>
12    <DialogFooter>
13      {/* Place Cancel first in DOM order so it gets default focus. */}
14      <DialogClose asChild>
15        <Button variant="ghost">Cancel</Button>
16      </DialogClose>
17      <DialogClose asChild>
18        <Button variant="destructive">Delete</Button>
19      </DialogClose>
20    </DialogFooter>
21  </DialogContent>
22</Dialog>

When to switch to alert mode

  • The action is destructive (delete, archive, sign out) and must NOT be cancelled accidentally by clicking outside.
  • You want screen readers to announce the dialog as alertdialog (more interruptive than the regular dialog role).
  • Otherwise leave severity at default.

Dialog (root) API

Dialog props
PropTypeDefaultDescription
openbooleanControlled open state. Pair with onOpenChange.
defaultOpenbooleanfalseUncontrolled initial open state.
onOpenChange(open: boolean) => voidFires whenever the open state changes.
modalbooleantrueWhen true (default), focus is trapped inside the dialog and outside content is inert.

DialogContent props

DialogContent severity/tone
PropTypeDefaultDescription
severity'default' | 'alert''default'default is role="dialog"; clicks on the overlay close it. alert flips to role="alertdialog", blocks overlay-click dismissal and hides the X button — the user must click an explicit footer action. Use for destructive or otherwise irreversible flows.
tone'default' | 'danger''default'Visual override. danger swaps the Memphis offset shadow to the destructive token, telegraphing high-stakes actions. Orthogonal to severity — combine freely.
hideClosebooleanfalseHide the built-in X close button. Already implicit when severity="alert" — alert mode never renders the X.

Accessibility

  • Always pair DialogTitle with the content; screen readers announce it as the dialog name.
  • Add DialogDescription for non-obvious actions; it is wired as aria-describedby.
  • Use DialogClose on close buttons so they close the dialog and return focus to the trigger.
  • In severity="alert", place Cancel first in the footer DOM order so Radix gives it default focus — the layout enforces column-reverse on small viewports so Cancel sits on top there.
Dialog — Damo UI