Alert dialog
A modal that asks a question the user has to answer
import { AlertDialog, ConfirmDialog } from "@nyte-ai/ui/alert-dialog";A Dialog with alert semantics. ConfirmDialog is a prebuilt destructive
confirmation.
Usage
- Start with
ConfirmDialog. Use the parts for other content or actions. - Include a Cancel
AlertDialog.Close. - Title and
confirmLabelname the same action and noun. - Put the destructive action last with
variant="solid" tone="danger".
Anatomy
<AlertDialog.Root>
<AlertDialog.Trigger />
<AlertDialog.Popup>
<AlertDialog.Header>
<AlertDialog.Title />
<AlertDialog.Description />
</AlertDialog.Header>
<AlertDialog.Footer>
<AlertDialog.Close /> {/* cancel */}
<AlertDialog.Close /> {/* confirm */}
</AlertDialog.Footer>
</AlertDialog.Popup>
</AlertDialog.Root>Examples
Confirm dialog
const [open, setOpen] = useState(false);
<Button variant="solid" tone="danger" onClick={() => setOpen(true)}>
Delete Chat
</Button>
<ConfirmDialog
open={open}
title="Delete Chat" confirmLabel="Delete Chat"
description="The chat and its history are removed."
onOpenChange={setOpen}
onConfirm={() => setOpen(false)}
/><ConfirmDialog
open={open}
pending={signOut.isPending}
error={signOut.isError ? "Sign-out failed. Try again." : undefined}
finalFocus={signOutRef}
title="Sign Out"
description="Other apps using this login are signed out too."
confirmLabel="Sign Out"
pendingLabel="Signing out…"
onOpenChange={setOpen}
onConfirm={() => signOut.mutate(undefined, { onSuccess: () => setOpen(false) })}
/>Parts
<AlertDialog.Root>
<AlertDialog.Trigger
render={
<Button variant="solid" tone="danger">
Delete Chat
</Button>
}
/>
<AlertDialog.Popup>
<AlertDialog.Header>
<AlertDialog.Title>Delete Chat</AlertDialog.Title>
<AlertDialog.Description>
The history tree and every head under it are removed. This cannot be undone.
</AlertDialog.Description>
</AlertDialog.Header>
<AlertDialog.Footer>
<AlertDialog.Close render={<Button variant="outline">Cancel</Button>} />
<AlertDialog.Close
render={
<Button variant="solid" tone="danger">
Delete Chat
</Button>
}
/>
</AlertDialog.Footer>
</AlertDialog.Popup>
</AlertDialog.Root>Props
ConfirmDialog
| Prop | Type | Default | Description |
|---|---|---|---|
open | boolean | ||
title | string | ||
description | React.ReactNode | The consequence. | |
confirmLabel | string | ||
pendingLabel | string | Status line shown while pending. | |
pending | boolean | false | Makes both actions busy and ignores requests to close. |
error | string | Shown under the description as an alert. | |
finalFocus | As AlertDialog.Popup | Where focus lands on close, for a dialog with no trigger. | |
onOpenChange | (open: boolean, eventDetails) => void | Called with false and the event details on Cancel or Escape, unless pending. | |
onConfirm | () => void | Called by the danger button. Close the dialog yourself. | |
tint | Tint |
Parts
| Part | Renders | Styling |
|---|---|---|
AlertDialog.Root | Nothing | None |
AlertDialog.Trigger | <button> | None |
AlertDialog.Popup | A portal, the scrim, a <div> | As Dialog.Popup |
AlertDialog.Header | <div> | As Dialog.Header |
AlertDialog.Title | <h2> | As Dialog.Title |
AlertDialog.Description | <p> | As Dialog.Description |
AlertDialog.Footer | <div> | As Dialog.Footer |
AlertDialog.Close | <button> | None |
Except AlertDialog.Root, each part takes xstyle, className, and style. className and style
take plain values, not functions of state. See Theming.
The part tables below come from Base UI, MIT, © Material-UI SAS.
Root
Groups all parts of the alert dialog. Doesn't render its own HTML element.
Root Props:
| Prop | Type | Default | Description |
|---|---|---|---|
| defaultOpen | boolean | false | Whether the dialog is initially open. To render a controlled dialog, use the open prop instead. |
| open | boolean | - | Whether the dialog is currently open. |
| onOpenChange | ((open: boolean, eventDetails: AlertDialog.Root.ChangeEventDetails) => void) | - | Event handler called when the alert dialog is opened or closed. |
| actionsRef | React.RefObject<AlertDialog.Root.Actions | null> | - | A ref to imperative actions. unmount: Manually unmounts the alert dialog.
Call this after any externally controlled closing animation finishes.close: Closes the alert dialog imperatively when called. |
| defaultTriggerId | string | null | - | ID of the trigger that the dialog is associated with.
This is useful in conjunction with the defaultOpen prop to create an initially open dialog. |
| handle | AlertDialog.Handle<Payload> | - | A handle to associate the alert dialog with a trigger. If specified, allows external triggers to control the alert dialog's open state. Can be created with the AlertDialog.createHandle() method. |
| onOpenChangeComplete | ((open: boolean) => void) | - | Event handler called after any animations complete when the dialog is opened or closed. |
| triggerId | string | null | - | ID of the trigger that the dialog is associated with.
This is useful in conjunction with the open prop to create a controlled dialog.
There's no need to specify this prop when the dialog is uncontrolled (that is, when the open prop is not set). |
| children | React.ReactNode | PayloadChildRenderFunction<Payload> | - | The content of the dialog.
This can be a regular React node or a render function that receives the payload of the active trigger. |
Trigger
A button that opens the alert dialog.
Renders a <button> element.
Trigger Props:
| Prop | Type | Default | Description |
|---|---|---|---|
| handle | AlertDialog.Handle<Payload> | - | A handle to associate the trigger with an alert dialog. Can be created with the AlertDialog.createHandle() method. |
| nativeButton | boolean | true | Whether the component renders a native <button> element when replacing it
via the render prop.
Set to false if the rendered element is not a button (for example, <div>). |
| payload | Payload | - | A payload to pass to the dialog when it is opened. |
| id | string | - | ID of the trigger. In addition to being forwarded to the rendered element,
it is also used to specify the active trigger for the dialog in controlled mode (with the DialogRoot triggerId prop). |
| className | string | ((state: AlertDialog.Trigger.State) => string | undefined) | - | CSS class applied to the element, or a function that returns a class based on the component's state. |
| style | React.CSSProperties | ((state: AlertDialog.Trigger.State) => React.CSSProperties | undefined) | - | Style applied to the element, or a function that returns a style object based on the component's state. |
| render | ReactElement | ((props: HTMLProps, state: AlertDialog.Trigger.State) => ReactElement) | - | Allows you to replace the component's HTML element
with a different tag, or compose it with another component. Accepts a ReactElement or a function that returns the element to render. |
Trigger Data Attributes:
| Attribute | Type | Description |
|---|---|---|
| data-popup-open | - | Present when the corresponding alert dialog is open. |
| data-disabled | - | Present when the trigger is disabled. |
Popup
A container for the dialog contents.
Renders a <div> element.
Popup Props:
| Prop | Type | Default | Description |
|---|---|---|---|
| initialFocus | boolean | React.RefObject<HTMLElement | null> | ((openType: InteractionType) => boolean | void | HTMLElement | null) | - | Determines the element to focus when the dialog is opened.
By default, focus moves to the first tabbable element inside the popup, except when the dialog
is opened by touch — then the popup itself is focused to avoid opening the virtual keyboard. false: Do not move focus.true: Move focus based on the default behavior (first tabbable element or popup).RefObject: Move focus to the ref element.function: Called with the interaction type (mouse, touch, pen, or keyboard).
Return an element to focus, true to use the default behavior, null to fall back to the default behavior, or false/undefined to do nothing. |
| finalFocus | boolean | React.RefObject<HTMLElement | null> | ((closeType: InteractionType) => boolean | void | HTMLElement | null) | - | Determines the element to focus when the dialog is closed. false: Do not move focus.true: Move focus based on the default behavior (trigger or previously focused element).RefObject: Move focus to the ref element.function: Called with the interaction type (mouse, touch, pen, or keyboard).
Return an element to focus, true to use the default behavior, null to fall back to the default behavior, or false/undefined to do nothing. |
| className | string | ((state: AlertDialog.Popup.State) => string | undefined) | - | CSS class applied to the element, or a function that returns a class based on the component's state. |
| style | React.CSSProperties | ((state: AlertDialog.Popup.State) => React.CSSProperties | undefined) | - | Style applied to the element, or a function that returns a style object based on the component's state. |
| render | ReactElement | ((props: HTMLProps, state: AlertDialog.Popup.State) => ReactElement) | - | Allows you to replace the component's HTML element
with a different tag, or compose it with another component. Accepts a ReactElement or a function that returns the element to render. |
Popup Data Attributes:
| Attribute | Type | Description |
|---|---|---|
| data-open | - | Present when the dialog is open. |
| data-closed | - | Present when the dialog is closed. |
| data-nested | - | Present when the dialog is nested within another dialog. |
| data-nested-dialog-open | - | Present when the dialog has other open dialogs nested within it. |
| data-starting-style | - | Present when the dialog begins animating in. |
| data-ending-style | - | Present when the dialog is animating out. |
Popup CSS Variables:
| Variable | Type | Description |
|---|---|---|
--nested-dialogs | number | Indicates how many dialogs are nested within. |
Title
A heading that labels the dialog.
Renders an <h2> element.
Title Props:
| Prop | Type | Default | Description |
|---|---|---|---|
| className | string | ((state: AlertDialog.Title.State) => string | undefined) | - | CSS class applied to the element, or a function that returns a class based on the component's state. |
| style | React.CSSProperties | ((state: AlertDialog.Title.State) => React.CSSProperties | undefined) | - | Style applied to the element, or a function that returns a style object based on the component's state. |
| render | ReactElement | ((props: HTMLProps, state: AlertDialog.Title.State) => ReactElement) | - | Allows you to replace the component's HTML element
with a different tag, or compose it with another component. Accepts a ReactElement or a function that returns the element to render. |
Description
A paragraph with additional information about the dialog.
Renders a <p> element.
Description Props:
| Prop | Type | Default | Description |
|---|---|---|---|
| className | string | ((state: AlertDialog.Description.State) => string | undefined) | - | CSS class applied to the element, or a function that returns a class based on the component's state. |
| style | React.CSSProperties | ((state: AlertDialog.Description.State) => React.CSSProperties | undefined) | - | Style applied to the element, or a function that returns a style object based on the component's state. |
| render | ReactElement | ((props: HTMLProps, state: AlertDialog.Description.State) => ReactElement) | - | Allows you to replace the component's HTML element
with a different tag, or compose it with another component. Accepts a ReactElement or a function that returns the element to render. |
Close
A button that closes the dialog.
Renders a <button> element.
Close Props:
| Prop | Type | Default | Description |
|---|---|---|---|
| nativeButton | boolean | true | Whether the component renders a native <button> element when replacing it
via the render prop.
Set to false if the rendered element is not a button (for example, <div>). |
| className | string | ((state: AlertDialog.Close.State) => string | undefined) | - | CSS class applied to the element, or a function that returns a class based on the component's state. |
| style | React.CSSProperties | ((state: AlertDialog.Close.State) => React.CSSProperties | undefined) | - | Style applied to the element, or a function that returns a style object based on the component's state. |
| render | ReactElement | ((props: HTMLProps, state: AlertDialog.Close.State) => ReactElement) | - | Allows you to replace the component's HTML element
with a different tag, or compose it with another component. Accepts a ReactElement or a function that returns the element to render. |
Close Data Attributes:
| Attribute | Type | Description |
|---|---|---|
| data-disabled | - | Present when the button is disabled. |
Accessibility
- The popup has
role="alertdialog", labelled byAlertDialog.Titleand described byAlertDialog.Description. - Outside press does not close. Escape does. To block that, call
details.cancel()inonOpenChangewhendetails.reasonisescape-key. - Focus moves into the popup on open and returns to the trigger on close. Tab cycles inside the popup.
- While open, outside content is inert and page scroll is locked.
ConfirmDialogfocuses Cancel on open, setsaria-busywhilepending, and gives its errorrole="alert".