Ark UI Logo
Components
Dialog

Dialog

A modal window that appears on top of the main content.

Loading...

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

import { Dialog } from '@ark-ui/react/dialog'
import { Portal } from '@ark-ui/react/portal'
import { XIcon } from 'lucide-react'
import button from 'styles/button.module.css'
import styles from 'styles/dialog.module.css'

export const Basic = () => (
  <Dialog.Root>
    <Dialog.Trigger className={button.Root}>Open Dialog</Dialog.Trigger>
    <Portal>
      <Dialog.Backdrop className={styles.Backdrop} />
      <Dialog.Positioner className={styles.Positioner}>
        <Dialog.Content className={styles.Content}>
          <Dialog.CloseTrigger className={styles.CloseTrigger}>
            <XIcon />
          </Dialog.CloseTrigger>
          <Dialog.Title className={styles.Title}>Welcome Back</Dialog.Title>
          <Dialog.Description className={styles.Description}>Sign in to your account to continue.</Dialog.Description>
        </Dialog.Content>
      </Dialog.Positioner>
    </Portal>
  </Dialog.Root>
)

Controlled

To create a controlled Dialog component, manage the state of the dialog using the open and onOpenChange props:

import { Dialog } from '@ark-ui/react/dialog'
import { Portal } from '@ark-ui/react/portal'
import { XIcon } from 'lucide-react'
import { useState } from 'react'
import button from 'styles/button.module.css'
import styles from 'styles/dialog.module.css'

export const Controlled = () => {
  const [open, setOpen] = useState(false)
  return (
    <Dialog.Root open={open} onOpenChange={(e) => setOpen(e.open)}>
      <Dialog.Trigger className={button.Root}>Open Dialog</Dialog.Trigger>
      <Portal>
        <Dialog.Backdrop className={styles.Backdrop} />
        <Dialog.Positioner className={styles.Positioner}>
          <Dialog.Content className={styles.Content}>
            <Dialog.CloseTrigger className={styles.CloseTrigger}>
              <XIcon />
            </Dialog.CloseTrigger>
            <Dialog.Title className={styles.Title}>Session Settings</Dialog.Title>
            <Dialog.Description className={styles.Description}>
              Manage your session preferences and security options.
            </Dialog.Description>
          </Dialog.Content>
        </Dialog.Positioner>
      </Portal>
    </Dialog.Root>
  )
}

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.

import { Dialog } from '@ark-ui/react/dialog'
import { Portal } from '@ark-ui/react/portal'
import { XIcon } from 'lucide-react'
import button from 'styles/button.module.css'
import styles from 'styles/dialog.module.css'

export const LazyMount = () => (
  <Dialog.Root lazyMount unmountOnExit>
    <Dialog.Trigger className={button.Root}>Open Dialog</Dialog.Trigger>
    <Portal>
      <Dialog.Backdrop className={styles.Backdrop} />
      <Dialog.Positioner className={styles.Positioner}>
        <Dialog.Content className={styles.Content}>
          <Dialog.CloseTrigger className={styles.CloseTrigger}>
            <XIcon />
          </Dialog.CloseTrigger>
          <Dialog.Title className={styles.Title}>Lazy Loaded</Dialog.Title>
          <Dialog.Description className={styles.Description}>
            This dialog content is only mounted when opened and unmounts on close.
          </Dialog.Description>
        </Dialog.Content>
      </Dialog.Positioner>
    </Portal>
  </Dialog.Root>
)

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
import { Dialog } from '@ark-ui/react/dialog'
import { Portal } from '@ark-ui/react/portal'
import button from 'styles/button.module.css'
import styles from 'styles/dialog.module.css'

export const AlertDialog = () => (
  <Dialog.Root role="alertdialog">
    <Dialog.Trigger className={button.Root}>Delete Account</Dialog.Trigger>
    <Portal>
      <Dialog.Backdrop className={styles.Backdrop} />
      <Dialog.Positioner className={styles.Positioner}>
        <Dialog.Content className={styles.Content}>
          <Dialog.Title className={styles.Title}>Are you absolutely sure?</Dialog.Title>
          <Dialog.Description className={styles.Description}>
            This action cannot be undone. This will permanently delete your account and remove your data from our
            servers.
          </Dialog.Description>
          <div className={styles.Actions}>
            <Dialog.CloseTrigger className={button.Root}>Cancel</Dialog.CloseTrigger>
            <button className={button.Root} data-variant="solid">
              Delete Account
            </button>
          </div>
        </Dialog.Content>
      </Dialog.Positioner>
    </Portal>
  </Dialog.Root>
)

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:

