class ToastService { private container: HTMLElement; private stylesInjected = false; constructor() { this.container = this.ensureContainer(); this.injectStyles(); } info(message: string, timeoutMs: number = 5000) { const el = this.createToast(message, 'info'); this.container.appendChild(el); // Auto-dismiss after timeout const timer = window.setTimeout(() => this.dismiss(el), timeoutMs); // Dismiss on click immediately el.addEventListener('click', () => { window.clearTimeout(timer); this.dismiss(el); }); } error(message: string) { const el = this.createToast(message, 'error'); this.container.appendChild(el); // Only dismiss on click el.addEventListener('click', () => this.dismiss(el)); } private dismiss(el: HTMLElement) { if (!el.parentElement) return; el.parentElement.removeChild(el); } private createToast(message: string, type: 'info' | 'error'): HTMLElement { const div = document.createElement('div'); div.className = `toast ${type}`; div.textContent = message; div.setAttribute('role', 'status'); div.setAttribute('aria-live', 'polite'); return div; } private ensureContainer(): HTMLElement { let container = document.getElementById('toast-container'); if (!container) { container = document.createElement('div'); container.id = 'toast-container'; document.body.appendChild(container); } return container; } private injectStyles() { if (this.stylesInjected) return; const style = document.createElement('style'); style.textContent = ` #toast-container { position: fixed; top: 12px; right: 12px; display: flex; flex-direction: column; gap: 8px; z-index: 9999; } .toast { max-width: 320px; padding: 10px 12px; border-radius: 6px; box-shadow: 0 2px 6px rgba(0,0,0,0.2); cursor: pointer; user-select: none; font-family: sans-serif; font-size: 14px; line-height: 1.3; } .toast.info { background-color: #d4edda; /* green-ish */ color: #155724; border-left: 4px solid #28a745; } .toast.error { background-color: #f8d7da; /* red-ish */ color: #721c24; border-left: 4px solid #dc3545; } `; document.head.appendChild(style); this.stylesInjected = true; } } export const toast = new ToastService();