wc-mixin/examples/index.html
Buddy 8865b49f4e Add examples page with a context manager
DSD, open/closed template, and light-DOM components that talk through
<main-context>: children register on… callbacks and share updates as events.
Served by Vite via npm run examples; examples/ is linted, formatted and
typechecked.
2026-11-10 09:59:09 -08:00

138 lines
5.2 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>wc-mixin examples</title>
<link rel="stylesheet" href="./style.css" />
<script type="module" src="./main.ts"></script>
</head>
<body>
<main>
<!--
The context manager: siblings below register callbacks with it and
share updates through it, instead of reaching for each other.
-->
<main-context>
<!--
Declarative shadow DOM: the parser attaches this shadow root, so the
banner renders (with its layout styles) before any JS loads. The
component's `css` adds the gradient animation once it upgrades, and its
props take over the text from here.
-->
<hero-banner id="banner" theme="sunset">
<template shadowrootmode="open">
<style>
:host { display: block; }
.stage {
display: grid;
gap: 0.75rem;
padding: clamp(2rem, 6vw, 4.5rem) clamp(1.25rem, 5vw, 3.5rem);
border-radius: 24px;
background: #0d0d14;
color: #f4f4fb;
overflow: hidden;
}
.eyebrow {
margin: 0;
font: 600 0.75rem/1 system-ui, sans-serif;
letter-spacing: 0.2em;
text-transform: uppercase;
opacity: 0.6;
}
h1 {
margin: 0;
font: 800 clamp(2.25rem, 8vw, 5rem)/1.02 system-ui, sans-serif;
letter-spacing: -0.03em;
overflow-wrap: anywhere;
}
.tagline { margin: 0; max-width: 36rem; font-size: 1.1rem; opacity: 0.8; }
</style>
<div class="stage">
<p class="eyebrow">Declarative shadow DOM</p>
<h1>Hello, wc-mixin</h1>
<p class="tagline">Typed props, refs and styles without the boilerplate.</p>
</div>
</template>
</hero-banner>
<div class="grid">
<section class="card">
<h2>Controls <span class="kind">light DOM</span></h2>
<p>
<code>&lt;labeled-field&gt;</code> and <code>&lt;color-swatch-picker&gt;</code> render
into the light DOM; their CSS lives in a <code>&lt;style&gt;</code> in
<code>&lt;head&gt;</code>. They never touch the other components: each edit is
shared with <code>&lt;main-context&gt;</code>, which calls the
<code>on…</code> callbacks the other components registered.
</p>
<div class="controls">
<labeled-field
id="headline"
name="headline"
label="Headline"
value="Hello, wc-mixin"
required
hint="Shared as headline → hero-banner"
></labeled-field>
<labeled-field
id="tagline"
name="tagline"
label="Tagline"
value="Typed props, refs and styles without the boilerplate."
hint="Shared as tagline → hero-banner"
></labeled-field>
<color-swatch-picker id="theme" label="Banner theme"></color-swatch-picker>
<labeled-field
id="stars"
name="stars"
label="Number of stars"
type="number"
value="5"
required
hint="Shared as stars → star-rating (1–10)"
></labeled-field>
<labeled-field
id="secret"
name="secret"
label="Secret message"
value="The cake is in the closed shadow root."
placeholder="Something hidden…"
hint="Shared as secret → secret-note"
></labeled-field>
</div>
</section>
<div class="controls">
<section class="card">
<h2>&lt;star-rating&gt; <span class="kind">template · open shadow</span></h2>
<p>Click or hover a star. Clicking the current value clears it.</p>
<star-rating id="rating" value="3">Rate this mixin</star-rating>
</section>
<section class="card">
<h2>&lt;secret-note&gt; <span class="kind">template · closed shadow</span></h2>
<p>The page can't reach inside, but the component can, through <code>this.root</code>.</p>
<secret-note id="note" message="The cake is in the closed shadow root."></secret-note>
</section>
<section class="card">
<h2>From the outside</h2>
<output id="probe"></output>
</section>
</div>
</div>
<section class="card">
<div class="log-head">
<h2>Attribute log</h2>
<button id="clear-log" type="button">Clear</button>
</div>
<p>Each prop change reflects to an attribute, and this list records them as mutations.</p>
<ol id="log"></ol>
</section>
</main-context>
</main>
</body>
</html>