← Public packages
@kentcdodds/package-app-kit
Design tokens, PWA install/update, About/version, cache helpers, and optional realtime notes sync for Kody package apps.
src/client/toast.ts
61 lines · 1.9 KB · TypeScript/** Browser toaster — exposes window.pakToast from [data-toast-host]. */
export function bootToast() {
const host = document.querySelector('[data-toast-host]')
if (!host) return
const timers = {}
function dismiss(id) {
const node = host.querySelector(`[data-toast-id="${id}"]`)
if (node) node.remove()
if (timers[id]) {
clearTimeout(timers[id])
delete timers[id]
}
}
function show(input) {
if (!input?.title) return null
const id = String(input.id || `t${Date.now()}${Math.random().toString(16).slice(2)}`)
dismiss(id)
const tone = input.tone || 'default'
const node = document.createElement('div')
node.className = 'pak-toast'
node.setAttribute('data-toast-id', id)
node.setAttribute('data-tone', tone)
const body = document.createElement('div')
const title = document.createElement('strong')
title.textContent = input.title
body.appendChild(title)
if (input.description) {
const p = document.createElement('p')
p.textContent = input.description
body.appendChild(p)
}
node.appendChild(body)
const actions = document.createElement('div')
actions.className = 'pak-toast-actions'
if (input.action?.label && typeof input.action.onClick === 'function') {
const act = document.createElement('button')
act.type = 'button'
act.textContent = input.action.label
act.addEventListener('click', () => input.action.onClick())
actions.appendChild(act)
}
const close = document.createElement('button')
close.type = 'button'
close.setAttribute('data-toast-dismiss', '')
close.setAttribute('aria-label', 'Dismiss')
close.textContent = '×'
close.addEventListener('click', () => dismiss(id))
actions.appendChild(close)
node.appendChild(actions)
host.appendChild(node)
let duration = input.durationMs
if (duration == null) duration = input.action ? 0 : 3400
if (duration > 0) timers[id] = setTimeout(() => dismiss(id), duration)
return id
}
window.pakToast = { show, dismiss }
}