Skip to content
SuperCoach

Components · Overlays

Alert dialog

Beta

Confirms a destructive action, such as removing a client.

When to use

  • To confirm an action that can't be undone: remove a client, delete a program that clients are on, cancel a subscription.
  • To confirm leaving with unsaved work: "Discard changes?"
  • When the consequence is serious enough that the coach must stop and choose.

When not to use

  • For actions that can be undone: do them right away and offer Undo in a Toast. Confirming every delete teaches coaches to click through.
  • For a task with fields, such as editing a meal: use a Dialog.
  • To show information with only an OK button: use an Alert on the page.

Anatomy

Open the alert dialog above to see its parts: the scrim over the page; the panel with an optional media icon, a title that asks the question, a description of the consequence, and a footer with Cancel and the action (action last). There is no close button: the coach has to choose.

Variants

VariantUse for
Destructive action (variant="destructive" on AlertDialogAction)Removing or deleting data, cancelling a subscription
Default actionConfirmations that aren't destructive, such as publishing a program to 30 clients
With media (AlertDialogMedia)An icon that makes the subject clear at a glance, such as a card for billing

States

StateWhat changesToken
Opening, closingFade and slight zoom; instant with reduced motionduration-(--duration-base)
OpenScrim over the page, panel on the modal layerbg-foreground, opacity-(--opacity-overlay), z-(--z-modal)
FocusStarts on Cancel; returns to the trigger on closering-ring/50
Click outsideNothing happens. Only Cancel, the action or Escape close itnone

The scrim color is a default: there is no overlay color token (QUESTIONS Q6).

Sizes

SizeWidthUse for
defaultUp to max-w-lg; text aligns to the start from the sm breakpointMost confirmations, with a description of a sentence or two
smmax-w-xs; centered text, buttons side by sideShort questions with a one-line description, such as "Discard changes?"

Usage guidelines

  • The action button repeats the verb in the title: "Remove Sara Al-Otaibi?" → Remove client.
  • Use the destructive style for the action only. Cancel stays outline.
  • Say what will be lost and whether it can be undone. If billing changes, say when.
  • When "Cancel" would be ambiguous, as in cancelling a subscription, name both choices: "Keep subscription" and "Cancel subscription".
Do.Two clear choices. The destructive one is red and last.
Don't.Is Cancel cancelling the subscription or the dialog? And Yes doesn't say what happens.

Content guidelines

  • Title: a question with the verb and the object, sentence case: "Remove Sara Al-Otaibi?", "Discard changes?"
  • Description: the consequence in one or two sentences. "This can't be undone." only when it's true.
  • Buttons: Cancel (or "Keep …") and a specific verb. Never "OK", "Yes" or "Confirm".
  • Arabic: the title as a verbal noun with a question mark: "إزالة سارة العتيبي؟". Buttons use the same verbal noun: "إزالة العميل".

Accessibility

KeyDoes
Enter or Space on the triggerOpens the alert dialog; focus goes to Cancel
Tab / Shift+TabMoves between Cancel and the action only; focus is trapped
Enter or SpaceActivates the focused button
EscapeCloses it, the same as Cancel, and returns focus to the trigger
  • Rendered as role="alertdialog" with aria-modal, labelled by the title and described by the description. A screen reader announces "Remove Sara Al-Otaibi?, alert dialog, Her program, check-ins and progress photos will be deleted. This can't be undone." and then "Cancel, button".
  • Focus starts on Cancel, the safe choice, so pressing Enter by habit doesn't delete anything.
  • Clicking the scrim doesn't close it, so a stray click can't be read as a choice.
  • Always include an AlertDialogTitle and an AlertDialogDescription.

RTL

The footer aligns to the end, so Cancel and the action sit on the left in RTL, with the action last (leftmost). In the default size, the title and description align to the start (right). In sm, they are centered and the two buttons share the row, Cancel at the start. The panel is centered in both directions.

Tokens used

Read from components/ui/alert-dialog.tsx at build time, so this list changes when the component does. Opacity modifiers such as /90 are shadcn hover and focus tints on top of the token.

