/** * PyRunner Toast Notification System */ const PyRunnerToast = { container: null, defaults: { duration: 5000, maxToasts: 5 }, init() { if (!this.container) { this.container = document.createElement('div'); this.container.id = 'toast-container'; this.container.className = 'fixed flex flex-col gap-3 pointer-events-none'; this.container.style.cssText = 'top: 5rem; right: 1rem; z-index: 9999;'; document.body.appendChild(this.container); } }, show(message, type = 'info', duration = this.defaults.duration) { this.init(); const toast = document.createElement('div'); toast.className = this.getToastClasses(type); toast.innerHTML = this.getToastHTML(message, type); toast.style.animation = 'toastSlideIn 0.3s ease-out'; const closeBtn = toast.querySelector('[data-toast-close]'); if (closeBtn) { closeBtn.addEventListener('click', () => this.dismiss(toast)); } while (this.container.children.length >= this.defaults.maxToasts) { this.dismiss(this.container.firstChild); } this.container.appendChild(toast); if (duration > 0) { setTimeout(() => this.dismiss(toast), duration); } return toast; }, dismiss(toast) { if (!toast || !toast.parentNode) return; toast.style.animation = 'toastSlideOut 0.2s ease-in forwards'; setTimeout(() => toast.remove(), 200); }, getToastClasses(type) { const base = 'pointer-events-auto max-w-sm w-full p-4 rounded-lg border shadow-lg flex items-start gap-3'; const types = { success: 'bg-code-surface border-code-green/30 text-code-green', error: 'bg-code-surface border-code-red/30 text-code-red', warning: 'bg-code-surface border-code-yellow/30 text-code-yellow', info: 'bg-code-surface border-code-accent/30 text-code-accent' }; return `${base} ${types[type] || types.info}`; }, getToastHTML(message, type) { const icons = { success: '', error: '', warning: '', info: '' }; return ` ${icons[type] || icons.info}

${message}

`; }, success(message, duration) { return this.show(message, 'success', duration); }, error(message, duration) { return this.show(message, 'error', duration); }, warning(message, duration) { return this.show(message, 'warning', duration); }, info(message, duration) { return this.show(message, 'info', duration); } }; window.Toast = PyRunnerToast;