import { Dialog } from '@ark-ui/react/dialog'
import { Portal } from '@ark-ui/react/portal'
import { XIcon } from 'lucide-react'
import { useRef } from 'react'
import button from 'styles/button.module.css'
import field from 'styles/field.module.css'
import styles from 'styles/dialog.module.css'

export const InitialFocus = () => {
  const inputRef = useRef<HTMLInputElement>(null)

  return (
    <Dialog.Root initialFocusEl={() => inputRef.current}>
      <Dialog.Trigger className={button.Root}>Open Dialog</Dialog.Trigger>
      <Portal>
        <Dialog.Backdrop className={styles.Backdrop} />
        <Dialog.Positioner className={styles.Positioner}>
          <Dialog.Content className={styles.Content}>
            <Dialog.CloseTrigger className={styles.CloseTrigger}>
              <XIcon />
            </Dialog.CloseTrigger>
            <Dialog.Title className={styles.Title}>Edit Profile</Dialog.Title>
            <Dialog.Description className={styles.Description}>
              The first input will be focused when the dialog opens.
            </Dialog.Description>
            <div className={styles.Body}>
              <input ref={inputRef} className={field.Input} placeholder="Enter your name..." />
              <input className={field.Input} placeholder="Enter your email..." />
            </div>
          </Dialog.Content>
        </Dialog.Positioner>
      </Portal>
    </Dialog.Root>
  )
}

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:

import { Dialog } from '@ark-ui/react/dialog'
import { Portal } from '@ark-ui/react/portal'
import { XIcon } from 'lucide-react'
import { useRef } from 'react'
import button from 'styles/button.module.css'
import styles from 'styles/dialog.module.css'

export const FinalFocus = () => {
  const finalRef = useRef<HTMLButtonElement>(null)

  return (
    <div className="stack">
      <button className={button.Root} ref={finalRef}>
        I will receive focus when dialog closes
      </button>
      <Dialog.Root finalFocusEl={() => finalRef.current}>
        <Dialog.Trigger className={button.Root}>Open Dialog</Dialog.Trigger>
        <Portal>
          <Dialog.Backdrop className={styles.Backdrop} />
          <Dialog.Positioner className={styles.Positioner}>
            <Dialog.Content className={styles.Content}>
              <Dialog.CloseTrigger className={styles.CloseTrigger}>
                <XIcon />
              </Dialog.CloseTrigger>
              <Dialog.Title className={styles.Title}>Focus Redirect</Dialog.Title>
              <Dialog.Description className={styles.Description}>
                When this dialog closes, focus will return to the button above instead of the trigger.
              </Dialog.Description>
            </Dialog.Content>
          </Dialog.Positioner>
        </Portal>
      </Dialog.Root>
    </div>
  )
}

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:

import { Dialog } from '@ark-ui/react/dialog'
import { Portal } from '@ark-ui/react/portal'
import { XIcon } from 'lucide-react'
import button from 'styles/button.module.css'
import styles from 'styles/dialog.module.css'

export const NonModal = () => (
  <Dialog.Root modal={false}>
    <Dialog.Trigger className={button.Root}>Open Non-Modal Dialog</Dialog.Trigger>
    <Portal>
      <Dialog.Backdrop className={styles.Backdrop} />
      <Dialog.Positioner className={styles.Positioner}>
        <Dialog.Content className={styles.Content}>
          <Dialog.CloseTrigger className={styles.CloseTrigger}>
            <XIcon />
          </Dialog.CloseTrigger>
          <Dialog.Title className={styles.Title}>Non-Modal Dialog</Dialog.Title>
          <Dialog.Description className={styles.Description}>
            This dialog allows interaction with elements outside. You can click buttons, select text, and interact with
            the page behind it.
          </Dialog.Description>
        </Dialog.Content>
      </Dialog.Positioner>
    </Portal>
  </Dialog.Root>
)

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:

