north-star / files / src / core / toast.ts
toast.ts
f495a654 2026-03-16 Pavel Safronov | 1 | type ToastOptions = { |
| 2 | className?: string; | |
| 3 | durationMs?: number; | |
| 4 | role?: 'status' | 'alert'; | |
| 5 | ariaLive?: 'polite' | 'assertive'; | |
| 6 | }; | |
| 7 | ||
| 8 | export const createToast = ({ | |
| 9 | className = 'toast', | |
| 10 | durationMs = 2200, | |
| 11 | role = 'status', | |
| 12 | ariaLive = 'polite' | |
| 13 | }: ToastOptions = {}) => { | |
| 14 | let hideTimer: number | null = null; | |
| 15 | ||
| 16 | const toast = document.createElement('div'); | |
| 17 | toast.className = className; | |
| 18 | toast.setAttribute('role', role); | |
| 19 | toast.setAttribute('aria-live', ariaLive); | |
| 20 | document.body.appendChild(toast); | |
| 21 | ||
| 22 | const show = (message: string) => { | |
| 23 | toast.textContent = message; | |
| 24 | toast.classList.add('is-visible'); | |
| 25 | ||
| 26 | if (hideTimer !== null) { | |
| 27 | window.clearTimeout(hideTimer); | |
| 28 | } | |
| 29 | ||
| 30 | hideTimer = window.setTimeout(() => { | |
| 31 | toast.classList.remove('is-visible'); | |
| 32 | hideTimer = null; | |
| 33 | }, durationMs); | |
| 34 | }; | |
| 35 | ||
| 36 | const destroy = () => { | |
| 37 | if (hideTimer !== null) { | |
| 38 | window.clearTimeout(hideTimer); | |
| 39 | hideTimer = null; | |
| 40 | } | |
| 41 | toast.remove(); | |
| 42 | }; | |
| 43 | ||
| 44 | return { | |
| 45 | show, | |
| 46 | destroy | |
| 47 | }; | |
| 48 | }; |