Jone

Alert Dialog

A high-quality, unstyled React alert dialog component that requires a user response to proceed.

A dialog that requires a user response to proceed.

Anatomy

Import the component and assemble its parts:

Anatomy
import { AlertDialog } from '@base-ui/react/alert-dialog';

<AlertDialog.Root>
  <AlertDialog.Trigger />
  <AlertDialog.Portal>
    <AlertDialog.Backdrop />
    <AlertDialog.Viewport>
      <AlertDialog.Popup>
        <AlertDialog.Title />
        <AlertDialog.Description />
        <AlertDialog.Close />
      </AlertDialog.Popup>
    </AlertDialog.Viewport>
  </AlertDialog.Portal>
</AlertDialog.Root>;

Examples

Open from a menu

In order to open a dialog using a menu, control the dialog state and open it imperatively using the onClick handler on the menu item.

Connecting a dialog to a menu
import * as React from 'react';
import { AlertDialog } from '@base-ui/react/alert-dialog';
import { Menu } from '@base-ui/react/menu';

function ExampleMenu() {
  const [dialogOpen, setDialogOpen] = React.useState(false);

  return (
    <React.Fragment>
      <Menu.Root>
        <Menu.Trigger>Open menu</Menu.Trigger>
        <Menu.Portal>
          <Menu.Positioner>
            <Menu.Popup>
              {/* Open the dialog when the menu item is clicked */}
              <Menu.Item onClick={() => setDialogOpen(true)}>Open dialog</Menu.Item>
            </Menu.Popup>
          </Menu.Positioner>
        </Menu.Portal>
      </Menu.Root>

      {/* Control the dialog state */}
      <AlertDialog.Root open={dialogOpen} onOpenChange={setDialogOpen}>
        <AlertDialog.Portal>
          <AlertDialog.Backdrop />
          <AlertDialog.Popup>
            {/* prettier-ignore */}
            {/* Rest of the dialog */}
          </AlertDialog.Popup>
        </AlertDialog.Portal>
      </AlertDialog.Root>
    </React.Fragment>
  );
}

Close confirmation

This example shows a nested confirmation dialog that opens if the text entered in the parent dialog is going to be discarded.

To implement this, both dialogs should be controlled. The confirmation dialog may be opened when onOpenChange callback of the parent dialog receives a request to close. This way, the confirmation is automatically shown when the user clicks the backdrop, presses the Esc key, or clicks a close button.

Use the [data-nested-dialog-open] selector and the var(--nested-dialogs) CSS variable to customize the styling of the parent dialog. Backdrops of the child dialogs won't be rendered so that you can present the parent dialog in a clean way behind the one on top of it.

Detached triggers

An alert dialog can be controlled by a trigger located either inside or outside the <AlertDialog.Root> component. For simple, one-off interactions, place the <AlertDialog.Trigger> inside <AlertDialog.Root>, as shown in the example at the top of this page.

However, if defining the alert dialog's content next to its trigger is not practical, you can use a detached trigger. This involves placing the <AlertDialog.Trigger> outside of <AlertDialog.Root> and linking them with a handle created by the AlertDialog.createHandle() function.

Detached triggers
const demoAlertDialog = AlertDialog.createHandle();

<AlertDialog.Trigger handle={demoAlertDialog}>Open</AlertDialog.Trigger>

<AlertDialog.Root handle={demoAlertDialog}>
  ...
</AlertDialog.Root>

Multiple triggers

A single alert dialog can be opened by multiple trigger elements. You can achieve this by using the same handle for several detached triggers, or by placing multiple <AlertDialog.Trigger> components inside a single <AlertDialog.Root>.

Multiple triggers within the Root part
<AlertDialog.Root>
  <AlertDialog.Trigger>Trigger 1</AlertDialog.Trigger>
  <AlertDialog.Trigger>Trigger 2</AlertDialog.Trigger>
  ...
</AlertDialog.Root>
Multiple detached triggers
const demoAlertDialog = AlertDialog.createHandle();

<AlertDialog.Trigger handle={demoAlertDialog}>Trigger 1</AlertDialog.Trigger>
<AlertDialog.Trigger handle={demoAlertDialog}>Trigger 2</AlertDialog.Trigger>
<AlertDialog.Root handle={demoAlertDialog}>
  ...
</AlertDialog.Root>

The alert dialog can render different content depending on which trigger opened it. This is achieved by passing a payload to the <AlertDialog.Trigger> and using the function-as-a-child pattern in <AlertDialog.Root>.

The payload can be strongly typed by providing a type argument to the createHandle() function:

Detached triggers with payload
const demoAlertDialog = AlertDialog.createHandle<{ message: string }>();

<AlertDialog.Trigger handle={demoAlertDialog} payload={{ message: 'Trigger 1' }}>
  Trigger 1
</AlertDialog.Trigger>

<AlertDialog.Trigger handle={demoAlertDialog} payload={{ message: 'Trigger 2' }}>
  Trigger 2
</AlertDialog.Trigger>

<AlertDialog.Root handle={demoAlertDialog}>
  {({ payload }) => (
    <AlertDialog.Portal>
      <AlertDialog.Popup>
        <AlertDialog.Title>Alert dialog</AlertDialog.Title>
        {payload !== undefined && (
          <AlertDialog.Description>
            Confirming {payload.message}
          </AlertDialog.Description>
        )}
      </AlertDialog.Popup>
    </AlertDialog.Portal>
  )}
</AlertDialog.Root>

Controlled mode with multiple triggers

You can control the alert dialog's open state externally using the open and onOpenChange props on <AlertDialog.Root>. This allows you to manage the alert dialog's visibility based on your application's state. When using multiple triggers, you have to manage which trigger is active with the triggerId prop on <AlertDialog.Root> and the id prop on each <AlertDialog.Trigger>.

Note that there is no separate onTriggerIdChange prop. Instead, the onOpenChange callback receives an additional argument, eventDetails, which contains the trigger element that initiated the state change.

API reference

Root

NameTypeDefaultDescription
actionsRefOptionalReact.RefObject<AlertDialogRoot.Actions | null> | undefinedA ref to imperative actions. - `unmount`: When specified, the dialog will not be unmounted when closed. Instead, the `unmount` function must be called to unmount the dialog manually. Useful when the dialog's animation is controlled by an external library. - `close`: Closes the dialog imperatively when called.
handleOptionalDialogHandle<Payload> | undefinedA 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.

On this page