# Dialog

## Overview

The dialog component presents a focused native `<dialog popover>` surface for confirmations, approvals, and compact review flows.

The component is classless by default. It styles semantic dialog structure directly through the native `<dialog>` element, a direct child `<form>`, a `<header>` for the title and dismissal control, and a `<footer>` for actions.

## When to use

Use a dialog for a focused confirmation, approval, or compact review task while preserving the surrounding page context; use its modal form when that page must become inert.

## When not to use

Do not use a dialog for routine page content or a lengthy workflow that needs a full page and stable navigation.

## Usage

```html
<button type="button" id="open-dialog" popovertarget="review-dialog" popovertargetaction="show">Open dialog</button>

<dialog id="review-dialog" popover aria-labelledby="dialog-title">
  <form>
    <header>
      <h2 id="dialog-title">Review changes</h2>
      <p>Confirm the update before publishing it to production.</p>
      <button class="tertiary icon" type="button" popovertarget="review-dialog" popovertargetaction="hide" aria-label="Close dialog">close</button>
    </header>

    <p>Shipping this change will make it visible to all users immediately.</p>

    <footer>
      <button class="secondary" type="button" popovertarget="review-dialog" popovertargetaction="hide">Cancel</button>
      <button type="button" popovertarget="review-dialog" popovertargetaction="hide">Confirm</button>
    </footer>
  </form>
</dialog>
```

Use this component when the user should complete or dismiss a focused task while keeping the surrounding page available.

Use a modal dialog opened with `showModal()` instead when the surrounding page must become inert.

Triggering a dialog from a separate button does not require JavaScript when the dialog is exposed as a popover. Use `popovertarget` on the trigger and `popovertargetaction="hide"` on dismissal controls.

## Behavior

Covered by [Playwright behavior tests](../../tests/e2e/components.spec.js).

- DLG-001: The dialog surface should size within the viewport and center itself without requiring a wrapper.
- DLG-002: The dialog shell exposes `--dialog-border-radius` and `--dialog-border-width` so its shape and edge definition can be customized consistently.
- DLG-003: Open and close transitions should fade opacity while preserving a reduced-motion fallback.
- DLG-004: The body layout should stack header, content, and actions with shared spacing tokens instead of one-off gaps or helper wrappers.
- DLG-005: Action rows should align to the end and wrap cleanly when space is constrained.
- DLG-006: The component should work with `popover` and `popovertarget` attributes so open and close actions can stay declarative.
- DLG-007: The dialog shell should rely on semantic elements and scoped descendant selectors rather than component-specific class names.
- DLG-008: Trigger buttons should open the dialog with `popovertargetaction="show"` when a popover interaction is needed.
## Accessibility

- Provide an accessible name with `aria-labelledby` or `aria-label`.
- Use a heading inside the dialog so the purpose is immediately clear.
- Keep dismiss controls keyboard reachable and give icon-only buttons an accessible name.
- Use native dialog behavior rather than replacing it with custom overlays or focus trapping logic unless product requirements exceed platform support.
- Keep the body content concise enough that the modal surface remains scannable on smaller screens.

## Variables

| Variable | Type | Description |
| --- | --- | --- |
| `--dialog-backdrop-color` | `<color>` | Sets the modal backdrop overlay color; change it to make the page behind dialogs more or less visually suppressed. |
| `--dialog-border-radius` | `<length>` | Sets the outer dialog corner radius and feeds the inner radius calculation; change it to align dialogs with the product surface shape. |
| `--dialog-border-width` | `<length>` | Sets the dialog border width and inner-radius offset; change it when dialogs need stronger or subtler edge definition. |
| `--dialog-color-accent-subtle` | `<color>` | Sets --dialog-color-accent-subtle so the component can default to shared theme or layout tokens while exposing an overrideable component API. |
| `--dialog-color-border-subtle` | `<color>` | Sets --dialog-color-border-subtle so the component can default to shared theme or layout tokens while exposing an overrideable component API. |
| `--dialog-color-text` | `<color>` | Sets --dialog-color-text so the component can default to shared theme or layout tokens while exposing an overrideable component API. |
| `--dialog-control-gap` | `<length>` | Sets --dialog-control-gap so the component can default to shared theme or layout tokens while exposing an overrideable component API. |
| `--dialog-font-size` | `<length>` | Sets --dialog-font-size so the component can default to shared theme or layout tokens while exposing an overrideable component API. |
| `--dialog-max-inline-size` | `<length>` | Sets the preferred maximum dialog width before viewport gutters are applied; change it for narrower confirmations or wider form dialogs. |
| `--dialog-shadow` | `Any` | Sets the dialog elevation shadow; change it to tune modal depth or reduce visual weight. |
| `--dialog-space-inline` | `<length>` | Sets --dialog-space-inline so the component can default to shared theme or layout tokens while exposing an overrideable component API. |
| `--dialog-space-stack` | `<length>` | Sets --dialog-space-stack so the component can default to shared theme or layout tokens while exposing an overrideable component API. |
| `--dialog-transition-duration` | `<time>` | Sets the open and close animation duration for the dialog and backdrop; change it when modal motion should feel faster or calmer. |

## Depends On

- `--color-accent-strong`
- `--color-accent-subtle`
- `--color-border-subtle`
- `--color-text`
- `--font-size`
- `--layout-control-gap`
- `--layout-control-radius`
- `--layout-space-inline`
- `--layout-space-stack`
- `--layout-surface-border-width`
