@brandon_m_behring/book-scaffold-astro 4.14.1 → 4.14.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +22 -0
- package/layouts/Base.astro +38 -12
- package/package.json +1 -1
package/CLAUDE.md
CHANGED
|
@@ -106,6 +106,28 @@ Two callout families coexist. Authors import what they need.
|
|
|
106
106
|
|
|
107
107
|
Full reference in `recipes/04-component-library.md`.
|
|
108
108
|
|
|
109
|
+
### Theme-change event (v4.14.2)
|
|
110
|
+
|
|
111
|
+
`Base.astro` emits `book:theme:change` on `window` whenever the **effective** theme changes — both the chrome's dark-mode toggle and a system `prefers-color-scheme` flip (the latter only when no explicit theme is pinned). Use it for **canvas / JS islands** that can't recolor via CSS alone; CSS-token elements recolor automatically from the `[data-theme]` attribute.
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
// inside a Preact island (client:visible / client:idle)
|
|
115
|
+
function currentTheme(): 'light' | 'dark' {
|
|
116
|
+
const t = document.documentElement.getAttribute('data-theme');
|
|
117
|
+
return t === 'light' || t === 'dark'
|
|
118
|
+
? t
|
|
119
|
+
: matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
|
120
|
+
}
|
|
121
|
+
useEffect(() => {
|
|
122
|
+
draw(currentTheme()); // initial paint
|
|
123
|
+
const onChange = (e: Event) => draw((e as CustomEvent).detail.theme);
|
|
124
|
+
window.addEventListener('book:theme:change', onChange);
|
|
125
|
+
return () => window.removeEventListener('book:theme:change', onChange);
|
|
126
|
+
}, []);
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
`detail.theme` is `'light' | 'dark'`. Pull design-token colors via `getComputedStyle(document.documentElement).getPropertyValue('--…')` so the canvas matches the page, and respect `prefers-reduced-motion` for any redraw animation. (Event-only by design — a `useThemeColors` helper graduates with the demo kit, #103.)
|
|
130
|
+
|
|
109
131
|
## Citation patterns
|
|
110
132
|
|
|
111
133
|
Academic profile uses BibTeX → `references.json`:
|
package/layouts/Base.astro
CHANGED
|
@@ -176,21 +176,47 @@ const ogDescription = description ?? bookConfig.description ?? '';
|
|
|
176
176
|
) : (
|
|
177
177
|
<main><slot /></main>
|
|
178
178
|
)}
|
|
179
|
+
{/*
|
|
180
|
+
Theme-change hook (#103, v4.14.2). Whenever the EFFECTIVE theme changes,
|
|
181
|
+
emit `book:theme:change` on `window` with `detail.theme` ∈ {'light','dark'}.
|
|
182
|
+
CSS recolors via the `data-theme` attribute alone; canvas/JS islands can't,
|
|
183
|
+
so they subscribe to this event (and read the attribute / matchMedia on
|
|
184
|
+
mount for the initial value) to redraw. Contract documented in the package
|
|
185
|
+
CLAUDE.md. Event-only by design — a `useThemeColors` helper graduates later
|
|
186
|
+
with the demo kit.
|
|
187
|
+
*/}
|
|
179
188
|
<script is:inline>
|
|
180
189
|
(function () {
|
|
190
|
+
var root = document.documentElement;
|
|
191
|
+
function effectiveTheme() {
|
|
192
|
+
var explicit = root.getAttribute('data-theme');
|
|
193
|
+
if (explicit === 'light' || explicit === 'dark') return explicit;
|
|
194
|
+
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
|
195
|
+
}
|
|
196
|
+
function emitThemeChange() {
|
|
197
|
+
window.dispatchEvent(new CustomEvent('book:theme:change', { detail: { theme: effectiveTheme() } }));
|
|
198
|
+
}
|
|
181
199
|
var btn = document.getElementById('theme-toggle');
|
|
182
|
-
if (
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
200
|
+
if (btn) {
|
|
201
|
+
btn.addEventListener('click', function () {
|
|
202
|
+
var current = root.getAttribute('data-theme');
|
|
203
|
+
// If no explicit theme, pick the opposite of prefers-color-scheme.
|
|
204
|
+
if (!current) {
|
|
205
|
+
current = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
|
206
|
+
}
|
|
207
|
+
var next = current === 'dark' ? 'light' : 'dark';
|
|
208
|
+
root.setAttribute('data-theme', next);
|
|
209
|
+
try { localStorage.setItem('theme', next); } catch (e) {}
|
|
210
|
+
emitThemeChange();
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
// A system-preference flip only changes the effective theme when no
|
|
214
|
+
// explicit theme is pinned — emit then so islands can redraw too.
|
|
215
|
+
try {
|
|
216
|
+
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', function () {
|
|
217
|
+
if (!root.getAttribute('data-theme')) emitThemeChange();
|
|
218
|
+
});
|
|
219
|
+
} catch (e) { /* older browsers: no media-query change events */ }
|
|
194
220
|
})();
|
|
195
221
|
</script>
|
|
196
222
|
</body>
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@brandon_m_behring/book-scaffold-astro",
|
|
3
3
|
"description": "Astro 6 + MDX toolkit for long-form technical books. Profile-aware (academic / tools / minimal); ships Tufte typography, KaTeX, BibTeX citations, Pagefind, Cloudflare Workers deploy. See PACKAGE_DESIGN.md for the API contract.",
|
|
4
|
-
"version": "4.14.
|
|
4
|
+
"version": "4.14.2",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"author": "Brandon Behring",
|