<!-- Generated by emit-docs.ts — do not edit. -->
# ToastRegion

The positioned live region that holds the toast stack (D64). Two things here are load-bearing and both look like details: 1. **The two live wrappers are always rendered**, empty queue included. A live region announces mutations to a subtree that already existed; a wrapper that mounts together with its first toast reads as a new subtree, and that first toast is never announced. 2. **`popover="manual"`, not `"auto"`.** Manual puts the region in the native top layer without light dismiss. The top layer is required because Dialog uses showModal() — also top layer — so a fixed region at --psi-z-overlay would paint *under* the modal backdrop, hiding the confirmation for the action a user just took inside a dialog. And `auto` would be dismissed by the very click that raised the toast. Routing reads `variant` off each child, the same Children.map technique Table uses for select-all injection. Consequence of the split, visible in the `InRegion` VR baseline: the stack is grouped by politeness, not strictly chronological — every assertive toast sorts below every polite one regardless of arrival order. Chronological order is preserved *within* each group. Keeping it exact across both would mean one live region with a politeness that changes per message, which is the thing the two wrappers exist to avoid. Accepted: at `limit` 3 the grouping reads as severity ordering, and the newest toast still lands nearest the screen edge within its group.

## Props

| Prop | Type | Default | Required | Description |
|---|---|---|---|---|
| `placement` | `"top-start" \| "top-end" \| "bottom-start" \| "bottom-end"` | bottom-end | no | Corner the stack occupies. |
| `aria-label` | `string` | Notifications | no | Accessible name for the region. |
| `children` | `ReactNode` | — | yes | The toast stack — `Toast` elements, routed to a live wrapper by variant. |
| `className` | `string` | — | no | Additional CSS class name(s) merged onto the component's root element. |
| `ref` | `Ref<HTMLDivElement>` | — | no | Forwarded ref to the region element. |

## Keyboard & assistive tech

| Keys | Behavior |
|---|---|
| Tab | Moves into the stacked toasts' controls in DOM order; the region itself is not focusable. |

Renders two always-present live wrappers — role="status"/aria-live="polite" and role="alert"/aria-live="assertive" — and routes each toast into one by variant (neutral/success polite, warning/danger assertive). Both stay in the DOM when the queue is empty: a live region announces mutations to a subtree that already existed, so a wrapper mounting with its first toast would leave that toast unannounced. Sits on the native top layer via popover="manual", so a toast raised from inside a modal Dialog is still painted above the backdrop and still announced — though showModal() makes everything outside the dialog inert, so it cannot be clicked until the dialog closes; manual (not auto) means no light dismiss, so the click that raised the toast cannot close it. The region is click-through (pointer-events: none) and each toast takes its own clicks back.

## Theming

This component has no `--psi-toast-region-*` tokens — its styling binds scale tokens only, so there is nothing component-scoped to override. Theme changes reach it through the semantic tokens of its children and surroundings.



## Rules

- One accent per visual group; everything else neutral or ghost.
- danger only for actions with real consequences.
- Sizes are px numbers (24|32|40|48), never S/M/L.
- Typography tokens are --psi-text-{size}-{lineHeight}-{weight}.
- Override component tokens (--psi-{component}-*), not semantic tokens, for one-off theming.
- --psi-button-font overrides button typography across all sizes (documented D34 override; ember → mono).
- Wrap labeled form controls in Field — label association, description/error line, aria-describedby and aria-invalid come wired; don't hand-roll label+message rows.
- Field is for a control with a *visible* label. A toolbar filter control named by aria-label or placeholder takes neither a Field nor a hand-rolled label row — compare filter-toolbar (no labels) with table-pagination ("Rows per page" visible, so Field).
- Use Dialog for blocking modal flows — title/footer slots, dismissible gate; danger stays on the footer Buttons, one accent per group.
