---
outline: deep
---

# Toast

Toasts are used to display brief, non-blocking notifications that auto-dismiss. Commonly used to confirm actions, report errors, or surface system messages without interrupting the user's workflow.

**`<l-toast>`** — Custom Element (no Shadow DOM)

## Options

### Basic

Place a single `<l-toast>` element anywhere inside the `<body>`. Call `toast()` to display notifications.

```html
<button
  class="l-button"
  onclick="toast({ text: 'This is a toast notification!' })"
>
  Show notification
</button>
```

### Variants

Pass `variant` in the options to apply accent colors: `info`, `success`, `warning`, `danger`.

```html
<div class="flex gap-2 flex-wrap">
  <button
    class="l-button"
    onclick="toast({ text: 'Neutral message' })"
  >
    Neutral
  </button>
  <button
    class="l-button"
    onclick="toast({ text: 'Informational message', variant: 'info' })"
  >
    Info
  </button>
  <button
    class="l-button"
    onclick="toast({ text: 'Operation successful!', variant: 'success' })"
  >
    Success
  </button>
  <button
    class="l-button"
    onclick="toast({ text: 'Please be careful', variant: 'warning' })"
  >
    Warning
  </button>
  <button
    class="l-button"
    onclick="toast({ text: 'Something went wrong', variant: 'danger' })"
  >
    Danger
  </button>
</div>
```

### Heading

Pass `heading` in the options to display a title above the message.

```html
<div class="flex gap-2 flex-wrap">
  <button
    class="l-button"
    onclick="
      toast({
        text: 'Your changes have been saved.',
        heading: 'Saved',
        variant: 'success',
        timer: true,
      })
    "
  >
    Success
  </button>
  <button
    class="l-button"
    onclick="
      toast({
        text: 'This action cannot be undone.',
        heading: 'Warning',
        variant: 'warning',
        timer: true,
      })
    "
  >
    Warning
  </button>
  <button
    class="l-button"
    onclick="
      toast({ text: 'Please try again later.', heading: 'Error', variant: 'danger', timer: true })
    "
  >
    Error
  </button>
</div>
```

### Icon

Pass `icon` with an Iconify icon name to replace the accent bar with an icon, colored by variant.

```html
<div class="flex gap-2 flex-wrap">
  <button
    class="l-button"
    onclick="
      toast({
        text: 'Informational message',
        heading: 'Info',
        variant: 'info',
        icon: 'lucide:info',
      })
    "
  >
    Info
  </button>
  <button
    class="l-button"
    onclick="
      toast({
        text: 'Operation successful!',
        heading: 'Success',
        variant: 'success',
        icon: 'lucide:circle-check',
      })
    "
  >
    Success
  </button>
  <button
    class="l-button"
    onclick="
      toast({
        text: 'Please be careful',
        heading: 'Warning',
        variant: 'warning',
        icon: 'lucide:triangle-alert',
      })
    "
  >
    Warning
  </button>
  <button
    class="l-button"
    onclick="
      toast({
        text: 'Something went wrong',
        heading: 'Error',
        variant: 'danger',
        icon: 'lucide:circle-x',
      })
    "
  >
    Danger
  </button>
</div>
```

### Duration

Control how long the toast stays visible. Set to `0` for persistent notifications that must be manually dismissed.

```html
<div class="flex gap-2 flex-wrap">
  <button
    class="l-button"
    onclick="toast({ text: 'Closes in 3 seconds', duration: 3000 })"
  >
    3s
  </button>
  <button
    class="l-button"
    onclick="toast({ text: 'Closes in 10 seconds', duration: 10000 })"
  >
    10s
  </button>
  <button
    class="l-button"
    onclick="toast({ text: 'Stays until dismissed', duration: 0 })"
  >
    Persistent
  </button>
  <button
    class="l-button"
    onclick="toast({ text: 'With countdown bar', duration: 5000, timer: true })"
  >
    With timer
  </button>
</div>
```

### Placement

Position the toast stack using the `placement` attribute.

```html
<div class="flex gap-2 flex-wrap">
  <button
    class="l-button"
    onclick="
      document.querySelector('l-toast').placement = 'top-start';
      toast({ text: 'Top start' });
    "
  >
    Top start
  </button>
  <button
    class="l-button"
    onclick="
      document.querySelector('l-toast').placement = 'top-center';
      toast({ text: 'Top center' });
    "
  >
    Top center
  </button>
  <button
    class="l-button"
    onclick="
      document.querySelector('l-toast').placement = 'top-end';
      toast({ text: 'Top end' });
    "
  >
    Top end
  </button>
  <button
    class="l-button"
    onclick="
      document.querySelector('l-toast').placement = 'bottom-start';
      toast({ text: 'Bottom start' });
    "
  >
    Bottom start
  </button>
  <button
    class="l-button"
    onclick="
      document.querySelector('l-toast').placement = 'bottom-center';
      toast({ text: 'Bottom center' });
    "
  >
    Bottom center
  </button>
  <button
    class="l-button"
    onclick="
      document.querySelector('l-toast').placement = 'bottom-end';
      toast({ text: 'Bottom end' });
    "
  >
    Bottom end
  </button>
</div>
```

