Toast
A toast reports something that already happened. It is the opposite of a Modal: it asks nothing, blocks nothing, and disappears without being answered. For a message that belongs to the page rather than to a moment, use Alert.
import { ToastProvider, ToastQueue } from "ropav";The queue
Toasts are added to a ToastQueue, and a ToastProvider renders whatever is in it. The queue is a plain object you make yourself, so it lives wherever your application state lives and can be reached from anywhere — a store, a composable, a module — without a component having to be mounted first.
toast-basic.vue
<script setup lang="ts">
import { Button, ToastProvider, ToastQueue } from "ropav";
const queue = new ToastQueue({ maxVisibleToasts: 3 });
const show = (variant: "danger" | "default" | "success") => {
queue.add({
description: "Everything after the title goes here.",
title: variant === "danger" ? "Sync failed" : "Saved",
variant,
});
};
</script>
<template>
<div class="row">
<Button size="sm" variant="secondary" @click="show('default')">Default</Button>
<Button size="sm" variant="secondary" @click="show('success')">Success</Button>
<Button size="sm" variant="danger-soft" @click="show('danger')">Danger</Button>
<ToastProvider placement="bottom" :queue />
</div>
</template>
<style scoped>
.row {
display: flex;
flex-wrap: wrap;
gap: calc(var(--rp-spacing) * 3);
}
</style>max-visible-toasts caps the stack; the rest wait their turn. One queue per placement is the usual arrangement when a page shows toasts in more than one corner — each stack is then independent.
toast.update replaces a message where it stands, keeping the toast's key and its place in the stack, which is how toast.promise settles a loading toast into its outcome rather than swapping one toast for another. A timeout or onClose left out of an update is kept.
Expanding
Pointing at the stack, or moving focus into it, opens it out so every toast stands at its own height instead of being clipped to the one in front. It closes again when the pointer and focus both leave, or on Escape. A single toast has nothing to open out of, and a touch leaves the stack closed — a finger has no hover to lose, so an opened stack would have nothing to close it.
is-expanded holds the stack open regardless, which is what a visual test wants. Unlike pointing at it, that does not pause the timers.
Placement
placement on the provider decides which corner the stack grows from, and the animation follows it: toasts at the top slide down, toasts at the bottom slide up. The stack animates itself, so passing createViewTransitionUpdate().wrapUpdate as the queue's wrapUpdate is what swaps that for a chain of view transitions.
Accessibility
- The region is a live region, so a toast is announced when it arrives without focus moving.
- A toast that carries an action stays until it is dismissed. Anything the reader has to act on should not be on a timer.
- Hovering or focusing the stack pauses the timers, so a toast cannot vanish while it is being read.
- Alt + T moves focus to the region from anywhere, so the toasts are reachable without tabbing through everything between.
hotkeychanges the combination, and an empty list turns it off.
API
Toast
| Prop | Type | Default | Description |
|---|---|---|---|
placement | "bottom" | "bottom end" | "bottom start" | "top" | "top end" | "top start" | — | Overrides the region's placement for this toast. |
scaleFactor | number | — | Overrides the region's scale factor for this toast. |
toast* | QueuedToast<ToastContentValue> | — | |
variant | "danger" | "accent" | "default" | "success" | "warning" | — |
Slots: default.
ToastActionButton
| Prop | Type | Default | Description |
|---|---|---|---|
fullWidth | boolean | — | Stretches the button to the full width of its container. |
isDisabled | boolean | — | Disables the button. |
isIconOnly | boolean | — | Renders the icon-only shape, for a button whose content is a single icon. |
isPending | boolean | — | Marks an in-flight action. Renders data-pending and blocks activation, while keeping the button focusable so assistive technology can still reach it. |
size | "xs" | "sm" | "md" | "lg" | "md" | Button size. |
type | "button" | "reset" | "submit" | "button" | Native button type. |
variant | "primary" | "secondary" | "tertiary" | "outline" | "ghost" | "danger" | "danger-soft" | "primary" | Button variant. |
Slots: default.
| Event | Payload |
|---|---|
click | MouseEvent |
ToastCloseButton
ToastCloseButton takes nothing but class.
ToastContent
Slots: default.
ToastDescription
Slots: default.
ToastIndicator
| Prop | Type | Default | Description |
|---|---|---|---|
isSwapped | boolean | — | Whether this indicator is replacing one the toast was already showing, which the stylesheet animates. The first indicator a toast renders is not a replacement and must not be marked as one, or every toast would arrive with its icon animating. |
variant | "danger" | "accent" | "default" | "success" | "warning" | — | Picks the default icon. Falls back to the toast's own variant. |
Slots: default.
ToastProvider
| Prop | Type | Default | Description |
|---|---|---|---|
ariaLabel | string | — | Names the region explicitly instead of with its notification count. |
gap | number | 12 | Pixels between stacked toasts. |
hotkey | readonly string[] | ["altKey","KeyT"] | Key combination that moves focus to the region, as KeyboardEvent modifier names plus an event.code. Modifiers left out have to be up, so Alt+T does not answer Ctrl+Alt+T. Pass an empty list to turn it off. |
isExpanded | boolean | — | Holds the stack open regardless of pointer or focus. Deliberately does not pause the clocks: expansion asked for by the page is not someone reading the toasts. |
maxVisibleToasts | number | — | How many toasts are drawn at once. Visual only — the rest are faded out, not dropped. Defaults to the queue's own hint, and to 3 when it has none. |
placement | "bottom" | "bottom end" | "bottom start" | "top" | "top end" | "top start" | "bottom" | Where the stack sits. |
portalContainer | string | HTMLElement | "body" | Where the region is rendered. |
queue | ToastQueue<ToastContentValue> | — | The queue to render. Defaults to the one the imperative toast() writes to. |
scaleFactor | number | 0.05 | How much smaller each toast is drawn than the one in front of it. |
width | string | number | 460 | A number is read as pixels. |
The default slot receives:
| Slot prop | Type |
|---|---|
isLoading | boolean |
toast | QueuedToast<ToastContentValue> |
ToastTitle
Slots: default.