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) forwards`,
},
});
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) forwards`,
},
'&:focus': { outline: 'none' },
});
function Content({ children, ...props }) {
return (
<AlertDialogPrimitive.Portal>
<StyledOverlay />
<StyledContent {...props}>{children}</StyledContent>
</AlertDialogPrimitive.Portal>
);
}
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
export const AlertDialog = AlertDialogPrimitive.Root;
export const AlertDialogTrigger = AlertDialogPrimitive.Trigger;
export const AlertDialogContent = Content;
export const AlertDialogTitle = StyledTitle;
export const AlertDialogDescription = StyledDescription;
export const AlertDialogAction = AlertDialogPrimitive.Action;
export 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;
Title
and Description
components.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.Portal>
<AlertDialog.Overlay />
<AlertDialog.Content>
<AlertDialog.Title />
<AlertDialog.Description />
<AlertDialog.Cancel />
<AlertDialog.Action />
</AlertDialog.Content>
</AlertDialog.Portal>
</AlertDialog.Root>
);
Contains all the parts of an alert dialog.
Prop | Type | Default |
---|---|---|
defaultOpen | boolean | |
open | boolean | |
onOpenChange | function | |
allowPinchZoom | boolean | false |
id | string |
A button that opens the dialog.
Prop | Type | Default |
---|---|---|
asChild | boolean | false |
When used, portals your overlay and content parts into the body
.
Prop | Type | Default |
---|---|---|
forceMount | boolean | |
container | HTMLElement | document.body |
A layer that covers the inert portion of the view when the dialog is open.
Prop | Type | Default |
---|---|---|
asChild | boolean | false |
forceMount | boolean |
Contains content to be rendered when the dialog is open.
Prop | Type | Default |
---|---|---|
asChild | boolean | false |
forceMount | boolean | |
onOpenAutoFocus | function | |
onCloseAutoFocus | function | |
onEscapeKeyDown | function |
A button that closes the dialog. This button should be distinguished visually from AlertDialog.Action
buttons.
Prop | Type | Default |
---|---|---|
asChild | boolean | false |
A button that closes the dialog. These buttons should be distinguished visually from the AlertDialog.Cancel
button.
Prop | Type | Default |
---|---|---|
asChild | boolean | false |
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.
Prop | Type | Default |
---|---|---|
asChild | boolean | false |
An accessible description to be announced when the dialog is opened. Alternatively, you can provide aria-describedby
to AlertDialog.Content
and exclude this component.
Prop | Type | Default |
---|---|---|
asChild | boolean | false |
Customise the element that your alert dialog portals into.
export default () => {
const [container, setContainer] = React.useState(null);
return (
<div>
<AlertDialog.Root>
<AlertDialog.Trigger />
<AlertDialog.Portal container={container}>
<AlertDialog.Overlay />
<AlertDialog.Content>...</AlertDialog.Content>
</AlertDialog.Portal>
</AlertDialog.Root>
<div ref={setContainer} />
</div>
);
};
Adheres to the Alert and Message Dialogs WAI-ARIA design pattern.
Key | Description |
---|---|
Space | Opens/closes the dialog. |
Enter | Opens/closes the dialog. |
Tab | Moves focus to the next focusable element. |
Shift + Tab | Moves focus to the previous focusable element. |
Esc | Closes the dialog and moves focus to AlertDialog.Trigger . |