feedback
Toast
Global toast notifications via Alpine.store and the ui:toast window event, rendered through a fixed body-level viewport.
Copied!
Examples
Dispatch toasts
Buttons that fire the ui:toast window event.
Copied!
<div class="flex flex-wrap gap-3">
<x-ui.button
x-on:click="window.dispatchEvent(new CustomEvent('ui:toast', { detail: { type: 'success', title: 'Payout approved', message: 'Rp 18.750.000 released to CV Nusantara.', duration: 4000 } }))"
>
Show success toast
</x-ui.button>
<x-ui.button
variant="outline"
x-on:click="window.dispatchEvent(new CustomEvent('ui:toast', { detail: { type: 'info', title: 'Export queued', message: 'Orders CSV for Oct 2026 will be ready shortly.' } }))"
>
Show info toast
</x-ui.button>
</div>
<div class="flex flex-wrap gap-3">
<button
type="button"
class="inline-flex h-9 items-center rounded-control bg-brand px-3.5 text-sm font-medium text-on-brand shadow-[inset_0_1px_0_0_rgba(255,255,255,0.16),0_1px_2px_0_rgba(0,0,0,0.06)] transition duration-150 hover:opacity-90 motion-safe:active:translate-y-[0.5px]"
x-on:click="window.dispatchEvent(new CustomEvent('ui:toast', { detail: { type: 'success', title: 'Payout approved', message: 'Rp 18.750.000 released to CV Nusantara.', duration: 4000 } }))"
>
Show success toast
</button>
<button
type="button"
class="inline-flex h-9 items-center rounded-control border border-border bg-surface-raised px-3.5 text-sm font-medium text-fg shadow-2xs"
x-on:click="window.dispatchEvent(new CustomEvent('ui:toast', { detail: { type: 'info', title: 'Export queued', message: 'Orders CSV for Oct 2026 will be ready shortly.' } }))"
>
Show info toast
</button>
</div>
Types
info, success, warning, and danger payloads.
Copied!
<div class="flex flex-wrap gap-3">
<x-ui.button variant="outline" size="sm" x-on:click="window.dispatchEvent(new CustomEvent('ui:toast', { detail: { type: 'info', title: 'Sync queued', message: 'Stock levels for Gudang A will refresh in ~30s.' } }))">Info</x-ui.button>
<x-ui.button variant="outline" size="sm" x-on:click="window.dispatchEvent(new CustomEvent('ui:toast', { detail: { type: 'success', title: 'Invoice sent', message: 'INV-2026-089 emailed to finance@tokomaju.id.' } }))">Success</x-ui.button>
<x-ui.button variant="outline" size="sm" x-on:click="window.dispatchEvent(new CustomEvent('ui:toast', { detail: { type: 'warning', title: 'Low stock', message: 'SKU-2048 has 8 units left in Gudang B.' } }))">Warning</x-ui.button>
<x-ui.button variant="outline" size="sm" x-on:click="window.dispatchEvent(new CustomEvent('ui:toast', { detail: { type: 'danger', title: 'Payment failed', message: 'Midtrans declined the Rp 2.450.000 charge.' } }))">Danger</x-ui.button>
</div>
<div class="flex flex-wrap gap-3">
<button type="button" class="inline-flex h-9 items-center rounded-control border border-border bg-surface-raised px-3.5 text-sm shadow-2xs" x-on:click="window.dispatchEvent(new CustomEvent('ui:toast', { detail: { type: 'info', title: 'Sync queued', message: 'Stock levels for Gudang A will refresh in ~30s.' } }))">Info</button>
<button type="button" class="inline-flex h-9 items-center rounded-control border border-border bg-surface-raised px-3.5 text-sm shadow-2xs" x-on:click="window.dispatchEvent(new CustomEvent('ui:toast', { detail: { type: 'success', title: 'Invoice sent', message: 'INV-2026-089 emailed to finance@tokomaju.id.' } }))">Success</button>
<button type="button" class="inline-flex h-9 items-center rounded-control border border-border bg-surface-raised px-3.5 text-sm shadow-2xs" x-on:click="window.dispatchEvent(new CustomEvent('ui:toast', { detail: { type: 'warning', title: 'Low stock', message: 'SKU-2048 has 8 units left in Gudang B.' } }))">Warning</button>
<button type="button" class="inline-flex h-9 items-center rounded-control border border-border bg-surface-raised px-3.5 text-sm shadow-2xs" x-on:click="window.dispatchEvent(new CustomEvent('ui:toast', { detail: { type: 'danger', title: 'Payment failed', message: 'Midtrans declined the Rp 2.450.000 charge.' } }))">Danger</button>
</div>
Props API
| Prop | Type | Default | Description |
|---|---|---|---|
| toast-viewport.position | bottom-right|top-right|top-center|bottom-center | bottom-right | Fixed placement for the toast stack. |
| event.detail.type | info|success|warning|danger | info | Semantic tone. danger uses role="alert"; others use role="status". |
| event.detail.duration | number | 5000 | Auto-dismiss milliseconds. Timer pauses while hovered or focused. |
Accessibility notes
Architected with WCAG 2.2 AA patterns in mind. These notes document the exact keyboard and ARIA behavior for this component.
- Viewport sits at the end of body and uses aria-live="polite" so new toasts are announced without stealing focus.
- danger toasts set role="alert". Other types set role="status".
- Auto-dismiss timers pause on mouseenter and focusin, then resume on mouseleave and focusout.
- Visible stack is capped at 5 toasts. Dismiss buttons are labeled for assistive tech.
- Dispatch with window.dispatchEvent(new CustomEvent("ui:toast", { detail: { type, title, message, duration } })).
Built by Praesepe
Architecture & custom software partner
Praesepe uses these exact UI primitives to ship SME dashboards, inventory systems, invoicing desks, and internal tools faster, without rebuilding a design system for every client.
- Same Blade + Tailwind 4 + Alpine 3 stack you see in this docs site
- Opinionated for Indonesian SME ops: invoices, stock, roles, approvals
- Architected with WCAG 2.2 AA patterns in mind for keyboard and ARIA