feat: sync showcase with WRNexusJS 0.8.7
@@ -1,4 +1,4 @@
|
||||
/* global AbortController, DOMParser, HTMLFormElement, HTMLInputElement, HTMLSelectElement, HTMLTextAreaElement, Node, URL, URLSearchParams, clearTimeout, document, fetch, navigator, setTimeout, window */
|
||||
/* global AbortController, DOMParser, HTMLFormElement, HTMLInputElement, HTMLSelectElement, HTMLTextAreaElement, MutationObserver, Node, URL, URLSearchParams, clearTimeout, document, fetch, navigator, setTimeout, window */
|
||||
|
||||
(() => {
|
||||
const SELECTOR = "[data-playground]";
|
||||
@@ -58,21 +58,10 @@
|
||||
|
||||
let design = storedDesign();
|
||||
applyDesign(design, false);
|
||||
|
||||
function updateActiveNavigation() {
|
||||
for (const link of document.querySelectorAll(".docs-directory a[href]")) {
|
||||
const target = new URL(link.href, window.location.origin);
|
||||
if (target.pathname === window.location.pathname) {
|
||||
link.setAttribute("aria-current", "page");
|
||||
} else {
|
||||
link.removeAttribute("aria-current");
|
||||
}
|
||||
}
|
||||
for (const link of document.querySelectorAll(".docs-directory a[href]")) {
|
||||
const target = new URL(link.href, window.location.origin);
|
||||
if (target.pathname === window.location.pathname) link.setAttribute("aria-current", "page");
|
||||
}
|
||||
|
||||
updateActiveNavigation();
|
||||
window.addEventListener("wrnexus:navigated", updateActiveNavigation);
|
||||
|
||||
window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", () => {
|
||||
if (design.mode === "system") applyDesign(design);
|
||||
});
|
||||
@@ -108,7 +97,7 @@
|
||||
|
||||
const name = field.name.slice(3);
|
||||
if (field instanceof HTMLInputElement && field.type === "checkbox") {
|
||||
if (field.checked) attributes.push(name);
|
||||
attributes.push(`${name}="${field.checked}"`);
|
||||
} else if (field.value !== "") {
|
||||
const value = field.hasAttribute("data-playground-json")
|
||||
? `'${field.value.replaceAll("'", "\\'")}'`
|
||||
@@ -202,6 +191,8 @@
|
||||
);
|
||||
window.__wrnexusHydrateScopes?.(preview);
|
||||
window.__wrnexusHydrateCsrFetches?.(preview);
|
||||
window.wireTheme?.bind?.(document);
|
||||
bindPlaygroundEvents(document);
|
||||
status.textContent = "Preview updated";
|
||||
} catch (error) {
|
||||
if (error?.name !== "AbortError") {
|
||||
@@ -212,6 +203,76 @@
|
||||
}
|
||||
}
|
||||
|
||||
const outputBindings = new WeakMap();
|
||||
const legacyObservedOutputs = new Set();
|
||||
|
||||
function formatOutputPayload(payload) {
|
||||
if (payload === undefined) return "No output payload";
|
||||
if (typeof payload === "string") return payload;
|
||||
try {
|
||||
return JSON.stringify(payload, null, 2);
|
||||
} catch {
|
||||
return String(payload);
|
||||
}
|
||||
}
|
||||
|
||||
function renderOutput(owner, outputName, payload) {
|
||||
const log = owner.querySelector("[data-playground-event-log]");
|
||||
if (!log) return;
|
||||
log.replaceChildren();
|
||||
const heading = document.createElement("strong");
|
||||
heading.textContent = `@${outputName}`;
|
||||
const output = document.createElement("pre");
|
||||
output.textContent = formatOutputPayload(payload);
|
||||
log.append(heading, output);
|
||||
}
|
||||
|
||||
function bindDirectOutput(host, owner, outputName) {
|
||||
let byName = outputBindings.get(host);
|
||||
if (!byName) {
|
||||
byName = new Map();
|
||||
outputBindings.set(host, byName);
|
||||
}
|
||||
if (byName.has(outputName)) return;
|
||||
const registry = (host.__wrnexusOutputHandlers ??= new Map());
|
||||
const handlers = registry.get(outputName) ?? new Set();
|
||||
const handler = (payload) => renderOutput(owner, outputName, payload);
|
||||
handlers.add(handler);
|
||||
registry.set(outputName, handlers);
|
||||
byName.set(outputName, handler);
|
||||
}
|
||||
|
||||
function bindPlaygroundEvents(root = document) {
|
||||
for (const playground of root.querySelectorAll?.(SELECTOR) ?? []) {
|
||||
const outputNames = (playground.getAttribute("data-playground-events") || "")
|
||||
.split(",")
|
||||
.map((name) => name.trim())
|
||||
.filter(Boolean);
|
||||
const host = playground.querySelector(
|
||||
"[data-playground-preview] [data-wrn-scope], [data-playground-preview] [data-ui-component], [data-playground-preview] [data-component]",
|
||||
);
|
||||
for (const outputName of outputNames) {
|
||||
if (host) bindDirectOutput(host, playground, outputName);
|
||||
// Legacy CustomEvent observation is retained only for compatibility-mode components.
|
||||
if (legacyObservedOutputs.has(outputName)) continue;
|
||||
legacyObservedOutputs.add(outputName);
|
||||
document.addEventListener(outputName, (legacyEvent) => {
|
||||
const owner = legacyEvent.target?.closest?.(SELECTOR);
|
||||
if (!owner) return;
|
||||
const declaredOutputs = (owner.getAttribute("data-playground-events") || "").split(",");
|
||||
if (!declaredOutputs.includes(outputName)) return;
|
||||
renderOutput(owner, outputName, legacyEvent.detail);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bindPlaygroundEvents();
|
||||
new MutationObserver(() => bindPlaygroundEvents(document)).observe(
|
||||
document.getElementById("app") || document.body,
|
||||
{ childList: true, subtree: true },
|
||||
);
|
||||
|
||||
function schedule(playground) {
|
||||
updateCode(playground);
|
||||
clearTimeout(timer);
|
||||
@@ -304,8 +365,7 @@
|
||||
const links = [...document.querySelectorAll("[data-docs-component-link]")];
|
||||
let visible = 0;
|
||||
for (const link of links) {
|
||||
const label = link.querySelector("[data-docs-component-name]")?.textContent || "";
|
||||
const matches = !query || label.toLowerCase().includes(query);
|
||||
const matches = !query || link.textContent.toLowerCase().includes(query);
|
||||
link.hidden = !matches;
|
||||
if (matches) visible++;
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" role="img" aria-label="design avatar"><rect width="64" height="64" rx="32" fill="#8b5cf6"/><text x="32" y="40" text-anchor="middle" font-family="Arial,sans-serif" font-size="24" fill="#fff">D</text></svg>
|
||||
|
After Width: | Height: | Size: 265 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" role="img" aria-label="engineering avatar"><rect width="64" height="64" rx="32" fill="#0ea5e9"/><text x="32" y="40" text-anchor="middle" font-family="Arial,sans-serif" font-size="24" fill="#fff">E</text></svg>
|
||||
|
After Width: | Height: | Size: 270 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" role="img" aria-label="growth avatar"><rect width="64" height="64" rx="32" fill="#10b981"/><text x="32" y="40" text-anchor="middle" font-family="Arial,sans-serif" font-size="24" fill="#fff">G</text></svg>
|
||||
|
After Width: | Height: | Size: 265 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 400" role="img" aria-label="Abstract blue mountain"><rect width="400" height="400" fill="#0284c7"/><path d="M80 290 190 120l130 170z" fill="#fff" opacity=".7"/></svg>
|
||||
|
After Width: | Height: | Size: 224 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 450" role="img" aria-label="Abstract dashboard preview"><rect width="800" height="450" fill="#1e1b4b"/><circle cx="610" cy="130" r="120" fill="#7c3aed" opacity=".55"/><rect x="90" y="90" width="430" height="270" rx="28" fill="#fff" opacity=".12"/></svg>
|
||||
|
After Width: | Height: | Size: 311 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1200 600" role="img" aria-label="Abstract green hero visual"><rect width="1200" height="600" fill="#059669"/><rect x="150" y="120" width="900" height="360" rx="36" fill="#fff" opacity=".18"/></svg>
|
||||
|
After Width: | Height: | Size: 251 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 36" role="img" aria-label="Acme logo"><rect width="120" height="36" rx="8" fill="#7c3aed"/><text x="60" y="23" text-anchor="middle" font-family="Arial,sans-serif" font-size="13" fill="#fff">Acme</text></svg>
|
||||
|
After Width: | Height: | Size: 265 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 36" role="img" aria-label="Northstar logo"><rect width="120" height="36" rx="8" fill="#7c3aed"/><text x="60" y="23" text-anchor="middle" font-family="Arial,sans-serif" font-size="13" fill="#fff">Northstar</text></svg>
|
||||
|
After Width: | Height: | Size: 275 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 36" role="img" aria-label="Vertex logo"><rect width="120" height="36" rx="8" fill="#7c3aed"/><text x="60" y="23" text-anchor="middle" font-family="Arial,sans-serif" font-size="13" fill="#fff">Vertex</text></svg>
|
||||
|
After Width: | Height: | Size: 269 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 36" role="img" aria-label="Orbit logo"><rect width="120" height="36" rx="8" fill="#7c3aed"/><text x="60" y="23" text-anchor="middle" font-family="Arial,sans-serif" font-size="13" fill="#fff">Orbit</text></svg>
|
||||
|
After Width: | Height: | Size: 267 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 36" role="img" aria-label="Acme logo"><rect width="120" height="36" rx="8" fill="#0284c7"/><text x="60" y="23" text-anchor="middle" font-family="Arial,sans-serif" font-size="13" fill="#fff">Acme</text></svg>
|
||||
|
After Width: | Height: | Size: 265 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 36" role="img" aria-label="Northstar logo"><rect width="120" height="36" rx="8" fill="#0284c7"/><text x="60" y="23" text-anchor="middle" font-family="Arial,sans-serif" font-size="13" fill="#fff">Northstar</text></svg>
|
||||
|
After Width: | Height: | Size: 275 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 36" role="img" aria-label="Vertex logo"><rect width="120" height="36" rx="8" fill="#0284c7"/><text x="60" y="23" text-anchor="middle" font-family="Arial,sans-serif" font-size="13" fill="#fff">Vertex</text></svg>
|
||||
|
After Width: | Height: | Size: 269 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 36" role="img" aria-label="Orbit logo"><rect width="120" height="36" rx="8" fill="#0284c7"/><text x="60" y="23" text-anchor="middle" font-family="Arial,sans-serif" font-size="13" fill="#fff">Orbit</text></svg>
|
||||
|
After Width: | Height: | Size: 267 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 36" role="img" aria-label="Acme logo"><rect width="120" height="36" rx="8" fill="#059669"/><text x="60" y="23" text-anchor="middle" font-family="Arial,sans-serif" font-size="13" fill="#fff">Acme</text></svg>
|
||||
|
After Width: | Height: | Size: 265 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 36" role="img" aria-label="Northstar logo"><rect width="120" height="36" rx="8" fill="#059669"/><text x="60" y="23" text-anchor="middle" font-family="Arial,sans-serif" font-size="13" fill="#fff">Northstar</text></svg>
|
||||
|
After Width: | Height: | Size: 275 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 36" role="img" aria-label="Vertex logo"><rect width="120" height="36" rx="8" fill="#059669"/><text x="60" y="23" text-anchor="middle" font-family="Arial,sans-serif" font-size="13" fill="#fff">Vertex</text></svg>
|
||||
|
After Width: | Height: | Size: 269 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 36" role="img" aria-label="Orbit logo"><rect width="120" height="36" rx="8" fill="#059669"/><text x="60" y="23" text-anchor="middle" font-family="Arial,sans-serif" font-size="13" fill="#fff">Orbit</text></svg>
|
||||
|
After Width: | Height: | Size: 267 B |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 450" role="img" aria-label="Abstract violet circle on a dark surface"><rect width="800" height="450" fill="#1e1b4b"/><circle cx="400" cy="225" r="120" fill="#7c3aed"/></svg>
|
||||
|
After Width: | Height: | Size: 231 B |