# Toast

> Brief, non-blocking messages about the result of an action, with optional Undo.

Category: Feedback · Status: stable · Package: @bindshq/stance-react@0.1.1 · Docs: https://stanceui.com/components/toast

Call toast() from anywhere after mounting a single <Toaster /> near your app root (these docs mount one for you). Toasts confirm outcomes such as “Template published” and offer quick follow-ups like Undo. They pause while hovered or focused, and toast.promise() tracks async work from loading to success or error. Use Alert for messages that must stay on the page, and ConfirmationDialog for decisions.

## Import

```tsx
import { Toaster, toast } from '@bindshq/stance-react';
```

Styles are imported once per app: `@bindshq/stance-tokens/css` and `@bindshq/stance-react/styles.css`.

## Examples

### Basic

```tsx
import { Button, toast } from '@bindshq/stance-react';

export function Basic() {
  return <Button onClick={() => toast('Signature copied to clipboard')}>Show toast</Button>;
}
```

### Tones

Errors and warnings are announced assertively; others politely.

```tsx
import { Button, toast } from '@bindshq/stance-react';

export function Tones() {
  return (
    <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>
      <Button
        variant="outline"
        onClick={() => toast.success('Template published', { description: 'Live for 32 people.' })}
      >
        Success
      </Button>
      <Button variant="outline" onClick={() => toast.info('Sync scheduled for 02:00')}>
        Info
      </Button>
      <Button variant="outline" onClick={() => toast.warning('Azure token expires in 3 days')}>
        Warning
      </Button>
      <Button
        variant="outline"
        onClick={() =>
          toast.error('Could not reach Exchange', { description: 'Check your relay settings.' })
        }
      >
        Error
      </Button>
    </div>
  );
}
```

### With an action

Offer Undo instead of asking for confirmation.

```tsx
import { Button, toast } from '@bindshq/stance-react';

export function WithAction() {
  return (
    <Button
      variant="danger"
      onClick={() =>
        toast('Ada Lovelace removed', {
          description: 'Their signature will be unassigned.',
          action: { label: 'Undo', onClick: () => toast.success('Ada Lovelace restored') },
        })
      }
    >
      Remove user
    </Button>
  );
}
```

### Tracking a promise

```tsx
import { Button, toast } from '@bindshq/stance-react';

export function PromiseToast() {
  return (
    <Button
      onClick={() =>
        toast.promise(new Promise<number>((resolve) => setTimeout(() => resolve(120), 1500)), {
          loading: 'Importing users from CSV…',
          success: (count) => `${count} users imported`,
          error: 'Import failed',
        })
      }
    >
      Import users
    </Button>
  );
}
```

## API reference

| Component | Prop | Type | Default | Description |
| --- | --- | --- | --- | --- |
| Toaster | `position` | `'top-left' \| 'top-center' \| 'top-right' \| 'bottom-left' \| 'bottom-center' \| 'bottom-right'` | `'bottom-right'` | Screen corner. Phones always use full width. |
| Toaster | `visibleToasts` | `number` | `3` | Maximum shown at once; the rest queue. |
| Toaster | `hotkey` | `string` | `'F8'` | Moves focus to the toasts. |
| Toaster | `label` | `string` | `'Notifications'` | Region label. |
| Toaster | `closeLabel` | `string` | `'Dismiss notification'` | Close button label. |
| toast | `toast(title \| options)` | `(ReactNode \| ToastOptions) => string` | None | Shows a toast and returns its id. |
| toast | `success / error / warning / info / loading` | `(title, options?) => string` | None | Tone shortcuts. |
| toast | `promise` | `(promise, { loading, success, error }, options?) => Promise` | None | Loading toast that updates when the promise settles. success/error may be functions of the result. |
| toast | `update / dismiss` | `(id, options) / (id?) => void` | None | Change or remove a toast; dismiss() with no id clears all. |
| ToastOptions | `title / description` | `ReactNode` | None | Content. |
| ToastOptions | `tone` | `'default' \| 'success' \| 'error' \| 'warning' \| 'info' \| 'loading'` | `'default'` | Meaning and icon. |
| ToastOptions | `duration` | `number` | `5000` | Auto-dismiss time in ms; Infinity keeps it open. Loading toasts persist. |
| ToastOptions | `action` | `{ label, onClick, keepOpen? }` | None | One follow-up action. |
| ToastOptions | `id / dismissible / onDismiss` | `string / boolean / () => void` | None | Dedupe by id, hide the close button, react to dismissal. |

## Accessibility

- Messages are announced through persistent live regions: polite for most tones, assertive for errors and warnings.
- Timers pause while the pointer is over the toasts, while they contain focus, and while the tab is hidden (WCAG 2.2.1 Timing Adjustable).
- Press F8 to move focus to the toasts to reach actions with the keyboard.
- Actions must also be available elsewhere; toasts disappear.

## Keyboard

| Keys | Action |
| --- | --- |
| `F8` | Focus the toast list. |
| `Tab` | Move between toast actions and close buttons. |

## Guidelines

**Do**

- Confirm completed actions in a few words: “Template published”.
- Offer Undo for reversible destructive actions.

**Don’t**

- Use toasts for errors the user must fix in a form; show them inline.
- Show more than one toast for one action.

## Related

- https://stanceui.com/components/alert
- https://stanceui.com/components/banner
- https://stanceui.com/components/notification
