toast() · kai-toast-region
Raise a transient notification from anywhere with one call — toast('Copied to clipboard'). The first toast lazily mounts a single viewport overlay on document.body; you never place an element by hand.
- Imperative API
- Shadow DOM overlay
- Undo actions
- Auto-stack (max 3)
- Pause on hover
Quick start
Section titled “Quick start”Import toast and call it. No element, no setup:
import { toast } from '@kitn.ai/ui/elements';
toast('Copied to clipboard');toast.success('Saved');The first call creates one <kai-toast-region> on document.body and binds it to a shared store, so every later toast() lands in the same stack. toast is also exported from the package root (@kitn.ai/ui) if you’d rather import it alongside the SolidJS layer.
The toast() API
Section titled “The toast() API”toast(message, options?) returns a { id, dismiss, update } handle. Two named helpers cover the common cases:
import { toast } from '@kitn.ai/ui/elements';
toast('Copied to clipboard'); // neutraltoast.success('Profile updated'); // emerald checktoast.dismiss(id); // remove one toast by idtoast.clear(); // remove all| Call | What it does |
|---|---|
toast(message, opts?) | Raise a neutral toast. Returns a ToastHandle. |
toast.success(message, opts?) | Same, with the success (check) variant. |
toast.dismiss(id) | Remove the toast with that id. |
toast.clear() | Remove every active toast. |
Options — the second argument to toast():
| Option | Type | Default | Notes |
|---|---|---|---|
id | string | auto | Pass an existing id to update that toast in place instead of stacking a new one. |
variant | 'neutral' | 'success' | 'neutral' | toast.success(…) sets this for you. |
action | { label, onAction } | — | Adds a button. Return false from onAction to keep the toast open. |
duration | number (ms) | 5000 | Auto-dismiss delay. 0 is sticky. With an action, the floor is 7000 so there’s time to act. |
dismissible | boolean | true | Whether the × close button shows. |
The returned handle controls the toast after it’s shown:
const t = toast('Uploading…', { duration: 0 }); // sticky while the work runs// later…t.update({ message: 'Uploaded', variant: 'success', duration: 2000 });// ort.dismiss();Examples
Section titled “Examples”Success
Section titled “Success”A confirmation with the emerald check. Auto-dismisses after 5 seconds.
import { toast } from '@kitn.ai/ui/elements';
toast.success('Copied to clipboard');Undo action
Section titled “Undo action”Add an action to offer a one-tap reversal. The toast stays up at least 7 seconds when it carries an action, so the user has time to react:
import { toast } from '@kitn.ai/ui/elements';
function deleteItem(item) { remove(item); toast('Item deleted', { action: { label: 'Undo', onAction: () => restore(item) }, });}Returning false from onAction keeps the toast open — useful when the action kicks off follow-up work you want to report in the same toast.
Stacking
Section titled “Stacking”Raise several toasts and they stack newest-on-top. The region shows up to max at once (3 by default); the rest queue and promote as slots free up:
import { toast } from '@kitn.ai/ui/elements';
toast('Connecting…');toast('Syncing files');toast.success('All set');Sticky (no auto-dismiss)
Section titled “Sticky (no auto-dismiss)”Set duration: 0 to keep a toast until you dismiss it — for ongoing work whose end you’ll signal yourself. Update it in place when the work finishes:
import { toast } from '@kitn.ai/ui/elements';
const t = toast('Generating report…', { duration: 0 });
await buildReport();
t.update({ message: 'Report ready', variant: 'success', duration: 2000 });The declarative element
Section titled “The declarative element”toast() is the path you’ll reach for. The imperative API is backed by <kai-toast-region> — a real kai-* web component with its own Shadow DOM and the shared kit stylesheet, so it’s viewport-positioned and fully themed, never a bare div.
You only touch the element directly to own the toast list yourself (e.g. driving it from your own state) or to change where the stack anchors. Set toasts in JavaScript (arrays can’t be HTML attributes) and listen for kai-dismiss / kai-action:
<kai-toast-region position="bottom-right" max="2"></kai-toast-region>
<script type="module"> import '@kitn.ai/ui/elements';
await customElements.whenDefined('kai-toast-region');
const region = document.querySelector('kai-toast-region'); region.toasts = [ { id: 't1', message: 'Saved', variant: 'success' }, { id: 't2', message: 'Item deleted', action: { label: 'Undo', onAction: () => restore() } }, ];
region.addEventListener('kai-dismiss', (e) => console.log('left:', e.detail.id, e.detail.reason)); region.addEventListener('kai-action', (e) => console.log('action:', e.detail.id, e.detail.label));</script>A toast item has the same shape as a toast() call:
| Field | Type | Notes |
|---|---|---|
id | string | Stable id; echoed in kai-dismiss / kai-action. |
message | string | The text. |
variant | 'neutral' | 'success' | Defaults to 'neutral'. |
action | { label, onAction } | Optional action button. |
duration | number (ms) | 0 = sticky; defaults to 5000 (floor 7000 with an action). |
dismissible | boolean | Show the × button. Defaults to true. |
Behavior
Section titled “Behavior”- Auto-dismiss after
duration(5s default), paused while hovered so it doesn’t vanish mid-read. - Stack cap at
max(3); overflow queues and promotes as toasts leave. - Announced via
aria-live="polite"/role="region"— screen readers hear new toasts without losing focus. - Reduced motion — the slide/fade is suppressed under
prefers-reduced-motion.
These apply to the <kai-toast-region> element.
| Property | Type | Default | Notes |
|---|---|---|---|
| toasts | [] | The toasts to render. Newest is shown on top. Set as a JS property (array); pass a new array reference to update. | |
| position | 'top-center' | Stack anchor: `'top-center'` (default), `'top-right'`, `'bottom-center'`, … | |
| max | number | 3 | Max simultaneously-visible toasts; the rest queue. Defaults to `3`. |
| stack | "expanded" | "collapsed" | 'expanded' | Stacking: 'expanded' (default, full column) | 'collapsed' (Sonner-style pile that expands on hover/focus). Attribute: stack. |
| appearance | "pill" | "card" | 'pill' | Default appearance for this region's toasts: `'pill'` (default, compact) | `'card'` (richer, with a description line). A per-toast `appearance` wins. Attribute: `appearance`. |
| inverse | boolean | false | Default high-contrast inverse treatment for this region's toasts. A per-toast `inverse` wins. Off by default. Attribute: `inverse`. |
| target | HTMLElement | — | Container element to anchor this region to (JS property). Set by the store for a scoped region; unset = the global viewport region. |
Events
Section titled “Events”| Event | Detail | Notes |
|---|---|---|
| kai-action | | A toast's action button was pressed. |
| kai-dismiss | | A toast left the stack. `reason` is `'timeout' | 'close' | 'action'`. |
Composed from
Section titled “Composed from”This element wraps these SolidJS components — reach for them directly when you need finer control than the props expose.