Mercurial
diff design_system/src/components/alert.js @ 251:117c4d53c9a4
[ui] Add HTML-first Web Component system
Co-authored-by: Copilot <[email protected]>
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Tue, 04 Aug 2026 09:14:57 -0700 |
| parents | |
| children | 2b6e732087ff |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/design_system/src/components/alert.js Tue Aug 04 09:14:57 2026 -0700 @@ -0,0 +1,73 @@ +export class ZenAlert extends HTMLElement { + static get observedAttributes() { + return ["dismissible", "tone"]; + } + + connectedCallback() { + if (!this._observer) { + this._observer = new MutationObserver(() => this.sync()); + } + this._observer.observe(this, { childList: true }); + this.sync(); + } + + disconnectedCallback() { + this._observer?.disconnect(); + this.unbindDismissControl(); + } + + attributeChangedCallback() { + this.sync(); + } + + unbindDismissControl() { + if (this._dismissControl && this._dismissHandler) { + this._dismissControl.removeEventListener( + "click", + this._dismissHandler, + ); + } + this._dismissControl = null; + this._dismissHandler = null; + } + + sync() { + this.setAttribute( + "role", + this.getAttribute("tone") === "danger" ? "alert" : "status", + ); + + let dismiss = this.querySelector(":scope > [data-zen-dismiss]"); + if (!this.hasAttribute("dismissible")) { + this.unbindDismissControl(); + if (dismiss?.dataset.zenGenerated === "true") dismiss.remove(); + return; + } + + if (!dismiss) { + dismiss = document.createElement("button"); + dismiss.type = "button"; + dismiss.dataset.zenDismiss = ""; + dismiss.dataset.zenGenerated = "true"; + dismiss.setAttribute("aria-label", "Dismiss message"); + dismiss.textContent = "×"; + this.append(dismiss); + } + if (dismiss === this._dismissControl) return; + + this.unbindDismissControl(); + this._dismissControl = dismiss; + this._dismissHandler = () => { + this.dispatchEvent(new CustomEvent("zen-dismiss", { + bubbles: true, + composed: true, + })); + this.remove(); + }; + dismiss.addEventListener("click", this._dismissHandler); + } +} + +if (!customElements.get("zen-alert")) { + customElements.define("zen-alert", ZenAlert); +}