<!-- https://getkonjo.com/design/components/toast · source: docs/design/components/toast.md -->

# Toast

A short confirmation of something the person just did, near the bottom of the screen, gone by
itself after five seconds.

```kata-specimen
toast-states
```

> Source: [`Toast.tsx`](../../../src/components/ui/Toast.tsx) — `ToastProvider` once at the root,
> `useToast()` anywhere. When a toast is right and when it is a banner or a badge:
> [notifications](../patterns/notifications.md).

## When to use it

- To confirm an action whose result is not otherwise on screen: "Session logged."
- To offer Undo for something reversible: "Ana moved to Kids 2." · Undo.

Not for an error that needs a decision — a toast disappears and the decision does not; use an
inline error or a banner. Not for something the screen already shows: if the row appeared, the
row is the confirmation.

## Anatomy

| Part | Token |
|---|---|
| Position | absolute, above the tab bar and the upload banner, `spacing.pageHorizontal` 20 from each side |
| Surface | `surface.hero` fill, `radius.input` 8, `touchTarget` 44 floor, `spacing.s12` padding, `spacing.s8` gap |
| Message | `typography.body`, `text.onHero`; wraps to as many lines as it needs |
| Action | no fill; `typography.label` 13/700 in `accent.onHero` (5.92:1 light, 5.25:1 dark on the surface), `spacing.s6` × `spacing.s8` padding, `hitSlop` 8 |
| Motion | fades in and out over `motion.duration.exit` 180ms; one toast at a time; a new one replaces the old |

## States

- **Message only** and **with an action** as drawn.
- **Action pressed**: `opacity.pressed` 0.85, then the toast dismisses and runs the action.
- **Action focused** (web keyboard): a 2px `border.focusOnHero` ring, because the surface inverts.
- **In a modal**: a screen presented over the tabs mounts its own `<ToastHost />`, or the toast
  paints underneath it.
- **Disabled, loading, error**: none. A toast is not a place for any of them.

## Content

- Past tense, plain, naming what happened: "Promotion recorded."
- One line. A longer message wraps and the toast grows — it is never cut off, but a toast that
  needs three lines is probably a banner.
- The action is one verb: "Undo".

## Accessibility

- The toast is a polite live region (`accessibilityLiveRegion="polite"`), so a screen reader
  announces it without stealing focus.
- The action is role `button`, labelled with its text.
- Five seconds is short for someone using a screen reader or switch control. Anything that must
  not be missed does not go in a toast.

**Known gap.** The dismiss time does not lengthen when the toast carries Undo, as the
[notifications](../patterns/notifications.md) chapter asks. That is a behaviour change, and it
belongs in the component, not per screen.

## Do and don't

```kata-specimen
toast-error
```

## Code

```tsx
import { useToast } from '../../components/ui';

const { showToast } = useToast();

showToast('Ana moved to Kids 2.', {
  action: { label: 'Undo', onPress: () => moveBack(ana.id) },
});
```