import { Dialog } from '@ark-ui/react/dialog'
import { Portal } from '@ark-ui/react/portal'
import { XIcon } from 'lucide-react'
import button from 'styles/button.module.css'
import styles from 'styles/dialog.module.css'

export const CloseOnInteractOutside = () => (
  <Dialog.Root closeOnInteractOutside={false}>
    <Dialog.Trigger className={button.Root}>Open Dialog</Dialog.Trigger>
    <Portal>
      <Dialog.Backdrop className={styles.Backdrop} />
      <Dialog.Positioner className={styles.Positioner}>
        <Dialog.Content className={styles.Content}>
          <Dialog.CloseTrigger className={styles.CloseTrigger}>
            <XIcon />
          </Dialog.CloseTrigger>
          <Dialog.Title className={styles.Title}>Custom Close Behavior</Dialog.Title>
          <Dialog.Description className={styles.Description}>
            This dialog will not close when clicking outside. Only the close button will dismiss it.
          </Dialog.Description>
        </Dialog.Content>
      </Dialog.Positioner>
    </Portal>
  </Dialog.Root>
)

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:

import { Dialog } from '@ark-ui/react/dialog'
import { Portal } from '@ark-ui/react/portal'
import { XIcon } from 'lucide-react'
import button from 'styles/button.module.css'
import field from 'styles/field.module.css'
import styles from 'styles/dialog.module.css'

export const CloseOnEscape = () => (
  <Dialog.Root closeOnEscape={false}>
    <Dialog.Trigger className={button.Root}>Open Dialog</Dialog.Trigger>
    <Portal>
      <Dialog.Backdrop className={styles.Backdrop} />
      <Dialog.Positioner className={styles.Positioner}>
        <Dialog.Content className={styles.Content}>
          <Dialog.CloseTrigger className={styles.CloseTrigger}>
            <XIcon />
          </Dialog.CloseTrigger>
          <Dialog.Title className={styles.Title}>Unsaved Changes</Dialog.Title>
          <Dialog.Description className={styles.Description}>
            This dialog prevents closing with the Escape key. Use the close button to dismiss.
          </Dialog.Description>
          <div className={styles.Body}>
            <textarea className={field.Textarea} placeholder="Type something..." rows={3} />
          </div>
        </Dialog.Content>
      </Dialog.Positioner>
    </Portal>
  </Dialog.Root>
)

Render Function

Use the Dialog.Context component to access the dialog's state and methods.

Example not found

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.

import { Dialog, useDialog } from '@ark-ui/react/dialog'
import { Portal } from '@ark-ui/react/portal'
import { XIcon } from 'lucide-react'
import button from 'styles/button.module.css'
import styles from 'styles/dialog.module.css'

export const RootProvider = () => {
  const dialog = useDialog()

  return (
    <div className="stack">
      <button className={button.Root} onClick={() => dialog.setOpen(true)}>
        Dialog is {dialog.open ? 'open' : 'closed'}
      </button>
      <Dialog.RootProvider value={dialog}>
        <Portal>
          <Dialog.Backdrop className={styles.Backdrop} />
          <Dialog.Positioner className={styles.Positioner}>
            <Dialog.Content className={styles.Content}>
              <Dialog.CloseTrigger className={styles.CloseTrigger}>
                <XIcon />
              </Dialog.CloseTrigger>
              <Dialog.Title className={styles.Title}>Controlled Externally</Dialog.Title>
              <Dialog.Description className={styles.Description}>
                This dialog is controlled via the useDialog hook.
              </Dialog.Description>
            </Dialog.Content>
          </Dialog.Positioner>
        </Portal>
      </Dialog.RootProvider>
    </div>
  )
}

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:

import { Dialog, useDialog } from '@ark-ui/react/dialog'
import { Portal } from '@ark-ui/react/portal'
import { XIcon } from 'lucide-react'
import button from 'styles/button.module.css'
import styles from 'styles/dialog.module.css'

