# Toast

**When to use:** Non-blocking notifications — save confirmations, error alerts, info messages, warnings. Toasts appear in a corner of the screen and auto-dismiss after a configurable duration.

**Keywords:** snackbar, notification popup

**Import:** `import { showToast, ThemeColor } from '@ahrowe/ui'`  
**Types:** `import type { ToastOptions, ToastContextConfig, ToastLabels, ToastPosition, ColorValue } from '@ahrowe/ui'`

**Setup:** [AhroweProvider](AhroweProvider.md) shows the toasts. Its `toast` prop sets the defaults for all of them:

```tsx
import { AhroweProvider } from '@ahrowe/ui';

<AhroweProvider toast={{ position: 'bottom-right', duration: 3000 }}>
  <App />
</AhroweProvider>
```

`ToastProvider` was removed in 0.41. It took the same settings as props: move them into `toast`.

**Usage:** Call `showToast` anywhere — no component hierarchy required:

```tsx
import { showToast, ThemeColor } from '@ahrowe/ui';

// Simple message, in the primary colour. A confirmation that something was saved reads as Success, below
showToast('Profile saved!');

// Semantic colours, each with its own icon
showToast('Something went wrong.', { color: ThemeColor.Error });
showToast('3 items updated.', { color: ThemeColor.Info });
showToast('Your changes were saved.', { color: ThemeColor.Success });
showToast('Disk space is low.', { color: ThemeColor.Warn });

// Persistent (no auto-dismiss)
showToast('Processing…', { duration: 0, showCloseButton: true });

// With progress bar showing remaining time
showToast('Uploading file…', {
  duration: 5000,
  showRemainingTime: true,
});

// Pause the auto-dismiss timer while hovered/focused (default true) — opt out per toast
showToast('Quick note', { pauseOnHover: false });

// Override position per-toast
showToast('Copied!', { position: 'top-center', duration: 1500 });

// With slot overrides
showToast('Done', {
  color: ThemeColor.Info,
  classNames: { root: 'my-toast' },
  styles: { progressBar: { backgroundColor: '#6200ea' } },
});
```

**ToastContextConfig**, the `toast` prop. Every key but `allowStacking` can also be passed to a single `showToast`:

| Key | Type | Default | Description |
|-----|------|---------|-------------|
| `position` | `ToastPosition` | `'top-right'` | Screen position |
| `duration` | `number` | `4000` | Auto-dismiss delay in ms; `0` = persistent |
| `showRemainingTime` | `boolean` | `true` | Show a progress bar draining to zero |
| `showCloseButton` | `boolean` | `true` | Show × button |
| `allowStacking` | `boolean` | `true` | Allow multiple toasts simultaneously |
| `pauseOnHover` | `boolean` | `true` | Pause the auto-dismiss timer while the toast is hovered or focused |
| `labels` | `ToastLabels` | | See **Labels** |

**Swipe to dismiss:** on touch devices, every toast can be dragged away to dismiss it, on top of the close button and auto-dismiss timer. A fast flick dismisses even without dragging far; dragging pauses the auto-dismiss timer for the duration of the gesture (regardless of `pauseOnHover`) and a vertical drag is left alone so it doesn't fight the page's own scrolling. It's gated to coarse (touch) pointers only — on mouse/trackpad devices the close button and auto-dismiss already cover it, and a drag there is more likely to be a text selection than an intentional dismiss.

**ToastPosition:** `'top-left'` `'top-center'` `'top-right'` `'bottom-left'` `'bottom-center'` `'bottom-right'`

**color:** a `ThemeColor` (default `Primary`) or any CSS colour, see [ThemeColor.md](ThemeColor.md). A `ThemeColor` also picks the icon: a bell for `Primary` and `Neutral`, then info, check, warning and cross; any other colour shows the bell.

**Slots:** `root` `icon` `content` `closeButton` `progressBar`

**Labels:** `close`, the dismiss button's screen-reader name. Set it for the whole app in `AhroweProvider`'s `toast={{ labels: { close: 'Schließen' } }}`, or per toast with `showToast('Saved', { labels: { close: 'Schließen' } })`. Type: `ToastLabels`.

## Sizing

A toast is sized and spaced by its font: the padding, the gap, the body copy, the icon, the close button, the variant accent bar and the progress bar all scale with the theme's text, as does the gap between stacked toasts.

Its `min-width` and `max-width` are `em` rather than pixels, so they bound the *measure* — roughly how many characters fit on a line — instead of a fixed width that would grow cramped as the text got larger.

## Migration from `type`

Before 0.43 a toast's colour was `type`, a string: `showToast('Saved', { type: 'success' })`. It
is now `color`, and `ToastType` is gone:

| Before | After |
|--------|-------|
| `{ type: 'default' }` | nothing: `Primary` is the default, with the same bell |
| `{ type: 'success' }` (and `'info'`, `'warn'`, `'error'`) | `{ color: ThemeColor.Success }` |

The string still works as a value, `{ color: 'success' }`, since a `ThemeColor` is that string.
`type` itself does not: TypeScript reports it, and in plain JavaScript the toast falls back to the
primary colour.
