const smNotifications = document.createElement('template') smNotifications.innerHTML = `
` customElements.define('sm-notifications', class extends HTMLElement { constructor() { super() this.shadow = this.attachShadow({ mode: 'open' }).append(smNotifications.content.cloneNode(true)) this.notificationPanel = this.shadowRoot.querySelector('.notification-panel') this.animationOptions = { duration: 300, fill: "forwards", easing: "ease" } this.push = this.push.bind(this) this.removeNotification = this.removeNotification.bind(this) this.clearAll = this.clearAll.bind(this) } push(messageBody, options = {}) { const {pinned} = options let notification = document.createElement('div'), composition = `` notification.classList.add('notification') if (pinned) notification.classList.add('pinned') composition += `${messageBody}
` notification.innerHTML = composition this.notificationPanel.append(notification) notification.animate([ { transform: `translateY(1rem)`, opacity: '0' }, { transform: `none`, opacity: '1' }, ], this.animationOptions) } removeNotification(notification){ notification.animate([ { transform: `none`, opacity: '1' }, { transform: `translateY(1rem)`, opacity: '0' } ], this.animationOptions).onfinish = () => { notification.remove() } } clearAll(){ Array.from(this.notificationPanel.children).forEach(child => { this.removeNotification(child) }) } connectedCallback() { this.notificationPanel.addEventListener('click', e => { if (e.target.closest('.close'))( this.removeNotification(e.target.closest('.notification')) ) }) const observer = new MutationObserver(mutationList => { mutationList.forEach(mutation => { if (mutation.type === 'childList') { if (mutation.addedNodes.length && !mutation.addedNodes[0].classList.contains('pinned')) setTimeout(() => { this.removeNotification(mutation.addedNodes[0]) }, 5000); } }) }) observer.observe(this.notificationPanel, { childList: true, }) } })