@timmo001/groundwork-tokens 0.9.27 → 0.9.28
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/package.json +1 -1
- package/src/page.ts +48 -1
package/package.json
CHANGED
package/src/page.ts
CHANGED
|
@@ -15,6 +15,7 @@ import glazing from "../themes/glazing.json" with { type: "json" };
|
|
|
15
15
|
import slate from "../themes/slate.json" with { type: "json" };
|
|
16
16
|
import snag from "../themes/snag.json" with { type: "json" };
|
|
17
17
|
import survey from "../themes/survey.json" with { type: "json" };
|
|
18
|
+
import type { ThemeStore } from "./runtime.ts";
|
|
18
19
|
import type { Theme } from "./schema.ts";
|
|
19
20
|
// Only for `document.modelContext`'s type; the tools themselves load lazily
|
|
20
21
|
import type {} from "./webmcp.ts";
|
|
@@ -99,6 +100,13 @@ export interface PageThemeOptions {
|
|
|
99
100
|
* entry, on the page with their CSS.
|
|
100
101
|
*/
|
|
101
102
|
readonly tones?: Readonly<Record<string, string>>;
|
|
103
|
+
/**
|
|
104
|
+
* Where the visitor's own theme is kept beyond this browser, such as an
|
|
105
|
+
* app's host or a profile. Its theme replaces the local one on load, and
|
|
106
|
+
* importing or resetting writes through to it. Local storage still caches
|
|
107
|
+
* the CSS, so the theme applies before the first paint.
|
|
108
|
+
*/
|
|
109
|
+
readonly store?: ThemeStore;
|
|
102
110
|
}
|
|
103
111
|
|
|
104
112
|
export interface PageTheme {
|
|
@@ -273,7 +281,7 @@ export const pageTheme = (options: PageThemeOptions): PageTheme => {
|
|
|
273
281
|
};
|
|
274
282
|
|
|
275
283
|
/** Solves a document under the custom id, applies it and keeps it. */
|
|
276
|
-
const applyCustom = async (document: Theme, text: string) => {
|
|
284
|
+
const applyCustom = async (document: Theme, text: string, keep = true) => {
|
|
277
285
|
const { appTonesCss, runtimeTheme } = await import("./runtime.ts");
|
|
278
286
|
const runtime = runtimeTheme(document, customThemeId);
|
|
279
287
|
|
|
@@ -290,6 +298,8 @@ export const pageTheme = (options: PageThemeOptions): PageTheme => {
|
|
|
290
298
|
savePicks();
|
|
291
299
|
commit(resolve(state.mode, document.name));
|
|
292
300
|
|
|
301
|
+
if (keep) await options.store?.save(text).catch(() => undefined);
|
|
302
|
+
|
|
293
303
|
return runtime.checks
|
|
294
304
|
.filter((result) => !result.passes)
|
|
295
305
|
.map(
|
|
@@ -361,6 +371,7 @@ export const pageTheme = (options: PageThemeOptions): PageTheme => {
|
|
|
361
371
|
|
|
362
372
|
picks = { light: fallback("light"), dark: fallback("dark") };
|
|
363
373
|
commit(resolve(defaultMode, null));
|
|
374
|
+
void options.store?.clear().catch(() => undefined);
|
|
364
375
|
},
|
|
365
376
|
subscribe: (listener) => {
|
|
366
377
|
listeners.add(listener);
|
|
@@ -373,6 +384,42 @@ export const pageTheme = (options: PageThemeOptions): PageTheme => {
|
|
|
373
384
|
|
|
374
385
|
commit(state);
|
|
375
386
|
|
|
387
|
+
// The store's theme wins over this browser's: another client may have
|
|
388
|
+
// changed or dropped it
|
|
389
|
+
if (options.store !== undefined) {
|
|
390
|
+
void options.store
|
|
391
|
+
.load()
|
|
392
|
+
.then(async (text) => {
|
|
393
|
+
if (text === read(stored.document)) return;
|
|
394
|
+
|
|
395
|
+
if (text === null) {
|
|
396
|
+
setStyle(null);
|
|
397
|
+
|
|
398
|
+
for (const key of [stored.document, stored.css, stored.name]) {
|
|
399
|
+
write(key, null);
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
picks = {
|
|
403
|
+
light:
|
|
404
|
+
picks.light === customThemeId ? fallback("light") : picks.light,
|
|
405
|
+
dark: picks.dark === customThemeId ? fallback("dark") : picks.dark,
|
|
406
|
+
};
|
|
407
|
+
savePicks();
|
|
408
|
+
commit(resolve(state.mode, null));
|
|
409
|
+
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
const { Result } = await import("effect");
|
|
414
|
+
const parsed = await readTheme(text);
|
|
415
|
+
|
|
416
|
+
if (Result.isSuccess(parsed)) {
|
|
417
|
+
await applyCustom(parsed.success, text, false);
|
|
418
|
+
}
|
|
419
|
+
})
|
|
420
|
+
.catch(() => undefined);
|
|
421
|
+
}
|
|
422
|
+
|
|
376
423
|
if (document.modelContext !== undefined) {
|
|
377
424
|
void import("./webmcp.ts").then(
|
|
378
425
|
async ({ coreThemes, registerThemeTools }) => {
|