wc-mixin/examples/index.html
Buddy 76d78e1925 Accept a CSSStyleSheet as css; move example CSS and templates into files
css is now string | CSSStyleSheet. A sheet is adopted as-is: into its own
shadow root, an enclosing shadow root, or document.adoptedStyleSheets for
light DOM at the document level. Strings behave as before.

The examples import their styles with `with { type: 'css' }` and their
static templates with `with { type: 'text' }`. Safari doesn't support those
yet, so vite.config.ts rewrites them into modules Vite builds: a constructed
CSSStyleSheet, or the file's text. npm run examples now just runs vite,
with root set in the config.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 11:44:27 -08:00

138 lines
5.2 KiB
HTML
Raw Permalink 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 is a CSS module adopted into
<code>document.adoptedStyleSheets</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>