# Toast

> Temporary notifications.

## Examples

### useToast()

Place `<UiToastViewport />` once near the app root.

```vue
<script setup lang="ts">
const toast = useToast();
</script>

<template>
  <div class="demo-row">
    <UiButton variant="secondary" @click="toast.success('Changes saved')">Success</UiButton>
    <UiButton variant="secondary" @click="toast.error('Couldn’t reach the server')">Error</UiButton>
    <UiButton variant="secondary" @click="toast.info('3 new comments')">Info</UiButton>
    <UiButton variant="ghost" @click="toast.info('Stays until dismissed', { duration: 0 })">
      Persistent
    </UiButton>
  </div>
</template>
```

### Action

`action` adds a button, e.g. Undo. Pressing it runs `onClick` and dismisses the toast.

```vue
<script setup lang="ts">
const toast = useToast();
const archived = ref(false);

function archive() {
  archived.value = true;
  toast.info("Conversation archived", {
    action: { label: "Undo", onClick: () => (archived.value = false) },
  });
}
</script>

<template>
  <div class="demo-stack">
    <UiButton variant="secondary" :disabled="archived" @click="archive">Archive</UiButton>
    <p class="demo-note">{{ archived ? "Archived" : "In your inbox" }}</p>
  </div>
</template>
```

## API

### ToastViewport

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `label` | `string` | — | Accessible name of the live region. Defaults to the `notifications` translation. |

| Slot | Props | Description |
| --- | --- | --- |
| `default` | `{ toast: Toast; dismiss: () => void; }` | Renders each toast, replacing the message and close button. |
| `close-icon` | — | Replaces each close button's icon. |

Types:

```ts
export interface Toast {
  id: number;
  message: string;
  tone: ToastTone;
  /** Milliseconds before auto-dismiss; `0` keeps it until dismissed. */
  duration: number;
  /** A button in the toast, e.g. "Undo". Pressing it also dismisses the toast. */
  action?: ToastAction;
}

export type ToastTone = "success" | "danger" | "info";

export interface ToastAction {
  label: string;
  onClick: () => void;
}
```

### ToastItem

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `toast` (required) | `Toast` | — | The toast to render, from `useToast().items`. |

| Event | Payload | Description |
| --- | --- | --- |
| `dismiss` | `[id: number]` | Timed out or closed. |

| Slot | Props | Description |
| --- | --- | --- |
| `default` | `{ toast: Toast; dismiss: () => void; }` | Replaces the message and close button. |
| `close-icon` | — | Replaces the close button's icon. |

Types:

```ts
export interface Toast {
  id: number;
  message: string;
  tone: ToastTone;
  /** Milliseconds before auto-dismiss; `0` keeps it until dismissed. */
  duration: number;
  /** A button in the toast, e.g. "Undo". Pressing it also dismisses the toast. */
  action?: ToastAction;
}

export type ToastTone = "success" | "danger" | "info";

export interface ToastAction {
  label: string;
  onClick: () => void;
}
```

## Styling

- Parts (`[data-part="…"]`): `toast-viewport`, `toast`, `toast-message`, `toast-action`, `toast-close`
- State attributes: `data-toast-tone`

- Parts (`[data-part="…"]`): `toast`, `toast-message`, `toast-action`, `toast-close`
- State attributes: `data-toast-tone`

## Accessibility

- Toasts are announced politely; errors are announced right away.
- Timers pause on hover, focus and hidden tabs, then resume with the time left. `duration: 0` keeps a toast until dismissed.
- Shown above an open modal dialog, but the browser makes it inert there: it can't be clicked or announced until the dialog closes.
