Skip to content
Kimenpre-v1
Color scheme

Component

ki-dialog

A modal dialog for one interrupting decision or short focused task: destructive confirmations, blocking choices, brief critical input.

Delete draft

This permanently removes the draft.

Cancel Delete
<ki-button id="open-demo-dialog" type="button">Delete draft</ki-button>
<ki-dialog id="demo-dialog" heading="Delete draft?">
<p>This permanently removes the draft.</p>
<ki-button slot="footer" type="button" autofocus id="demo-dialog-cancel">Cancel</ki-button>
<ki-button slot="footer" tone="danger" variant="primary" type="button" id="demo-dialog-confirm">Delete</ki-button>
</ki-dialog>
<script type="module">
const dialog = document.getElementById('demo-dialog');
document.getElementById('open-demo-dialog').addEventListener('click', () => dialog.show());
document.getElementById('demo-dialog-cancel').addEventListener('click', () => dialog.close());
document.getElementById('demo-dialog-confirm').addEventListener('click', () => dialog.close());
</script>

Footer actions never close automatically — wire each one to close(). Every close path reports why in the ki-close event’s detail.reason: method for close() calls, escape for the Escape key, backdrop for opt-in backdrop dismissal (close-on-backdrop). Update application state from ki-close, after focus has already returned through the native mechanism:

dialog.addEventListener('ki-close', (event) => {
console.log(event.detail.reason); // 'method' | 'escape' | 'backdrop'
});

ki-close is not cancelable — it reports a close that already happened, never a veto point.

When to use: destructive confirmations, blocking choices, and brief critical input that must be resolved before returning to the page. Always provide a heading, place actions in the footer slot, wire each footer action to close(), and in destructive confirmations put autofocus on the least destructive action.

When not to use: non-blocking feedback (ki-alert, future ki-toast), supplementary hints (ki-tooltip), long forms or multi-step flows (navigate or use a future full-screen variant), menus, or pickers.

Properties & attributes

AttributePropertyTypeDefaultDescription
close-on-backdropcloseOnBackdropbooleanfalseOpts into backdrop light-dismiss. Omit this attribute for critical confirmations; close-on-backdrop="false" still enables it. When to use: low-risk dialogs where an outside click may safely dismiss. When NOT to use: destructive confirmations or decisions that should not be lost to a stray click; omit the attribute entirely rather than setting it to "false".
headingheadingstring | undefinedVisible dialog title and accessible-name source. Always provide a heading; an empty value intentionally leaves the native dialog unnamed. When to use: name the interrupting decision, for example "Delete account?". When NOT to use: do not omit it for production dialogs; APG modal dialogs require an accessible name.
openopenbooleanfalseReflected live modal state. Add it or call show() to open; remove it or call close() to close. When open, the native dialog enters the top layer and the page behind is inert. When to use: bind application state to the dialog's modal lifecycle. When NOT to use: do not set the internal native <dialog open> attribute; the host attribute is the only public source of truth.

Events

EventDetail typeDescription
ki-closeCustomEvent<KiDialogCloseDetail>Post-close notification for every close path. Footer actions report method when they call close(), Escape reports escape, and opt-in backdrop dismissal reports backdrop. When to use: update application state after the dialog is already closed and focus has returned through the native mechanism. When NOT to use: do not expect this event to veto closing; it is not cancelable in v1.

Methods

MethodDescription
close() => Promise<void>Closes the dialog and reports method. No-op when already closed. Equivalent to removing the host open attribute. Footer actions never close automatically; wire them to this method. When to use: resolve footer actions, programmatic dismissals, and application-controlled cancellation. When NOT to use: do not use for Escape or backdrop bookkeeping; those paths set their own close reasons.
show() => Promise<void>Opens the dialog modally. No-op when already open. Equivalent to adding the host open attribute. When to use: call from the invoker that should receive focus again after close. When NOT to use: do not call repeatedly to refresh content; update slotted content directly while open.

Slots

SlotDescription
(default)Dialog body content.
footerDialog actions; applications wire every action to close().

CSS parts

PartDescription
bodyScrollable body region.
dialogInternal native dialog surface.
footerAction row, collapsed when empty.
headingVisible h2 title, rendered only when heading is non-empty.

CSS custom properties

The public styling contract of ki-dialog: reassign these tokens at :root or on a subtree — never override internals.

