class ToastNotification extends HTMLElement { constructor() { super(); this.attachShadow({ mode: 'open' }); this._timeout = null; } static get observedAttributes() { return ['type', 'title', 'message', 'duration', 'visible']; } connectedCallback() { this.render(); } attributeChangedCallback(name, oldValue, newValue) { if (oldValue !== newValue) { this.render(); } } disconnectedCallback() { if (this._timeout) { clearTimeout(this._timeout); } } show() { this.setAttribute('visible', 'true'); this.render(); const duration = parseInt(this.getAttribute('duration')) || 5000; if (this._timeout) { clearTimeout(this._timeout); } this._timeout = setTimeout(() => { this.hide(); }, duration); } hide() { this.setAttribute('visible', 'false'); this.render(); if (this._timeout) { clearTimeout(this._timeout); this._timeout = null; } } render() { const type = this.getAttribute('type') || 'success'; const title = this.getAttribute('title') || 'Notification'; const message = this.getAttribute('message') || ''; const visible = this.getAttribute('visible') === 'true'; const typeConfig = { success: { iconBg: 'bg-green-100', iconColor: 'text-green-600', icon: '' }, error: { iconBg: 'bg-red-100', iconColor: 'text-red-600', icon: '' }, warning: { iconBg: 'bg-yellow-100', iconColor: 'text-yellow-600', icon: '' }, info: { iconBg: 'bg-blue-100', iconColor: 'text-blue-600', icon: '' } }; const config = typeConfig[type] || typeConfig.success; this.shadowRoot.innerHTML = `
${config.icon}

${title}

${message ? `

${message}

` : ''}
`; } } customElements.define('toast-notification', ToastNotification);