### Programmatic API

```js
import { toast } from 'luxen-ui/toast';

// Basic
toast({ text: 'Saved successfully!' });

// With variant
toast({ text: 'File uploaded', variant: 'success' });

// With heading and custom duration
toast({
  text: 'Undo this action?',
  heading: 'Warning',
  variant: 'warning',
  duration: 0,
});
```

### Features

- **Function-based API** — call `toast({ text: '...' })` from anywhere, no component wiring needed
- **Timer pausing on hover & focus** — countdown pauses when hovered or focused, resumes when the pointer or focus leaves
- **Timer pausing on hidden tab** — countdown pauses when the browser tab loses visibility, resumes with the remaining time when the user returns
- **Swipe to dismiss** — drag a toast horizontally to dismiss it; works with mouse, touch, and pen input
- **`@starting-style` enter animations** — smooth CSS entry transitions using the `@starting-style` at-rule
- **Keyboard dismiss** — press <kbd>Escape</kbd> to dismiss the most recent toast
- **FLIP reorder animations** — remaining toasts animate smoothly into their new positions when one is dismissed

## Accessibility

### Criteria

- **Live region** — Container uses `role="log"` with `aria-live="polite"` for screen reader announcements
- **Role** — Items use `role="status"` (`role="alert"` for `danger` variant)
- **Accessible name** — Heading and message linked via `aria-labelledby` / `aria-describedby`
- **Decorative elements** — Icons, accent bar, and timer bar are hidden with `aria-hidden="true"`
- **Timer pausing** — Timer pauses on hover and focus, providing keyboard parity
- **Motion** — Respects `prefers-reduced-motion`

### Rules

- Keep messages short and readable within the auto-dismiss duration
- Set `duration` to `5000` or longer for readability
- Use `variant="danger"` for critical alerts — it promotes the toast to `role="alert"`
- Ensure any actions in toasts are also available elsewhere on the page
- Use dialogs instead of toasts for information that requires user action

### Keyboard interactions

- `Escape` — Dismisses the most recent toast
- `Tab` — Moves focus into the toast (pauses the auto-dismiss timer)

## API reference

### Importing

```js
// Side-effect import (registers <l-toast> element)
import 'luxen-ui/toast';

// Or import the standalone function (auto-creates <l-toast>)
import { toast } from 'luxen-ui/toast';
toast({ text: 'Hello!' });
```

```css
@import 'luxen-ui/css/toast';
@import 'luxen-ui/css/close-button';
```

### Attributes & Properties

- **placement**: `ToastPlacement` (default: `'top-end'`) — Position of the toast stack on the screen.
- **duration**: `number` (default: `5000`) — Default auto-dismiss delay in milliseconds. 0 disables auto-dismiss.
- **variant**: `ToastVariant | undefined` — Default variant for toast items: `info`, `success`, `warning`, `danger`.

### Methods

- **toast(options: ToastOptions)** → `HTMLElement` — Create and show a toast notification.

### ToastOptions

- **text**: `string` — The message text to display. Required unless `html` is provided
- **html**: `string` — HTML content for the message, sanitized via the [Sanitizer API](https://developer.mozilla.org/en-US/docs/Web/API/HTML_Sanitizer_API). Ignored if `text` is provided
- **heading**: `string` — Heading text displayed above the message
- **icon**: `string` — Iconify icon name (e.g. `lucide:check`). Replaces the accent bar, colored by variant
- **variant**: `string` (default: Element's `variant`) — Override variant for this toast
- **duration**: `number` (default: Element's `duration`) — Override auto-dismiss delay in ms. `0` or `Infinity` to keep open until dismissed
- **timer**: `boolean` (default: `false`) — Show a countdown progress bar at the bottom

### Events

- **show** (cancelable) — Emitted when a toast begins to show. Cancelable. Properties: `toast`.
- **after-show** — Emitted after the show animation completes. Not cancelable. Properties: `toast`.
- **hide** (cancelable) — Emitted when a toast begins to hide. Cancelable. Properties: `toast`.
- **after-hide** — Emitted after the hide animation completes and toast is removed. Properties: `toast`.

### CSS classes

- `.l-toast-accent` — The left accent bar, colored by variant.
- `.l-toast-icon` — The leading icon, colored by variant (replaces the accent bar).
- `.l-toast-content` — The content column wrapping the heading and message.
- `.l-toast-timer` — The countdown progress bar (for timed toasts).

### CSS custom properties

- `--gap` — Gap between stacked toast items.
- `--width` — Width of the toast stack.
- `--show-duration` — Duration of the show animation.
- `--hide-duration` — Duration of the hide animation.