export const Nested = () => {
  const parentDialog = useDialog()
  const childDialog = useDialog()

  return (
    <>
      <button className={button.Root} onClick={() => parentDialog.setOpen(true)}>
        Open Parent Dialog
      </button>

      <Dialog.RootProvider value={parentDialog}>
        <Portal>
          <Dialog.Backdrop className={styles.Backdrop} />
          <Dialog.Positioner className={styles.Positioner}>
            <Dialog.Content className={styles.Content}>
              <Dialog.CloseTrigger className={styles.CloseTrigger}>
                <XIcon />
              </Dialog.CloseTrigger>
              <Dialog.Title className={styles.Title}>Parent Dialog</Dialog.Title>
              <Dialog.Description className={styles.Description}>
                This is the parent dialog. Open a nested dialog to see automatic z-index management.
              </Dialog.Description>
              <div className={styles.Body}>
                <button className={button.Root} onClick={() => childDialog.setOpen(true)}>
                  Open Nested Dialog
                </button>
              </div>
            </Dialog.Content>
          </Dialog.Positioner>
        </Portal>
      </Dialog.RootProvider>

      <Dialog.RootProvider value={childDialog}>
        <Portal>
          <Dialog.Backdrop className={styles.Backdrop} />
          <Dialog.Positioner className={styles.Positioner}>
            <Dialog.Content className={styles.Content}>
              <Dialog.CloseTrigger className={styles.CloseTrigger}>
                <XIcon />
              </Dialog.CloseTrigger>
              <Dialog.Title className={styles.Title}>Nested Dialog</Dialog.Title>
              <Dialog.Description className={styles.Description}>
                This dialog is nested within the parent with proper z-index layering.
              </Dialog.Description>
            </Dialog.Content>
          </Dialog.Positioner>
        </Portal>
      </Dialog.RootProvider>
    </>
  )
}

Confirmation Dialog

Dialogs can intercept close attempts to show confirmation prompts. This pattern is useful for preventing data loss from unsaved changes:

import { Dialog, useDialog } from '@ark-ui/react/dialog'
import { Portal } from '@ark-ui/react/portal'
import { XIcon } from 'lucide-react'
import { useState } from 'react'
import button from 'styles/button.module.css'
import field from 'styles/field.module.css'
import styles from 'styles/dialog.module.css'

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 (
    <>
      <button className={button.Root} onClick={() => parentDialog.setOpen(true)}>
        Open Form
      </button>

      <Dialog.RootProvider value={parentDialog}>
        <Portal>
          <Dialog.Backdrop className={styles.Backdrop} />
          <Dialog.Positioner className={styles.Positioner}>
            <Dialog.Content className={styles.Content}>
              <Dialog.CloseTrigger className={styles.CloseTrigger}>
                <XIcon />
              </Dialog.CloseTrigger>
              <Dialog.Title className={styles.Title}>Edit Content</Dialog.Title>
              <Dialog.Description className={styles.Description}>
                Make changes to your content. You'll be asked to confirm before closing if there are unsaved changes.
              </Dialog.Description>
              <div className={styles.Body}>
                <textarea
                  className={field.Textarea}
                  value={formContent}
                  onChange={(e) => setFormContent(e.target.value)}
                  placeholder="Enter some text..."
                  rows={4}
                />
              </div>
            </Dialog.Content>
          </Dialog.Positioner>
        </Portal>
      </Dialog.RootProvider>

      <Dialog.RootProvider value={confirmDialog}>
        <Portal>
          <Dialog.Backdrop className={styles.Backdrop} />
          <Dialog.Positioner className={styles.Positioner}>
            <Dialog.Content className={styles.Content}>
              <Dialog.CloseTrigger className={styles.CloseTrigger}>
                <XIcon />
              </Dialog.CloseTrigger>
              <Dialog.Title className={styles.Title}>Unsaved Changes</Dialog.Title>
              <Dialog.Description className={styles.Description}>
                You have unsaved changes. Are you sure you want to close without saving?
              </Dialog.Description>
              <div className={styles.Actions}>
                <button className={button.Root} onClick={() => confirmDialog.setOpen(false)}>
                  Keep Editing
                </button>
                <button className={button.Root} data-variant="solid" onClick={handleConfirmClose}>
                  Discard Changes
                </button>
              </div>
            </Dialog.Content>
          </Dialog.Positioner>
        </Portal>
      </Dialog.RootProvider>
    </>
  )
}

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:

