# Toast

A short message about something the user just did, in the corner of the screen: Changes saved, Link copied, Upload failed. It closes on its own after a few seconds. Mount one Toaster at the root of the app and call toast({ title }) from an event handler; a Toast element shown with state works too.

## Usage

### When to use

- Confirm an action the user just took, without stopping them: Changes saved, Link copied.
- Offer a quick undo right after an action, when the same undo also exists elsewhere.

### When not to use

- An error that blocks work. Show it in the page, next to what failed, for example with Field.
- A question or a decision. Use AlertDialog.
- A state that lasts, such as a failed build. Use Badge.

## Variants

### variant

default has no icon. success, danger, warning and info add their status icon; the surface stays neutral.

Values: `default`, `success`, `danger`, `warning`, `info`. Default: `default`.

## Examples

### Saved

Shown with state here; in an app, call toast({ variant: "success", title: "Changes saved" }).

```tsx
<Toaster>
  <Toast open={open} onOpenChange={setOpen} variant="success" title="Changes saved" />
</Toaster>
```

### With an action

A longer duration, since the user has to reach the button. The action also lives in the History panel.

```tsx
<Toaster>
  <Toast
    open={open}
    onOpenChange={setOpen}
    title="Project archived"
    description="It is hidden from your project list."
    duration={8000}
    action={<ToastAction altText="Undo from the History panel" onClick={undo}>Undo</ToastAction>}
  />
</Toaster>
```

### Failed

```tsx
<Toaster>
  <Toast open={open} onOpenChange={setOpen} variant="danger" title="Upload failed" description="The file is larger than 25 MB." />
</Toaster>
```

### Info

```tsx
<Toaster>
  <Toast open={open} onOpenChange={setOpen} variant="info" title="Export started" description="The file downloads when it is ready." />
</Toaster>
```

## Do and don't

### Do

- Confirm an action the user just took: Changes saved, Link copied.
- Write the title in the past tense, and keep it to a few words.
- Mount one Toaster at the root of the app, and call toast() after the action is done.

### Don't

- Don't put an error that blocks work in a toast; show it in the page, next to what failed.
- Don't use it for a question or a decision; use AlertDialog.
- Don't put the only way to do something in a toast action; it closes on its own.

## Props

| Name | Type | Values | Default | Description |
| --- | --- | --- | --- | --- |
| `variant` | `enum` | `default`, `success`, `danger`, `warning`, `info` | `default` | default has no icon. success, danger, warning and info add their status icon; the surface stays neutral. |
| `title` (required) | `node` |  |  | What happened, in a few words, past tense: Changes saved. |
| `description` | `node` |  |  | One more sentence when the title is not enough. |
| `duration` | `number` |  | `4000` | How long it stays, in ms. Make it longer for a toast with an action or a long description. |
| `action` | `node` |  |  | One ToastAction, such as Undo. Its altText says where else to do it. |
| `dismissible` | `boolean` |  | `true` | The Dismiss button. Keep it, so a toast never sits over content the user needs. |
| `open` | `boolean` |  |  | Set on Toast shown with state. Whether it is shown. Pair it with onOpenChange. |
| `onOpenChange` | `function` |  |  | Set on Toast shown with state. Called with false when the time is up, or on Dismiss, Escape or a swipe. |

### Slots

| Name | Required | Description |
| --- | --- | --- |
| `toaster` | yes | One Toaster, mounted once at the root of the app. |

## Anatomy

| Part | Description |
| --- | --- |
| `root` | Toast: the raised surface with a border, radius-container and shadow-med, px-lg py-md, gap-md between its parts. |
| `viewport` | Toaster: the stack in the end corner at the bottom of the screen, 384px wide at most, gap-sm between toasts, p-lg from the edges. |
| `icon` | The status icon for success, danger, warning and info: Tabler icons, 16px, in the status text color, level with the title. |
| `title` | What happened: 14px medium primary text. |
| `description` | Optional second line: 13px secondary text. |
| `action` | ToastAction: one small secondary Button, such as Undo. |
| `close` | The Dismiss button: a 24px icon button with a Tabler X, 16px, secondary. |
| `hitArea` | Transparent ::before on the Dismiss button, never smaller than size-target-min. |

## Accessibility

Role: `status`

| Keys | Action |
| --- | --- |
| `F8` | Moves focus to the toasts, so a keyboard user can reach an action or dismiss them. |
| `Tab` | Moves through the action and the Dismiss button of each toast. |
| `Escape` | Closes the focused toast. |

- Every toast is announced politely, after what a screen reader is reading. It never takes focus.
- The timer pauses while the pointer is over a toast or focus is inside it, and while the window is in the background.
- A ToastAction needs altText: how to do the same without the toast (Undo from the History panel). A toast can close before anyone reaches it, so the action must also exist elsewhere.
- The status icon is decorative; the title says what happened, so the state never relies on color alone.
- It rises in only when the user allows motion, and fades in otherwise. It closes at once.

## Install

```bash
npx shadcn add https://werewolf-ui.vercel.app/r/toast.json
```

This also adds `styles/werewolf.css`, the tokens every component uses, and any other component it needs. Import that file once in your root CSS, after `@import "tailwindcss"`, with a path relative to that CSS file (from `app/globals.css` it is `@import "../styles/werewolf.css"`).
