Mercurial
view design_system/src/components/primitives.js @ 260:1f9877b637e9
Add Copilot-powered cyberpunk JRPG chat
Integrate the production JRPG chat with Seobeo streaming, Deita persistence, and a Bazel-managed Copilot SDK and LiteLLM inference stack.
Co-authored-by: Copilot <[email protected]>
| author | MrJuneJune <mrjunejune@users.noreply.github.com> |
|---|---|
| date | Wed, 05 Aug 2026 09:19:41 -0700 |
| parents | 60a876c4587a |
| children |
line wrap: on
line source
/** @const {!ReadonlyArray<string>} Registered presentation-only elements. */ export const ZEN_PRIMITIVE_ELEMENTS = [ "zen-aspect-ratio", "zen-attachment", "zen-avatar", "zen-badge", "zen-breadcrumb", "zen-bubble", "zen-box", "zen-button-group", "zen-chart", "zen-direction", "zen-empty", "zen-input", "zen-input-group", "zen-item", "zen-kbd", "zen-label", "zen-heading", "zen-marker", "zen-message", "zen-native-select", "zen-pagination", "zen-progress", "zen-scroll-area", "zen-separator", "zen-skeleton", "zen-spinner", "zen-table", "zen-text", "zen-textarea", "zen-typography", ]; function parseRatio(value) { const [width, height] = String(value || "16/9") .split("/") .map(Number); if (!Number.isFinite(width) || !Number.isFinite(height) || width <= 0 || height <= 0) return "16 / 9"; return `${width} / ${height}`; } /** * Applies small semantic enhancements shared by presentation primitives. * * @extends {HTMLElement} */ export class ZenPrimitive extends HTMLElement { connectedCallback() { this.sync(); } static get observedAttributes() { return ["dir", "ratio", "value", "width"]; } attributeChangedCallback() { if (this.isConnected) this.sync(); } sync() { switch (this.localName) { case "zen-aspect-ratio": this.style.setProperty( "--zenbu-aspect-ratio", parseRatio(this.getAttribute("ratio")), ); break; case "zen-breadcrumb": { const navigation = this.querySelector(":scope > nav"); if (navigation && !navigation.hasAttribute("aria-label")) { navigation.setAttribute("aria-label", "Breadcrumb"); } break; } case "zen-chart": if (!this.hasAttribute("role")) this.setAttribute("role", "img"); break; case "zen-direction": if (!this.hasAttribute("dir") && this.hasAttribute("value")) { this.dir = this.getAttribute("value"); } break; case "zen-pagination": { const navigation = this.querySelector(":scope > nav"); if (navigation && !navigation.hasAttribute("aria-label")) { navigation.setAttribute("aria-label", "Pagination"); } break; } case "zen-native-select": { if (!this.querySelector("select")) break; let icon = this.querySelector( ":scope > zen-icon[data-zen-select-icon]", ); if (!icon) { icon = document.createElement("zen-icon"); icon.dataset.zenSelectIcon = ""; icon.dataset.zenGenerated = "true"; icon.setAttribute("name", "chevron-down"); this.append(icon); } break; } case "zen-separator": if (!this.querySelector(":scope > hr")) { if (!this.hasAttribute("role")) { this.setAttribute("role", "separator"); } if (!this.hasAttribute("aria-orientation")) { this.setAttribute( "aria-orientation", this.getAttribute("orientation") === "vertical" ? "vertical" : "horizontal", ); } } break; case "zen-skeleton": if (this.hasAttribute("width")) { this.style.setProperty( "--zenbu-skeleton-width", this.getAttribute("width"), ); } else { this.style.removeProperty("--zenbu-skeleton-width"); } if (!this.hasAttribute("role")) this.setAttribute("aria-hidden", "true"); break; case "zen-spinner": if (!this.hasAttribute("role")) this.setAttribute("role", "status"); if (!this.hasAttribute("aria-label")) { this.setAttribute("aria-label", "Loading"); } break; } } } for (const name of ZEN_PRIMITIVE_ELEMENTS) { if (!customElements.get(name)) { customElements.define(name, class extends ZenPrimitive {}); } }