GitHub

Dialog

Modal dialog with backdrop, focus trap, Esc-to-close, and focus restore. Slot the body as default content and footer actions into slot="footer".

Stable wc import '@esa/ecology/esa-dialog';

Preview

The default md dialog (480px). The close button, backdrop click, and Esc all dismiss it.

<button data-target="dlg-md">Open dialog</button>

<esa-dialog id="dlg-md" heading="Medium dialog">
  <p>The default md dialog. The close button, backdrop click, and Esc all dismiss it.</p>
  <button slot="footer" data-close="dlg-md">Close</button>
</esa-dialog>

Sizes

Five widths cover compact prompts through immersive, edge-to-edge flows.

The most compact dialog (280px), one step below sm. Tab cycles within; Esc closes.

A compact dialog (360px). Tab cycles within; Esc closes.

The default md dialog (480px).

A large dialog (640px) for richer content.

Edge-to-edge dialog for immersive flows.

<esa-dialog size="xs" heading="Extra small dialog"></esa-dialog>
<esa-dialog size="sm" heading="Small dialog"></esa-dialog>
<esa-dialog heading="Medium dialog"></esa-dialog>
<esa-dialog size="lg" heading="Large dialog"></esa-dialog>
<esa-dialog size="fullscreen" heading="Fullscreen dialog"></esa-dialog>

API

PropTypeDefaultDescription
open boolean false Reflected attribute that drives visibility. Set imperatively via show() / close().
heading string '' Title shown in the header and used as the dialog accessible name.
show-close-button boolean true Renders the header close (×) button.
size 'xs' | 'sm' | 'md' | 'lg' | 'fullscreen' 'md' Panel width: 280 / 360 / 480 / 640px, or edge-to-edge.

Methods

PropTypeDefaultDescription
show() method Opens the dialog and traps focus.
close() method Closes the dialog, restores focus, and emits the close event.

Events

EventTypeDefaultDescription
close CustomEvent Fired when the dialog closes (close button, backdrop click, or Esc). Bubbles and is composed.

Accessibility

  • The panel is role="dialog" with aria-modal="true"; heading provides the accessible name.
  • Focus is trapped while open — Tab and Shift+Tab cycle within the panel.
  • Opening stores the previously focused element and restores it on close.
  • Escape closes the dialog; the close button carries an aria-label.

Theming surface

Every public token this component reads, extracted from its source at build time. The Resolves to column walks each token's real lineage — component → semantic → primitive → raw value — so you can see exactly where re-pointing it lands. A spoke re-skins by overriding these in its theme-<slug>.css; component internals are never edited. No hook for what you need? File it with /request-lego.

TokenTierResolves to
--dialog-bg component #fcfcfc via --color-surface-elevated--color-gray-1
--dialog-border-color component #d9d9d9 via --color-border-light--color-gray-6
--dialog-color component #202020 via --color-text-primary--color-gray-12
--dialog-radius component 0.75rem via --radius-400
--dialog-width component 480px
--dialog-width-lg component 640px
--dialog-width-sm component 360px
--dialog-width-xs component 280px
--focus-ring-color component #65ba74 via --color-border-focus--color-grass-8
--focus-ring-width component 2px
--dialog-footer-bg ad-hoc transparent
--dialog-header-bg ad-hoc transparent
--color-backdrop semantic rgba(0, 0, 0, 0.5) via --color-black-a-7
--color-surface-sunken semantic #f0f0f0 via --color-gray-3
--color-text-secondary semantic #646464 via --color-gray-11
--focus-ring-offset semantic 2px
--font-sans semantic 'DM Sans', sans-serif
--transition-fast semantic 150ms ease
--type-size-400 semantic clamp(1rem, 0.88rem + 0.6vw, 1.25rem)
--font-weight-semibold primitive 550
--radius-200 primitive 0.5rem
--spacing-200 primitive 0.5rem
--spacing-300 primitive 0.75rem
--spacing-500 primitive 1.5rem
--z-modal primitive 400
--z-modal-backdrop primitive 300