AlertDialog

Alert dialogs require an explicit response before a consequential action proceeds.

Overview and decision boundary

Use AlertDialog when a destructive or difficult-to-reverse action must pause for one explicit response.

Do not hide side effects, default focus to a destructive action, or put multi-step workflows in AlertDialog.

import * as React from 'react';import { AlertDialog, AlertDialogAction, AlertDialogBackdrop, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, Button } from '@nerio-ui/ui/client';function DeleteProjectDialog() {  const cancelRef = React.useRef<HTMLButtonElement>(null);  return (    <AlertDialog>      <AlertDialogTrigger render={<Button variant="danger">Delete project</Button>} />      <AlertDialogPortal>        <AlertDialogBackdrop />        <AlertDialogContent initialFocus={cancelRef}>          <AlertDialogHeader>            <AlertDialogTitle>Delete project?</AlertDialogTitle>            <AlertDialogDescription>This permanently removes the project and cannot be undone.</AlertDialogDescription>          </AlertDialogHeader>          <AlertDialogFooter>            <AlertDialogCancel ref={cancelRef} render={<Button variant="secondary">Cancel</Button>} />            <AlertDialogAction render={<Button variant="danger" onClick={deleteProject}>Delete project</Button>} />          </AlertDialogFooter>        </AlertDialogContent>      </AlertDialogPortal>    </AlertDialog>  );}

Advanced destructive confirmation

Exact-name confirmation is optional consumer-owned product policy. Compose it inside AlertDialogBody when a high-risk action needs a stronger response than the primitive confirmation boundary.

import * as React from 'react';import { AlertDialog, AlertDialogAction, AlertDialogBackdrop, AlertDialogBody, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, Button, Field, Input } from '@nerio-ui/ui/client';function DeleteProjectDialog() {  const cancelRef = React.useRef<HTMLButtonElement>(null);  const projectName = "Nerio";  const [confirmation, setConfirmation] = React.useState("");  const isConfirmed = confirmation === projectName;  return (    <AlertDialog onOpenChange={(open) => !open && setConfirmation("")}>      <AlertDialogTrigger render={<Button variant="danger">Delete project</Button>} />      <AlertDialogPortal>        <AlertDialogBackdrop />        <AlertDialogContent initialFocus={cancelRef}>          <AlertDialogHeader>            <AlertDialogTitle>Delete project?</AlertDialogTitle>            <AlertDialogDescription>This permanently removes the project and cannot be undone.</AlertDialogDescription>          </AlertDialogHeader>          <AlertDialogBody>            <Field label={`Type “${projectName}” to confirm`} description="The project name is case-sensitive.">              <Input autoComplete="off" value={confirmation} onChange={(event) => setConfirmation(event.target.value)} />            </Field>          </AlertDialogBody>          <AlertDialogFooter>            <AlertDialogCancel ref={cancelRef} render={<Button variant="secondary">Cancel</Button>} />            <AlertDialogAction disabled={!isConfirmed} render={<Button variant="danger" onClick={deleteProject}>Delete project</Button>} />          </AlertDialogFooter>        </AlertDialogContent>      </AlertDialogPortal>    </AlertDialog>  );}

Installation and imports

Install the editable registry source, or use the matching package entrypoint when the product keeps Nerio as a workspace dependency.

pnpm exec nerio add alert-dialogimport * as React from 'react';import { AlertDialog, AlertDialogAction, AlertDialogBackdrop, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, Button } from '@nerio-ui/ui/client';

Usage

import * as React from 'react';import { AlertDialog, AlertDialogAction, AlertDialogBackdrop, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, Button } from '@nerio-ui/ui/client';function DeleteProjectDialog() {  const cancelRef = React.useRef<HTMLButtonElement>(null);  return (    <AlertDialog>      <AlertDialogTrigger render={<Button variant="danger">Delete project</Button>} />      <AlertDialogPortal>        <AlertDialogBackdrop />        <AlertDialogContent initialFocus={cancelRef}>          <AlertDialogHeader>            <AlertDialogTitle>Delete project?</AlertDialogTitle>            <AlertDialogDescription>This permanently removes the project and cannot be undone.</AlertDialogDescription>          </AlertDialogHeader>          <AlertDialogFooter>            <AlertDialogCancel ref={cancelRef} render={<Button variant="secondary">Cancel</Button>} />            <AlertDialogAction render={<Button variant="danger" onClick={deleteProject}>Delete project</Button>} />          </AlertDialogFooter>        </AlertDialogContent>      </AlertDialogPortal>    </AlertDialog>  );}

Variants

VariantPurpose
ConfirmationOne explicit cancel/action decision.

Anatomy

