Dialog

This is an accessible modal pattern with a trigger part, a portal part, an overlay part, and a content part. A dialog can contain a second dialog. In a stack of dialogs, only the top dialog obeys the global close interactions.

Anatomy

All of the parts are in Dialog.Root. Dialog.Trigger opens the dialog. The modal layers, Dialog.Overlay and Dialog.Content, are in Dialog.Portal. The children snippet of the root receives the state functions: close, open, toggle, and isOpen.

<script>
	import { Dialog } from '@human-kit/ui';
</script>

<Dialog.Root>
	{#snippet children({ close })}
		<Dialog.Trigger>Open</Dialog.Trigger>
		<Dialog.Portal>
			<Dialog.Overlay />
			<Dialog.Content>...</Dialog.Content>
		</Dialog.Portal>
	{/snippet}
</Dialog.Root>

Controlled state

Bind open on Dialog.Root to control the dialog from your own code. Then a trigger is optional. Use defaultOpen when the component controls the state. The onOpenChange prop reports each change.

Nested dialogs

Put a Dialog.Root in the content of a different dialog to make a stack. The component controls the stack. Each overlay and each panel gets a higher z-index. The Escape key and a click outside close only the top dialog.

Usage guidelines

  • Put all of the dialog parts in Dialog.Root.
  • Use Dialog.Trigger as the button that opens the dialog.
  • Put the modal layers in Dialog.Portal.
  • Use Dialog.Overlay and Dialog.Content together for the usual modal behavior.
  • Use nested Dialog.Root parts when you need a stack. The component controls which dialog is on top.
  • Use shouldCloseOnEscape and shouldCloseOnInteractOutside on Dialog.Content to stop the default close interactions.

Accessibility

  • While the dialog is open, Dialog.Content has role="dialog" with aria-modal="true".
  • The focus stays in the open dialog. Assistive technology does not read the content outside the dialog.
  • While a modal dialog is open, the body does not scroll.
  • The Escape key closes the top dialog. When a dialog closes, the focus goes back to the trigger.

API reference

Root

The container with the state. It holds the open state and the reference to the trigger. It gives the state functions ({ close, open, toggle, isOpen }) to its children snippet.

Prop Type Default

* required. Native HTML attributes of the underlying element are also accepted.

Trigger

The button that registers itself as the trigger of the dialog. A click opens and closes the dialog.

Prop Type Default

* required. Native HTML attributes of the underlying element are also accepted.

Data attribute Description
data-dialog-trigger Identifies the trigger button.

Portal

The portal that puts the dialog layers in the document body. They are there only while the dialog is open, and they stay until the exit animation is complete.

Prop Type Default

* required. Native HTML attributes of the underlying element are also accepted.

Overlay

The backdrop behind the dialog content. Its z-index comes from the position of the dialog in the stack.

Prop Type Default

* required. Native HTML attributes of the underlying element are also accepted.

Data attribute Description
data-dialog-overlay Identifies the overlay element.
data-entering Present while the enter animation operates.
data-exiting Present while the exit animation operates.
data-state "open" while the dialog is open, "closed" during exit.

Content

The modal panel, with role="dialog" and aria-modal. It keeps the focus inside, it obeys an interaction outside it, it stops the page scroll, and it hides the outside content from assistive technology. In a stack, only the top dialog obeys the close interactions.

Prop Type Default

* required. Native HTML attributes of the underlying element are also accepted.

Data attribute Description
data-dialog-content Identifies the dialog panel element.
data-dialog-positioner Identifies the fixed element that puts the panel at the center.
data-entering Present while the enter animation operates.
data-exiting Present while the exit animation operates.
data-state "open" while the dialog is open, "closed" during exit.

Title

Prop Type Default

* required. Native HTML attributes of the underlying element are also accepted.

Data attribute Description
data-dialog-title Identifies the heading that names the dialog.

Description

Prop Type Default

* required. Native HTML attributes of the underlying element are also accepted.

Data attribute Description
data-dialog-description Identifies the supporting description.

Close

Prop Type Default

* required. Native HTML attributes of the underlying element are also accepted.

Data attribute Description
data-dialog-close Identifies a button that closes the dialog.