Skip to content

Alert Dialog

A modal dialog that interrupts the user's workflow to get a response, usually some sort of confirmation. This is different than a typical Dialog in that it requires some user response, like "Save", or "Cancel", etc.

Most of the time you'll use AlertDialog, AlertDialogLabel, and AlertDialogDescription together. If you need more control over the styling of the modal you can drop down a level and use AlertDialogOverlay and AlertDialogContent instead of AlertDialog.

When a Dialog opens, the least destructive action should be focused so that if a user accidentally hits enter when the dialog opens no damage is done. This is accomplished with the leastDestructiveRef prop.

Every dialog must render an AlertDialogLabel so the screen reader knows what to say about the dialog. If an AlertDialogDescription is also rendered, the screen reader will also announce that. If you render more than these two elements and some buttons, the screen reader might not announce it so it's important to keep the content inside of AlertDialogLabel and AlertDialogDescription.

This is built on top of Dialog, so AlertDialog spreads its props and renders a Dialog, same for AlertDialogOverlay to DialogOverlay, and AlertDialogContent to DialogContent.

function Example(props) {  const [showDialog, setShowDialog] = React.useState(false);  const cancelRef = React.useRef();  const open = () => setShowDialog(true);  const close = () => setShowDialog(false);
  return (    <div>      <button onClick={open}>Delete something</button>
      {showDialog && (        <AlertDialog leastDestructiveRef={cancelRef}>          <AlertDialogLabel>Please Confirm!</AlertDialogLabel>
          <AlertDialogDescription>            Are you sure you want to delete something? This action is permanent,            and we're totally not just flipping a field called "deleted" to            "true" in our database, we're actually deleting something.          </AlertDialogDescription>
          <div className="alert-buttons">            <button onClick={close}>Yes, delete</button>{" "}            <button ref={cancelRef} onClick={close}>              Nevermind, don't delete.            </button>          </div>        </AlertDialog>      )}    </div>  );}

Installation

From the command line in your project directory, run npm install @reach/alert-dialog or yarn add @reach/alert-dialog. Then import the components that you need:

npm install @reach/alert-dialog# oryarn add @reach/alert-dialog
import {  AlertDialog,  AlertDialogLabel,  AlertDialogDescription,  AlertDialogOverlay,  AlertDialogContent,} from "@reach/alert-dialog";

Component API

AlertDialog

High-level component to render an alert dialog.

<AlertDialog leastDestructiveRef={someRef}>  <AlertDialogLabel />  <AlertDialogContent /></AlertDialog>

AlertDialog Props

PropTypeRequired
Dialog props
isOpenboolfalse
onDismissfuncfalse
leastDestructiveReffuncfalse
childrennodetrue
AlertDialog Dialog props

Any props not listed above will be spread onto the underlying Dialog element, which in turn is spread onto the underlying div[data-reach-dialog-content].

See documentation for Dialog props for more information.

<AlertDialog style={{ color: "red" }}>  <AlertDialogLabel>    My text is red because the style prop got applied to the div underneath  </AlertDialogLabel></AlertDialog>
AlertDialog isOpen

isOpen?: boolean

Controls whether the dialog is open or not. Defaults to true.

<AlertDialog isOpen={true}>  <AlertDialogLabel>I will be open</AlertDialogLabel></AlertDialog>
<AlertDialog isOpen={false}>  <AlertDialogLabel>I will be closed</AlertDialogLabel></AlertDialog>

Note, however, that the dialog will not render to the DOM when isOpen={false}, but you may want to save on the number of elements created in your render function. If you'd rather not have the dialog always rendered, you can put a guard in front of it and only render when it should be open. In this case you don’t need the isOpen prop at all.

{  state.confirmDelete && (    <AlertDialog isOpen={true}>      <AlertDialogLabel>I will be open</AlertDialogLabel>    </AlertDialog>  );}

You should probably do this when your dialog contains a lot of elements. It's also useful for transition animations.

AlertDialog onDismiss

onDismiss?: (event?: React.SyntheticEvent) => void;

When the user clicks outside the modal or hits the escape key, this function will be called. If you want the modal to close, you’ll need to set state.

IMPORTANT: Ensure that onDismiss and the click handler of the leastDestructiveRef are identical!

function Example(props) {  const [showDialog, setShowDialog] = React.useState(false);  const cancelRef = React.useRef();
  const open = () => setShowDialog(true);  const destroyStuff = () => {    console.log("Destroyed!");    setShowDialog(false);  };  // make sure `close` and the `onClick` of the  // `leastDestructiveRef` are identical, best to just  // pass them both the same function  const close = () => setShowDialog(false);
  return (    <div>      <button onClick={open}>Delete something</button>
      {showDialog && (        <AlertDialog onDismiss={close} leastDestructiveRef={cancelRef}>          <AlertDialogLabel>Please Confirm!</AlertDialogLabel>
          <AlertDialogDescription>            Are you sure you want to delete something? This action is permanent,            and we're totally not just flipping a field called "deleted" to            "true" in our database, we're actually deleting something.          </AlertDialogDescription>
          <div className="alert-buttons">            <button onClick={destroyStuff}>Yes, delete</button>{" "}            <button ref={cancelRef} onClick={close}>              Nevermind, don't delete.            </button>          </div>        </AlertDialog>      )}    </div>  );}
AlertDialog leastDestructiveRef

leastDestructiveRef?: React.RefObject<HTMLElement>;

To prevent accidental data loss, an alert dialog should focus the least destructive action button when it opens.

function Example(props) {  const [showDialog, setShowDialog] = React.useState(false);
  // we'll pass this ref to both AlertDialog and our button  const cancelRef = React.useRef();
  const open = () => setShowDialog(true);  const close = () => setShowDialog(false);
  return (    <div>      <button onClick={open}>Publish something</button>
      {showDialog && (        <AlertDialog leastDestructiveRef={cancelRef}>          <AlertDialogLabel>Please Confirm!</AlertDialogLabel>
          <AlertDialogDescription>            Are you sure you want to publish this thing?          </AlertDialogDescription>
          <div className="alert-buttons">            <button onClick={this.close}>Yes, publish and keep editing</button>{" "}            <button onClick={this.close}>Yes, publish and view</button>{" "}            <button ref={cancelRef} onClick={close}>              Don't publish, keep working            </button>          </div>        </AlertDialog>      )}    </div>  );}
AlertDialog children

children: React.ReactNode

Accepts any renderable content but should generally be restricted to AlertDialogLabel, AlertDialogDescription and action buttons, other content might not be announced to the user by the screen reader.

<AlertDialog>  <AlertDialogLabel>Please Confirm!</AlertDialogLabel>
  <AlertDialogDescription>A longer message</AlertDialogDescription>
  <div>    <button onClick={destroyStuff}>A Destructive Action</button>{" "}    <button ref={leastDestructiveRef}>Least Destructive Action</button>  </div></AlertDialog>

AlertDialogLabel

The first thing ready by screen readers when the dialog opens, usually the title of the dialog like "Warning!" or "Please confirm!".

This is required. The AlertDialog will throw an error if no label is rendered.

AlertDialogLabel CSS Selectors

Please see the styling guide.

Use the following CSS to target the label:

[data-reach-alert-dialog-label] {}

AlertDialogLabel Props

AlertDialogLabel div props

All props are spread to an underlying div element.

<AlertDialogLabel className="alert-label" />

AlertDialogDescription

Additional content read by screen readers, usually a longer description about what you need from the user like "This action is permanent, are you sure?" etc.

AlertDialogDescription CSS Selectors

Please see the styling guide.

Use the following CSS to target the description:

[data-reach-alert-dialog-description] {}

AlertDialogDescription Props

AlertDialogDescription div props

All props are spread to an underlying div element.

<AlertDialogDescription className="alert-description" />

AlertDialogOverlay

Low-level component if you need more control over the styles or rendering of the dialog overlay. In the following example we use the AlertDialogOverlay and AlertDialogContent to have more control over the styles.

Note: You must render an AlertDialogContent inside.

function Example(props) {  const [showDialog, setShowDialog] = React.useState(false);
  // we'll pass this ref to both AlertDialog and our button  const cancelRef = React.useRef();
  const open = () => setShowDialog(true);  const close = () => setShowDialog(false);
  return (    <div>      <button onClick={open}>Delete something</button>
      {showDialog && (        <AlertDialogOverlay          style={{ background: "hsla(0, 50%, 50%, 0.85)" }}          leastDestructiveRef={cancelRef}        >          <AlertDialogContent style={{ background: "#f0f0f0" }}>            <AlertDialogLabel>Please Confirm!</AlertDialogLabel>
            <AlertDialogDescription>              Are you sure you want delete stuff, it will be permanent.            </AlertDialogDescription>
            <div className="alert-buttons">              <button onClick={close}>Yes, delete</button>{" "}              <button ref={cancelRef} onClick={close}>                Nevermind              </button>            </div>          </AlertDialogContent>        </AlertDialogOverlay>      )}    </div>  );}

AlertDialogOverlay CSS Selectors

Please see the styling guide.

Use the following CSS to target the overlay:

[data-reach-alert-dialog-overlay] {}

AlertDialogOverlay Props

PropTypeRequired
DialogOverlay props
isOpenboolfalse
onDismissfuncfalse
leastDestructiveRefreffalse
childrennodetrue
AlertDialogOverlay DialogOverlay props

Any props not listed above will be spread onto the underlying DialogOverlay, and in turn spread onto the underlying div element.

See documentation for DialogOverlay props for more information.

<AlertDialogOverlay className="light-modal" />
AlertDialogOverlay isOpen

isOpen?: boolean

Same as AlertDialog isOpen. Defaults to true.

AlertDialogOverlay onDismiss

onDismiss?: (event?: React.SyntheticEvent) => void

Same as AlertDialog onDismiss

AlertDialogOverlay leastDestructiveRef

leastDestructiveRef?: React.RefObject<HTMLElement>

Same as AlertDialog leastDestructiveRef

AlertDialogOverlay children

children: React.ReactNode

Should be an AlertDialogContent.

<AlertDialogOverlay>  <AlertDialogContent /></AlertDialogOverlay>

AlertDialogContent

Low-level component if you need more control over the styles or rendering of the dialog content.

Note: Must be a child of AlertDialogOverlay.

Note: You only need to use this when you are also styling AlertDialogOverlay, otherwise you can use the high-level AlertDialog component and pass the props to it.

<AlertDialogOverlay style={someSpecificStyles}>  <AlertDialogContent className={orAClassName} /></AlertDialogOverlay>

AlertDialogContent CSS Selectors

Please see the styling guide.

Use the following CSS to target the content:

[data-reach-alert-dialog-content] {}

AlertDialogContent Props

PropTypeRequired
DialogContent props
childrennodetrue
AlertDialogContent DialogContent props

Any props not listed above will be spread onto the underlying DialogContent element, and then again onto the underlying div.

See documentation for DialogContent props for more information.

<AlertDialogContent className="nice-border" />
AlertDialogContent children

children: React.ReactNode

Same as AlertDialog children