Rime

AlertDialog

A short interrupting confirm with Cancel and one action; focus starts on Cancel and the scrim never dismisses it.

AlertDialog asks one question with two answers. It is role="alertdialog": focus starts on Cancel, so a stray Enter never confirms; Esc cancels; Tab is trapped; a click on the scrim does nothing, because the choice must be made.

tone="danger" draws a warning tile and the danger button. busy locks both buttons and shows a spinner on the action while it runs. The header keeps one left edge. It wears the --modal-* glass, so it matches Modal in every preset.

inline renders the open panel in the page flow: no portal, scrim, focus trap, scroll lock or outside-click listener. It exists for docs, previews and static mock-ups; never ship it as the live overlay.

Installation

npx shadcn@latest add KezLahd/rime/alert-dialog

Also installs: base, button, icon, scroll-area.

Usage

import { AlertDialog } from "@/components/ui";

<AlertDialog
  open={open}
  tone="danger"
  title="Delete Project Atlas?"
  description="Its 12 tasks and 48 files are deleted with it."
  actionLabel="Delete project"
  onCancel={() => setOpen(false)}
  onAction={remove}
  busy={pending}
/>

Examples

Open

Delete Project Atlas?

Its 12 tasks and 48 files are deleted with it. This cannot be undone.

Danger, with a busy state

Default tone

API

Generated from the component's TypeScript types and JSDoc (scripts/gen-ui-registry.mjs), so it always matches the source.

AlertDialog

AlertDialog props
PropTypeDefaultDescription
openRequiredboolean
onCancelRequired() => voidCancel, Esc. There is no scrim click: the choice must be made.
onActionRequired() => voidThe action button. Close the dialog yourself once it has run.
titleRequiredReactNode
descriptionReactNode
actionLabelRequiredstringA verb plus the object: "Delete project", never "OK".
cancelLabelstring
tone"default" | "danger"danger draws the action in the danger fill and a warning tile.
busybooleanThe action is in flight: both buttons lock and the action shows a spinner.
busyLabelstring
childrenReactNodeExtra content under the description: a short list of what changes.
inlinebooleanRender the open panel in the page flow: no portal, scrim, focus trap or scroll lock (docs, previews).
classNamestring

Theme tokens

Per-component tokens are undeclared by default, so the default shown is the fallback the CSS uses. Set one at :root (or in theme.css) to restyle every instance. Live values are read from this page, so they follow the Rime Studio.

AlertDialog per-component tokens
TokenDefaultLive value
--alert-dialog-radiusvar(--r-xl)…
--alert-dialog-title-size18px…
--alert-dialog-width440px…

System tokens it reads

AlertDialog system tokens
TokenDefaultLive value
--danger-filltokens.css…
--danger-inktokens.css…
--danger-linetokens.css…
--densitytokens.css…
--durtokens.css…
--dur-slowtokens.css…
--easetokens.css…
--ease-outtokens.css…
--font-displaytokens.css…
--ink-bodytokens.css…
--ink-headingtokens.css…
--ink-secondarytokens.css…
--modal-blurtokens.css…
--modal-scrimtokens.css…
--modal-scrim-blurtokens.css…
--modal-shadowtokens.css…
--modal-surfacetokens.css…
--r-mdtokens.css…
--r-xltokens.css…
--text-bodytokens.css…
--text-smalltokens.css…
--tracking-displaytokens.css…
--z-modaltokens.css…

Accessibility

  • role="alertdialog" with aria-modal, labelled by the title and described by the description, so both are read on open.
  • Initial focus is Cancel. Esc cancels; the scrim does not.
  • busy sets aria-busy and disables both buttons until the action settles.

Do and don't

Do

  • Name the action with a verb and the object: "Delete project".
  • Say in the description what is lost.

Don't

  • Don't use it for forms; that is Modal.
  • Don't use it for very large irreversible changes; that is TypeToConfirmModal.
  • Never label the action "OK" or "Yes".

For AI agents

This page as markdown, rendered from the same registry entry. Point an agent at it (or add .md to this page's URL), or at /llms.txt for the index.

Open alert-dialog.md

Related: modal, type-to-confirm