Radix homepageRadix Homepage
PrimitivesBeta

Alert Dialog

A modal dialog that interrupts the user with important content and expects a response.

import React from 'react';
import { styled, keyframes } from '@stitches/react';
import { violet, blackA, red, mauve } from '@radix-ui/colors';
import * as AlertDialogPrimitive from '@radix-ui/react-alert-dialog';
const overlayShow = keyframes({
'0%': { opacity: 0 },
'100%': { opacity: 1 },
});
const contentShow = keyframes({
'0%': { opacity: 0, transform: 'translate(-50%, -48%) scale(.96)' },
'100%': { opacity: 1, transform: 'translate(-50%, -50%) scale(1)' },
});
const StyledOverlay = styled(AlertDialogPrimitive.Overlay, {
backgroundColor: blackA.blackA9,
position: 'fixed',
inset: 0,
'@media (prefers-reduced-motion: no-preference)': {
animation: `${overlayShow} 150ms cubic-bezier(0.16, 1, 0.3, 1)`,
},
});
function Root({ children, ...props }) {
return (
<AlertDialogPrimitive.Root {...props}>
<StyledOverlay />
{children}
</AlertDialogPrimitive.Root>
);
}
const StyledContent = styled(AlertDialogPrimitive.Content, {
backgroundColor: 'white',
borderRadius: 6,
boxShadow: 'hsl(206 22% 7% / 35%) 0px 10px 38px -10px, hsl(206 22% 7% / 20%) 0px 10px 20px -15px',
position: 'fixed',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
width: '90vw',
maxWidth: '500px',
maxHeight: '85vh',
padding: 25,
'@media (prefers-reduced-motion: no-preference)': {
animation: `${contentShow} 150ms cubic-bezier(0.16, 1, 0.3, 1)`,
willChange: 'transform',
},
'&:focus': { outline: 'none' },
});
const StyledTitle = styled(AlertDialogPrimitive.Title, {
margin: 0,
color: mauve.mauve12,
fontSize: 17,
fontWeight: 500,
});
const StyledDescription = styled(AlertDialogPrimitive.Description, {
marginBottom: 20,
color: mauve.mauve11,
fontSize: 15,
lineHeight: 1.5,
});
// Exports
const AlertDialog = Root;
const AlertDialogTrigger = AlertDialogPrimitive.Trigger;
const AlertDialogContent = StyledContent;
const AlertDialogTitle = StyledTitle;
const AlertDialogDescription = StyledDescription;
const AlertDialogAction = AlertDialogPrimitive.Action;
const AlertDialogCancel = AlertDialogPrimitive.Cancel;
// Your app...
const Flex = styled('div', { display: 'flex' });
const Button = styled('button', {
all: 'unset',
display: 'inline-flex',
alignItems: 'center',
justifyContent: 'center',
borderRadius: 4,
padding: '0 15px',
fontSize: 15,
lineHeight: 1,
fontWeight: 500,
height: 35,
variants: {
variant: {
violet: {
backgroundColor: 'white',
color: violet.violet11,
boxShadow: `0 2px 10px ${blackA.blackA7}`,
'&:hover': { backgroundColor: mauve.mauve3 },
'&:focus': { boxShadow: `0 0 0 2px black` },
},
red: {
backgroundColor: red.red4,
color: red.red11,
'&:hover': { backgroundColor: red.red5 },
'&:focus': { boxShadow: `0 0 0 2px ${red.red7}` },
},
mauve: {
backgroundColor: mauve.mauve4,
color: mauve.mauve11,
'&:hover': { backgroundColor: mauve.mauve5 },
'&:focus': { boxShadow: `0 0 0 2px ${mauve.mauve7}` },
},
},
},
defaultVariants: {
variant: 'violet',
},
});
const AlertDialogDemo = () => (
<AlertDialog>
<AlertDialogTrigger asChild>
<Button>Delete account</Button>
</AlertDialogTrigger>
<AlertDialogContent >
<AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
<AlertDialogDescription>
This action cannot be undone. This will permanently delete your account and remove your data
from our servers.
</AlertDialogDescription>
<Flex css={{ justifyContent: 'flex-end' }}>
<AlertDialogCancel asChild>
<Button variant="mauve" css={{ marginRight: 25 }}>
Cancel
</Button>
</AlertDialogCancel>
<AlertDialogAction asChild>
<Button variant="red">Yes, delete account</Button>
</AlertDialogAction>
</Flex>
</AlertDialogContent>
</AlertDialog>
);
export default AlertDialogDemo;

Features

  • Focus is automatically trapped.
  • Can be controlled or uncontrolled.
  • Manages screen reader announcements with Title and Description components.
  • Esc closes the component automatically.

Install the component from your command line.

npm install @radix-ui/react-alert-dialog

Import all parts and piece them together.

import * as AlertDialog from '@radix-ui/react-alert-dialog';
export default () => (
<AlertDialog.Root>
<AlertDialog.Trigger />
<AlertDialog.Overlay />
<AlertDialog.Content>
<AlertDialog.Title />
<AlertDialog.Description />
<AlertDialog.Cancel />
<AlertDialog.Action />
</AlertDialog.Content>
</AlertDialog.Root>
);

Contains all the parts of an alert dialog.

PropTypeDefault
defaultOpenbooleanNo default value
openbooleanNo default value
onOpenChangefunctionNo default value
idstringNo default value

A button that opens the dialog.

PropTypeDefault
asChildbooleanfalse

A layer that covers the inert portion of the view when the dialog is open.

PropTypeDefault
asChildbooleanfalse
forceMountbooleanNo default value

Contains content to be rendered when the dialog is open.

PropTypeDefault
asChildbooleanfalse
forceMountbooleanNo default value
onOpenAutoFocusfunctionNo default value
onCloseAutoFocusfunctionNo default value
onEscapeKeyDownfunctionNo default value

A button that closes the dialog. This button should be distinguished visually from AlertDialog.Action buttons.

PropTypeDefault
asChildbooleanfalse

A button that closes the dialog. These buttons should be distinguished visually from the AlertDialog.Cancel button.

PropTypeDefault
asChildbooleanfalse

An accessible name to be announced when the dialog is opened. Alternatively, you can provide aria-label or aria-labelledby to AlertDialog.Content and exclude this component.

PropTypeDefault
asChildbooleanfalse

An accessible description to be announced when the dialog is opened. Alternatively, you can provide aria-describedby to AlertDialog.Content and exclude this component.

PropTypeDefault
asChildbooleanfalse

Adheres to the Alert and Message Dialogs WAI-ARIA design pattern.

KeyDescription
SpaceOpens/closes the dialog.
EnterOpens/closes the dialog.
TabMoves focus to the next focusable element.
Shift + TabMoves focus to the previous focusable element.
EscCloses the dialog and moves focus to AlertDialog.Trigger.