[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.

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 (
    <Dialog.Root lazyMount>
      <Dialog.Trigger>Open Dialog</Dialog.Trigger>
      <Dialog.Content>
        <Suspense fallback={<div>Loading...</div>}>
          <HeavyComponent />
        </Suspense>
      </Dialog.Content>
    </Dialog.Root>
  )
}

API Reference

Props

Root

PropDefaultType
aria-label
string

Human readable label for the dialog, in event the dialog title is not rendered

closeOnEscapetrue
boolean

Whether to close the dialog when the escape key is pressed

closeOnInteractOutsidetrue
boolean

Whether to close the dialog when the outside is clicked

defaultOpenfalse
boolean

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

Element to receive focus when the dialog is closed

id
string

The unique identifier of the machine.

ids
Partial<{ trigger: string positioner: string backdrop: string content: string closeTrigger: string title: string description: string }>

The ids of the elements in the dialog. Useful for composition.

immediate
boolean

Whether to synchronize the present change immediately or defer it to the next frame

initialFocusEl
() => MaybeElement

Element to receive focus when the dialog is opened

lazyMountfalse
boolean

Whether to enable lazy mounting

modaltrue
boolean

Whether to prevent pointer interaction outside the element and hide all content below it

onEscapeKeyDown
(event: KeyboardEvent) => void

Function called when the escape key is pressed

onExitComplete
VoidFunction

Function called when the animation ends in the closed state

onFocusOutside
(event: FocusOutsideEvent) => void

Function called when the focus is moved outside the component

onInteractOutside
(event: InteractOutsideEvent) => void

Function called when an interaction happens outside the component

onOpenChange
(details: OpenChangeDetails) => void

Function to call when the dialog's open state changes

onPointerDownOutside
(event: PointerDownOutsideEvent) => void

Function called when the pointer is pressed down outside the component

onRequestDismiss
(event: LayerDismissEvent) => void

Function called when this layer is closed due to a parent layer being closed

open
boolean

The controlled open state of the dialog

persistentElements
(() => Element | null)[]

Returns the persistent elements that: - should not have pointer-events disabled - should not trigger the dismiss event

present
boolean

Whether the node is present (controlled by the user)

preventScrolltrue
boolean

Whether to prevent scrolling behind the dialog when it's opened

restoreFocus
boolean

Whether to restore focus to the element that had focus before the dialog was opened

role'dialog'
'dialog' | 'alertdialog'

The dialog's role

skipAnimationOnMountfalse
boolean

Whether to allow the initial presence animation.

trapFocustrue
boolean

Whether to trap focus inside the dialog when it's opened

unmountOnExitfalse
boolean

Whether to unmount on exit.

Backdrop

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
CSS VariableDescription
--layer-indexThe index of the dismissable in the layer stack
Data AttributeValue
[data-scope]dialog
[data-part]backdrop
[data-state]"open" | "closed"

CloseTrigger

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.

Content

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
CSS VariableDescription
--layer-indexThe index of the dismissable in the layer stack
--nested-layer-countThe number of nested dialogs
Data AttributeValue
[data-scope]dialog
[data-part]content
[data-state]"open" | "closed"
[data-nested]dialog
[data-has-nested]dialog

Description

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.

Positioner

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.

RootProvider

PropDefaultType
value
UseDialogReturn

asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
immediate
boolean

Whether to synchronize the present change immediately or defer it to the next frame

lazyMountfalse
boolean

Whether to enable lazy mounting

onExitComplete
VoidFunction

Function called when the animation ends in the closed state

present
boolean

Whether the node is present (controlled by the user)

skipAnimationOnMountfalse
boolean

Whether to allow the initial presence animation.

unmountOnExitfalse
boolean

Whether to unmount on exit.

Title

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.

Trigger

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
Data AttributeValue
[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

PropertyType
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.

Keyboard Support

KeyDescription
Enter
When focus is on the trigger, opens the dialog.
Tab
Moves focus to the next focusable element within the content. Focus is trapped within the dialog.
Shift + Tab
Moves focus to the previous focusable element. Focus is trapped within the dialog.
Esc
Closes the dialog and moves focus to trigger or the defined final focus element