@adea-ai/ui 0.128.0 → 0.128.1
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/dist/NOTICE
CHANGED
|
@@ -366,15 +366,15 @@ byte for byte into a recovery envelope at read time, before any write can touch
|
|
|
366
366
|
main key; the legacy single-key value is read only while the main key is absent and
|
|
367
367
|
is never deleted; and blocked storage reads as nothing stored. The envelope shape is
|
|
368
368
|
unchanged. The no-flash boot script in `packages/ui/src/components/theme/theme-script.ts`
|
|
369
|
-
is rewritten from that port's `appearanceThemeScript` to read the same document,
|
|
370
|
-
introduces no further upstream source.
|
|
369
|
+
is rewritten from that port's `appearanceThemeScript` to read the same document, carries
|
|
370
|
+
the same header, and introduces no further upstream source.
|
|
371
371
|
|
|
372
372
|
Copyright (c) 2026 Wing
|
|
373
373
|
Licensed under the MIT License.
|
|
374
374
|
|
|
375
|
-
`preference-store.ts`
|
|
376
|
-
under "Appearance editor translated from Zeron" above, applies to
|
|
377
|
-
portion.
|
|
375
|
+
`preference-store.ts` and `theme-script.ts` retain that header. Zeron's MIT notice,
|
|
376
|
+
reproduced in full under "Appearance editor translated from Zeron" above, applies to
|
|
377
|
+
the translated portion.
|
|
378
378
|
|
|
379
379
|
## Strict binary layout extracted from the accepted Adea donor port
|
|
380
380
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theme-script.d.ts","sourceRoot":"","sources":["../../../src/components/theme/theme-script.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"theme-script.d.ts","sourceRoot":"","sources":["../../../src/components/theme/theme-script.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AAE7D;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED;;;GAGG;AACH,MAAM,MAAM,kBAAkB,GAAG,kBAAkB,GAAG;IACpD;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,QAAQ,GAAG,YAAY,CAAA;IACjC,oEAAoE;IACpE,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AACH,wBAAgB,WAAW,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;AACxD,wBAAgB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,MAAM,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"theme-script.js","names":[],"sources":["../../../src/components/theme/theme-script.ts"],"sourcesContent":["import { fontSettingsBootstrapScript } from '#lib/appearance-font-settings'\nimport { isCustomAccent } from '#lib/accent-roles'\nimport { safeScriptStringLiteral } from '#lib/safe-script'\nimport { REDUCED_TRANSPARENCY_QUERY, surfaceAlpha } from '#lib/theme-surface'\nimport { accentPresets } from '#lib/tokens'\nimport { builtinThemes, defaultDarkThemeId, defaultLightThemeId } from '#lib/themes'\nimport type { ThemeStorageSchema } from './theme-persistence'\n\n/**\n * A string as a JavaScript literal that is also safe inside an inline `<script>`.\n *\n * `JSON.stringify` produces a correct JavaScript literal, and it is **not** safe\n * here: it leaves `<` and `>` alone, so a value containing `</script>` ends the tag\n * early and everything after it is parsed as HTML. That is the classic inline-script\n * injection, and it is a real one even though the value is a developer-supplied prop\n * rather than user input — a prop can come from configuration, and a key that happens\n * to contain a closing tag should not be able to execute.\n *\n * The escape is also correct JavaScript: `\\u003c` is `<` to the parser, so the value\n * is byte-identical at runtime and inert to the HTML tokenizer. `\\u2028` and `\\u2029`\n * are escaped for the neighbouring reason — they are legal inside a JSON string and\n * were, before ES2019, line terminators to a JavaScript parser.\n *\n * CodeQL flags the unescaped form as `js/bad-code-sanitization`, which is how this\n * was found; `tests/theme-script.test.ts` pins it so it cannot come back.\n */\nexport function inlineScriptLiteral(value: string): string {\n return safeScriptStringLiteral(value)\n}\n\n/**\n * Options for the host-shaped no-flash script: the document's {@link ThemeStorageSchema}\n * plus what the script paints from it.\n */\nexport type ThemeScriptOptions = ThemeStorageSchema & {\n /**\n * The accent painted when the document has none, an unrecognised one, or the\n * legacy `theme` spelling — the host's default (adea: `violet`). Without it those\n * cases paint no `data-accent`, which is what the provider writes for `theme`.\n * Setting it means the `[data-accent]` block of the default preset paints on the\n * first frame instead of after hydration.\n */\n defaultAccent?: string\n /**\n * Also resolve the surface axis (`data-surface`, `data-reduce-transparency`,\n * `--surface-alpha`) from the document and the operating system's Reduce\n * Transparency setting. A `translucent` preference resolves to `frosted`: the\n * host's translucency capability is not known until the provider mounts, and the\n * provider re-resolves it then. Match the provider's `surface` prop.\n */\n surface?: boolean\n /**\n * Match the provider's `palette` prop. The attributes written are the same either\n * way: a catalogue variant's palette is the host stylesheet's job (`stylesheet`) or\n * the provider's, at mount (`inline`), and a stored theme's own tokens are written\n * inline in both.\n */\n palette?: 'inline' | 'stylesheet'\n /** The only `version` of the library document read. Default `1`. */\n libraryVersion?: number\n}\n\n/**\n * The no-flash script.\n *\n * Rendered inline in `<head>` before any stylesheet that matters. Without it a dark\n * preference paints the light theme first and then swaps, which is the flash every\n * themed application has to solve and the one thing a provider cannot do from\n * inside the body.\n *\n * ## The string form\n *\n * `themeScript('key')` serves a provider that stores an unversioned\n * `localStorage[key]` document. Deliberately tiny and dependency-free: it reads the\n * stored preference, resolves `system`, and sets the class. It does not apply the\n * variant's roles — the default theme in `theme.css` covers the first paint, and the\n * provider writes the rest on mount. Its output is a compatibility surface (a\n * consumer may have it in a snapshot), so it does not change.\n *\n * ## The options form\n *\n * `themeScript({ key, ... })` serves a host with a versioned document (see\n * `createVersionedPersistence`) and writes what the provider will write, so mounting\n * repaints nothing:\n *\n * - `class=\"dark\"`, `color-scheme`, `data-theme`, `data-appearance` and, for a\n * compact document, `data-density`;\n * - `data-accent`: a preset id as stored, `custom` for a `#rrggbb` (never the hex\n * itself, which is the worst possible attribute content), `defaultAccent` when the\n * document has none, nothing for a theme-derived `ansi-*` accent (it has no\n * stylesheet block; the provider paints it inline);\n * - the theme: the stored id when the catalogue or the stored library holds it, else\n * the default of the resolved appearance, exactly as the provider resolves it. A\n * library theme's own tokens are written inline, so an imported theme paints on the\n * first frame;\n * - the surface axis, when `surface` is set;\n * - the font settings, guarded to the document's `version`.\n *\n * The document's `version`, when the schema names one, must match exactly. The legacy\n * key is read only while the main key is absent: an unreadable main document is not\n * \"no preference\", so it does not resurrect an older value.\n *\n * The script reads values out of `localStorage` and writes them to `dataset` and\n * `style`, which are *property* assignments rather than code: a stored id, accent or\n * token can set an attribute and cannot execute. The values that reach the source as\n * text (keys, ids, the default accent) go through {@link inlineScriptLiteral} for the\n * reason documented there.\n */\nexport function themeScript(storageKey?: string): string\nexport function themeScript(options: ThemeScriptOptions): string\nexport function themeScript(input: string | ThemeScriptOptions = 'adea-appearance'): string {\n if (typeof input === 'string') return stringFormScript(input)\n return optionsFormScript(input)\n}\n\nfunction stringFormScript(storageKey: string): string {\n const script = `(function(){try{var s=localStorage.getItem(${inlineScriptLiteral(storageKey)});var p=s?JSON.parse(s):{};var a=p.appearance||'system';var d=a==='dark'||(a==='system'&&window.matchMedia('(prefers-color-scheme: dark)').matches);var r=document.documentElement;if(d)r.classList.add('dark');r.style.colorScheme=d?'dark':'light';if(p.accent&&p.accent!=='theme')r.dataset.accent=p.accent;if(p.density==='compact')r.dataset.density='compact';}catch(e){}})();`\n return `${script}${fontSettingsBootstrapScript(storageKey)}`\n}\n\nconst literal = safeScriptStringLiteral\n\nfunction optionsFormScript(options: ThemeScriptOptions): string {\n const field = options.appearanceField ?? 'appearance'\n const versionGuard =\n options.version === undefined ? '' : `&&x.version===${Number(options.version)}`\n const presets = accentPresets\n .filter((preset) => preset.id !== 'theme')\n .map((preset) => literal(preset.id))\n const defaultAccent =\n options.defaultAccent === undefined\n ? ''\n : isCustomAccent(options.defaultAccent)\n ? 'custom'\n : options.defaultAccent\n\n const parts: string[] = []\n parts.push(\n `(function(){try{`,\n `var r=document.documentElement,s=r.style;`,\n `var q=function(m){try{return window.matchMedia(m).matches}catch(e){return false}};`,\n `var get=function(k){try{return localStorage.getItem(k)}catch(e){return null}};`,\n // The main document. `raw !== null` rather than truthiness: an empty string is a\n // stored (corrupt) value, so it does not fall through to the legacy key.\n `var raw=get(${literal(options.key)}),doc=null,legacy=null;`,\n `if(raw!==null){try{var x=JSON.parse(raw);if(x&&typeof x==='object'&&!Array.isArray(x)${versionGuard})doc=x}catch(e){}}`\n )\n if (options.legacyAppearanceKey !== undefined) {\n parts.push(`else legacy=get(${literal(options.legacyAppearanceKey)});`)\n }\n parts.push(\n `var m=doc?doc[${literal(field)}]:legacy;`,\n `var mode=m==='light'||m==='dark'?m:'system';`,\n `var dark=mode==='dark'||(mode==='system'&&q('(prefers-color-scheme: dark)'));`,\n `var fallback=dark?${literal(defaultDarkThemeId)}:${literal(defaultLightThemeId)};`,\n `var want=doc?(dark?doc.darkThemeId:doc.lightThemeId):null;`,\n `if(typeof want!=='string')want=fallback;`,\n `var ids=[${builtinThemes.map((theme) => literal(theme.id)).join(',')}];`,\n `var id=ids.indexOf(want)!==-1?want:null,tokens=null;`\n )\n if (options.libraryKey !== undefined) {\n parts.push(\n `if(id===null){try{var lib=JSON.parse(get(${literal(options.libraryKey)})||'null');`,\n `if(lib&&typeof lib==='object'&&lib.version===${Number(options.libraryVersion ?? 1)}&&Array.isArray(lib.themes)){`,\n `for(var i=0;i!==lib.themes.length;i++){var t=lib.themes[i];`,\n `if(t&&t.id===want&&t.flatTokens&&typeof t.flatTokens==='object'){id=want;tokens=t.flatTokens;break}}}}catch(e){}}`\n )\n }\n parts.push(\n `if(id===null)id=fallback;`,\n `r.classList.toggle('dark',dark);`,\n `s.colorScheme=dark?'dark':'light';`,\n `r.dataset.theme=id;`,\n `r.dataset.appearance=dark?'dark':'light';`\n )\n if (options.libraryKey !== undefined) {\n parts.push(\n `if(tokens){for(var n in tokens){if(Object.prototype.hasOwnProperty.call(tokens,n)&&n.slice(0,2)==='--'&&typeof tokens[n]==='string')s.setProperty(n,tokens[n])}}`\n )\n }\n parts.push(\n `var a=doc&&typeof doc.accent==='string'?doc.accent:'';`,\n `var accent=[${presets.join(',')}].indexOf(a)!==-1?a:/^#[0-9a-fA-F]{6}$/.test(a)?'custom':a.slice(0,5)==='ansi-'?'':${literal(defaultAccent)};`,\n `if(accent)r.dataset.accent=accent;`,\n `if(doc&&doc.density==='compact')r.dataset.density='compact';`\n )\n if (options.surface) {\n parts.push(\n // Reduce Transparency forces the opaque surface; a translucent request resolves\n // to frosted because the host's capability is unknown before the provider mounts.\n `var reduce=q(${literal(REDUCED_TRANSPARENCY_QUERY)})||!!(doc&&doc.reduceTransparency===true);`,\n `var surface=reduce?'opaque':doc&&(doc.surface==='frosted'||doc.surface==='translucent')?'frosted':'opaque';`,\n `r.dataset.surface=surface;`,\n `r.dataset.reduceTransparency=reduce?'true':'false';`,\n `s.setProperty('--surface-alpha',${JSON.stringify(surfaceAlpha)}[surface]);`\n )\n }\n parts.push(`}catch(e){}})();`)\n\n return `${parts.join('')}${fontSettingsBootstrapScript(options.key, options.version)}`\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AA0BA,SAAgB,oBAAoB,OAAuB;CACzD,OAAO,wBAAwB,KAAK;AACtC;AAkFA,SAAgB,YAAY,QAAqC,mBAA2B;CAC1F,IAAI,OAAO,UAAU,UAAU,OAAO,iBAAiB,KAAK;CAC5D,OAAO,kBAAkB,KAAK;AAChC;AAEA,SAAS,iBAAiB,YAA4B;CAEpD,OAAO,GAAG,8CADmD,oBAAoB,UAAU,EAAE,wXAC1E,4BAA4B,UAAU;AAC3D;AAEA,IAAM,UAAU;AAEhB,SAAS,kBAAkB,SAAqC;CAC9D,MAAM,QAAQ,QAAQ,mBAAmB;CACzC,MAAM,eACJ,QAAQ,YAAY,KAAA,IAAY,KAAK,iBAAiB,OAAO,QAAQ,OAAO;CAC9E,MAAM,UAAU,cACb,QAAQ,WAAW,OAAO,OAAO,OAAO,CAAC,CACzC,KAAK,WAAW,QAAQ,OAAO,EAAE,CAAC;CACrC,MAAM,gBACJ,QAAQ,kBAAkB,KAAA,IACtB,KACA,eAAe,QAAQ,aAAa,IAClC,WACA,QAAQ;CAEhB,MAAM,QAAkB,CAAC;CACzB,MAAM,KACJ,oBACA,6CACA,sFACA,kFAGA,eAAe,QAAQ,QAAQ,GAAG,EAAE,0BACpC,wFAAwF,aAAa,mBACvG;CACA,IAAI,QAAQ,wBAAwB,KAAA,GAClC,MAAM,KAAK,mBAAmB,QAAQ,QAAQ,mBAAmB,EAAE,GAAG;CAExE,MAAM,KACJ,iBAAiB,QAAQ,KAAK,EAAE,YAChC,gDACA,iFACA,qBAAqB,QAAQ,kBAAkB,EAAE,GAAG,QAAQ,mBAAmB,EAAE,IACjF,8DACA,4CACA,YAAY,cAAc,KAAK,UAAU,QAAQ,MAAM,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,KACtE,sDACF;CACA,IAAI,QAAQ,eAAe,KAAA,GACzB,MAAM,KACJ,4CAA4C,QAAQ,QAAQ,UAAU,EAAE,cACxE,gDAAgD,OAAO,QAAQ,kBAAkB,CAAC,EAAE,gCACpF,+DACA,mHACF;CAEF,MAAM,KACJ,6BACA,oCACA,sCACA,uBACA,2CACF;CACA,IAAI,QAAQ,eAAe,KAAA,GACzB,MAAM,KACJ,kKACF;CAEF,MAAM,KACJ,0DACA,eAAe,QAAQ,KAAK,GAAG,EAAE,qFAAqF,QAAQ,aAAa,EAAE,IAC7I,sCACA,8DACF;CACA,IAAI,QAAQ,SACV,MAAM,KAGJ,gBAAgB,QAAQ,0BAA0B,EAAE,6CACpD,+GACA,8BACA,uDACA,mCAAmC,KAAK,UAAU,YAAY,EAAE,YAClE;CAEF,MAAM,KAAK,kBAAkB;CAE7B,OAAO,GAAG,MAAM,KAAK,EAAE,IAAI,4BAA4B,QAAQ,KAAK,QAAQ,OAAO;AACrF"}
|
|
1
|
+
{"version":3,"file":"theme-script.js","names":[],"sources":["../../../src/components/theme/theme-script.ts"],"sourcesContent":["/*\n * Copyright (c) 2026 Wing\n * Licensed under the MIT License.\n *\n * The options form is rewritten from Adea's accepted port of Zeron's preference\n * store (`appearanceThemeScript` in `packages/ui/src/components/appearance.ts`,\n * https://github.com/zeronsh/zeron) so the boot script reads the document the shared\n * persistence writes. See NOTICE.\n */\nimport { fontSettingsBootstrapScript } from '#lib/appearance-font-settings'\nimport { isCustomAccent } from '#lib/accent-roles'\nimport { safeScriptStringLiteral } from '#lib/safe-script'\nimport { REDUCED_TRANSPARENCY_QUERY, surfaceAlpha } from '#lib/theme-surface'\nimport { accentPresets } from '#lib/tokens'\nimport { builtinThemes, defaultDarkThemeId, defaultLightThemeId } from '#lib/themes'\nimport type { ThemeStorageSchema } from './theme-persistence'\n\n/**\n * A string as a JavaScript literal that is also safe inside an inline `<script>`.\n *\n * `JSON.stringify` produces a correct JavaScript literal, and it is **not** safe\n * here: it leaves `<` and `>` alone, so a value containing `</script>` ends the tag\n * early and everything after it is parsed as HTML. That is the classic inline-script\n * injection, and it is a real one even though the value is a developer-supplied prop\n * rather than user input — a prop can come from configuration, and a key that happens\n * to contain a closing tag should not be able to execute.\n *\n * The escape is also correct JavaScript: `\\u003c` is `<` to the parser, so the value\n * is byte-identical at runtime and inert to the HTML tokenizer. `\\u2028` and `\\u2029`\n * are escaped for the neighbouring reason — they are legal inside a JSON string and\n * were, before ES2019, line terminators to a JavaScript parser.\n *\n * CodeQL flags the unescaped form as `js/bad-code-sanitization`, which is how this\n * was found; `tests/theme-script.test.ts` pins it so it cannot come back.\n */\nexport function inlineScriptLiteral(value: string): string {\n return safeScriptStringLiteral(value)\n}\n\n/**\n * Options for the host-shaped no-flash script: the document's {@link ThemeStorageSchema}\n * plus what the script paints from it.\n */\nexport type ThemeScriptOptions = ThemeStorageSchema & {\n /**\n * The accent painted when the document has none, an unrecognised one, or the\n * legacy `theme` spelling — the host's default (adea: `violet`). Without it those\n * cases paint no `data-accent`, which is what the provider writes for `theme`.\n * Setting it means the `[data-accent]` block of the default preset paints on the\n * first frame instead of after hydration.\n */\n defaultAccent?: string\n /**\n * Also resolve the surface axis (`data-surface`, `data-reduce-transparency`,\n * `--surface-alpha`) from the document and the operating system's Reduce\n * Transparency setting. A `translucent` preference resolves to `frosted`: the\n * host's translucency capability is not known until the provider mounts, and the\n * provider re-resolves it then. Match the provider's `surface` prop.\n */\n surface?: boolean\n /**\n * Match the provider's `palette` prop. The attributes written are the same either\n * way: a catalogue variant's palette is the host stylesheet's job (`stylesheet`) or\n * the provider's, at mount (`inline`), and a stored theme's own tokens are written\n * inline in both.\n */\n palette?: 'inline' | 'stylesheet'\n /** The only `version` of the library document read. Default `1`. */\n libraryVersion?: number\n}\n\n/**\n * The no-flash script.\n *\n * Rendered inline in `<head>` before any stylesheet that matters. Without it a dark\n * preference paints the light theme first and then swaps, which is the flash every\n * themed application has to solve and the one thing a provider cannot do from\n * inside the body.\n *\n * ## The string form\n *\n * `themeScript('key')` serves a provider that stores an unversioned\n * `localStorage[key]` document. Deliberately tiny and dependency-free: it reads the\n * stored preference, resolves `system`, and sets the class. It does not apply the\n * variant's roles — the default theme in `theme.css` covers the first paint, and the\n * provider writes the rest on mount. Its output is a compatibility surface (a\n * consumer may have it in a snapshot), so it does not change.\n *\n * ## The options form\n *\n * `themeScript({ key, ... })` serves a host with a versioned document (see\n * `createVersionedPersistence`) and writes what the provider will write, so mounting\n * repaints nothing:\n *\n * - `class=\"dark\"`, `color-scheme`, `data-theme`, `data-appearance` and, for a\n * compact document, `data-density`;\n * - `data-accent`: a preset id as stored, `custom` for a `#rrggbb` (never the hex\n * itself, which is the worst possible attribute content), `defaultAccent` when the\n * document has none, nothing for a theme-derived `ansi-*` accent (it has no\n * stylesheet block; the provider paints it inline);\n * - the theme: the stored id when the catalogue or the stored library holds it, else\n * the default of the resolved appearance, exactly as the provider resolves it. A\n * library theme's own tokens are written inline, so an imported theme paints on the\n * first frame;\n * - the surface axis, when `surface` is set;\n * - the font settings, guarded to the document's `version`.\n *\n * The document's `version`, when the schema names one, must match exactly. The legacy\n * key is read only while the main key is absent: an unreadable main document is not\n * \"no preference\", so it does not resurrect an older value.\n *\n * The script reads values out of `localStorage` and writes them to `dataset` and\n * `style`, which are *property* assignments rather than code: a stored id, accent or\n * token can set an attribute and cannot execute. The values that reach the source as\n * text (keys, ids, the default accent) go through {@link inlineScriptLiteral} for the\n * reason documented there.\n */\nexport function themeScript(storageKey?: string): string\nexport function themeScript(options: ThemeScriptOptions): string\nexport function themeScript(input: string | ThemeScriptOptions = 'adea-appearance'): string {\n if (typeof input === 'string') return stringFormScript(input)\n return optionsFormScript(input)\n}\n\nfunction stringFormScript(storageKey: string): string {\n const script = `(function(){try{var s=localStorage.getItem(${inlineScriptLiteral(storageKey)});var p=s?JSON.parse(s):{};var a=p.appearance||'system';var d=a==='dark'||(a==='system'&&window.matchMedia('(prefers-color-scheme: dark)').matches);var r=document.documentElement;if(d)r.classList.add('dark');r.style.colorScheme=d?'dark':'light';if(p.accent&&p.accent!=='theme')r.dataset.accent=p.accent;if(p.density==='compact')r.dataset.density='compact';}catch(e){}})();`\n return `${script}${fontSettingsBootstrapScript(storageKey)}`\n}\n\nconst literal = safeScriptStringLiteral\n\nfunction optionsFormScript(options: ThemeScriptOptions): string {\n const field = options.appearanceField ?? 'appearance'\n const versionGuard =\n options.version === undefined ? '' : `&&x.version===${Number(options.version)}`\n const presets = accentPresets\n .filter((preset) => preset.id !== 'theme')\n .map((preset) => literal(preset.id))\n const defaultAccent =\n options.defaultAccent === undefined\n ? ''\n : isCustomAccent(options.defaultAccent)\n ? 'custom'\n : options.defaultAccent\n\n const parts: string[] = []\n parts.push(\n `(function(){try{`,\n `var r=document.documentElement,s=r.style;`,\n `var q=function(m){try{return window.matchMedia(m).matches}catch(e){return false}};`,\n `var get=function(k){try{return localStorage.getItem(k)}catch(e){return null}};`,\n // The main document. `raw !== null` rather than truthiness: an empty string is a\n // stored (corrupt) value, so it does not fall through to the legacy key.\n `var raw=get(${literal(options.key)}),doc=null,legacy=null;`,\n `if(raw!==null){try{var x=JSON.parse(raw);if(x&&typeof x==='object'&&!Array.isArray(x)${versionGuard})doc=x}catch(e){}}`\n )\n if (options.legacyAppearanceKey !== undefined) {\n parts.push(`else legacy=get(${literal(options.legacyAppearanceKey)});`)\n }\n parts.push(\n `var m=doc?doc[${literal(field)}]:legacy;`,\n `var mode=m==='light'||m==='dark'?m:'system';`,\n `var dark=mode==='dark'||(mode==='system'&&q('(prefers-color-scheme: dark)'));`,\n `var fallback=dark?${literal(defaultDarkThemeId)}:${literal(defaultLightThemeId)};`,\n `var want=doc?(dark?doc.darkThemeId:doc.lightThemeId):null;`,\n `if(typeof want!=='string')want=fallback;`,\n `var ids=[${builtinThemes.map((theme) => literal(theme.id)).join(',')}];`,\n `var id=ids.indexOf(want)!==-1?want:null,tokens=null;`\n )\n if (options.libraryKey !== undefined) {\n parts.push(\n `if(id===null){try{var lib=JSON.parse(get(${literal(options.libraryKey)})||'null');`,\n `if(lib&&typeof lib==='object'&&lib.version===${Number(options.libraryVersion ?? 1)}&&Array.isArray(lib.themes)){`,\n `for(var i=0;i!==lib.themes.length;i++){var t=lib.themes[i];`,\n `if(t&&t.id===want&&t.flatTokens&&typeof t.flatTokens==='object'){id=want;tokens=t.flatTokens;break}}}}catch(e){}}`\n )\n }\n parts.push(\n `if(id===null)id=fallback;`,\n `r.classList.toggle('dark',dark);`,\n `s.colorScheme=dark?'dark':'light';`,\n `r.dataset.theme=id;`,\n `r.dataset.appearance=dark?'dark':'light';`\n )\n if (options.libraryKey !== undefined) {\n parts.push(\n `if(tokens){for(var n in tokens){if(Object.prototype.hasOwnProperty.call(tokens,n)&&n.slice(0,2)==='--'&&typeof tokens[n]==='string')s.setProperty(n,tokens[n])}}`\n )\n }\n parts.push(\n `var a=doc&&typeof doc.accent==='string'?doc.accent:'';`,\n `var accent=[${presets.join(',')}].indexOf(a)!==-1?a:/^#[0-9a-fA-F]{6}$/.test(a)?'custom':a.slice(0,5)==='ansi-'?'':${literal(defaultAccent)};`,\n `if(accent)r.dataset.accent=accent;`,\n `if(doc&&doc.density==='compact')r.dataset.density='compact';`\n )\n if (options.surface) {\n parts.push(\n // Reduce Transparency forces the opaque surface; a translucent request resolves\n // to frosted because the host's capability is unknown before the provider mounts.\n `var reduce=q(${literal(REDUCED_TRANSPARENCY_QUERY)})||!!(doc&&doc.reduceTransparency===true);`,\n `var surface=reduce?'opaque':doc&&(doc.surface==='frosted'||doc.surface==='translucent')?'frosted':'opaque';`,\n `r.dataset.surface=surface;`,\n `r.dataset.reduceTransparency=reduce?'true':'false';`,\n `s.setProperty('--surface-alpha',${JSON.stringify(surfaceAlpha)}[surface]);`\n )\n }\n parts.push(`}catch(e){}})();`)\n\n return `${parts.join('')}${fontSettingsBootstrapScript(options.key, options.version)}`\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAmCA,SAAgB,oBAAoB,OAAuB;CACzD,OAAO,wBAAwB,KAAK;AACtC;AAkFA,SAAgB,YAAY,QAAqC,mBAA2B;CAC1F,IAAI,OAAO,UAAU,UAAU,OAAO,iBAAiB,KAAK;CAC5D,OAAO,kBAAkB,KAAK;AAChC;AAEA,SAAS,iBAAiB,YAA4B;CAEpD,OAAO,GAAG,8CADmD,oBAAoB,UAAU,EAAE,wXAC1E,4BAA4B,UAAU;AAC3D;AAEA,IAAM,UAAU;AAEhB,SAAS,kBAAkB,SAAqC;CAC9D,MAAM,QAAQ,QAAQ,mBAAmB;CACzC,MAAM,eACJ,QAAQ,YAAY,KAAA,IAAY,KAAK,iBAAiB,OAAO,QAAQ,OAAO;CAC9E,MAAM,UAAU,cACb,QAAQ,WAAW,OAAO,OAAO,OAAO,CAAC,CACzC,KAAK,WAAW,QAAQ,OAAO,EAAE,CAAC;CACrC,MAAM,gBACJ,QAAQ,kBAAkB,KAAA,IACtB,KACA,eAAe,QAAQ,aAAa,IAClC,WACA,QAAQ;CAEhB,MAAM,QAAkB,CAAC;CACzB,MAAM,KACJ,oBACA,6CACA,sFACA,kFAGA,eAAe,QAAQ,QAAQ,GAAG,EAAE,0BACpC,wFAAwF,aAAa,mBACvG;CACA,IAAI,QAAQ,wBAAwB,KAAA,GAClC,MAAM,KAAK,mBAAmB,QAAQ,QAAQ,mBAAmB,EAAE,GAAG;CAExE,MAAM,KACJ,iBAAiB,QAAQ,KAAK,EAAE,YAChC,gDACA,iFACA,qBAAqB,QAAQ,kBAAkB,EAAE,GAAG,QAAQ,mBAAmB,EAAE,IACjF,8DACA,4CACA,YAAY,cAAc,KAAK,UAAU,QAAQ,MAAM,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,KACtE,sDACF;CACA,IAAI,QAAQ,eAAe,KAAA,GACzB,MAAM,KACJ,4CAA4C,QAAQ,QAAQ,UAAU,EAAE,cACxE,gDAAgD,OAAO,QAAQ,kBAAkB,CAAC,EAAE,gCACpF,+DACA,mHACF;CAEF,MAAM,KACJ,6BACA,oCACA,sCACA,uBACA,2CACF;CACA,IAAI,QAAQ,eAAe,KAAA,GACzB,MAAM,KACJ,kKACF;CAEF,MAAM,KACJ,0DACA,eAAe,QAAQ,KAAK,GAAG,EAAE,qFAAqF,QAAQ,aAAa,EAAE,IAC7I,sCACA,8DACF;CACA,IAAI,QAAQ,SACV,MAAM,KAGJ,gBAAgB,QAAQ,0BAA0B,EAAE,6CACpD,+GACA,8BACA,uDACA,mCAAmC,KAAK,UAAU,YAAY,EAAE,YAClE;CAEF,MAAM,KAAK,kBAAkB;CAE7B,OAAO,GAAG,MAAM,KAAK,EAAE,IAAI,4BAA4B,QAAQ,KAAK,QAAQ,OAAO;AACrF"}
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2026 Wing
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*
|
|
5
|
+
* The options form is rewritten from Adea's accepted port of Zeron's preference
|
|
6
|
+
* store (`appearanceThemeScript` in `packages/ui/src/components/appearance.ts`,
|
|
7
|
+
* https://github.com/zeronsh/zeron) so the boot script reads the document the shared
|
|
8
|
+
* persistence writes. See NOTICE.
|
|
9
|
+
*/
|
|
1
10
|
import { fontSettingsBootstrapScript } from '../../lib/appearance-font-settings'
|
|
2
11
|
import { isCustomAccent } from '../../lib/accent-roles'
|
|
3
12
|
import { safeScriptStringLiteral } from '../../lib/safe-script'
|
package/package.json
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2026 Wing
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*
|
|
5
|
+
* The options form is rewritten from Adea's accepted port of Zeron's preference
|
|
6
|
+
* store (`appearanceThemeScript` in `packages/ui/src/components/appearance.ts`,
|
|
7
|
+
* https://github.com/zeronsh/zeron) so the boot script reads the document the shared
|
|
8
|
+
* persistence writes. See NOTICE.
|
|
9
|
+
*/
|
|
1
10
|
import { fontSettingsBootstrapScript } from '#lib/appearance-font-settings'
|
|
2
11
|
import { isCustomAccent } from '#lib/accent-roles'
|
|
3
12
|
import { safeScriptStringLiteral } from '#lib/safe-script'
|