Dialog
Preview
A modal dialog that traps focus, closes on Escape and returns focus to the opener, plus a confirmation dialog with a loading state.
Example
<Button onClick={() => setOpen(true)}>Rename dashboard</Button>
<Dialog
open={open}
onOpenChange={setOpen}
title="Rename dashboard"
description="The new name shows in the sidebar and in shared links."
footer={
<>
<Button variant="ghost" onClick={() => setOpen(false)}>Cancel</Button>
<Button variant="primary" onClick={rename}>Rename</Button>
</>
}
>
<TextField label="Name" defaultValue="Q3 revenue" />
</Dialog>
<ConfirmDialog
open={confirm}
onOpenChange={setConfirm}
destructive
title="Delete “Q3 revenue”?"
description="The dashboard and its charts will be removed for everyone."
confirmLabel="Delete dashboard"
onConfirm={() => api.deleteDashboard(id)} // a promise shows a spinner until it resolves
/>Usage
Dialog is controlled: pass open and onOpenChange. Put buttons in footer, primary action last. ConfirmDialog renders Cancel and one confirm action; return a promise from onConfirm to show a loading state, and the dialog closes when it resolves. DialogPanel is the surface alone, for static previews.
Props
Dialog
PropTypeDefaultDescription
openrequiredboolean——
onOpenChangerequired(open: boolean) => void——
titlerequiredReactNode——
descriptionReactNode——
childrenReactNode——
footerReactNode——
size'sm' | 'md' | 'lg'DialogSize'sm'—
role'dialog' | 'alertdialog''dialog'
alertdialog for confirmations that interrupt.initialFocusRefObject<HTMLElement | null>—Element to focus on open (default: the first focusable element).
dismissiblebooleantrueClose on Escape and backdrop click (default true).
showClosebooleanfalseClose button in the corner (default false).
classNamestring——
ConfirmDialog
PropTypeDefaultDescription
confirmLabelReactNode'Confirm'—
cancelLabelReactNode'Cancel'—
destructivebooleanfalseRed confirm button for actions that delete or cannot be undone.
onConfirmrequired() => unknown—Runs on confirm. Return a promise to show a loading state; the dialog closes when it resolves.
onCancel() => void——
childrenReactNode——
size'sm' | 'md' | 'lg'DialogSize——
classNamestring——
titlerequiredReactNode——
descriptionReactNode——
openrequiredboolean——
onOpenChangerequired(open: boolean) => void——
dismissiblebooleantrueClose on Escape and backdrop click (default true).
Also accepts the props of Omit<DialogProps, 'footer' | 'role' | 'initialFocus' | 'showClose'>, spread onto the root element.
Accessibility
role="dialog"(oralertdialog) named by the title and described by the description.- Focus moves into the dialog (to
initialFocus, or the first focusable element), stays there, and returns to the opener on close. ConfirmDialog focuses Cancel. - Escape and a backdrop click close it unless
dismissible={false}. Page scroll is locked while it is open.
Report an issueBuilt Oct 21, 2026