Toast

A toast is the one component here that cannot be static: it appears in response to something happening. The page renders an empty region with toasts(), and toast() from sitelo/ui/client appends to it.

The region is a polite live region, so anything appended is announced without stealing focus.

Setting it up

Put the region anywhere in the body — it is fixed-position, so where does not matter:

import { toasts } from 'sitelo/ui'

body(
  // …the page…
  toasts(),
)

This is the one part of the runtime nothing on the page triggers for you, so it is the one part you import yourself:

import { toast } from 'sitelo/ui/client'

document.querySelector('#save').addEventListener('click', () => {
  toast('Saved.', { color: 'success' })
})

Or reach it the way the components do, and skip the bundle entirely:

button({ onclick: "import('/su/toast.js').then(m=>m.toast('Saved.'))" }, 'Save')

Try it

This page renders a toasts() region and loads the runtime, so the buttons below really do produce toasts — bottom right.

stack({ direction: 'row', gap: 'sm', wrap: true },
  button({
    variant: 'soft',
    color: 'success',
    onclick: "window.siteloUiToast && window.siteloUiToast('Saved.', 'success')",
  }, 'Success'),
  button({
    variant: 'soft',
    color: 'warning',
    onclick: "window.siteloUiToast && window.siteloUiToast('Two pages have no meta description.', 'warning')",
  }, 'Warning'),
  button({
    variant: 'soft',
    color: 'danger',
    onclick: "window.siteloUiToast && window.siteloUiToast('The build failed. Check the link report.', 'danger')",
  }, 'Danger'),
  button({
    variant: 'soft',
    color: 'neutral',
    onclick: "window.siteloUiToast && window.siteloUiToast('This one stays until you close it.', 'neutral', 0)",
  }, 'Until dismissed'),
)

Options

duration is how long the toast stays, in milliseconds; 0 keeps it up until someone closes it. Every toast gets a close button, wired to the same dismiss handler an alert uses.

toast('Saved.', { color: 'success' })
toast('Still working…', { color: 'neutral', duration: 0 })
toast('Deployed in 1.7s', { color: 'success', duration: 8000 })

What it renders

A toast is an alert() in the toasts region — same markup, same colours, same dismiss button. Nothing new to learn, and nothing extra to style.

Saved.
stack({ gap: 'sm', style: 'width: 100%; max-width: 24rem' },
  alert({ color: 'success', dismissible: true }, 'Saved.'),
  alert({ color: 'danger', dismissible: true }, 'The build failed. Check the link report.'),
)

When to use one

A toast is for confirming something the reader just did. It is the wrong place for anything they need to act on or read carefully — it disappears, it is easy to miss, and on a static site most messages belong in the page itself as an alert().

Props

toasts() takes no props of its own. toast() from sitelo/ui/client:

ArgumentTypeDefaultDescription
messagestringThe text. Set as textContent, so it is never parsed as markup.
color'primary' | 'neutral' | 'success' | 'warning' | 'danger''neutral'Which palette to use.
durationnumber4000Milliseconds before it disappears. 0 keeps it up.

It returns the element it added, or null when the page has no toasts() region.