SlotPurpose
portalContainer boundary for the portalled confirmation.
triggerControl that requests the confirmation.
backdropModal backdrop that does not dismiss on pointer press.
contentViewport-bounded alertdialog surface with deliberate focus.
headerGroups the accessible name and concrete consequence.
titleRequired accessible name phrased as the decision.
descriptionExplains the consequence without ambiguous language.
bodyOptional supporting content; keep the decision concise.
footerAction row with cancel before confirmation.
cancelSafe response and recommended initial-focus target.
actionExplicit confirmation boundary that closes after the consumer handler runs.

States

StatePurpose
OpenPointer dismissal is disabled and focus stays in the alertdialog.
CancelledThe safe response closes and restores focus.
ConfirmedThe consumer handler runs and the dialog closes.

Motion

  • overlay entry and exit
  • reduced-motion fade-only state change

Accessibility

  • Uses the Base UI Alert Dialog primitive with role=alertdialog, modal focus containment, Escape dismissal, scroll locking, and pointer dismissal disabled.
  • AlertDialogTitle provides the accessible name and AlertDialogDescription explains the consequence in concrete language.
  • Place AlertDialogCancel before AlertDialogAction and pass its ref to AlertDialogContent initialFocus for destructive or difficult-to-reverse actions.
  • AlertDialogCancel and AlertDialogAction are explicit close boundaries; mutation, async orchestration, permissions, routing, and confirmation copy remain consumer-owned.
  • Focus returns to the trigger after either response and every action keeps native Button keyboard semantics through render composition.

Review the shared responsibility and evidence boundaries in the Accessibility foundation alongside this component-specific contract. Use the Spacing & layout foundation for shared density, wrapping, overflow, reflow, and component-versus-product ownership guidance. The Color foundation, Typography foundation, and Localization foundation define the shared visual-role, text-resilience, direction, and locale boundaries used by component examples.

API

PropPurpose
AlertDialogControlled or uncontrolled Base UI Alert Dialog root.
AlertDialogContentAccepts initialFocus, finalFocus, className, native popup props, and a forwarded ref.
AlertDialogCancelExplicit safe close boundary and recommended initial-focus target.
AlertDialogActionExplicit confirm close boundary; consumers attach mutation behavior to the rendered Button.

Implementation contract

ContractValue
Registry itemalert-dialog installs 1 source file into the configured components directory.
Base UIalert-dialog
Registry dependenciesdialog
Package dependencies@base-ui/react, clsx, react, tailwind-merge, tailwindcss

Styling contract

ContractValue
AuthoringComplete, statically detectable Tailwind CSS v4 recipes own component visuals.
ValuesSemantic and component --n-* variables remain the canonical customization layer.
OverridesCustomizable slots merge consumer className values with tailwindCn so conflicting utilities resolve deterministically.
Residual CSSOnly shared keyframes and scoped no-Preflight compatibility rules remain; there is no parallel visual selector layer.

Design notes

  • AlertDialog is a response boundary, not an async mutation orchestrator.
  • Exact-name confirmation is optional consumer-owned policy composed inside AlertDialogBody.
  • A normal Dialog remains appropriate for reversible tasks and forms with their own completion model.

Do / do not

Do

Name the action and consequence precisely, focus Cancel first, and keep one clear confirmation action.

Compose an exact entity-name confirmation when consumer product policy requires it.

Do not

Do not hide side effects, default focus to a destructive action, or put multi-step workflows in AlertDialog.

Tokens

These are the primary customization points. Override semantic or component tokens instead of changing component source.

TokenPurpose
--n-dialog-width-mdPublic customization point for this component contract.
--n-dialog-viewport-insetPublic customization point for this component contract.
--n-dialog-paddingPublic customization point for this component contract.
--n-dialog-header-gapPublic customization point for this component contract.
--n-dialog-header-marginPublic customization point for this component contract.
--n-dialog-body-gapPublic customization point for this component contract.
--n-overlay-z-indexPublic customization point for this component contract.
--n-overlay-backgroundPublic customization point for this component contract.
--n-overlay-borderPublic customization point for this component contract.
--n-overlay-backdropPublic customization point for this component contract.
--n-overlay-backdrop-filterPublic customization point for this component contract.
--n-overlay-foregroundPublic customization point for this component contract.
--n-overlay-foreground-mutedPublic customization point for this component contract.
--n-overlay-control-backgroundPublic customization point for this component contract.
--n-overlay-control-background-hoverPublic customization point for this component contract.
--n-overlay-surface-filterPublic customization point for this component contract.
--n-overlay-shadowPublic customization point for this component contract.
--n-motion-overlay-enter-durationPublic customization point for this component contract.
--n-motion-overlay-enter-easingPublic customization point for this component contract.
--n-motion-overlay-exit-durationPublic customization point for this component contract.
--n-motion-overlay-exit-easingPublic customization point for this component contract.
--n-focus-ringPublic customization point for this component contract.