Cookbook / Toast

Toast

container

Toast — auto-dismiss via onMount setTimeout, manual dismiss action, aria-live polite status region.

id
aihu-toast
since
0.5.0
file
aihu-toast.aihu
propstateactiononMountonDisposeshowon:clickinterpolation

Run it

source · static

This recipe doesn't have a hydrated island in the demo gallery yet. An in-browser, WASM-compiled playground (edit this source and re-render live) is planned as a follow-up — read the real source below.

Source

aihu-toast.aihu
governedaihu-toast.aihuaihu1.4 kB
// toast — prop message + action dismiss, auto-dismiss via onMount setTimeout

@state {
  const message = prop({ default: 'Something happened.' })
  const duration = prop({ default: 3000 })

  let visible = state(false)
  let _timerId: number | null = null

  const dismiss = action(() => {
      visible = false
      if (_timerId !== null) { clearTimeout(_timerId); _timerId = null }
    })

  onMount(() => {
      visible = true
      _timerId = setTimeout(() => { visible = false }, duration) as unknown as number
    })
  onDispose(() => {
      if (_timerId !== null) { clearTimeout(_timerId); _timerId = null }
    })
}

@template {
  <div
    class={['toast', visible && 'toast-visible']}
    role="status"
    aria-live="polite"
    show={visible}
  >
    <span class="toast-msg">{message}</span>
    <button class="toast-close" on:click={dismiss} aria-label="Dismiss">×</button>
  </div>
}

@style {
  .toast { display: flex; align-items: center; gap: 0.75rem; padding: 0.6rem 1rem; background: var(--toast-bg, #333); color: var(--toast-fg, #fff); border-radius: 6px; box-shadow: 0 4px 16px rgba(0,0,0,0.2); min-width: 16rem; max-width: 90vw; }
  .toast-msg { flex: 1; font-size: 0.9rem; }
  .toast-close { background: none; border: none; color: inherit; font-size: 1.2rem; cursor: pointer; opacity: 0.7; line-height: 1; padding: 0; }
  .toast-close:hover { opacity: 1; }
  [hidden] { display: none; }
}

Requires

concerns
statea11y

Anti-patterns

  • Do not auto-dismiss without clearing the timer in onDispose — a disposed toast must not fire a dangling timeout.

Related recipes