A fixed-position coordinator that manages a stack of x-toast notifications. Provides viewport placement, capacity management, and an imperative API for spawning toasts programmatically.
<x-toaster></x-toaster>Place x-toast elements as children of x-toaster. The toaster handles positioning, stacking, and coordinated dismissal.
<x-toaster position="top-end">
<x-toast type="success" heading="Saved" message="Your file was saved."></x-toast>
</x-toaster>const toaster = document.querySelector('x-toaster');
toaster.toast({
type: 'success',
heading: 'File saved',
message: 'Your changes have been saved.',
timeoutMs: 4000,
showProgress: true,
});| Attribute | Type | Default | Description |
|---|---|---|---|
position |
enum | "top-end" |
Viewport placement. See values below. |
max-toasts |
number | 5 |
Maximum visible toasts. Oldest is evicted when exceeded. |
label |
string | "Notifications" |
aria-label for the region landmark. |
| Value | Placement |
|---|---|
top-start |
Top-left (logical inline-start) |
top-center |
Top, horizontally centred |
top-end |
Top-right (logical inline-end) — default |
bottom-start |
Bottom-left |
bottom-center |
Bottom, horizontally centred |
bottom-end |
Bottom-right |
| JS Property | Attribute | Type | Notes |
|---|---|---|---|
position |
position |
string | Reflects attribute. |
maxToasts |
max-toasts |
number | Reflects attribute. |
label |
label |
string | Reflects attribute. |
Creates an x-toast element with the given options, appends it to the toaster, and returns the element reference.
toaster.toast(options: {
type?: 'info' | 'success' | 'warning' | 'error';
heading?: string;
message?: string;
icon?: string;
dismissible?: boolean; // default: true (x-toast default)
timeoutMs?: number;
showProgress?: boolean;
}) → HTMLElementThe returned element is a live <x-toast> node. You can call .dismiss() on it directly to programmatically remove it.
Fired when a child toast is about to be dismissed. Provides a chance to observe or veto dismissals.
| Property | Value |
|---|---|
bubbles |
true |
composed |
true |
cancelable |
true |
Detail:
| Field | Type | Notes |
|---|---|---|
type |
string | Toast type (info, success, warning, error) |
reason |
string | Dismissal reason ("button", "keyboard", "timeout", "api", etc.) |
heading |
string | Toast heading text |
message |
string | Toast message text |
Cancellation: Call event.preventDefault() to abort the dismissal. The toast stays visible.
toaster.addEventListener('x-toaster-dismiss', e => {
if (e.detail.reason === 'timeout') {
e.preventDefault(); // keep this toast alive despite timeout
}
});| Part | Element | Notes |
|---|---|---|
| (none) | — | Toaster shadow DOM contains only a <slot>. Use ::slotted(x-toast) to style children. |
| Property | Default | Description |
|---|---|---|
--x-toaster-inset |
16px |
Distance from viewport edges |
--x-toaster-gap |
8px |
Vertical gap between toasts |
--x-toaster-max-width |
480px |
Max width of the overlay container |
--x-toaster-z-index |
9000 |
Stack order above page content |
- Top positions (
top-*): newest toast appears nearest the corner; older toasts are pushed toward the center. - Bottom positions (
bottom-*): newest toast appears nearest the corner; older toasts are pushed toward the center.
This is achieved via flex-direction: column-reverse (top) and flex-direction: column (bottom), with toasts always appended as the last DOM child.
- The
x-toasterhost hasrole="region"andaria-label(configurable vialabel). - Individual
x-toastchildren carry their ownrole="status"orrole="alert"announcements. pointer-events: noneon the host ensures non-toast areas of the overlay don't block interaction with underlying content.
x-toast is fully standalone. When placed inside x-toaster, the following protocol applies:
x-toastfiresx-toast-dismiss(bubbles, composed) when dismissed by button, keyboard, or timeout.x-toasterintercepts the event (reason ≠"toaster-remove"), callspreventDefault(), and firesx-toaster-dismiss.- If
x-toaster-dismissis not prevented,x-toastercallstoast.dismiss("toaster-remove"). x-toastreceives the second dismiss call, fires anotherx-toast-dismiss(reason:"toaster-remove"), whichx-toasterdoes not intercept →x-toastanimates exit and removes itself.
<x-toaster position="bottom-center" style="--x-toaster-gap: 12px;">
</x-toaster>
<script>
import '@vanelsas/baredom/x-toaster';
import '@vanelsas/baredom/x-toast';
const toaster = document.querySelector('x-toaster');
toaster.toast({ type: 'info', message: 'Page loaded.' });
</script>toaster.addEventListener('x-toaster-dismiss', e => {
if (e.detail.type === 'error') {
e.preventDefault(); // errors must be manually dismissed
}
});const ref = toaster.toast({ type: 'warning', message: 'Check your input.' });
// Later:
ref.dismiss('resolved');