Semantic color tokens used by this component
TokenUtilitiesSuperCoachCoach
--backgroundbg-backgroundwhitewhite
--foregroundbg-foregroundneutral-950neutral-950
--mutedbg-mutedneutral-100neutral-100
--muted-foregroundtext-muted-foregroundneutral-600neutral-600
  • Layerz-(--z-modal)
  • Layerz-(--z-overlay)
  • Motionduration-(--duration-base)
  • Opacityopacity-(--opacity-overlay)
  • Radiusrounded-lg
  • Radiusrounded-md
  • Shadowshadow-lg
  • Typetext-lg
  • Typefont-semibold
  • Typetext-sm

Props

<AlertDialog>

Also takes every prop of Radix AlertDialog.Root

No props of its own.

<AlertDialogTrigger>

Also takes every prop of Radix AlertDialog.Trigger

No props of its own.

<AlertDialogContent>

Also takes every prop of Radix AlertDialog.Content

AlertDialogContent props
PropTypeDefault
size?"default" | "sm""default"

<AlertDialogHeader>

Also takes every prop of <div>

No props of its own.

<AlertDialogFooter>

Also takes every prop of <div>

No props of its own.

<AlertDialogTitle>

Also takes every prop of Radix AlertDialog.Title

No props of its own.

<AlertDialogDescription>

Also takes every prop of Radix AlertDialog.Description

No props of its own.

<AlertDialogMedia>

Also takes every prop of <div>

No props of its own.

<AlertDialogAction>

Also takes every prop of Radix AlertDialog.Action

AlertDialogAction props
PropTypeDefault
variant?from <Button>"default"
size?from <Button>"default"

<AlertDialogCancel>

Also takes every prop of Radix AlertDialog.Cancel

AlertDialogCancel props
PropTypeDefault
variant?from <Button>"outline"
size?from <Button>"default"

AlertDialogCancel and AlertDialogAction also take Button's variant and size. Cancel defaults to outline, the action to default.

Replaces in coach-admin

From the read-only audit of coach-admin: 90 style values, 111 uses.

coach-admin's confirmation modals (feature changes, deleting progress images, bulk status changes, exports, and the Bootstrap .confirmation-modal) become this component.

Classes and selectors

  • .feature-confirm-modal__row5
  • .feature-confirm-modal__feature-icon4
  • .feature-confirm-modal__meta-sep3
  • .feature-confirm-modal__feature-name3
  • .error-boundary-report-confirmation3
  • .feature-confirm-modal__foot3
  • .confirmation-modal .modal-footer .btn-danger, .confirmation2
  • .feature-confirm-modal__badge2
  • .confirm-cancel-button2
  • .feature-confirm-modal__subtitle2
  • .feature-confirm-modal__feature-meta2
  • .feature-confirm-modal__head2

Files

  • src/reusableComponents/features/FeatureChangeConfirmModal.scss69
  • src/reusableComponents/DeleteImagesModal/DeleteImagesModal.scss26
  • src/views/User/components/ExportConfirmationModal.scss3
  • src/views/User/components/clients-list/BulkStatusConfirmBody.scss2
  • src/reusableComponents/DeleteImagesModal/DeleteImagesModal.tsx1

The inventory lists the first 12 locations of each value, so file counts are a lower bound.

SCSS variables in these styles

  • $subtitle-text-color→ --muted-foreground
  • $border-strong-color→ --border-strong
  • $light-primary-colornot a color: spacing, size or layout
  • $light-surface-bg→ --muted
  • $danger-text-color→ --destructive-text
  • $danger-bg-color→ --destructive-subtle
  • $spacing-2xsnot a color: spacing, size or layout
  • $border-color→ --border
  • $success-color→ nearest green-500 (no semantic token)
  • $spacing-mdnot a color: spacing, size or layout
  • $spacing-xsnot a color: spacing, size or layout
  • $spacing-smnot a color: spacing, size or layout

Dialog, Button, Toast.