Alert Dialog
<script setup lang="ts">
import {
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogOverlay,
AlertDialogPortal,
AlertDialogRoot,
AlertDialogTitle,
AlertDialogTrigger,
} from 'radix-vue'
function handleAction() {
alert('clicked action button!')
}
</script>
<template>
<AlertDialogRoot>
<AlertDialogTrigger
class="bg-white text-grass11 font-semibold hover:bg-white/90 shadow-sm inline-flex h-[35px] items-center justify-center rounded-[4px] px-[15px] leading-none outline-none focus:shadow-[0_0_0_2px] focus:shadow-black transition-all"
>
Delete account
</AlertDialogTrigger>
<AlertDialogPortal>
<AlertDialogOverlay class="bg-blackA9 data-[state=open]:animate-overlayShow fixed inset-0 z-30" />
<AlertDialogContent
class="z-[100] text-[15px] data-[state=open]:animate-contentShow fixed top-[50%] left-[50%] max-h-[85vh] w-[90vw] max-w-[500px] translate-x-[-50%] translate-y-[-50%] rounded-[6px] bg-white p-[25px] shadow-[hsl(206_22%_7%_/_35%)_0px_10px_38px_-10px,_hsl(206_22%_7%_/_20%)_0px_10px_20px_-15px] focus:outline-none"
>
<AlertDialogTitle class="text-mauve12 m-0 text-[17px] font-semibold">
Are you absolutely sure?
</AlertDialogTitle>
<AlertDialogDescription class="text-mauve11 mt-4 mb-5 text-[15px] leading-normal">
This action cannot be undone. This will permanently delete your account and remove your data from our servers.
</AlertDialogDescription>
<div class="flex justify-end gap-[25px]">
<AlertDialogCancel
class="text-mauve11 bg-mauve4 hover:bg-mauve5 focus:shadow-mauve7 inline-flex h-[35px] items-center justify-center rounded-[4px] px-[15px] font-semibold leading-none outline-none focus:shadow-[0_0_0_2px]"
>
Cancel
</AlertDialogCancel>
<AlertDialogAction
class="text-red11 bg-red4 hover:bg-red5 focus:shadow-red7 inline-flex h-[35px] items-center justify-center rounded-[4px] px-[15px] font-semibold leading-none outline-none focus:shadow-[0_0_0_2px]"
@click="handleAction"
>
Yes, delete account
</AlertDialogAction>
</div>
</AlertDialogContent>
</AlertDialogPortal>
</AlertDialogRoot>
</template>
Features
- Focus is automatically trapped.
- Can be controlled or uncontrolled.
- Manages screen reader announcements with
Title
andDescription
components. - Esc closes the component automatically.
Installation
Install the component from your command line.
npm install radix-vue
Anatomy
Import all parts and piece them together.
<script setup lang="ts">
import {
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogOverlay,
AlertDialogPortal,
AlertDialogRoot,
AlertDialogTitle,
AlertDialogTrigger,
} from 'radix-vue'
</script>
<template>
<AlertDialogRoot>
<AlertDialogTrigger />
<AlertDialogPortal>
<AlertDialogOverlay />
<AlertDialogContent>
<AlertDialogTitle />
<AlertDialogDescription />
<AlertDialogCancel />
<AlertDialogAction />
</AlertDialogContent>
</AlertDialogPortal>
</AlertDialogRoot>
</template>
API Reference
Root
Contains all the parts of an alert dialog.
Prop | Default | Type |
---|---|---|
defaultOpen | boolean The open state of the dialog when it is initially rendered. Use when you do not need to control its open state. | |
open | boolean The controlled open state of the dialog. Can be binded as |
Emit | Payload |
---|---|
update:open | [value: boolean] Event handler called when the open state of the dialog changes. |
Trigger
A button that opens the dialog.
Prop | Default | Type |
---|---|---|
as | 'div' | AsTag | Component The element or component this component should render as. Can be overwrite by |
asChild | boolean Change the default rendered element for the one passed as a child, merging their props and behavior. Read our Composition guide for more details. |
Data Attribute | Value |
---|---|
[data-state] | "open" | "closed" |
Portal
When used, portals your overlay and content parts into the body
.
Prop | Default | Type |
---|---|---|
disabled | boolean Disable teleport and render the component inline | |
forceMount | boolean Used to force mounting when more control is needed. Useful when controlling animation with Vue animation libraries. | |
to | string | HTMLElement Vue native teleport component prop |
Overlay
A layer that covers the inert portion of the view when the dialog is open.
Prop | Default | Type |
---|---|---|
as | 'div' | AsTag | Component The element or component this component should render as. Can be overwrite by |
asChild | boolean Change the default rendered element for the one passed as a child, merging their props and behavior. Read our Composition guide for more details. | |
forceMount | boolean Used to force mounting when more control is needed. Useful when controlling animation with Vue animation libraries. |
Data Attribute | Value |
---|---|
[data-state] | "open" | "closed" |
Content
Contains content to be rendered when the dialog is open.
Prop | Default | Type |
---|---|---|
as | 'div' | AsTag | Component The element or component this component should render as. Can be overwrite by |
asChild | boolean Change the default rendered element for the one passed as a child, merging their props and behavior. Read our Composition guide for more details. | |
disableOutsidePointerEvents | boolean When | |
forceMount | boolean Used to force mounting when more control is needed. Useful when controlling animation with Vue animation libraries. | |
trapFocus | boolean When |
Emit | Payload |
---|---|
closeAutoFocus | [event: Event] Event handler called when auto-focusing on close. Can be prevented. |
escapeKeyDown | [event: KeyboardEvent] Event handler called when the escape key is down. Can be prevented. |
focusOutside | [event: FocusOutsideEvent] Event handler called when the focus moves outside of the |
interactOutside | [event: PointerDownOutsideEvent | FocusOutsideEvent] Event handler called when an interaction happens outside the |
openAutoFocus | [event: Event] Event handler called when auto-focusing on open. Can be prevented. |
pointerDownOutside | [event: PointerDownOutsideEvent] Event handler called when the a |
Data Attribute | Value |
---|---|
[data-state] | "open" | "closed" |
Cancel
A button that closes the dialog. This button should be distinguished visually from AlertDialogAction
buttons.
Prop | Default | Type |
---|---|---|
as | 'div' | AsTag | Component The element or component this component should render as. Can be overwrite by |
asChild | boolean Change the default rendered element for the one passed as a child, merging their props and behavior. Read our Composition guide for more details. |
Action
A button that closes the dialog. These buttons should be distinguished visually from the AlertDialogCancel
button.
Prop | Default | Type |
---|---|---|
as | 'div' | AsTag | Component The element or component this component should render as. Can be overwrite by |
asChild | boolean Change the default rendered element for the one passed as a child, merging their props and behavior. Read our Composition guide for more details. |
Title
An accessible name to be announced when the dialog is opened. Alternatively, you can provide aria-label
or aria-labelledby
to AlertDialogContent
and exclude this component.
Prop | Default | Type |
---|---|---|
as | 'div' | AsTag | Component The element or component this component should render as. Can be overwrite by |
asChild | boolean Change the default rendered element for the one passed as a child, merging their props and behavior. Read our Composition guide for more details. |
Description
An accessible description to be announced when the dialog is opened. Alternatively, you can provide aria-describedby
to AlertDialogContent
and exclude this component.
Prop | Default | Type |
---|---|---|
as | 'div' | AsTag | Component The element or component this component should render as. Can be overwrite by |
asChild | boolean Change the default rendered element for the one passed as a child, merging their props and behavior. Read our Composition guide for more details. |
Examples
Close after asynchronous form submission
Use the controlled props to programmatically close the Alert Dialog after an async operation has completed.
<script setup>
import {
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogOverlay,
AlertDialogPortal,
AlertDialogRoot,
AlertDialogTitle,
AlertDialogTrigger,
} from 'radix-vue'
const wait = () => new Promise(resolve => setTimeout(resolve, 1000))
const open = ref(false)
</script>
<template>
<AlertDialogRoot v-model:open="open">
<AlertDialogTrigger>Open</AlertDialogTrigger>
<AlertDialogPortal>
<AlertDialogOverlay />
<AlertDialogContent>
<form
@submit.prevent="
(event) => {
wait().then(() => open = false);
}
"
>
<!-- some inputs -->
<button type="submit">
Submit
</button>
</form>
</AlertDialogContent>
</AlertDialogPortal>
</AlertDialogRoot>
</template>
Custom portal container
Customise the element that your alert dialog portals into.
<script setup>
import { ref } from 'vue'
const container = ref(null)
</script>
<template>
<div>
<AlertDialogRoot>
<AlertDialogTrigger />
<AlertDialogPortal :to="container">
<AlertDialogOverlay />
<AlertDialogContent>...</AlertDialogContent>
</AlertDialogPortal>
</AlertDialogRoot>
<div ref="container" />
</div>
</template>
Accessibility
Adheres to the Alert and Message Dialogs WAI-ARIA design pattern.
Keyboard Interactions
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 AlertDialogTrigger . |