diff --git a/Software/MainBoard/rust/src_webpack/src/toast.ts b/Software/MainBoard/rust/src_webpack/src/toast.ts index bca6b71..868788e 100644 --- a/Software/MainBoard/rust/src_webpack/src/toast.ts +++ b/Software/MainBoard/rust/src_webpack/src/toast.ts @@ -1,60 +1,50 @@ class ToastService { - private container: HTMLElement; - private stylesInjected = false; + 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) { - console.error(message); - 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); + constructor() { + this.container = document.getElementById('toast-container') as HTMLElement; + this.injectStyles(); } - return container; - } - private injectStyles() { - if (this.stylesInjected) return; - const style = document.createElement('style'); - style.textContent = ` + 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) { + console.error(message); + 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 injectStyles() { + if (this.stylesInjected) return; + const style = document.createElement('style'); + style.textContent = ` #toast-container { position: fixed; top: 12px; @@ -86,9 +76,9 @@ class ToastService { border-left: 4px solid #dc3545; } `; - document.head.appendChild(style); - this.stylesInjected = true; - } + document.head.appendChild(style); + this.stylesInjected = true; + } } export const toast = new ToastService();