TokenDescription
--ki-dialog-backdrop-bgcolor used by the dialog component for backdrop background.
--ki-dialog-backdrop-blurbackdrop blur used by the dialog component glass surface (MarsUI BACKGROUND_BLUR Blur/24 = CSS 12px; material3 resolves to blur none via the semantic override; perf-measure before enabling per DNA section 5).
--ki-dialog-bgcolor used by the dialog component for background (flat fallback of the MarsUI glass gradient: Surface/Special/light-s0_dark-s2; components paint the gradient from ki.dialog.bg-start to ki.dialog.bg-end).
--ki-dialog-bg-endcolor used by the dialog component for the glass gradient end (MarsUI Surface/Special/light-s0_dark-s2: white light / Dark/800 dark).
--ki-dialog-bg-startcolor used by the dialog component for the glass gradient start (MarsUI Surface/Special/blur_base_light White/80; dark resolves rgba(36,36,36,0.8)). Paint background: linear-gradient(180deg, var(--ki-dialog-bg-start), var(--ki-dialog-bg-end)).
--ki-dialog-borderborder used by the dialog component for border (MarsUI 1px solid Outline/base_em Black/3 light / White/3 dark; retires the migrated Black/5 foundation reference).
--ki-dialog-fgcolor used by the dialog component for foreground.
--ki-dialog-focus-ring-colorcolor used by the dialog component for focus ring color.
--ki-dialog-focus-ring-offsetdimension used by the dialog component for focus ring offset.
--ki-dialog-focus-ring-widthdimension used by the dialog component for focus ring width.
--ki-dialog-gapdimension used by the dialog component for gap.
--ki-dialog-heading-font-sizedimension used by the dialog component for heading font size.
--ki-dialog-heading-font-weightfont weight used by the dialog component for heading font weight.
--ki-dialog-heading-line-heightdimension used by the dialog component for heading line height.
--ki-dialog-max-widthdimension used by the dialog component for max width (surface size scale; the former ki.space.26xl reference misused the spacing scale).
--ki-dialog-min-widthdimension used by the dialog component for min width (surface size scale; the former ki.space.25xl reference misused the spacing scale).
--ki-dialog-motion-durationduration used by the dialog component for the enter transition (MarsUI moderate step 240ms; retires the migrated 0ms token that disabled the @starting-style fade).
--ki-dialog-motion-easingeasing used by the dialog component for the enter transition (MarsUI decelerate curve; retires the migrated linear pair).
--ki-dialog-paddingdimension used by the dialog component for padding.
--ki-dialog-radiusdimension used by the dialog component for radius (MarsUI compact Modal master 16414:19665: Radius/big_component/radius_sm 20px; the large variant anchors 24px big_component/radius_md).
--ki-dialog-shadowDialog elevation: MarsUI elevation ramp level e4 (brief §5, high modal surface; replaces the migrated approximation). material3 keeps its own e3 override (M3 dialog = level3).
--ki-focus-primaryMarsUI Focus/primary: 3px spread focus ring of Outline/primary_base_em_alpha, read from the Figma master as #845abe33 = brand 500 at 20% (Kimen name: outline.primary-base-em-alpha / brand.500-alpha-2). The previous 40% (outline.primary-low-em-alpha / brand.500-alpha-4) came from specs/002-ki-button/design-extraction.md §2.5, which read the alpha off the Dark canvas mode and recorded it as the Light value; the ring shipped 2x too strong in light and 2.8x in dark across twelve components.
--ki-motion-distance-mdMotion travel distance md (8px): entrance slide offsets (e.g. dialog rise).
--ki-motion-duration-fastFast interaction transition duration.
--ki-motion-easing-outDecelerating interaction transition easing curve.
--ki-motion-easing-standard-accelerateUtility exit curve. M3 md.sys.motion.easing.standard-accelerate. onmars: the MarsUI accelerate curve (ki.easing.in).
--ki-typography-family-bodysemantic font family for typography family body.
--ki-typography-line-height-parasemantic dimension for typography line height para.
--ki-typography-size-body-1semantic dimension for typography size body 1.
--ki-typography-weight-body-normalsemantic font weight for typography weight body normal.

Always provide a heading — APG modal dialogs require an accessible name. In destructive confirmations put autofocus on the least destructive action. Call show() from the invoker that should receive focus again after close. Non-blocking feedback belongs to ki-alert; supplementary hints to ki-tooltip.

Open ki-dialog in Storybook