Dialog
A modal window that appears on top of the main content.
A modal window that appears on top of the main content.
Dialog Description
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.
Learn how to use the Dialog
component in your project. Let’s take a look at
the most basic example
import { Dialog, Portal } from '@ark-ui/react'
const Basic = () => (
<Dialog.Root>
<Dialog.Trigger>Open Dialog</Dialog.Trigger>
<Portal>
<Dialog.Backdrop />
<Dialog.Positioner>
<Dialog.Content>
<Dialog.Title>Dialog Title</Dialog.Title>
<Dialog.Description>Dialog Description</Dialog.Description>
<Dialog.CloseTrigger>Close</Dialog.CloseTrigger>
</Dialog.Content>
</Dialog.Positioner>
</Portal>
</Dialog.Root>
)
import { Dialog } from '@ark-ui/solid'
import { Portal } from 'solid-js/web'
const Basic = () => {
return (
<Dialog.Root>
<Dialog.Trigger>Open Dialog</Dialog.Trigger>
<Portal>
<Dialog.Backdrop />
<Dialog.Positioner>
<Dialog.Content>
<Dialog.Title>Dialog Title</Dialog.Title>
<Dialog.Description>Dialog Description</Dialog.Description>
<Dialog.CloseTrigger>Close</Dialog.CloseTrigger>
</Dialog.Content>
</Dialog.Positioner>
</Portal>
</Dialog.Root>
)
}
<script setup lang="ts">
import { Teleport, ref } from 'vue'
import { Dialog } from '@ark-ui/vue'
const open = ref(false)
</script>
<template>
<Dialog.Root>
<Dialog.Trigger>Open Dialog</Dialog.Trigger>
<Teleport to="body">
<Dialog.Backdrop />
<Dialog.Positioner>
<Dialog.Content>
<Dialog.Title>Dialog Title</Dialog.Title>
<Dialog.Description>Dialog Description</Dialog.Description>
<Dialog.CloseTrigger>Close</Dialog.CloseTrigger>
</Dialog.Content>
</Dialog.Positioner>
</Teleport>
</Dialog.Root>
</template>
To create a controlled Dialog component, manage the state of the dialog using
the open
and onOpenChange
props:
import { Dialog, Portal } from '@ark-ui/react'
import { useState } from 'react'
const Controlled = () => {
const [isOpen, setIsOpen] = useState(false)
return (
<>
<button onClick={() => setIsOpen(true)}>Open Dialog</button>
<Dialog.Root open={isOpen} onOpenChange={(e) => setIsOpen(e.open)}>
<Portal>
<Dialog.Backdrop />
<Dialog.Positioner>
<Dialog.Content>
<Dialog.Title>Dialog Title</Dialog.Title>
<Dialog.Description>Dialog Description</Dialog.Description>
<Dialog.CloseTrigger>Close</Dialog.CloseTrigger>
</Dialog.Content>
</Dialog.Positioner>
</Portal>
</Dialog.Root>
</>
)
}
import { Dialog } from '@ark-ui/solid'
import { createSignal } from 'solid-js'
import { Portal } from 'solid-js/web'
const Controlled = () => {
const [isOpen, setIsOpen] = createSignal(false)
return (
<>
<button onClick={() => setIsOpen(true)}>Open Dialog</button>
<Dialog.Root open={isOpen()} onOpenChange={() => setIsOpen(false)}>
<Portal>
<Dialog.Backdrop />
<Dialog.Positioner>
<Dialog.Content>
<Dialog.Title>Dialog Title</Dialog.Title>
<Dialog.Description>Dialog Description</Dialog.Description>
<Dialog.CloseTrigger>Close</Dialog.CloseTrigger>
</Dialog.Content>
</Dialog.Positioner>
</Portal>
</Dialog.Root>
</>
)
}
<script setup lang="ts">
import { Teleport, ref } from 'vue'
import { Dialog } from '@ark-ui/vue'
const open = ref(false)
</script>
<template>
<button @click="() => (open = true)">Open Dialog</button>
<Dialog.Root v-model:open="open">
<Teleport to="body">
<Dialog.Backdrop />
<Dialog.Positioner>
<Dialog.Content>
<Dialog.Title>Dialog Title</Dialog.Title>
<Dialog.Description>Dialog Description</Dialog.Description>
<Dialog.CloseTrigger>Close</Dialog.CloseTrigger>
</Dialog.Content>
</Dialog.Positioner>
</Teleport>
</Dialog.Root>
</template>
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.
import { Dialog, Portal } from '@ark-ui/react'
const LazyMount = () => (
<Dialog.Root lazyMount unmountOnExit onExitComplete={() => console.log('onExitComplete invoked')}>
<Dialog.Trigger>Open Dialog</Dialog.Trigger>
<Portal>
<Dialog.Backdrop />
<Dialog.Positioner>
<Dialog.Content>
<Dialog.Title>Dialog Title</Dialog.Title>
<Dialog.Description>Dialog Description</Dialog.Description>
<Dialog.CloseTrigger>Close</Dialog.CloseTrigger>
</Dialog.Content>
</Dialog.Positioner>
</Portal>
</Dialog.Root>
)
import { Dialog } from '@ark-ui/solid'
const LazyMount = () => {
return (
<Dialog.Root lazyMount unmountOnExit>
<Dialog.Trigger>Open Dialog</Dialog.Trigger>
<Dialog.Backdrop />
<Dialog.Positioner>
<Dialog.Content>
<Dialog.Title>Dialog Title</Dialog.Title>
<Dialog.Description>Dialog Description</Dialog.Description>
<Dialog.CloseTrigger>Close</Dialog.CloseTrigger>
</Dialog.Content>
</Dialog.Positioner>
</Dialog.Root>
)
}
<script setup lang="ts">
import { Teleport, ref } from 'vue'
import { Dialog } from '@ark-ui/vue'
const open = ref(false)
</script>
<template>
<Dialog.Root lazyMount unmountOnExit @exit-complete="() => console.log('onExitComplete invoked')">
<Dialog.Trigger>Open Dialog</Dialog.Trigger>
<Teleport to="body">
<Dialog.Backdrop />
<Dialog.Positioner>
<Dialog.Content>
<Dialog.Title>Dialog Title</Dialog.Title>
<Dialog.Description>Dialog Description</Dialog.Description>
<Dialog.CloseTrigger>Close</Dialog.CloseTrigger>
</Dialog.Content>
</Dialog.Positioner>
</Teleport>
</Dialog.Root>
</template>
The Dialog component supports the use of a render function as a child for more
control. This allows access to dialog states like isOpen
:
import { Dialog, Portal } from '@ark-ui/react'
const RenderFn = () => (
<Dialog.Root>
{({ isOpen }) => (
<>
<Dialog.Trigger>Open Dialog</Dialog.Trigger>
<Portal>
<Dialog.Backdrop />
<Dialog.Positioner>
<Dialog.Content>
<Dialog.Title>Dialog Title</Dialog.Title>
<Dialog.Description>Dialog Description</Dialog.Description>
<Dialog.CloseTrigger>Close</Dialog.CloseTrigger>
</Dialog.Content>
</Dialog.Positioner>
</Portal>
<p>Dialog is {isOpen ? 'open' : 'closed'}</p>
</>
)}
</Dialog.Root>
)
import { Dialog } from '@ark-ui/solid'
import { Portal } from 'solid-js/web'
const RenderFn = () => {
return (
<Dialog.Root>
{(api) => (
<>
<Dialog.Trigger>Open Dialog</Dialog.Trigger>
<Portal>
<Dialog.Backdrop />
<Dialog.Positioner>
<Dialog.Content>
<Dialog.Title>Dialog Title</Dialog.Title>
<Dialog.Description>Dialog Description</Dialog.Description>
<Dialog.CloseTrigger>Close</Dialog.CloseTrigger>
</Dialog.Content>
</Dialog.Positioner>
</Portal>
<p>Dialog is {api().isOpen ? 'open' : 'closed'}</p>
</>
)}
</Dialog.Root>
)
}
<script setup lang="ts">
import { Teleport, ref } from 'vue'
import { Dialog } from '@ark-ui/vue'
const open = ref(false)
</script>
<template>
<Dialog.Root v-slot="api">
<Dialog.Trigger>Open Dialog</Dialog.Trigger>
<Teleport to="body">
<Dialog.Backdrop />
<Dialog.Positioner>
<Dialog.Content>
<Dialog.Title>Dialog Title</Dialog.Title>
<Dialog.Description>Dialog Description</Dialog.Description>
<Dialog.CloseTrigger>Close</Dialog.CloseTrigger>
</Dialog.Content>
</Dialog.Positioner>
</Teleport>
<p>Dialog is {{ api.isOpen ? 'open' : 'closed' }}</p>
</Dialog.Root>
</template>
aria-label Human readable label for the dialog, in event the dialog title is not rendered | string | |
closeOnEscapeKeyDown Whether to close the dialog when the escape key is pressed | boolean | |
closeOnInteractOutside Whether to close the dialog when the outside is clicked | boolean | |
defaultOpen The initial open state of the dialog. | boolean | |
dir The document's text/writing direction. | 'ltr' | 'rtl' | "ltr" |
finalFocusEl Element to receive focus when the dialog is closed | HTMLElement | (() => MaybeElement) | |
getRootNode A root node to correctly resolve document in custom environments. E.x.: Iframes, Electron. | () => Node | ShadowRoot | Document | |
id The unique identifier of the machine. | string | |
ids The ids of the elements in the dialog. Useful for composition. | Partial<{
trigger: string
positioner: string
backdrop: string
content: string
closeTrigger: string
title: string
description: string
}> | |
initialFocusEl Element to receive focus when the dialog is opened | HTMLElement | (() => MaybeElement) | |
lazyMount Whether to enable lazy mounting | boolean | false |
modal Whether to prevent pointer interaction outside the element and hide all content below it | boolean | |
onEscapeKeyDown Callback to be invoked when the escape key is pressed | (event: KeyboardEvent) => void | |
onExitComplete Function called when the animation ends in the closed state. | () => void | |
onFocusOutside Function called when the focus is moved outside the component | (event: FocusOutsideEvent) => void | |
onInteractOutside Function called when an interaction happens outside the component | (event: InteractOutsideEvent) => void | |
onOpenChange Callback to be invoked when the dialog is opened or closed | (details: OpenChangeDetails) => void | |
onPointerDownOutside Function called when the pointer is pressed down outside the component | (event: PointerDownOutsideEvent) => void | |
open Whether the dialog is open | boolean | |
present Whether the node is present (controlled by the user) | boolean | |
preventScroll Whether to prevent scrolling behind the dialog when it's opened | boolean | |
restoreFocus Whether to restore focus to the element that had focus before the dialog was opened | boolean | |
role The dialog's role | 'dialog' | 'alertdialog' | "dialog" |
trapFocus Whether to trap focus inside the dialog when it's opened | boolean | |
unmountOnExit Whether to unmount on exit. | boolean | false |
asChild Render as a different element type. | boolean |
asChild Render as a different element type. | boolean |
asChild Render as a different element type. | boolean |
asChild Render as a different element type. | boolean |
asChild Render as a different element type. | boolean |
asChild Render as a different element type. | boolean |
asChild Render as a different element type. | boolean |
Previous
Date Range PickerNext
Editable