Mercurial
view design_system/src/components/story.js @ 252:7a7581f040e8
[ui] Add scoped notification component
Co-authored-by: Copilot <[email protected]>
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Tue, 04 Aug 2026 11:57:16 -0700 |
| parents | 117c4d53c9a4 |
| children | 2b6e732087ff |
line wrap: on
line source
function normalizeSource(source) { const lines = source.replace(/^\n|\n\s*$/g, "").split("\n"); const indentation = lines .filter(line => line.trim()) .map(line => line.match(/^\s*/)[0].length); const minimum = indentation.length ? Math.min(...indentation) : 0; return lines.map(line => line.slice(minimum)).join("\n"); } export class ZenStory extends HTMLElement { connectedCallback() { if (this.dataset.ready === "true") return; const template = this.querySelector(":scope > template"); if (!template) return; this.dataset.ready = "true"; const heading = document.createElement("header"); const title = document.createElement("h3"); title.textContent = this.getAttribute("name") || "Example"; heading.append(title); const copy = document.createElement("button"); copy.type = "button"; copy.textContent = "Copy HTML"; copy.addEventListener("click", async () => { try { await navigator.clipboard.writeText( normalizeSource(template.innerHTML), ); copy.textContent = "Copied"; } catch { copy.textContent = "Copy unavailable"; } setTimeout(() => { copy.textContent = "Copy HTML"; }, 1200); }); heading.append(copy); const canvas = document.createElement("div"); canvas.className = "story-canvas"; canvas.append(template.content.cloneNode(true)); const source = document.createElement("pre"); const code = document.createElement("code"); code.textContent = normalizeSource(template.innerHTML); source.append(code); this.prepend(heading, canvas, source); } } if (!customElements.get("zen-story")) { customElements.define("zen-story", ZenStory); }