// Short notices at the bottom of the screen (styles from the mockup's .toast), instead of alert(). // A module-level store, so mutations can report from anywhere without a context provider. import { useSyncExternalStore } from 'react' interface Notice { id: number; text: string; error: boolean } let current: Notice | null = null let nextId = 1 let timer: ReturnType | undefined const listeners = new Set<() => void>() const emit = () => listeners.forEach(l => l()) export function toast(text: string, { error = false } = {}) { current = { id: nextId++, text, error } clearTimeout(timer) // Errors stay a little longer: they usually need reading. timer = setTimeout(() => { current = null; emit() }, error ? 7000 : 3500) emit() } export function Toaster() { const notice = useSyncExternalStore(cb => { listeners.add(cb); return () => listeners.delete(cb) }, () => current) return (
{notice?.text}
) }