
# Toast

**Short messages at the edge of the screen that close on their own.**

**Reference:** [View Source](https://github.com/jramke/fluid-primitives/tree/main/Resources/Private/Primitives/Toast) · [Zag.js Docs](https://zagjs.com/components/react/toast)

**ToastExamples.html**

```html
<ui:toaster rootId="toaster">
    <ui:toaster.toastTemplate>
        <ui:toast.root>
            <ui:toast.indicator type="{f:constant(name: 'Jramke\FluidPrimitives\Enum\ToastType::Success')}" class="mt-0.5 shrink-0 text-success">
                <svg class="size-4" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                    <circle cx="12" cy="12" r="10" />
                    <path d="m9 12 2 2 4-4" />
                </svg>
            </ui:toast.indicator>
            <ui:toast.indicator type="{f:constant(name: 'Jramke\FluidPrimitives\Enum\ToastType::Warning')}" class="mt-0.5 shrink-0 text-warning">
                <svg class="size-4" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                    <path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3" />
                    <path d="M12 9v4" />
                    <path d="M12 17h.01" />
                </svg>
            </ui:toast.indicator>
            <ui:toast.indicator type="{f:constant(name: 'Jramke\FluidPrimitives\Enum\ToastType::Error')}" class="mt-0.5 shrink-0 text-destructive">
                <svg class="size-4" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                    <circle cx="12" cy="12" r="10" />
                    <path d="m15 9-6 6" />
                    <path d="m9 9 6 6" />
                </svg>
            </ui:toast.indicator>
            <ui:toast.indicator type="{f:constant(name: 'Jramke\FluidPrimitives\Enum\ToastType::Loading')}" class="mt-0.5 shrink-0 text-muted-foreground">
                <svg class="animate-spin size-4" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
                    <path d="M21 12a9 9 0 1 1-6.219-8.56" />
                </svg>
            </ui:toast.indicator>
            <div class="grid flex-1 gap-1">
                <ui:toast.title />
                <ui:toast.description />
            </div>
            <ui:toast.actionTrigger />
            <ui:toast.closeTrigger />
        </ui:toast.root>
    </ui:toaster.toastTemplate>
</ui:toaster>

<div {ui:ref(name: 'actions' )}>
    <ui:button>Send message</ui:button>
</div>

<vite:asset entry="EXT:docs/Resources/Private/Components/ui/ToastExamples/Simple.entry.ts" />
```

**Toaster.entry.ts**

```ts
import { mount } from 'fluid-primitives';
import { Toaster } from 'fluid-primitives/toaster';

// The page layout renders <ui:toaster rootId="toaster" /> on every page.
export const toast = mount('ui:toaster', 'toaster', ({ props }) =>
    new Toaster(props).init()
)!.store;

```

**Simple.entry.ts**

```ts
import { mountAll } from 'fluid-primitives';
import { toast } from '../Toaster/Toaster.entry';

mountAll('ui:toastExamples.simple', ({ createHydrator }) => {
    createHydrator()
        .query('actions')
        ?.addEventListener('click', () => {
            toast.create({
                type: 'success',
                title: 'Message sent',
                description: 'We usually reply within one business day.',
            });
        });
});

```

## Features

- Settings as Fluid props, toasts from any script through one `toast` export
- `success`, `info`, `warning`, `error` and `loading` toasts, styled through `data-type`
- Markup per type, such as an icon, and a template per type, which change in place with the type
- Closes after a duration per type and waits while you hover or focus it, or while the tab is in the background
- Lets the toasts overlap or lists them, and queues them beyond `max`
- Updates a toast in place instead of adding the same one twice
- Action trigger, close trigger and loading toasts that follow a promise
- `Alt+T` moves the focus to the toasts, `Escape` closes the focused one
- Screen readers announce new toasts through a live region

## Anatomy

```html
<primitives:toaster>
    <primitives:toaster.toastTemplate>
        <primitives:toast.root>
            <primitives:toast.indicator />
            <primitives:toast.title />
            <primitives:toast.description />
            <primitives:toast.actionTrigger />
            <primitives:toast.closeTrigger />
        </primitives:toast.root>
    </primitives:toaster.toastTemplate>
</primitives:toaster>
```

The toaster is the region the toasts appear in and holds their settings. Its `toastTemplate` is the template of one toast: the client clones it for every toast and fills in the title, the description and the label of the action trigger. A part keeps what the template puts into it while the toast has no text for it. An `indicator` shows markup for one type, and a `toastTemplate` with a `type` is the template of one type.

A toast template holds plain markup. A component that hydrates, such as `ui:button`, or a `ui:portal` inside it is cloned without its script, so it doesn't work in a toast.

## Installation

```bash
typo3 ui:add toaster toast
```

Or copy the files manually from GitHub into your project: https://github.com/jramke/fluid-primitives/tree/main/Resources/Private/Registry/Toaster https://github.com/jramke/fluid-primitives/tree/main/Resources/Private/Registry/Toast

Read more about installing [Components and Primitives](/docs/core-concepts/primitives.md).

Render the toaster once in your page layout, with the `rootId` its entry file mounts:

```html
<ui:toaster rootId="toaster" />
```

Without content, it renders the toast template you see in the demo above, with an icon for four types. Put a `ui:toaster.toastTemplate` inside to use one of your own. That replaces the default template, so one of yours has no `type`, for the toasts of every type without a template of its own. A toast template has exactly one root element, a `ui:toast.root`. The entry file exports the store of the toaster as `toast`. Import it wherever you create a toast:

```ts
import { toast } from '../Toaster/Toaster.entry';

toast.create({ type: 'success', title: 'Message sent' });
```

## Examples

### Create a toast

`toast.create()` returns the id of the toast, for `toast.update()` and `toast.dismiss()`. A toast takes a `title`, a `description`, a `type`, a `duration`, an `action`, `closable` and a `priority` from 1 (highest) to 8 for the queue. The store also has `remove()` (without the exit animation), `pause()` and `resume()`, `promise()`, and `success()`, `info()`, `warning()`, `error()` and `loading()` as shortcuts for the `type`.

### Pick a type

Each button below shows a toast of another `type`. The toast renders it as `data-type` and shows the `toast.indicator` of its type, the others are `hidden`. The toaster of the first demo has an indicator with an icon for four types, an `info` toast shows none. When the type changes, as in a promise, the indicators change with it. Only these five types can have an indicator and a template of their own. An icon in an indicator is decoration, so give it `aria-hidden="true"`. For screen readers, name the type in the title, or put visually hidden text such as "Error:" into the indicator. A `success` toast stays for 2 seconds, the others for 5 seconds. Set `duration` on the toast or on the toaster to change that.

**ToastExamples.html**

```html
<div class="flex flex-wrap gap-2" {ui:ref(name: 'actions' )}>
    <ui:button variant="secondary" data-type="success">Success</ui:button>
    <ui:button variant="secondary" data-type="info">Info</ui:button>
    <ui:button variant="secondary" data-type="warning">Warning</ui:button>
    <ui:button variant="secondary" data-type="error">Error</ui:button>
</div>

<vite:asset entry="EXT:docs/Resources/Private/Components/ui/ToastExamples/Types.entry.ts" />

```

**Types.entry.ts**

```ts
import { mountAll } from 'fluid-primitives';
import { toast } from '../Toaster/Toaster.entry';

const toasts = {
    success: { title: 'Profile saved' },
    info: { title: 'New opening hours', description: 'We open at 9:00 on Saturdays.' },
    warning: {
        title: 'Your session ends in 5 minutes',
        description: 'Save your draft to keep it.',
    },
    error: { title: 'Payment failed', description: 'Your card was declined. Try another one.' },
};

mountAll('ui:toastExamples.types', ({ createHydrator }) => {
    createHydrator()
        .query('actions')
        ?.addEventListener('click', event => {
            const type = (event.target as Element).closest<HTMLElement>('[data-type]')?.dataset
                .type as keyof typeof toasts | undefined;
            if (type) toast.create({ type, ...toasts[type] });
        });
});

```

### Add an action

Pass an `action` with a `label` and an `onClick`. Click "Undo" in the toast: the action runs, and the toast closes.

**ToastExamples.html**

```html
<div {ui:ref(name: 'actions' )}>
    <ui:button variant="secondary">Remove from cart</ui:button>
</div>

<vite:asset entry="EXT:docs/Resources/Private/Components/ui/ToastExamples/Action.entry.ts" />

```

**Action.entry.ts**

```ts
import { mountAll } from 'fluid-primitives';
import { toast } from '../Toaster/Toaster.entry';

mountAll('ui:toastExamples.action', ({ createHydrator }) => {
    createHydrator()
        .query('actions')
        ?.addEventListener('click', () => {
            toast.create({
                title: 'Linen shirt removed from your cart',
                action: {
                    label: 'Undo',
                    onClick: () => toast.create({ title: 'Linen shirt is back in your cart' }),
                },
            });
        });
});

```

### Follow a promise

`toast.promise()` shows a `loading` toast until the promise settles, then turns it into the `success` or the `error` toast.

**ToastExamples.html**

```html
<div {ui:ref(name: 'actions' )}>
    <ui:button variant="secondary">Send newsletter</ui:button>
</div>

<vite:asset entry="EXT:docs/Resources/Private/Components/ui/ToastExamples/Promise.entry.ts" />

```

**Promise.entry.ts**

```ts
import { mountAll } from 'fluid-primitives';
import { toast } from '../Toaster/Toaster.entry';

mountAll('ui:toastExamples.promise', ({ createHydrator }) => {
    createHydrator()
        .query('actions')
        ?.addEventListener('click', () => {
            const sending = new Promise(resolve => setTimeout(resolve, 2000));

            toast.promise(sending, {
                loading: { title: 'Sending the newsletter' },
                success: {
                    title: 'Newsletter sent',
                    description: 'It went out to 1,204 subscribers.',
                },
                error: { title: 'The newsletter could not be sent' },
            });
        });
});

```

### Update a toast instead of adding it twice

Give the toast an `id`, and update it while `toast.isVisible()` says it is still there. Click "Save draft" a few times: one toast counts the saves and shakes on every click. Screen readers announce the new description.

**ToastExamples.html**

```html
<div {ui:ref(name: 'actions' )}>
    <ui:button variant="secondary">Save draft</ui:button>
</div>

<vite:asset entry="EXT:docs/Resources/Private/Components/ui/ToastExamples/Deduplicate.entry.ts" />

```

**Deduplicate.entry.ts**

```ts
import { mountAll } from 'fluid-primitives';
import { toast } from '../Toaster/Toaster.entry';

const shake = [
    { transform: 'translateX(0)' },
    { transform: 'translateX(-4px)' },
    { transform: 'translateX(4px)' },
    { transform: 'translateX(-2px)' },
    { transform: 'translateX(0)' },
];

mountAll('ui:toastExamples.deduplicate', ({ createHydrator }) => {
    let saves = 0;
    createHydrator()
        .query('actions')
        ?.addEventListener('click', () => {
            if (!toast.isVisible('draft')) saves = 0;
            saves++;
            const draft = { title: 'Draft saved', description: `Saved ${saves} times.` };

            if (saves === 1) {
                toast.create({ id: 'draft', ...draft });
                return;
            }

            // the new text is what screen readers announce, the shake is for everyone else
            toast.update('draft', draft);
            if (!matchMedia('(prefers-reduced-motion: reduce)').matches) {
                document
                    .querySelector('[data-toast-root="draft"]')
                    ?.animate(shake, { duration: 300 });
            }
        });
});

```

### List the toasts

The toasts overlap by default and spread out while you hover or focus them. Set `overlap` to `false` to list them one below the other. This demo has a toaster of its own, with another `placement` and its own `mount()`. Give every toaster of a page its own `placement`: two toasters with the same one share the id of their region, and `Alt+T` focuses only one of them.

**ToastExamples.html**

```html
<ui:toaster rootId="stack-toaster" overlap="{false}" placement="{f:constant(name: 'Jramke\FluidPrimitives\Enum\ToastPlacement::TopEnd')}">
    <ui:toaster.toastTemplate>
        <ui:toast.root>
            <div class="grid flex-1 gap-1">
                <ui:toast.title />
                <ui:toast.description />
            </div>
            <ui:toast.actionTrigger />
            <ui:toast.closeTrigger />
        </ui:toast.root>
    </ui:toaster.toastTemplate>
</ui:toaster>

<div {ui:ref(name: 'actions' )}>
    <ui:button variant="secondary">Add to wishlist</ui:button>
</div>

<vite:asset entry="EXT:docs/Resources/Private/Components/ui/ToastExamples/Stack.entry.ts" />

```

**Stack.entry.ts**

```ts
import { mount, mountAll } from 'fluid-primitives';
import { Toaster } from 'fluid-primitives/toaster';

const wishlistToast = mount('ui:toaster', 'stack-toaster', ({ props }) =>
    new Toaster(props).init()
)!.store;
const products = ['Linen shirt', 'Canvas tote', 'Wool scarf', 'Leather belt'];

mountAll('ui:toastExamples.stack', ({ createHydrator }) => {
    let added = 0;
    createHydrator()
        .query('actions')
        ?.addEventListener('click', () => {
            wishlistToast.create({
                title: `${products[added++ % products.length]} added to your wishlist`,
            });
        });
});

```

### Give a type a template of its own

A `toastTemplate` with a `type` is the template of the toasts of that type, the one without a `type` the template of all others. When a toast changes to a type with another template, as when a promise fails, it stays in its place and takes the content of the new template:

```html
<ui:toaster rootId="toaster">
    <ui:toaster.toastTemplate>...</ui:toaster.toastTemplate>
    <ui:toaster.toastTemplate
        type="{f:constant(name: 'Jramke\FluidPrimitives\Enum\ToastType::Error')}"
    >
        <ui:toast.root class="border-destructive">
            <div class="grid flex-1 gap-1">
                <ui:toast.title>Something went wrong</ui:toast.title>
                <ui:toast.description />
                <a
                    href="{f:uri.page(pageUid: settings.supportPage)}"
                    class="text-sm underline underline-offset-4"
                    >Contact support</a
                >
            </div>
            <ui:toast.closeTrigger />
        </ui:toast.root>
    </ui:toaster.toastTemplate>
</ui:toaster>
```

The title of this template says "Something went wrong" while the toast has no title of its own.

### Fill an element of your own

Pass the data of a toast as `meta`, and mark the element in the template with `ui:ref`. A subclass of `Toast` fills it, and a subclass of `Toaster` creates that toast. This demo has a toaster of its own for the cart, and each button passes the image of its product:

**ToastExamples.html**

```html
<ui:toaster rootId="cart-toaster" placement="{f:constant(name: 'Jramke\FluidPrimitives\Enum\ToastPlacement::Top')}">
    <ui:toaster.toastTemplate>
        <ui:toast.root class="items-center">
            <img class="size-12 shrink-0 rounded-md" width="48" height="48" alt="" {ui:ref(name: 'image', context: 'toast' )} />
            <div class="grid flex-1 gap-1">
                <ui:toast.title />
                <ui:toast.description />
            </div>
            <ui:toast.closeTrigger />
        </ui:toast.root>
    </ui:toaster.toastTemplate>
</ui:toaster>

<div class="flex flex-wrap gap-2" {ui:ref(name: 'actions' )}>
    <ui:button variant="secondary" data-name="Linen shirt" data-image="{f:uri.resource(path: 'EXT:docs/Resources/Public/Images/Products/linen-shirt.svg')}">Add linen shirt</ui:button>
    <ui:button variant="secondary" data-name="Canvas tote" data-image="{f:uri.resource(path: 'EXT:docs/Resources/Public/Images/Products/canvas-tote.svg')}">Add canvas tote</ui:button>
    <ui:button variant="secondary" data-name="Sunglasses" data-image="{f:uri.resource(path: 'EXT:docs/Resources/Public/Images/Products/sunglasses.svg')}">Add sunglasses</ui:button>
</div>

<vite:asset entry="EXT:docs/Resources/Private/Components/ui/ToastExamples/Cart.entry.ts" />

```

**Cart.entry.ts**

```ts
import type { Props } from '@zag-js/toast';
import { mount, mountAll } from 'fluid-primitives';
import { Toast } from 'fluid-primitives/toast';
import { Toaster } from 'fluid-primitives/toaster';

class CartToast extends Toast {
    render() {
        super.render();
        const imageEl = this.hydrator.query<HTMLImageElement>('image');
        const image = this.machine.service.prop('meta')?.image;
        if (imageEl && image && imageEl.getAttribute('src') !== image) imageEl.src = image;
    }
}

class CartToaster extends Toaster {
    protected createToast(props: Props) {
        return new CartToast(props).init();
    }
}

const cartToast = mount('ui:toaster', 'cart-toaster', ({ props }) =>
    new CartToaster(props).init()
)!.store;

mountAll('ui:toastExamples.cart', ({ createHydrator }) => {
    createHydrator()
        .query('actions')
        ?.addEventListener('click', event => {
            const product = (event.target as Element).closest<HTMLElement>('[data-image]')?.dataset;
            if (!product) return;
            cartToast.create({
                title: `${product.name} added to your cart`,
                description: 'Ships in 1-2 business days.',
                meta: { image: product.image },
            });
        });
});

```

Give such an element a fixed size, an image a `width` and a `height`: the toaster measures a toast when its content changes, not when an image loads.

A type change can swap every part of a toast except its root for the ones of another template. Query the parts in `render()`, as the cart toast does, and don't keep them or add listeners to them in `init()`. To animate the swap, override `replaceContent()` and call `super.replaceContent()` inside.

### Style the toasts with your own CSS

The client places every toast through CSS variables on its root, so your CSS has to use them: `--x` and `--y` for `translate`, `--scale` for `scale`, and `--z-index`, `--height` and `--opacity`. Transition them, and the toasts slide in, pile up and spread out. A closing toast has `data-state="closed"`, and a toast behind the front one has `data-sibling`:

```html
<primitives:toast.root class="toast">...</primitives:toast.root>
```

```css
.toast {
    translate: var(--x) var(--y);
    scale: var(--scale);
    z-index: var(--z-index);
    height: var(--height);
    opacity: var(--opacity);
    transition-property: translate, scale, opacity, height;
    transition-duration: 400ms;
    transition-timing-function: cubic-bezier(0.21, 1.02, 0.73, 1);
}

.toast[data-state='closed'] {
    transition-duration: 200ms;
}

/* a toast behind the front one takes the height of the front one, so hide what it holds */
.toast > * {
    transition: opacity 400ms;
}

.toast[data-overlap][data-sibling] > * {
    opacity: 0;
}
```

## Show TYPO3 flash messages

Write a component of your own that renders the flash messages as JSON and marks the `<script>` with [`ui:ref`](/docs/viewhelpers/ref.md). `f:page.footerData` puts it at the end of the page, apart from the markup of your plugin:

**`Components/FlashMessages/FlashMessages.html`**:

```html
<ui:prop name="queueIdentifier" type="string" optional="{true}" />

<f:flashMessages as="flashMessages" queueIdentifier="{queueIdentifier}">
    <f:page.footerData>
        <script type="application/json" {ui:ref(name: 'messages')}>{flashMessages -> f:format.json() -> f:format.raw()}</script>
    </f:page.footerData>
</f:flashMessages>

<vite:asset entry="EXT:my_extension/Resources/Private/Components/FlashMessages/FlashMessages.entry.ts" />
```

Use it where your plugin template has `f:flashMessages`. It reads the same queue, the one of the plugin by default:

```html
<ui:flashMessages />
```

`f:format.json` escapes `<` and `>`, so a message cannot end the `<script>` element. The entry file finds the `<script>` by its ref and shows the messages with the toaster. The keys of `types` are the values of `ContextualFeedbackSeverity`:

**`Components/FlashMessages/FlashMessages.entry.ts`**:

```ts
import { mountAll } from 'fluid-primitives';
import { toast } from '../ui/Toaster/Toaster.entry';

const types = { [-2]: 'info', [-1]: 'info', 0: 'success', 1: 'warning', 2: 'error' } as const;

export function showFlashMessages(
    messages: { severity: keyof typeof types; title: string; message: string }[]
) {
    messages.forEach(({ severity, title, message }) =>
        toast.create({ type: types[severity], title, description: message })
    );
}

mountAll('ui:flashMessages', ({ createHydrator }) => {
    const script = createHydrator().query('messages');
    if (!script) return;

    showFlashMessages(JSON.parse(script.textContent ?? '[]'));
    script.remove();
});
```

### Flash messages of an AJAX request

An action you call with [`extbase.post()`](/docs/client-utilities/extbase.md) answers with JSON, so nothing renders its flash messages. Send them along in the response and flush the queue, otherwise they show up on the next page load:

```php
public function subscribeAction(Subscriber $subscriber): ResponseInterface
{
    $this->subscriberRepository->add($subscriber);
    $this->addFlashMessage('Check your inbox to confirm the subscription.', 'Almost done');

    return $this->jsonResponse(json_encode([
        'flashMessages' => $this->getFlashMessageQueue()->getAllMessagesAndFlush(),
    ], JSON_THROW_ON_ERROR));
}
```

```ts
import { extbase } from 'fluid-primitives';
import { showFlashMessages } from '../FlashMessages/FlashMessages.entry';

const response = await extbase.post(url, values);
showFlashMessages((await response.json()).flashMessages);
```

## API Reference

### toaster

The region the toasts appear in, with their settings. Renders a `<div>` element.

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `placement` | `Enum\ToastPlacement` | No | `BottomEnd` | Where on the screen the toasts appear. |
| `overlap` | `boolean` | No | `true` | Whether the toasts pile up on top of each other and spread out on hover or focus. Set it to `false` to list them one below the other. |
| `max` | `integer` | No | `10` | How many toasts are visible at once. More toasts wait in a queue, the most important first. When they overlap, each toast behind the front one is 5% smaller than the one before, so far more than 10 turn the pile into an hourglass. |
| `gap` | `integer` | No | `16` | The space between the toasts, in pixels. |
| `offsets` | `string\|array` | No | `'1rem'` | The distance from the edges of the viewport, a CSS length or an array with one for each of `top`, `right`, `bottom` and `left`. |
| `duration` | `integer` | No | `-` | How long a toast stays, in milliseconds. Without it, the type of the toast decides: 2 seconds for `success`, 5 seconds for the others, and a `loading` toast stays until it is updated. |
| `removeDelay` | `integer` | No | `200` | How long a dismissed toast stays in the DOM, in milliseconds, so its exit animation can play. |
| `pauseOnPageIdle` | `boolean` | No | `true` | Whether the toasts wait while the browser tab is in the background. |
| `hotkey` | `string[]` | No | `-` | The keys that move the focus to the toasts, as `KeyboardEvent` modifier properties and codes, `altKey` and `KeyT` (Alt+T) by default. |
| `translations` | `array` | No | `-` | Localized labels: `groupLabel` names the region of the toasts for screen readers, `closeTriggerLabel` the close trigger of each toast. Use `f:translate` for per-template localization overrides when needed. |
| `attributes` | `array` | No | `[]` | Additional attributes that should be rendered on the component where ui:attributes is used. |
| `rootId` | `string` | No | `-` | The root ID of the component, used for hydration and identification. |
| `ids` | `array` | No | `[]` | The IDs of of the component parts for composition. |
| `autoMount` | `boolean` | No | `true` | Whether the client initializes the component on its own. Set it to false to mount it yourself with `mount()` |
| `provider` | `string` | No | `-` | The `id` of the `.provider` this root takes its `rootId` and props from. |
| `class` | `string` | No | `-` | The CSS class(es) to be applied to the component. |

### toaster.toastTemplate

The template of one toast, with a `toast.root` as its root element, or of the toasts of one `type`. Renders a `<template>` element.

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `type` | `Enum\ToastType` | No | `-` | The type of toast this template is for. A toast takes the template of its type, or the one without a type. |

### toast.root

One toast, the root element of the toast template. Renders a `<div>` element.

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `attributes` | `array` | No | `[]` | Additional attributes that should be rendered on the component where ui:attributes is used. |
| `asChild` | `boolean` | No | `-` | If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. |
| `rootId` | `string` | No | `-` | The root ID of the component, used for hydration and identification. |
| `ids` | `array` | No | `[]` | The IDs of of the component parts for composition. |
| `autoMount` | `boolean` | No | `true` | Whether the client initializes the component on its own. Set it to false to mount it yourself with `mount()` |
| `provider` | `string` | No | `-` | The `id` of the `.provider` this root takes its `rootId` and props from. |
| `class` | `string` | No | `-` | The CSS class(es) to be applied to the component. |

#### Rendered data attributes

| Attribute | Description |
| --- | --- |
| `data-toast-root` | <uid> |
| `data-state` | "open" \| "closed" |
| `data-type` | The type of the item |
| `data-placement` | The placement of the toast |
| `data-align` |  |
| `data-side` | The side of the trigger that the toast is positioned on |
| `data-mounted` | Present when mounted |
| `data-paused` | Present when paused |
| `data-first` |  |
| `data-sibling` |  |
| `data-stack` |  |
| `data-overlap` | Present when overlapping |

### toast.indicator

Markup for one `type` of toast, such as its icon, `hidden` while the toast has another type. Renders a `<div>` element.

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `type` | `Enum\ToastType` | Yes | `-` | The type of toast the indicator is shown for. |
| `attributes` | `array` | No | `[]` | Additional attributes that should be rendered on the component where ui:attributes is used. |
| `asChild` | `boolean` | No | `-` | If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. |
| `class` | `string` | No | `-` | The CSS class(es) to be applied to the component. |

### toast.title

The title of the toast, or what the template puts into it while the toast has none. Hidden when both are empty. Renders a `<div>` element.

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `attributes` | `array` | No | `[]` | Additional attributes that should be rendered on the component where ui:attributes is used. |
| `asChild` | `boolean` | No | `-` | If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. |
| `class` | `string` | No | `-` | The CSS class(es) to be applied to the component. |

### toast.description

The description of the toast, or what the template puts into it while the toast has none. Hidden when both are empty. Renders a `<div>` element.

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `attributes` | `array` | No | `[]` | Additional attributes that should be rendered on the component where ui:attributes is used. |
| `asChild` | `boolean` | No | `-` | If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. |
| `class` | `string` | No | `-` | The CSS class(es) to be applied to the component. |

### toast.actionTrigger

Runs the action of the toast and closes it, hidden when the toast has no action. Renders a `<button>` element.

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `attributes` | `array` | No | `[]` | Additional attributes that should be rendered on the component where ui:attributes is used. |
| `asChild` | `boolean` | No | `-` | If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. |
| `class` | `string` | No | `-` | The CSS class(es) to be applied to the component. |

### toast.closeTrigger

Closes the toast, hidden when it is not closable. Renders a `<button>` element.

| Name | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `attributes` | `array` | No | `[]` | Additional attributes that should be rendered on the component where ui:attributes is used. |
| `asChild` | `boolean` | No | `-` | If true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. |
| `class` | `string` | No | `-` | The CSS class(es) to be applied to the component. |

### Machine JavaScript API

| Name | Type | Description |
| --- | --- | --- |
| `getCount` | `() => number` | The total number of toasts |
| `getToasts` | `() => ToastProps[]` | The toasts |
| `subscribe` | `(callback: (toasts: Options<O>[]) => void) => VoidFunction` | Subscribe to the toast group |
| `getGroupState` | `() => GroupState` | Returns the state of the group |
