ComponentsAlertDialog

AlertDialog

Display a modal with important content that expects confirmation from the user.

Documentation

Usage

import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogBody,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTrigger,
} from "@optiaxiom/react";
 
export function App() {
  return (
    <AlertDialog>
      <AlertDialogTrigger>Delete comment</AlertDialogTrigger>
 
      <AlertDialogContent>
        <AlertDialogHeader>Delete comment?</AlertDialogHeader>
 
        <AlertDialogBody>
          The comment and all replies will be deleted.
        </AlertDialogBody>
 
        <AlertDialogFooter>
          <AlertDialogCancel />
          <AlertDialogAction>Yes, delete</AlertDialogAction>
        </AlertDialogFooter>
      </AlertDialogContent>
    </AlertDialog>
  );
}

Controlled

Use the open and defaultOpen props to toggle between controlled and uncontrolled usage. And combine it with onOpenChange to listen for changes to the state.

import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogBody,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTrigger,
} from "@optiaxiom/react";
import { useState } from "react";
 
export function App() {
  const [open, setOpen] = useState(false);
 
  return (
    <AlertDialog onOpenChange={setOpen} open={open}>
      <AlertDialogTrigger>Delete comment</AlertDialogTrigger>
 
      <AlertDialogContent>
        <AlertDialogHeader>Delete comment?</AlertDialogHeader>
 
        <AlertDialogBody>
          The comment and all replies will be deleted.
        </AlertDialogBody>
 
        <AlertDialogFooter>
          <AlertDialogCancel />
          <AlertDialogAction>Yes, delete</AlertDialogAction>
        </AlertDialogFooter>
      </AlertDialogContent>
    </AlertDialog>
  );
}

Sizes

Use the size prop to change the size of the dialog box.

import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogBody,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTrigger,
} from "@optiaxiom/react";
import { type ComponentPropsWithRef } from "react";
 
export function App({
  size,
}: Pick<ComponentPropsWithRef<typeof AlertDialogContent>, "size">) {
  return (
    <AlertDialog>
      <AlertDialogTrigger>Delete comment</AlertDialogTrigger>
 
      <AlertDialogContent size={size}>
        <AlertDialogHeader>Are you sure?</AlertDialogHeader>
        <AlertDialogBody>
          The comment and all replies will be deleted.
        </AlertDialogBody>
        <AlertDialogFooter>
          <AlertDialogCancel />
          <AlertDialogAction>Yes, delete</AlertDialogAction>
        </AlertDialogFooter>
      </AlertDialogContent>
    </AlertDialog>
  );
}

Handling confirmation

Add an onClick handler to AlertDialogAction to perform an action on confirmation.

import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogBody,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTrigger,
  Flex,
  Text,
} from "@optiaxiom/react";
import { useState } from "react";
 
export function App() {
  const [open, setOpen] = useState(false);
  const [state, setState] = useState("");
 
  return (
    <Flex flexDirection="row">
      <AlertDialog
        onOpenChange={(open) => {
          if (open) {
            setState("");
          }
          setOpen(open);
        }}
        open={open}
      >
        <AlertDialogTrigger>Delete comment</AlertDialogTrigger>
 
        <AlertDialogContent>
          <AlertDialogHeader>Delete comment?</AlertDialogHeader>
 
          <AlertDialogBody>
            The comment and all replies will be deleted.
          </AlertDialogBody>
 
          <AlertDialogFooter>
            <AlertDialogCancel />
 
            <AlertDialogAction onClick={() => setState("confirm")}>
              Yes, delete
            </AlertDialogAction>
          </AlertDialogFooter>
        </AlertDialogContent>
      </AlertDialog>
 
      {state && (
        <Text>
          Clicked <strong>{state}</strong>
        </Text>
      )}
    </Flex>
  );
}

Handling async events

We can prevent closing the dialog in the action button’s onClick handler to perform async operations.

Make sure to use the controlled props and call event.preventDefault() in your action to stop the modal from being dismissed.

import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogBody,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTrigger,
} from "@optiaxiom/react";
import { useState } from "react";
 
export function App() {
  const [loading, setLoading] = useState(false);
  const [open, setOpen] = useState(false);
 
  return (
    <AlertDialog
      onOpenChange={
        /**
         * 3. Make sure to disable closing the modal.
         */
        loading ? undefined : setOpen
      }
      open={open}
    >
      <AlertDialogTrigger>Delete task</AlertDialogTrigger>
 
      <AlertDialogContent>
        <AlertDialogHeader>Are you sure?</AlertDialogHeader>
        <AlertDialogBody>
          The task and all contents will be deleted. This action cannot be
          undone.
        </AlertDialogBody>
        <AlertDialogFooter>
          <AlertDialogCancel disabled={loading} />
          <AlertDialogAction
            disabled={loading}
            loading={loading}
            onClick={(event) => {
              /**
               * 1. Prevent the modal from being dismissed.
               */
              event.preventDefault();
 
              /**
               * 2. Set your loading state and perform your async operation.
               */
              setLoading(true);
              setTimeout(() => {
                setLoading(false);
 
                /**
                 * 4. Close the modal manually once the operation is complete.
                 */
                setOpen(false);
              }, 3000);
            }}
          >
            Yes, Delete
          </AlertDialogAction>
        </AlertDialogFooter>
      </AlertDialogContent>
    </AlertDialog>
  );
}

