v0.3.0
Note: This documentation is in active development — content may be incomplete

Dialog

View as Markdown

Overview

Dialogs present focused, interruptive content above the main interface, typically requiring acknowledgment or a decision before continuing.

<Dialog.Root>
	<Dialog.Trigger render={<Button label="Open dialog" priority="primary" />} />
	<Dialog.Content>
		<Dialog.Header
			title="Here's a sample dialog"
			description="It can include an optional description that provides a bit more context for the user. Isn't that nice?"
		/>
		<Dialog.Actions>
			<Button label="Confirm" priority="primary" />
			<Dialog.Close render={<Button label="Cancel" />} />
		</Dialog.Actions>
	</Dialog.Content>
</Dialog.Root>

Usage Guidelines

  • Use for important interruptions: Use a dialog when users need to stop and make a decision before continuing, such as confirming a destructive action or completing a short focused task. Avoid it for information that can stay in the page flow.
  • Keep content focused: Limit dialog content to the context people need to make the decision or complete the task. Long forms, dense layouts, or content that requires extended browsing usually fit better in the page itself.
  • Make actions clear: Include a clear primary action and a clear way to dismiss the dialog. Use action labels that describe the outcome, such as "Delete project" or "Save changes," rather than vague labels like "OK."

API Reference

Dialog.Root

Controls dialog state and provides context for all nested dialog parts.

PropTypeDefault
childrenReactNode | ((actions: { close: () => void }) => ReactNode)-
openboolean-
defaultOpenboolean-
onOpenChange(open: boolean) => void-

Dialog.Trigger

Interactive element that opens the dialog when activated.

PropTypeDefault
renderReactElement-
disabledbooleanfalse
childrenReactNode-

Dialog.Content

Portal-rendered container for the dialog surface, backdrop, and viewport positioning.

PropTypeDefault
childrenReactNode-
classNamestring-
initialFocusRefObject<HTMLElement> | (() => HTMLElement | null)-
finalFocusRefObject<HTMLElement> | (() => HTMLElement | null)-

Dialog.Header

Structured heading block that renders the dialog title and optional description.

PropTypeDefault
titlestring-
descriptionstring-

Dialog.Body

Main content region for dialog copy, fields, or custom layout.

PropTypeDefault
childrenReactNode-

Dialog.Actions

Action row for primary and secondary controls, typically aligned to the end.

PropTypeDefault
childrenReactNode-

Dialog.Close

Control that closes the dialog, often used for cancel or dismiss actions.

PropTypeDefault
renderReactElement-
childrenReactNode-
disabledbooleanfalse

Examples

Confirmation

Use a dialog to confirm an action that interrupts the current flow, especially when the result is destructive or difficult to undo.

<Dialog.Root>
	{({ close }) => (
		<>
			<Dialog.Trigger render={<Button label="Delete workspace" />} />
			<Dialog.Content>
				<Dialog.Header
					title="Delete workspace?"
					description="This removes all projects, drafts, and team access for this workspace. This action cannot be undone."
				/>
				<Dialog.Actions>
					<Button label="Delete workspace" priority="primary" onClick={() => close()} />
					<Dialog.Close render={<Button label="Keep workspace" />} />
				</Dialog.Actions>
			</Dialog.Content>
		</>
	)}
</Dialog.Root>

Short tasks

Dialogs can hold short, focused tasks such as renaming an item or updating a single setting. Keep the content brief so the task stays easy to complete in place.

<Dialog.Root>
	{({ close }) => (
		<>
			<Dialog.Trigger render={<Button label="Rename workspace" priority="primary" />} />
			<Dialog.Content>
				<Dialog.Header title="Update project" description="Changes will be reflected upon publish" />
				<Dialog.Body>
					<Stack gap={5}>
						<Field label="Title">
							<Input defaultValue="My Example Project" width="fluid" />
						</Field>
						<Field label="Description">
							<Input defaultValue="It's really cool" width="fluid" />
						</Field>
					</Stack>
				</Dialog.Body>
				<Dialog.Actions>
					<Button label="Save changes" priority="primary" onClick={() => close()} />
					<Dialog.Close render={<Button label="Cancel" />} />
				</Dialog.Actions>
			</Dialog.Content>
		</>
	)}
</Dialog.Root>

Controlled state

Use the controlled API when dialog visibility depends on application state instead of on a user-initiated trigger, such as part of a larger workflow.

const [open, setOpen] = useState(false);

<Dialog.Root open={open} onOpenChange={setOpen}>
	{({ close }) => (
		<>
			<Button label="Open controlled dialog" priority="primary" onClick={() => setOpen(true)} />
			<Dialog.Content>
				<Dialog.Header
					title="Publish changes?"
					description="This dialog is controlled by external state instead of relying only on the trigger."
				/>
				<Dialog.Actions>
					<Button label="Publish" priority="primary" onClick={() => close()} />
					<Dialog.Close render={<Button label="Cancel" />} />
				</Dialog.Actions>
			</Dialog.Content>
		</>
	)}
</Dialog.Root>

On this page

(Top)OverviewUsage GuidelinesAPI ReferenceDialog.RootDialog.TriggerDialog.ContentDialog.HeaderDialog.BodyDialog.ActionsDialog.CloseExamplesConfirmationShort tasksControlled state
v0.3.0

Overview

AboutGetting started

Components

AvatarBadgeBannerButtonCalloutCheckboxChipCodeCode InputColor InputData TableDialogDividerDisclosureDrawerEditable TextEmbedEmphasisError BoundaryFieldFile InputFlexFormFrameGridImageInlineInputMarqueeMenuPortalRootRadio GroupRich Text EditorSelectSkeletonSlotSortableSpacerSpinnerStackStatus IconStepperSwitchTab SwitchTextText AreaToggleUrlIcon