Mercurial
comparison design_system/src/components/story.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 |
comparison
equal
deleted
inserted
replaced
| 250:745fd127b2a1 | 251:117c4d53c9a4 |
|---|---|
| 1 function normalizeSource(source) { | |
| 2 const lines = source.replace(/^\n|\n\s*$/g, "").split("\n"); | |
| 3 const indentation = lines | |
| 4 .filter(line => line.trim()) | |
| 5 .map(line => line.match(/^\s*/)[0].length); | |
| 6 const minimum = indentation.length | |
| 7 ? Math.min(...indentation) | |
| 8 : 0; | |
| 9 return lines.map(line => line.slice(minimum)).join("\n"); | |
| 10 } | |
| 11 | |
| 12 export class ZenStory extends HTMLElement { | |
| 13 connectedCallback() { | |
| 14 if (this.dataset.ready === "true") return; | |
| 15 const template = this.querySelector(":scope > template"); | |
| 16 if (!template) return; | |
| 17 this.dataset.ready = "true"; | |
| 18 | |
| 19 const heading = document.createElement("header"); | |
| 20 const title = document.createElement("h3"); | |
| 21 title.textContent = this.getAttribute("name") || "Example"; | |
| 22 heading.append(title); | |
| 23 | |
| 24 const copy = document.createElement("button"); | |
| 25 copy.type = "button"; | |
| 26 copy.textContent = "Copy HTML"; | |
| 27 copy.addEventListener("click", async () => { | |
| 28 try { | |
| 29 await navigator.clipboard.writeText( | |
| 30 normalizeSource(template.innerHTML), | |
| 31 ); | |
| 32 copy.textContent = "Copied"; | |
| 33 } catch { | |
| 34 copy.textContent = "Copy unavailable"; | |
| 35 } | |
| 36 setTimeout(() => { | |
| 37 copy.textContent = "Copy HTML"; | |
| 38 }, 1200); | |
| 39 }); | |
| 40 heading.append(copy); | |
| 41 | |
| 42 const canvas = document.createElement("div"); | |
| 43 canvas.className = "story-canvas"; | |
| 44 canvas.append(template.content.cloneNode(true)); | |
| 45 | |
| 46 const source = document.createElement("pre"); | |
| 47 const code = document.createElement("code"); | |
| 48 code.textContent = normalizeSource(template.innerHTML); | |
| 49 source.append(code); | |
| 50 | |
| 51 this.prepend(heading, canvas, source); | |
| 52 } | |
| 53 } | |
| 54 | |
| 55 if (!customElements.get("zen-story")) { | |
| 56 customElements.define("zen-story", ZenStory); | |
| 57 } |