Toast
Stacked notifications via window.mo.toast or declarative data-toast triggers. Hover pauses the timer; placement and duration are options.
INSTALL
1pnpm dlx @sayagodev/mo add toastOr import the files from the package (no copy):
1import "@sayagodev/mo/css/toast.css";2import "@sayagodev/mo/js/toast.js";
EXAMPLES
Show toast
1<button type="button" class="outline" data-toast="Your meeting has been scheduled." data-toast-title="Event created">Show Toast</button>2
Types
1<div class="hstack gap-2">2 <button type="button" class="outline" data-toast="This is a neutral toast.">Default</button>3 <button type="button" class="outline" data-toast="Everything went well." data-toast-title="Success" data-toast-variant="success">Success</button>4 <button type="button" class="outline" data-toast="Heads up, here is some information." data-toast-title="Info" data-toast-variant="info">Info</button>5 <button type="button" class="outline" data-toast="Be careful with this action." data-toast-title="Warning" data-toast-variant="warning">Warning</button>6 <button type="button" class="outline" data-toast="Something went wrong." data-toast-title="Error" data-toast-variant="danger">Error</button>7</div>8
Promise result
1<div class="hstack gap-2">2 <button type="button" class="outline"3 onclick="mo.toast.promise(new Promise(res => setTimeout(() => res({ when: 'Friday at 9:00' }), 1500)), { loading: 'Creating event…', success: (d) => `Event created for ${d.when}.`, error: 'Could not create event.' })">4 Create Event5 </button>6 <button type="button" class="ghost" data-toast='Event "Team Standup" created for Friday at 9:00.' data-toast-title="Promise resolved" data-toast-variant="success">Declarative trigger</button>7</div>8
With action
1<template id="ex-toast-action">2 <output data-variant="warning">3 <div class="toast-content">4 <h6 class="toast-title">Delete project?</h6>5 <div class="toast-message">This action cannot be undone.</div>6 <div class="hstack gap-2" style="margin-top: 0.5rem">7 <button type="button" onclick="mo.toast.dismiss()">Accept</button>8 <button type="button" class="ghost" onclick="mo.toast.dismiss()">Cancel</button>9 </div>10 </div>11 </output>12</template>13<button type="button" class="outline" onclick="mo.toast.el(document.getElementById('ex-toast-action'), { duration: 0 })">Delete project…</button>14
Triggers
1<button2 type="button"3 data-variant="secondary"4 onclick="mo.toast('Your changes were saved.', 'Saved', { variant: 'success' })"5>6 Success toast7</button>8<button9 type="button"10 class="outline"11 onclick="mo.toast('Could not reach the server. Retry?', 'Error', { variant: 'danger', placement: 'bottom-center' })"12>13 Error toast14</button>15<button type="button" class="ghost" onclick="mo.toast('Heads up — something happened.')">16 Plain toast17</button>18
USAGE
1<!-- declarative -->2<button data-toast="Saved!" data-toast-title="Success"3 data-toast-variant="success" data-toast-placement="bottom-right">4 Show Toast5</button>6 7<!-- imperative -->8mo.toast('Message', 'Title', { variant: 'success', placement: 'top-right' })9mo.toast.promise(promise, {10 loading: 'Saving…',11 success: (data) => `Saved as ${data.name}`,12 error: (err) => err.message,13})14mo.toast.el(templateOrElement, { duration: 0 })15mo.toast.clear(placement?)16mo.toast.dismiss(placement?) // alias of clear
API
NAMEKINDDESCRIPTION
[data-toast]attributeClick-to-toast trigger; message is the value
-title / -variant / -placement / -durationattributeTrigger option attributes
mo.toast.elelementRender a <template>/element as toast; duration: 0 keeps it until dismissed
mo.toast.dismisselementAlias of clear; dismisses all toasts (or one placement)
mo.toast.promiseelementLoading → success/error on one toast updated in place; success/error take msg or fn(result|error)
varianttokeninfo · success · warning · danger (sets --variant-color)
placementtokentop/bottom + left/center/right
.toast-title / .toast-messageclassMarkup API for custom el() toasts
FILES
src/css/toast.csssrc/js/toast.jsInstall:
mo add toastTHEMING · PLAYGROUND
This is the exact component from the examples above, wearing a completely different theme. Edit the tokens and --mo-* hooks in the editor — autocomplete knows them all — and the preview obeys in real time. Your CSS always wins.
Global tokens
--border--destructive--foreground--muted-foreground--popover--popover-foreground--radius--success--warningComponent hooks
--mo-toast-max-width--mo-toast-min-width--mo-toast-paddingPreview
Your CSS
Try it: type --mo- for the component hooks, or edit any value — the preview obeys in real time.