import { Meta, Canvas, Controls } from '@storybook/addon-docs/blocks'
import * as ToastStories from './Toast.stories'

<Meta of={ToastStories} />

# Toast

A pill that says what just happened — three types, an optional leading
check, an optional action — and **ToastProvider**/**useToast**, which own
the positioning (bottom-left), the portal, and the auto-dismiss.

<Canvas of={ToastStories.AllTypes} />

## When

- Confirming an action's outcome, briefly: "Created", "Link copied",
  "Changes saved".
- `actionLabel` + `onAction` add the one follow-up worth offering — an
  "Undo", a "View".
- **The leading icon says which type it is**: a check for `success`,
  `brand` and `neutral`, a `!` for `warning`, an `×` for `error`. It was a
  check on all of them, so a warning arrived with a tick beside it and a
  caller with bad news turned the icon off instead.
- `neutral` states, `success` celebrates, `brand` speaks with the accent's
  voice, `error` reports a failure, and `warning` says something needs
  knowing — a notice usually paired with `durationMs: 0` and a Dismiss,
  because a warning that fades takes itself with it.

<Canvas of={ToastStories.WithAction} />

## When not

- Something the person must read or act on → put it in the surface; a
  toast dismisses itself.
- A question before the action → **ConfirmDialog**.
- Standing status → **Chip**, or your surface's own chrome.

## How

```tsx
import { ToastProvider, useToast } from '@estiva-app/ui'

// once, at the root
<ToastProvider>{app}</ToastProvider>

// anywhere below it
const { showToast } = useToast()
showToast({ label: 'Link copied', type: 'success' })
```

- **Three at once** (D7). The newest stands nearest the corner. A fourth
  hides the oldest, which comes back when one of the three closes — so a
  warning kept up with `durationMs: 0` is never lost under newer ones.
- Auto-dismiss is 5s; `durationMs: 0` keeps one up until it is dismissed.
  The timers pause while the pointer is over the toasts, while focus is in
  them, and while the window is in the background.
- **The action closes its own toast.** Pressing it runs `onAction`, if you
  gave one, then closes that toast and no other. A Dismiss is just
  `actionLabel: 'Dismiss'`.
- `showToast` returns the toast's id. `dismissToast(id)` closes that toast;
  `dismissToast()` with no id closes **every** toast on screen.
- A toast can be swiped away towards its corner — left or down.
- It is Base UI's `Toast`. The stack is a region named "Notifications" that
  a screen reader announces politely; an `error` toast is announced at once.
- **Each toast is a `dialog`** (not modal), so it can take focus. A test that
  waits for "no dialog" after closing one will find the toast: ask for the
  dialog by its name.
- Focus on a toast shows the browser's own outline, as the package's buttons
  do.
- `useToast` outside a provider throws — mount the provider at the root,
  once.

## What it owns

It does these by itself. Write none of them around it.

| It does | So you never write | Refused when written by hand |
|---|---|---|
| Floats on top of the page | a portal, or a `z-index` to win | ✓ |
| Says what it is to assistive technology: a message, announced as it arrives | `role="status"` or `aria-live` | ✓ |
| F6 moves focus to the toasts from anywhere; Escape closes one | a key listener |  |
| Leaves by itself after a while | a timer |  |

## Keys

| Key | What happens |
|---|---|
| F6 | Moves focus to the toasts, from anywhere on the page |
| Tab | Walks the toasts and their actions; Shift+Tab from the region goes back to where you were |
| Enter, Space | On an action: presses it |
| Escape | On a toast: closes it |

## Props

<Controls of={ToastStories.Neutral} />
