Overview
Dialog provides a fully-featured modal dialog system using the native <dialog> element. It includes automatic focus trapping, backdrop dismissal, escape key handling, and z-index coordination for multiple overlays.
Installation
import { Dialog } from '@vuetify/v0'
Dialog requires createStackPlugin to be installed at the app level for z-index coordination.
Basic Usage
<script setup lang="ts">
import { Dialog } from '@vuetify/v0'
</script>
<template>
<Dialog.Root>
<Dialog.Activator>
Open Dialog
</Dialog.Activator>
<Dialog.Content>
<Dialog.Title>Dialog Title</Dialog.Title>
<Dialog.Description>Dialog description text.</Dialog.Description>
<p>Dialog content goes here.</p>
<Dialog.Close>Close</Dialog.Close>
</Dialog.Content>
</Dialog.Root>
</template>
v-model Binding
Control dialog state externally:
<script setup lang="ts">
import { ref } from 'vue'
import { Dialog } from '@vuetify/v0'
const isOpen = ref(false)
</script>
<template>
<Dialog.Root v-model="isOpen">
<Dialog.Activator>
Open Dialog
</Dialog.Activator>
<Dialog.Content>
<Dialog.Title>Controlled Dialog</Dialog.Title>
<Dialog.Close>Close</Dialog.Close>
</Dialog.Content>
</Dialog.Root>
<button @click="isOpen = true">Open from outside</button>
</template>
Blocking Dialogs
Prevent backdrop dismissal for critical dialogs:
<Dialog.Root>
<Dialog.Activator>Open Critical Dialog</Dialog.Activator>
<Dialog.Content :blocking="true">
<Dialog.Title>Action Required</Dialog.Title>
<p>This dialog requires explicit user action.</p>
<Dialog.Close>Confirm</Dialog.Close>
</Dialog.Content>
</Dialog.Root>
Use blocking dialogs for destructive actions or when explicit user confirmation is required.
Disable Backdrop Dismissal
<Dialog.Content :close-on-click-outside="false">
<Dialog.Title>No Backdrop Dismissal</Dialog.Title>
<p>Must use close button.</p>
<Dialog.Close>Close</Dialog.Close>
</Dialog.Content>
Custom Namespace
Use custom namespaces for nested dialog contexts:
<Dialog.Root namespace="custom-dialog">
<Dialog.Activator namespace="custom-dialog">
Open
</Dialog.Activator>
<Dialog.Content namespace="custom-dialog">
<Dialog.Title namespace="custom-dialog">Title</Dialog.Title>
<Dialog.Close namespace="custom-dialog">Close</Dialog.Close>
</Dialog.Content>
</Dialog.Root>
Component API
Dialog.Root
Root component that manages dialog state and provides context.
as
string | Component
default:"null"
Element or component to render as (renderless by default).
namespace
string
default:"'v0:dialog'"
Namespace for dependency injection.
Unique identifier for the dialog (auto-generated if not provided).
Controls the open/closed state of the dialog.
Slot Props
interface DialogRootSlotProps {
id: string
isOpen: boolean
open: () => void
close: () => void
}
Dialog.Activator
Button that opens the dialog when clicked.
as
string | Component
default:"'button'"
Element or component to render as.
namespace
string
default:"'v0:dialog'"
Namespace for dependency injection.
Slot Props
interface DialogActivatorSlotProps {
isOpen: boolean
attrs: {
'type': 'button' | undefined
'aria-haspopup': 'dialog'
'aria-expanded': boolean
'data-dialog-open': '' | undefined
}
}
Dialog.Content
Dialog content panel using native <dialog> element.
as
string | Component
default:"'dialog'"
Element or component to render as.
namespace
string
default:"'v0:dialog'"
Namespace for dependency injection.
Close dialog when clicking outside content.
When true, clicking the scrim will not dismiss this dialog. Use for critical dialogs requiring explicit user action.
Events
Emitted when dialog is cancelled (e.g., via Escape key).
Emitted when dialog closes.
Slot Props
interface DialogContentSlotProps {
isOpen: boolean
globalTop: boolean
zIndex: number
attrs: {
'id': string
'role': 'dialog'
'aria-modal': 'true'
'aria-labelledby': string
'aria-describedby': string
}
}
Dialog.Title
Accessible title for the dialog.
as
string | Component
default:"'h2'"
Element or component to render as.
namespace
string
default:"'v0:dialog'"
Namespace for dependency injection.
Slot Props
interface DialogTitleSlotProps {
attrs: {
id: string
}
}
Dialog.Description
Accessible description for the dialog.
as
string | Component
default:"'p'"
Element or component to render as.
namespace
string
default:"'v0:dialog'"
Namespace for dependency injection.
Slot Props
interface DialogDescriptionSlotProps {
attrs: {
id: string
}
}
Dialog.Close
Button that closes the dialog when clicked.
as
string | Component
default:"'button'"
Element or component to render as.
namespace
string
default:"'v0:dialog'"
Namespace for dependency injection.
Slot Props
interface DialogCloseSlotProps {
isOpen: boolean
attrs: {
'type': 'button' | undefined
'aria-label': 'Close'
}
}
Accessibility
- Uses native
<dialog> element with showModal() for proper modal behavior
- Automatic focus trapping and restoration
- Escape key handling built-in
- ARIA attributes automatically managed:
role="dialog"
aria-modal="true"
aria-labelledby links to Dialog.Title
aria-describedby links to Dialog.Description
- Backdrop click dismissal (can be disabled)
Context API
import { useDialogContext } from '@vuetify/v0'
const context = useDialogContext('v0:dialog')
interface DialogContext {
isOpen: ShallowRef<boolean>
id: string
titleId: string
descriptionId: string
open: () => void
close: () => void
}