# Toast

Level: organism.

## Purpose and use

Announce an operation result with optional follow-up actions and diagnostic text.
Use Alert for persistent context beside a field and Modal for a blocking decision.

## Anatomy, behavior, and accessibility

- A semantic Toast Setting Icon leads optional title/subtitle, error-copy text,
  one or two action buttons and close. The second action requires actions=true.
- Warning/danger use role=alert; info/success use role=status. The icon is
  decorative, so the text must explain the outcome without relying on color.
- Actions emit immediately without removing the toast. Close starts an internal
  exit state and emits `dismiss` only after the matching exit animation ends.
  Error-copy emits errorCopyClick and immediately changes its icon to a check
  for two seconds; repeated activation restarts the feedback timer.
- Buttons are native and named; error-copy includes the diagnostic text in its
  accessible name. Keep titles concise and action labels specific. Avoid putting
  secrets or unnecessary personal information into diagnostic copy.

## Open Questions

Copy feedback does not write to the clipboard or confirm success. The parent must
handle errorCopyClick. There is no auto-dismiss timer, toast queue, stacking manager
or loading/disabled action state in this component.

## Local component contract

This is the active owned contract for `component.toast`. The API below
is verified against the current local implementation, focused test and story.
The Source commit `0112cba0779a2d2a4b6c7a17243201694344d70a` remains
migration provenance, not the runtime owner.

### Classes and selectors

- `WblToastComponent` — `wbl-toast` (src/app/design-system/patterns/toast/toast.component.ts).

### Inputs

- `WblToastComponent.type = input<WblToastSettingIconType>('info')`
- `WblToastComponent.title = input(true)`
- `WblToastComponent.titleText = input('Title')`
- `WblToastComponent.subtitle = input(true)`
- `WblToastComponent.subtitleText = input('Subtitle')`
- `WblToastComponent.errorCopy = input(false)`
- `WblToastComponent.errorCopyText = input('error123 texttexttexttexttexttexttexttexttexttext')`
- `WblToastComponent.actions = input(false)`
- `WblToastComponent.actionLabel = input('Button')`
- `WblToastComponent.action2 = input(true)`
- `WblToastComponent.action2Label = input('Button')`
- `WblToastComponent.close = input(true)`

### Public types and allowed values

```ts
type WblToastSettingIconType = 'info' | 'success' | 'warning' | 'danger';
```

### Models

- None.

### Outputs

- `WblToastComponent.dismiss = output<void>()`
- `WblToastComponent.actionClick = output<void>()`
- `WblToastComponent.action2Click = output<void>()`
- `WblToastComponent.errorCopyClick = output<void>()`

### Slots and projection markers

- The exact template has no Angular content-projection slot.

### Local evidence

- Code: `src/app/design-system/patterns/toast/toast.component.ts`.
- Focused test: `src/app/design-system/patterns/toast/toast.component.spec.ts`.
- Public export: `export * from './patterns/toast/toast.component';` in `src/app/design-system/index.ts`.
- Storybook: `storybook/stories/toast.stories.ts` (`Design System/Patterns/wbl-toast`).
  `AnimatedDismiss` demonstrates the complete retained-exit lifecycle.

## Figma status

UI Kit node [`3910:389`](https://www.figma.com/design/EO9tuCsqwuHL8cZ4Eb2psR/?node-id=3910-389)
is the current visual evidence for the 372px Toast geometry, spacing,
icon/text hierarchy, actions and close affordance. No published component key
is claimed by this runtime contract.

## Provenance

The archived source-document copy is historical evidence only. The active
resolver is local code/test/export and the exact Storybook story above.

## M-002 refinement

Toast aligns its 372px inline size, geometry, spacing, icon/text hierarchy and
close affordance with the UI Kit node above. Its public inputs and outputs are
unchanged.

Reusable motion behavior applies to every Toast consumer:

- enter: 300ms `Fade-in` and `Slide-right` through `--duration-slow`;
- close sets internal `isClosing`, adds `wbl-toast--closing`, and runs 200ms
  `Fade-out` plus `Slide-left` through `--duration-toast-dismiss`;
- only an `animationend` whose animation name ends with `wbl-toast-hide`
  completes closing and emits the existing `dismiss` output;
- `prefers-reduced-motion` reduces both animation durations to 1ms without
  delaying the semantic status/alert announcement;
- motion does not move focus or change the current `role=status|alert` mapping.

Transport Requests uses this retained-exit lifecycle for delete success and
error feedback. Parent state removes the component in response to `dismiss`.