Customize trigger

By default we use the Button component for the dialog trigger which accepts all of the existing button props.

We can also completely change the trigger by using asChild and passing our own component.

import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogBody,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTrigger,
} from "@optiaxiom/react";
import { IconTrash } from "@tabler/icons-react";
 
export function App() {
  return (
    <AlertDialog>
      <AlertDialogTrigger
        appearance="danger-outline"
        aria-label="Delete task"
        icon={<IconTrash />}
      />
 
      <AlertDialogContent>
        <AlertDialogHeader>Are you sure?</AlertDialogHeader>
        <AlertDialogBody>
          Are you sure you want to delete this task?
        </AlertDialogBody>
        <AlertDialogFooter>
          <AlertDialogCancel />
          <AlertDialogAction>Yes, Delete</AlertDialogAction>
        </AlertDialogFooter>
      </AlertDialogContent>
    </AlertDialog>
  );
}

Related

Alert

Show inline messages about important or time-sensitive changes.

Dialog

Display a modal dialog box.

Props

AlertDialog

Doesn't render its own HTML element.

Prop

defaultOpen

The initial open state in uncontrolled mode.

false | true

onOpenChange

Handler that is called when the open state changes.

(open: boolean) => void

open

The open state in controlled mode.

false | true

AlertDialogTrigger

Supports all Button props in addition to its own. Renders a <button> element.

Prop

addonAfter

Display content inside the button after children.

ReactNode

addonBefore

Display content inside the button before children.

ReactNode

appearance

Control the appearance by selecting between the different button types.

"default" | "danger" | "primary" | "subtle" | "danger-outline" | "inverse"

asChild

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read the Composition guide for more details.

false | true

className

string

disabled

Whether the button is disabled.

false | true

icon

Display an icon before or after the button content or omit children to only show the icon.

ReactNode

iconOnly

Whether button should have square shape.

false | true

iconPosition

Control whether to show the icon before or after the button content.

"end" | "start"

loading

Whether to show loading spinner inside the button.

false | true

size

Control the size of the button.

"sm" | "md" | "lg"

AlertDialogContent

Supports all Box props in addition to its own. Renders a <div> element.

Prop

asChild

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read the Composition guide for more details.

false | true

className

string

onCloseAutoFocus

Event handler called when auto-focusing on close. Can be prevented.

(event: Event) => void

onEscapeKeyDown

Event handler called when the escape key is down. Can be prevented.

(event: KeyboardEvent) => void

onFocusOutside

Event handler called when the focus moves outside of the DismissableLayer. Can be prevented.

(event: FocusOutsideEvent) => void

onOpenAutoFocus

Event handler called when auto-focusing on open. Can be prevented.

(event: Event) => void

size

Control the size/width of the dialog box.

"sm" | "md" | "lg"

Default: sm

AlertDialogHeader

Supports all Box props in addition to its own. Renders a <div> element.

Prop

addonBefore

We show an alert icon before the title by default but this can be replaced with any other icon.

ReactNode

asChild

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read the Composition guide for more details.

false | true

className

string

AlertDialogBody

Supports all Box props in addition to its own. Renders a <div> element.

Prop

asChild

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read the Composition guide for more details.

false | true

className

string

AlertDialogFooter

Supports all Box props in addition to its own. Renders a <div> element.

Prop

asChild

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read the Composition guide for more details.

false | true

className

string

AlertDialogCancel

Supports all Button props in addition to its own. Renders a <button> element.

Prop

addonAfter

Display content inside the button after children.

ReactNode

addonBefore

Display content inside the button before children.

ReactNode

appearance

Control the appearance by selecting between the different button types.

"default" | "danger" | "primary" | "subtle" | "danger-outline" | "inverse"

Default: subtle

asChild

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read the Composition guide for more details.

false | true

className

string

disabled

Whether the button is disabled.

false | true

icon

Display an icon before or after the button content or omit children to only show the icon.

ReactNode

iconOnly

Whether button should have square shape.

false | true

iconPosition

Control whether to show the icon before or after the button content.

"end" | "start"

loading

Whether to show loading spinner inside the button.

false | true

size

Control the size of the button.

"sm" | "md" | "lg"

Default: lg

AlertDialogAction

Supports all Button props in addition to its own. Renders a <button> element.

Prop

addonAfter

Display content inside the button after children.

ReactNode

addonBefore

Display content inside the button before children.

ReactNode

appearance

Control the appearance by selecting between the different button types.

"default" | "danger" | "primary" | "subtle" | "danger-outline" | "inverse"

Default: danger

asChild

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read the Composition guide for more details.

false | true

className

string

disabled

Whether the button is disabled.

false | true

icon

Display an icon before or after the button content or omit children to only show the icon.

ReactNode

iconOnly

Whether button should have square shape.

false | true

iconPosition

Control whether to show the icon before or after the button content.

"end" | "start"

loading

Whether to show loading spinner inside the button.

false | true

size

Control the size of the button.

"sm" | "md" | "lg"

Default: lg

Changelog

0.1.0

  • Added component