# Dialog
URL: https://ark-ui.com/docs/components/dialog
Source: https://raw.githubusercontent.com/chakra-ui/ark/refs/heads/main/website/src/content/pages/components/dialog.mdx
A modal window that appears on top of the main content.
---
## Anatomy
To use the dialog component correctly, you'll need to understand its anatomy and how we name its parts.
> Each part includes a `data-part` attribute to help identify them in the DOM.
## Examples
Learn how to use the `Dialog` component in your project. Let's take a look at the most basic example
**Example: basic**
#### React
```tsx
import { Dialog } from '@ark-ui/react/dialog'
import { Portal } from '@ark-ui/react/portal'
import { XIcon } from 'lucide-react'
export const Basic = () => (
Open DialogDialog TitleDialog Description
)
```
#### Solid
```tsx
import { XIcon } from 'lucide-solid'
import { Dialog } from '@ark-ui/solid/dialog'
import { Portal } from 'solid-js/web'
export const Basic = () => {
return (
Open DialogDialog TitleDialog Description
)
}
```
#### Vue
```vue
Open DialogDialog TitleDialog Description
```
#### Svelte
```svelte
Open DialogDialog TitleDialog Description
```
### Controlled
To create a controlled Dialog component, manage the state of the dialog using the `open` and `onOpenChange` props:
**Example: controlled**
#### React
```tsx
import { Dialog } from '@ark-ui/react/dialog'
import { Portal } from '@ark-ui/react/portal'
import { XIcon } from 'lucide-react'
import { useState } from 'react'
export const Controlled = () => {
const [isOpen, setIsOpen] = useState(false)
return (
<>
setIsOpen(e.open)}>
Dialog TitleDialog Description
>
)
}
```
#### Solid
```tsx
import { XIcon } from 'lucide-solid'
import { Dialog } from '@ark-ui/solid/dialog'
import { createSignal } from 'solid-js'
import { Portal } from 'solid-js/web'
export const Controlled = () => {
const [open, setOpen] = createSignal(false)
return (
<>
setOpen(false)}>
Dialog TitleDialog Description
>
)
}
```
#### Vue
```vue
Dialog TitleDialog Description
```
#### Svelte
```svelte
Controlled DialogThis dialog's open state is controlled externally.
```
### Lazy Mount
Lazy mounting is a feature that allows the content of a dialog to be rendered only when the dialog is first opened. This
is useful for performance optimization, especially when dialog content is large or complex. To enable lazy mounting, use
the `lazyMount` prop on the `Dialog.Root` component.
In addition, the `unmountOnExit` prop can be used in conjunction with `lazyMount` to unmount the dialog content when the
Dialog is closed, freeing up resources. The next time the dialog is activated, its content will be re-rendered.
**Example: lazy-mount**
#### React
```tsx
import { Dialog } from '@ark-ui/react/dialog'
import { Portal } from '@ark-ui/react/portal'
import { XIcon } from 'lucide-react'
export const LazyMount = () => (
console.log('onExitComplete invoked')}>
Open DialogDialog TitleDialog Description
)
```
#### Solid
```tsx
import { XIcon } from 'lucide-solid'
import { Dialog } from '@ark-ui/solid/dialog'
export const LazyMount = () => {
return (
Open DialogDialog TitleDialog Description
)
}
```
#### Vue
```vue
Open DialogDialog TitleDialog Description
```
#### Svelte
```svelte
console.log('onExitComplete invoked')}>
Open DialogLazy Mounted DialogThis dialog content is only rendered when the dialog is first opened.
```
### Alert Dialog
For critical confirmations or destructive actions, use `role="alertdialog"`. Alert dialogs differ from regular dialogs
in important ways:
- **Automatic focus**: The close/cancel button receives focus when opened, prioritizing the safest action
- **Requires explicit dismissal**: Cannot be closed by clicking outside, only via button clicks or Escape key
**Example: alert-dialog**
#### React
```tsx
import { Dialog } from '@ark-ui/react/dialog'
import { Portal } from '@ark-ui/react/portal'
import { XIcon } from 'lucide-react'
export const AlertDialog = () => (
Delete AccountAre you absolutely sure?
This action cannot be undone. This will permanently delete your account and remove your data from our
servers.
)
```
#### Solid
```tsx
import { XIcon } from 'lucide-solid'
import { Dialog } from '@ark-ui/solid/dialog'
import { Portal } from 'solid-js/web'
export const AlertDialog = () => {
return (
Delete AccountAre you absolutely sure?
This action cannot be undone. This will permanently delete your account and remove your data from our
servers.
)
}
```
#### Vue
```vue
Delete AccountAre you absolutely sure?
This action cannot be undone. This will permanently delete your account and remove your data from our
servers.
Cancel
```
#### Svelte
```svelte
Delete AccountAre you absolutely sure?
This action cannot be undone. This will permanently delete your account and remove your data from our servers.
Cancel
```
### Initial Focus
Control which element receives focus when the dialog opens using the `initialFocusEl` prop. This is useful for forms
where you want to focus a specific input field:
**Example: initial-focus**
#### React
```tsx
import { Dialog } from '@ark-ui/react/dialog'
import { Portal } from '@ark-ui/react/portal'
import { XIcon } from 'lucide-react'
import { useRef } from 'react'
export const InitialFocus = () => {
const inputRef = useRef(null)
return (
inputRef.current}>
Open DialogEdit Profile
Make changes to your profile here. The first input will be focused when the dialog opens.
)
}
```
#### Solid
```tsx
import { XIcon } from 'lucide-solid'
import { Dialog } from '@ark-ui/solid/dialog'
import { Portal } from 'solid-js/web'
export const InitialFocus = () => {
let inputRef: HTMLInputElement | null = null
return (
inputRef}>
Open DialogEdit Profile
Make changes to your profile here. The first input will be focused when the dialog opens.
)
}
```
#### Vue
```vue
Open DialogEdit Profile
Make changes to your profile here. The first input will be focused when the dialog opens.
```
#### Svelte
```svelte
inputRef}>
Open DialogEdit Profile
Make changes to your profile here. The first input will be focused when the dialog opens.
```
### Final Focus
Control which element receives focus when the dialog closes using the `finalFocusEl` prop. By default, focus returns to
the trigger element, but you can specify a different element:
**Example: final-focus**
#### React
```tsx
import { Dialog } from '@ark-ui/react/dialog'
import { Portal } from '@ark-ui/react/portal'
import { XIcon } from 'lucide-react'
import { useRef } from 'react'
export const FinalFocus = () => {
const finalRef = useRef(null)
return (
<>
finalRef.current}>
Open DialogDialog Title
When this dialog closes, focus will return to the button above instead of the trigger.
>
)
}
```
#### Solid
```tsx
import { XIcon } from 'lucide-solid'
import { Dialog } from '@ark-ui/solid/dialog'
import { Portal } from 'solid-js/web'
export const FinalFocus = () => {
let finalRef: HTMLButtonElement | null = null
return (
<>
finalRef}>
Open DialogDialog Title
When this dialog closes, focus will return to the button above instead of the trigger.
>
)
}
```
#### Vue
```vue
Open DialogDialog Title
When this dialog closes, focus will return to the button above instead of the trigger.
```
#### Svelte
```svelte
finalRef}>
Open DialogDialog Title
When this dialog closes, focus will return to the button above instead of the trigger.
```
### Non-Modal Dialog
Use `modal={false}` to create a non-modal dialog that allows interaction with elements outside of it. This disables
focus trapping, scroll prevention, and pointer blocking, making it useful for auxiliary panels or inspector windows:
**Example: non-modal**
#### React
```tsx
import { Dialog } from '@ark-ui/react/dialog'
import { Portal } from '@ark-ui/react/portal'
import { XIcon } from 'lucide-react'
export const NonModal = () => (
Open Non-Modal DialogNon-Modal Dialog
This dialog allows interaction with elements outside. You can click buttons, select text, and interact with
the page behind it.
)
```
#### Solid
```tsx
import { XIcon } from 'lucide-solid'
import { Dialog } from '@ark-ui/solid/dialog'
import { Portal } from 'solid-js/web'
export const NonModal = () => {
return (
Open Non-Modal DialogNon-Modal Dialog
This dialog allows interaction with elements outside. You can click buttons, select text, and interact
with the page behind it.
)
}
```
#### Vue
```vue
Open Non-Modal DialogNon-Modal Dialog
This dialog allows interaction with elements outside. You can click buttons, select text, and interact with
the page behind it.
```
#### Svelte
```svelte
Open Non-Modal DialogNon-Modal Dialog
This dialog allows interaction with elements outside. You can click buttons, select text, and interact with
the page behind it.
```
### Close on Interact Outside
Prevent the dialog from closing when clicking outside by setting `closeOnInteractOutside={false}`. Use the
`onInteractOutside` event with `e.preventDefault()` for advanced control:
**Example: close-on-interact-outside**
#### React
```tsx
import { Dialog } from '@ark-ui/react/dialog'
import { Portal } from '@ark-ui/react/portal'
import { XIcon } from 'lucide-react'
export const CloseOnInteractOutside = () => (
{
const target = e.target as HTMLElement
if (target.closest('[data-allow-close]')) {
return
}
e.preventDefault()
}}
>
Open DialogCustom Close Behavior
This dialog will not close when clicking outside. Try clicking the backdrop or pressing Escape to see that
it stays open. Only the close button will dismiss it.
)
```
#### Solid
```tsx
import { XIcon } from 'lucide-solid'
import { Dialog } from '@ark-ui/solid/dialog'
import { Portal } from 'solid-js/web'
export const CloseOnInteractOutside = () => {
return (
{
const target = e.target as HTMLElement
if (target.closest('[data-allow-close]')) {
return
}
e.preventDefault()
}}
>
Open DialogCustom Close Behavior
This dialog will not close when clicking outside. Try clicking the backdrop or pressing Escape to see that
it stays open. Only the close button will dismiss it.
)
}
```
#### Vue
```vue
Open DialogCustom Close Behavior
This dialog will not close when clicking outside. Try clicking the backdrop or pressing Escape to see that
it stays open. Only the close button will dismiss it.
```
#### Svelte
```svelte
Open DialogCustom Close Behavior
This dialog will not close when clicking outside. Try clicking the backdrop or pressing
Escape to see that it stays open. Only the close button will dismiss it.
```
### Close on Escape
Prevent the dialog from closing when pressing Escape by setting `closeOnEscape={false}`. Use the `onEscapeKeyDown` event
with `e.preventDefault()` to implement custom behavior like unsaved changes warnings:
**Example: close-on-escape**
#### React
```tsx
import { Dialog } from '@ark-ui/react/dialog'
import { Portal } from '@ark-ui/react/portal'
import { XIcon } from 'lucide-react'
export const CloseOnEscape = () => (
{
const hasUnsavedChanges = true
if (hasUnsavedChanges) {
e.preventDefault()
alert('You have unsaved changes. Please save or discard them before closing.')
}
}}
>
Open DialogUnsaved Changes
This dialog prevents closing with Escape key. Try pressing Escape to see the warning. Use the close button
to dismiss.
)
```
#### Solid
```tsx
import { XIcon } from 'lucide-solid'
import { Dialog } from '@ark-ui/solid/dialog'
import { Portal } from 'solid-js/web'
export const CloseOnEscape = () => {
return (
{
const hasUnsavedChanges = true
if (hasUnsavedChanges) {
e.preventDefault()
alert('You have unsaved changes. Please save or discard them before closing.')
}
}}
>
Open DialogUnsaved Changes
This dialog prevents closing with Escape key. Try pressing Escape to see the warning. Use the close button
to dismiss.
)
}
```
#### Vue
```vue
Open DialogUnsaved Changes
This dialog prevents closing with Escape key. Try pressing Escape to see the warning. Use the close button
to dismiss.
```
#### Svelte
```svelte
Open DialogUnsaved Changes
This dialog prevents closing with Escape key. Try pressing Escape to see the warning. Use the close button to
dismiss.
```
### Render Function
Use the `Dialog.Context` component to access the dialog's state and methods.
**Example: render-fn**
#### React
```tsx
import { Dialog } from '@ark-ui/react/dialog'
import { Portal } from '@ark-ui/react/portal'
import { XIcon } from 'lucide-react'
export const RenderFn = () => (
Open DialogDialog TitleDialog Description{(dialog) =>
Dialog is {dialog.open ? 'open' : 'closed'}
}
)
```
#### Solid
```tsx
import { XIcon } from 'lucide-solid'
import { Dialog } from '@ark-ui/solid/dialog'
import { Portal } from 'solid-js/web'
export const RenderFn = () => {
return (
Open DialogDialog TitleDialog Description{(context) =>
```
#### Svelte
```svelte
{#snippet children(dialog)}
{dialog().open ? 'Close' : 'Open'} DialogDialog State: {dialog().open ? 'Open' : 'Closed'}This example uses a render function to access dialog state.
{/snippet}
```
### Root Provider
The `useDialog` hook gives you programmatic access to the dialog's state and methods. Use it with `Dialog.RootProvider`
when you need to control the dialog from outside its component tree.
**Example: root-provider**
#### React
```tsx
import { Dialog, useDialog } from '@ark-ui/react/dialog'
import { Portal } from '@ark-ui/react/portal'
import { XIcon } from 'lucide-react'
export const RootProvider = () => {
const dialog = useDialog()
return (
<>
Open DialogDialog TitleDialog Description
>
)
}
```
#### Solid
```tsx
import { XIcon } from 'lucide-solid'
import { Dialog, useDialog } from '@ark-ui/solid/dialog'
import { Portal } from 'solid-js/web'
export const RootProvider = () => {
const dialog = useDialog()
return (
<>
Open DialogDialog TitleDialog Description
>
)
}
```
#### Vue
```vue
Open DialogDialog TitleDialog Description
```
#### Svelte
```svelte
Open DialogDialog TitleDialog Description
```
> **Note:** There are two ways to use the Dialog component: (1) `Dialog.Root` for declarative usage, or (2)
> `useDialog()` + `Dialog.RootProvider` for programmatic control with access to state properties and methods like
> `setOpen()`. Never use both approaches together - choose one based on your needs.
### Nested Dialogs
Multiple dialogs can be stacked with automatic z-index management. Zag.js manages layering through CSS variables like
`--z-index` and `--layer-index`, which are automatically updated when dialogs are opened or closed:
**Example: nested**
#### React
```tsx
import { Dialog, useDialog } from '@ark-ui/react/dialog'
import { Portal } from '@ark-ui/react/portal'
import { XIcon } from 'lucide-react'
export const Nested = () => {
const parentDialog = useDialog()
const childDialog = useDialog()
return (
<>
Parent Dialog
This is the parent dialog. Open a nested dialog from here to see automatic z-index management via CSS
variables like --z-index and --layer-index.
Nested Dialog
This dialog is nested within the parent. Notice how it layers on top with proper z-index management.
>
)
}
```
#### Solid
```tsx
import { XIcon } from 'lucide-solid'
import { Dialog, useDialog } from '@ark-ui/solid/dialog'
import { Portal } from 'solid-js/web'
export const Nested = () => {
const parentDialog = useDialog()
const childDialog = useDialog()
return (
<>
Parent Dialog
This is the parent dialog. Open a nested dialog from here to see automatic z-index management via CSS
variables like --z-index and --layer-index.
Nested Dialog
This dialog is nested within the parent. Notice how it layers on top with proper z-index management.
>
)
}
```
#### Vue
```vue
Parent Dialog
This is the parent dialog. Open a nested dialog from here to see automatic z-index management via CSS
variables like --z-index and --layer-index.
Nested Dialog
This dialog is nested within the parent. Notice how it layers on top with proper z-index management.
```
#### Svelte
```svelte
Parent Dialog
This is the parent dialog. Open a nested dialog from here to see automatic z-index management via CSS
variables like `--z-index` and `--layer-index`.
Nested Dialog
This dialog is nested within the parent. Notice how it layers on top with proper z-index management.
```
### Confirmation Dialog
Dialogs can intercept close attempts to show confirmation prompts. This pattern is useful for preventing data loss from
unsaved changes:
**Example: confirmation**
#### React
```tsx
import { Dialog, useDialog } from '@ark-ui/react/dialog'
import { Portal } from '@ark-ui/react/portal'
import { XIcon } from 'lucide-react'
import { useState } from 'react'
export const Confirmation = () => {
const [formContent, setFormContent] = useState('')
const [isParentDialogOpen, setIsParentDialogOpen] = useState(false)
const parentDialog = useDialog({
open: isParentDialogOpen,
onOpenChange: (details) => {
if (!details.open && formContent.trim()) {
confirmDialog.setOpen(true)
} else {
setIsParentDialogOpen(details.open)
}
},
})
const confirmDialog = useDialog()
const handleConfirmClose = () => {
confirmDialog.setOpen(false)
parentDialog.setOpen(false)
setFormContent('')
}
return (
<>
Edit Content
Make changes to your content. If you have unsaved changes, you'll be asked to confirm before closing.
Unsaved Changes
You have unsaved changes. Are you sure you want to close without saving?
>
)
}
```
#### Solid
```tsx
import { XIcon } from 'lucide-solid'
import { Dialog, useDialog } from '@ark-ui/solid/dialog'
import { createSignal } from 'solid-js'
import { Portal } from 'solid-js/web'
export const Confirmation = () => {
const [formContent, setFormContent] = createSignal('')
const parentDialog = useDialog({
onOpenChange: (details) => {
if (!details.open && formContent().trim()) {
confirmDialog().setOpen(true)
}
},
})
const confirmDialog = useDialog()
const handleConfirmClose = () => {
confirmDialog().setOpen(false)
parentDialog().setOpen(false)
setFormContent('')
}
return (
<>
Edit Content
Make changes to your content. If you have unsaved changes, you'll be asked to confirm before closing.
Unsaved Changes
You have unsaved changes. Are you sure you want to close without saving?
>
)
}
```
#### Vue
```vue
Edit Content
Make changes to your content. If you have unsaved changes, you'll be asked to confirm before closing.
Unsaved Changes
You have unsaved changes. Are you sure you want to close without saving?
```
#### Svelte
```svelte
Edit Content
Make changes to your content. If you have unsaved changes, you'll be asked to confirm before closing.
Unsaved Changes
You have unsaved changes. Are you sure you want to close without saving?
```
## Guides
### Nested Dialog Styling
You can create a zoom-out effect for parent dialogs using the `data-has-nested` attribute and `--nested-layer-count`
variable:
```css
[data-scope='dialog'][data-part='backdrop'][data-has-nested] {
transform: scale(calc(1 - var(--nested-layer-count) * 0.05));
}
```
### Lazy Mount and Dynamic Imports
When using `lazyMount` and dynamically rendering components in the dialog (via `React.lazy`, Next.js `dynamic`), wrap
the imported component in a `Suspense` component to render a fallback.
```tsx
import { Dialog } from '@ark-ui/react/dialog'
import { Suspense } from 'react'
import dynamic from 'next/dynamic'
const HeavyComponent = dynamic(() => import('./HeavyComponent'))
export default function DialogExample() {
return (
Open DialogLoading...}>
)
}
```
## API Reference
### Props
**Component API Reference**
#### React
**Root Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `aria-label` | `string` | No | Human readable label for the dialog, in event the dialog title is not rendered |
| `closeOnEscape` | `boolean` | No | Whether to close the dialog when the escape key is pressed |
| `closeOnInteractOutside` | `boolean` | No | Whether to close the dialog when the outside is clicked |
| `defaultOpen` | `boolean` | No | The initial open state of the dialog when rendered.
Use when you don't need to control the open state of the dialog. |
| `finalFocusEl` | `() => MaybeElement` | No | Element to receive focus when the dialog is closed |
| `id` | `string` | No | The unique identifier of the machine. |
| `ids` | `Partial<{
trigger: string
positioner: string
backdrop: string
content: string
closeTrigger: string
title: string
description: string
}>` | No | The ids of the elements in the dialog. Useful for composition. |
| `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame |
| `initialFocusEl` | `() => MaybeElement` | No | Element to receive focus when the dialog is opened |
| `lazyMount` | `boolean` | No | Whether to enable lazy mounting |
| `modal` | `boolean` | No | Whether to prevent pointer interaction outside the element and hide all content below it |
| `onEscapeKeyDown` | `(event: KeyboardEvent) => void` | No | Function called when the escape key is pressed |
| `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state |
| `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component |
| `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component |
| `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function to call when the dialog's open state changes |
| `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component |
| `onRequestDismiss` | `(event: LayerDismissEvent) => void` | No | Function called when this layer is closed due to a parent layer being closed |
| `open` | `boolean` | No | The controlled open state of the dialog |
| `persistentElements` | `(() => Element | null)[]` | No | Returns the persistent elements that:
- should not have pointer-events disabled
- should not trigger the dismiss event |
| `present` | `boolean` | No | Whether the node is present (controlled by the user) |
| `preventScroll` | `boolean` | No | Whether to prevent scrolling behind the dialog when it's opened |
| `restoreFocus` | `boolean` | No | Whether to restore focus to the element that had focus before the dialog was opened |
| `role` | `'dialog' | 'alertdialog'` | No | The dialog's role |
| `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. |
| `trapFocus` | `boolean` | No | Whether to trap focus inside the dialog when it's opened |
| `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |
**Backdrop Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**Backdrop Data Attributes:**
| Attribute | Value |
|-----------|-------|
| `[data-scope]` | dialog |
| `[data-part]` | backdrop |
| `[data-state]` | "open" | "closed" |
**CloseTrigger Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**Content Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**Content Data Attributes:**
| Attribute | Value |
|-----------|-------|
| `[data-scope]` | dialog |
| `[data-part]` | content |
| `[data-state]` | "open" | "closed" |
| `[data-nested]` | dialog |
| `[data-has-nested]` | dialog |
**Description Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**Positioner Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**RootProvider Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `value` | `UseDialogReturn` | Yes | |
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame |
| `lazyMount` | `boolean` | No | Whether to enable lazy mounting |
| `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state |
| `present` | `boolean` | No | Whether the node is present (controlled by the user) |
| `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. |
| `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |
**Title Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**Trigger Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**Trigger Data Attributes:**
| Attribute | Value |
|-----------|-------|
| `[data-scope]` | dialog |
| `[data-part]` | trigger |
| `[data-state]` | "open" | "closed" |
#### Solid
**Root Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `aria-label` | `string` | No | Human readable label for the dialog, in event the dialog title is not rendered |
| `closeOnEscape` | `boolean` | No | Whether to close the dialog when the escape key is pressed |
| `closeOnInteractOutside` | `boolean` | No | Whether to close the dialog when the outside is clicked |
| `defaultOpen` | `boolean` | No | The initial open state of the dialog when rendered.
Use when you don't need to control the open state of the dialog. |
| `finalFocusEl` | `() => MaybeElement` | No | Element to receive focus when the dialog is closed |
| `id` | `string` | No | The unique identifier of the machine. |
| `ids` | `Partial<{
trigger: string
positioner: string
backdrop: string
content: string
closeTrigger: string
title: string
description: string
}>` | No | The ids of the elements in the dialog. Useful for composition. |
| `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame |
| `initialFocusEl` | `() => MaybeElement` | No | Element to receive focus when the dialog is opened |
| `lazyMount` | `boolean` | No | Whether to enable lazy mounting |
| `modal` | `boolean` | No | Whether to prevent pointer interaction outside the element and hide all content below it |
| `onEscapeKeyDown` | `(event: KeyboardEvent) => void` | No | Function called when the escape key is pressed |
| `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state |
| `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component |
| `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component |
| `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function to call when the dialog's open state changes |
| `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component |
| `onRequestDismiss` | `(event: LayerDismissEvent) => void` | No | Function called when this layer is closed due to a parent layer being closed |
| `open` | `boolean` | No | The controlled open state of the dialog |
| `persistentElements` | `(() => Element | null)[]` | No | Returns the persistent elements that:
- should not have pointer-events disabled
- should not trigger the dismiss event |
| `present` | `boolean` | No | Whether the node is present (controlled by the user) |
| `preventScroll` | `boolean` | No | Whether to prevent scrolling behind the dialog when it's opened |
| `restoreFocus` | `boolean` | No | Whether to restore focus to the element that had focus before the dialog was opened |
| `role` | `'dialog' | 'alertdialog'` | No | The dialog's role |
| `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. |
| `trapFocus` | `boolean` | No | Whether to trap focus inside the dialog when it's opened |
| `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |
**Backdrop Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**Backdrop Data Attributes:**
| Attribute | Value |
|-----------|-------|
| `[data-scope]` | dialog |
| `[data-part]` | backdrop |
| `[data-state]` | "open" | "closed" |
**CloseTrigger Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**Content Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**Content Data Attributes:**
| Attribute | Value |
|-----------|-------|
| `[data-scope]` | dialog |
| `[data-part]` | content |
| `[data-state]` | "open" | "closed" |
| `[data-nested]` | dialog |
| `[data-has-nested]` | dialog |
**Description Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**Positioner Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**RootProvider Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `value` | `UseDialogReturn` | Yes | |
| `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame |
| `lazyMount` | `boolean` | No | Whether to enable lazy mounting |
| `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state |
| `present` | `boolean` | No | Whether the node is present (controlled by the user) |
| `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. |
| `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |
**Title Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'h2'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**Trigger Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `(props: ParentProps<'button'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**Trigger Data Attributes:**
| Attribute | Value |
|-----------|-------|
| `[data-scope]` | dialog |
| `[data-part]` | trigger |
| `[data-state]` | "open" | "closed" |
#### Vue
**Root Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `aria-label` | `string` | No | Human readable label for the dialog, in event the dialog title is not rendered |
| `closeOnEscape` | `boolean` | No | Whether to close the dialog when the escape key is pressed |
| `closeOnInteractOutside` | `boolean` | No | Whether to close the dialog when the outside is clicked |
| `defaultOpen` | `boolean` | No | The initial open state of the dialog when rendered.
Use when you don't need to control the open state of the dialog. |
| `finalFocusEl` | `() => HTMLElement | null` | No | Element to receive focus when the dialog is closed |
| `id` | `string` | No | The unique identifier of the machine. |
| `ids` | `Partial<{
trigger: string
positioner: string
backdrop: string
content: string
closeTrigger: string
title: string
description: string
}>` | No | The ids of the elements in the dialog. Useful for composition. |
| `initialFocusEl` | `() => HTMLElement | null` | No | Element to receive focus when the dialog is opened |
| `lazyMount` | `boolean` | No | Whether to enable lazy mounting |
| `modal` | `boolean` | No | Whether to prevent pointer interaction outside the element and hide all content below it |
| `open` | `boolean` | No | The controlled open state of the dialog |
| `persistentElements` | `(() => Element | null)[]` | No | Returns the persistent elements that:
- should not have pointer-events disabled
- should not trigger the dismiss event |
| `preventScroll` | `boolean` | No | Whether to prevent scrolling behind the dialog when it's opened |
| `restoreFocus` | `boolean` | No | Whether to restore focus to the element that had focus before the dialog was opened |
| `role` | `'dialog' | 'alertdialog'` | No | The dialog's role |
| `trapFocus` | `boolean` | No | Whether to trap focus inside the dialog when it's opened |
| `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |
**Backdrop Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**Backdrop Data Attributes:**
| Attribute | Value |
|-----------|-------|
| `[data-scope]` | dialog |
| `[data-part]` | backdrop |
| `[data-state]` | "open" | "closed" |
**CloseTrigger Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**Content Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**Content Data Attributes:**
| Attribute | Value |
|-----------|-------|
| `[data-scope]` | dialog |
| `[data-part]` | content |
| `[data-state]` | "open" | "closed" |
| `[data-nested]` | dialog |
| `[data-has-nested]` | dialog |
**Description Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**Positioner Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**RootProvider Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `value` | `DialogApi` | Yes | |
| `lazyMount` | `boolean` | No | Whether to enable lazy mounting |
| `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |
**Title Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**Trigger Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**Trigger Data Attributes:**
| Attribute | Value |
|-----------|-------|
| `[data-scope]` | dialog |
| `[data-part]` | trigger |
| `[data-state]` | "open" | "closed" |
#### Svelte
**Root Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `aria-label` | `string` | No | Human readable label for the dialog, in event the dialog title is not rendered |
| `closeOnEscape` | `boolean` | No | Whether to close the dialog when the escape key is pressed |
| `closeOnInteractOutside` | `boolean` | No | Whether to close the dialog when the outside is clicked |
| `defaultOpen` | `boolean` | No | The initial open state of the dialog when rendered.
Use when you don't need to control the open state of the dialog. |
| `finalFocusEl` | `() => MaybeElement` | No | Element to receive focus when the dialog is closed |
| `id` | `string` | No | The unique identifier of the machine. |
| `ids` | `Partial<{
trigger: string
positioner: string
backdrop: string
content: string
closeTrigger: string
title: string
description: string
}>` | No | The ids of the elements in the dialog. Useful for composition. |
| `immediate` | `boolean` | No | Whether to synchronize the present change immediately or defer it to the next frame |
| `initialFocusEl` | `() => MaybeElement` | No | Element to receive focus when the dialog is opened |
| `lazyMount` | `boolean` | No | Whether to enable lazy mounting |
| `modal` | `boolean` | No | Whether to prevent pointer interaction outside the element and hide all content below it |
| `onEscapeKeyDown` | `(event: KeyboardEvent) => void` | No | Function called when the escape key is pressed |
| `onExitComplete` | `VoidFunction` | No | Function called when the animation ends in the closed state |
| `onFocusOutside` | `(event: FocusOutsideEvent) => void` | No | Function called when the focus is moved outside the component |
| `onInteractOutside` | `(event: InteractOutsideEvent) => void` | No | Function called when an interaction happens outside the component |
| `onOpenChange` | `(details: OpenChangeDetails) => void` | No | Function to call when the dialog's open state changes |
| `onPointerDownOutside` | `(event: PointerDownOutsideEvent) => void` | No | Function called when the pointer is pressed down outside the component |
| `onRequestDismiss` | `(event: LayerDismissEvent) => void` | No | Function called when this layer is closed due to a parent layer being closed |
| `open` | `boolean` | No | The controlled open state of the dialog |
| `persistentElements` | `(() => Element | null)[]` | No | Returns the persistent elements that:
- should not have pointer-events disabled
- should not trigger the dismiss event |
| `present` | `boolean` | No | Whether the node is present (controlled by the user) |
| `preventScroll` | `boolean` | No | Whether to prevent scrolling behind the dialog when it's opened |
| `restoreFocus` | `boolean` | No | Whether to restore focus to the element that had focus before the dialog was opened |
| `role` | `'alertdialog' | 'dialog'` | No | The dialog's role |
| `skipAnimationOnMount` | `boolean` | No | Whether to allow the initial presence animation. |
| `trapFocus` | `boolean` | No | Whether to trap focus inside the dialog when it's opened |
| `unmountOnExit` | `boolean` | No | Whether to unmount on exit. |
**Backdrop Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No | |
**Backdrop Data Attributes:**
| Attribute | Value |
|-----------|-------|
| `[data-scope]` | dialog |
| `[data-part]` | backdrop |
| `[data-state]` | "open" | "closed" |
**CloseTrigger Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No | |
**Content Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No | |
**Content Data Attributes:**
| Attribute | Value |
|-----------|-------|
| `[data-scope]` | dialog |
| `[data-part]` | content |
| `[data-state]` | "open" | "closed" |
| `[data-nested]` | dialog |
| `[data-has-nested]` | dialog |
**Description Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'p'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No | |
**Positioner Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No | |
**RootProvider Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `value` | `UseDialogReturn` | Yes | |
**Title Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'h2'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No | |
**Trigger Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `ref` | `Element` | No | |
**Trigger Data Attributes:**
| Attribute | Value |
|-----------|-------|
| `[data-scope]` | dialog |
| `[data-part]` | trigger |
| `[data-state]` | "open" | "closed" |
### Context
These are the properties available when using `Dialog.Context`, `useDialogContext` hook or `useDialog` hook.
**API:**
| Property | Type | Description |
|----------|------|-------------|
| `open` | `boolean` | Whether the dialog is open |
| `setOpen` | `(open: boolean) => void` | Function to open or close the dialog |
## Accessibility
Complies with the [Dialog WAI-ARIA design pattern](https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/).
### Keyboard Support