JavaScript Toast
@lemonadejs/toast · ✓ 11 contract checks · framework-agnostic · zero dependencies
<Toast /> — transient, stackable notifications with a queue, on the
v6 contract model.
The component is a HOST: mount it once, grab the api through props.ref and fire toasts imperatively from anywhere:
let toast;
html<${Toast} ref="${(api) => (toast = api)}" position="bottom-right" />
toast.success(‘Saved’);
toast.show(‘Reconnecting…’, { duration: 0, action: { label: ‘Retry’, onclick: retry } });
Queue model: up to max toasts are visible at once; overflow waits in
an internal FIFO and is promoted when a visible toast finishes leaving.
Each toast auto-dismisses after its duration (host default 4000ms,
per-toast override, 0 = sticky until closed; hover or focus PAUSES the
clock, leaving resumes it), then plays a 200ms leave
animation (data-leaving) before it is removed and onclose(message)
fires. Manual close (×), the action button and unmount all clear the
pending timers — destroy-clean. clear() drops everything at once,
silently (bulk reset, no onclose storm).
Severities (info | success | warning | error) share the alert block’s palette but the CSS is self-contained; no severity = the neutral dark snackbar look.
Example
import { html, ref } from 'lemonadejs';
import Toast from '@lemonadejs/toast';
const App = () => {
const toast = ref();
const archive = () =>
toast.current.show('Conversation with Ana Costa archived', {
action: { label: 'Undo', onclick: () => toast.current.info('Conversation restored') },
});
return html`<div>
<${Toast} ref="${toast}" position="bottom-right" />
<button onclick="${() => toast.current.success('Invoice #1042 sent')}">Send invoice</button>
<button onclick="${archive}">Archive conversation</button>
<button onclick="${() => toast.current.warning('Storage is 95% full')}">Check storage</button>
<button onclick="${() => toast.current.error('Payment declined: card expired', { duration: 0 })}">
Charge card
</button>
</div>`;
};Installation
npm install @lemonadejs/toast
import Toast from '@lemonadejs/toast';
import '@lemonadejs/toast/style.css';
Three deployment forms, one component:
html`<${Toast} />` // by value (no registration)
setComponents({ Toast }); // then <Toast /> by name anywhere
createWebComponent(Toast); // <lm-toast> in plain HTML/any framework
Props
Every declared prop arrives as a live state — pass a value for a snapshot or a state for a two-way live wire. Attribute strings are coerced to the declared type.
| Prop | Type | Default | Description |
|---|---|---|---|
position | string | '' | ” = bottom-left |
duration | number | 4000 | default auto-dismiss ms; 0 = sticky |
max | number | 5 | visible at once; overflow queues |
closable | boolean | true | × button on each toast |
Events
All event names are lowercase (the platform convention — LJS-305 warns otherwise).
onclose— (message) when one toast is dismissed
API
import { ref } from 'lemonadejs';
const toast = ref();
html`<${Toast} ref="${toast}" />`;
// toast.current.show(...) · toast.current.success(...) · toast.current.error(...) · toast.current.warning(...) · toast.current.info(...) · toast.current.clear(...)
show()success()error()warning()info()clear()
Styling
All classes follow the lm-toast-* convention; visual variants are data-*
attributes on the root. Override freely — there is no styling engine to fight.
Contract
The machine-readable schema ships with the package:
import contract from '@lemonadejs/toast/contract.json';
verify.json carries the conformance proof produced by verify(Toast).
Looking for the v5 plugin? See the archived v5 documentation.