EXEPERTAI LAB

Research alpha

Time Machine
EXEPERTAI LAB
GALLERY / COLLECTION
← Browse Astryx gallery
Dialog·component·@astryxdesign/core

Alert Dialog

A modal dialog that asks the user to confirm a destructive action.

Open in Playground @astryxdesign/core/AlertDialog

Showcases and examples

2 documented examples

AlertDialog — Delete

A delete button that asks the user to confirm before deleting.

Preview loads on approachPreview loads on approach
Exact source · alert-dialog-delete-confirmation
// Copyright (c) Meta Platforms, Inc. and affiliates.

'use client';

import {
  AlertDialog,
  useImperativeAlertDialog,
} from '@astryxdesign/core/AlertDialog';

// Remove isInline for production — alert dialogs should be modal.
export default function AlertDialogDeleteConfirmation() {
  const alert = useImperativeAlertDialog();

  const alertProps = {
    title: 'Delete item?',
    description:
      'This action cannot be undone. The item and all its data will be permanently removed.',
    actionLabel: 'Delete',
  } as const;

  return (
    <>
      <AlertDialog
        isOpen
        isInline
        onOpenChange={() => {}}
        {...alertProps}
        onAction={() =>
          alert.show({...alertProps, onAction: () => alert.hide()})
        }
      />
      {alert.element}
    </>
  );
}

Usage

AlertDialog asks the user to confirm a destructive or irreversible action before it happens. Use it for things like deleting content, revoking access, or discarding unsaved changes.

It implements the WAI-ARIA APG Alert Dialog pattern: role="alertdialog", a title linked by aria-labelledby, a consequence description linked by aria-describedby, focus moved into the dialog on open and returned to the trigger on close, and no dismissal by clicking outside. Escape cancels.


AlertDialog passes its requested width through to Dialog, which clamps the surface to the container and dynamic viewport with token gutters. Generic Dialog footers should wrap, but Dialog does not own action semantics or order; consumer composition controls that. AlertDialog owns its confirmation semantics: above 640px, actions render horizontally and may move onto another row; at 640px and below, the destructive action appears above Cancel and both buttons fill the footer width. Button labels retain their standard single-line behavior. The breakpoint follows available width, not pointer or hover capability. The body scrolls when block space is constrained.


For cases where you want to show an alert without managing open state, use the useImperativeAlertDialog hook: call alert.show(options) and render alert.element in your tree.

  • Make the action button label specific: "Delete project" is better than "OK" or "Confirm".
  • Describe what will happen in the description so the user knows the consequences before confirming.
  • Keep the cancel button as the least-destructive focus target. On narrow screens the destructive action is visually and structurally above Cancel, but Cancel still receives initial focus.
  • Use concise, specific action labels. Above 640px, complete buttons may move onto another row; at 640px and below, the destructive action appears above Cancel and both buttons fill the footer width.
  • Use AlertDialog for non-destructive actions; use a standard Dialog instead.
  • Rely on color alone to signal danger; the action label itself should say what will happen.
  • Close the dialog from onAction before the work finishes; hold it open with isActionLoading and call onOpenChange(false) when the action settles.

Typed props

PropType and behavior
isOpenboolean · required
Whether the dialog is open.
onOpenChange(isOpen: boolean) => unknown · required
Visibility change callback.
titlestring · required
Dialog title. Linked via aria-labelledby.
descriptionstring · required
Consequence description. Linked via aria-describedby.
actionLabelstring · required
Action button label.
onAction() => unknown · required
Called when action button is clicked. Does NOT auto-close.
cancelLabelstring · default 'Cancel'
Cancel button label.
actionVariantButtonVariant · default 'destructive'
Action button variant.
isActionLoadingboolean
Shows loading spinner on the action button.
widthnumber | string · default 400
Requested dialog width. Dialog preserves this preferred width and clamps it to the container and dynamic viewport with token gutters.
isInlineboolean · default false
Renders alert dialog content inline without modal behavior. For documentation previews and showcases only. Not being a modal, the inline path renders role="group" instead of role="alertdialog".

Anatomy

Title · required

The question being asked. Renders as a level-2 heading and labels the dialog via aria-labelledby.

Description · required

What will happen if the user confirms. Linked to the dialog via aria-describedby.

Cancel button · required

Ghost button that dismisses without acting. Takes initial focus, and Escape does the same thing.

Action button · required

The confirming action. Destructive by default; shows a spinner while isActionLoading is set.

Backdrop · required

Overlay behind the dialog that blocks page interaction. Clicking it does not dismiss.

Theming

Targets

astryx-alert-dialog