@weasel-js/theme 1.15.2 → 1.16.0

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/index.d.ts CHANGED
@@ -1,21 +1,8 @@
1
- import { o as ColorList, p as ColorSourceContext, q as TokenName, r as ResolvedTheme, a as Theme, S as Selection, s as TokenValue } from './definition-nZbgRG7A.js';
2
- export { t as AxisDef, A as AxisDefs, u as AxisValue, v as BAKED_THEMES, B as BakedTheme, w as ByAxis, x as ColorContext, y as ColorListItem, F as FlatTokens, G as GeneratedColors, z as GeneratedTheme, P as PinObject, e as PinValue, D as RampColors, R as RawToken, E as SerializableColorList, H as THEMES, I as THEME_SOURCES, T as ThemeDefinition, J as ThemeInput, V as Varying, K as colorCount, M as defineTheme, Q as enumerateSelections, U as fullSelection, W as isByAxis, X as rampSteps, Y as resolveTheme, Z as selectionKey, _ as themeAxes, $ as themeTints, a0 as weaselTheme } from './definition-nZbgRG7A.js';
1
+ import { o as TokenName, p as ResolvedTheme, a as Theme, S as Selection, q as TokenValue, r as ColorList, s as ColorSourceContext } from './definition-DfbYMDu0.js';
2
+ export { t as AxisDef, A as AxisDefs, u as AxisValue, v as BAKED_THEMES, B as BakedTheme, w as ByAxis, x as ColorContext, y as ColorListItem, F as FlatTokens, G as GeneratedColors, z as GeneratedTheme, P as PinObject, e as PinValue, D as RampColors, R as RawToken, E as SerializableColorList, H as THEMES, I as THEME_SOURCES, T as ThemeDefinition, J as ThemeInput, V as Varying, K as colorCount, M as defineTheme, Q as enumerateSelections, U as fullSelection, W as isByAxis, X as rampSteps, Y as resolveTheme, Z as selectionKey, _ as themeAxes, $ as themeTints, a0 as weaselTheme } from './definition-DfbYMDu0.js';
3
3
  export { C as ColorMode, a as ColorModePreference, i as isColorModePreference } from './colorMode-CoklZomJ.js';
4
4
  import { ColorSource, ColorLiteral } from '@weasel-js/paint';
5
5
 
6
- /**
7
- * The `i`th color of `list`, wrapping. A ramp list reads the resolved theme, so
8
- * the answer follows its mode; a `ColorSource` item resolves against the
9
- * context's palette, then its theme. Throws on an item nothing answers.
10
- */
11
- declare function colorAt(list: ColorList, i: number, ctx?: ColorSourceContext): string;
12
- /**
13
- * As `colorAt`, but a ramp list, and an item that names the theme, answers
14
- * with its custom property (`var(--wzl-swatch-sky)`), so a color written into
15
- * CSS follows a mode change without re-rendering, provider or not.
16
- */
17
- declare function colorCssAt(list: ColorList, i: number, ctx?: ColorSourceContext): string;
18
-
19
6
  /** One row of `TOKEN_MANIFEST`: a token, its DTCG type, the name-prefix
20
7
  * group it belongs to, its value in the default theme and selection, and
21
8
  * the description it was authored with (empty string if none). */
@@ -150,6 +137,19 @@ declare function serializeTokenValue(type: string, value: TokenValue): string;
150
137
  */
151
138
  declare function parseTokenValue(type: string, text: string): TokenValue;
152
139
 
140
+ /**
141
+ * The `i`th color of `list`, wrapping. A ramp list reads the resolved theme, so
142
+ * the answer follows its mode; a `ColorSource` item resolves against the
143
+ * context's palette, then its theme. Throws on an item nothing answers.
144
+ */
145
+ declare function colorAt(list: ColorList, i: number, ctx?: ColorSourceContext): string;
146
+ /**
147
+ * As `colorAt`, but a ramp list, and an item that names the theme, answers
148
+ * with its custom property (`var(--wzl-swatch-sky)`), so a color written into
149
+ * CSS follows a mode change without re-rendering, provider or not.
150
+ */
151
+ declare function colorCssAt(list: ColorList, i: number, ctx?: ColorSourceContext): string;
152
+
153
153
  /** The angle a component comes from: who it is for, how it speaks, what an action does. */
154
154
  declare const STANCES: readonly ["clarify", "aside", "advanced", "debug", "preview", "confirm", "cancel"];
155
155
  /** One stance. */
package/dist/index.js CHANGED
@@ -1,16 +1,18 @@
1
- export { TINT_REF, applyTheme, blendTheme, colorAt, colorCount, colorCssAt, colorSourceCss, colorSourceLiteral, isColorModePreference, rampSteps, resolveCurrentColor, themeTints } from './chunk-TG3EV42T.js';
2
- import { AXES_EXT, overrideKey, ALPHA_EXT } from './chunk-Z675UQ26.js';
1
+ import { isRamp, rampProperty, colorItemAt, colorSourceLiteral, defaultContext, colorSourceCss } from './chunk-SFVRMAMW.js';
2
+ export { TINT_REF, applyTheme, blendTheme, colorCount, colorSourceCss, colorSourceLiteral, isColorModePreference, rampSteps, resolveCurrentColor, themeTints } from './chunk-SFVRMAMW.js';
3
+ import { AXES_EXT, overrideKey, ALPHA_EXT } from './chunk-7OMMT3WJ.js';
3
4
  import './chunk-44CG54ZK.js';
4
5
  import { TOKEN_MANIFEST } from './chunk-4PFMGV3U.js';
5
6
  export { TOKEN_MANIFEST } from './chunk-4PFMGV3U.js';
6
7
  import { readCssNumber } from './chunk-M3R5MV7Q.js';
7
8
  import { themeAxes } from './chunk-UCQC6GZR.js';
8
9
  export { parseTokenValue, resolveTheme, serializeTokenValue, themeAxes } from './chunk-UCQC6GZR.js';
9
- import { weaselTheme } from './chunk-NCAQ54LO.js';
10
- export { BAKED_THEMES, THEMES, THEME_SOURCES, defineTheme, weaselTheme } from './chunk-NCAQ54LO.js';
10
+ import { weaselTheme } from './chunk-X2KI4SSJ.js';
11
+ export { BAKED_THEMES, THEMES, THEME_SOURCES, defineTheme, weaselTheme } from './chunk-X2KI4SSJ.js';
11
12
  import { mergeAxes } from './chunk-P5F3GZV6.js';
12
13
  export { enumerateSelections, fullSelection, isByAxis, selectionKey } from './chunk-P5F3GZV6.js';
13
14
  import { isPlainObject } from '@weasel-js/registry';
15
+ import { colorLiteralToCss } from '@weasel-js/paint';
14
16
 
15
17
  // src/tokenPx.ts
16
18
  var DEFAULTS = new Map(TOKEN_MANIFEST.map((t) => [t.name, t.defaultValue]));
@@ -200,6 +202,22 @@ function loadDTCG(doc) {
200
202
  }
201
203
  return { name: doc.name, extends: base, axes, tokens };
202
204
  }
205
+ function answered(css, i) {
206
+ if (css === null) throw new Error(`colorAt: nothing answers item ${i} of the color list`);
207
+ return css;
208
+ }
209
+ function colorAt(list, i, ctx = defaultContext()) {
210
+ if (isRamp(list)) return ctx.resolved[rampProperty(list, i, ctx.theme)];
211
+ const item = colorItemAt(list, i);
212
+ if (typeof item === "string") return item;
213
+ const literal = colorSourceLiteral(item, ctx);
214
+ return answered(literal && colorLiteralToCss(literal), i);
215
+ }
216
+ function colorCssAt(list, i, ctx = defaultContext()) {
217
+ if (isRamp(list)) return `var(${rampProperty(list, i, ctx.theme)})`;
218
+ const item = colorItemAt(list, i);
219
+ return typeof item === "string" ? item : answered(colorSourceCss(item, ctx), i);
220
+ }
203
221
 
204
222
  // src/appearance.ts
205
223
  var STANCES = ["clarify", "aside", "advanced", "debug", "preview", "confirm", "cancel"];
@@ -259,6 +277,6 @@ function resolveStanceSlots(tokens, base, { stance, nested, stanced } = {}) {
259
277
  return out;
260
278
  }
261
279
 
262
- export { EMPHASES, EMPHASIS_FG, EMPHASIS_SLOTS, GRADES, GRADE_SLOTS, GRADE_TOKENS, STANCES, STANCE_SLOTS, expandVars, loadDTCG, parseBoxShadow, resolveStanceSlots, stanceSlotNames, tokenPx };
280
+ export { EMPHASES, EMPHASIS_FG, EMPHASIS_SLOTS, GRADES, GRADE_SLOTS, GRADE_TOKENS, STANCES, STANCE_SLOTS, colorAt, colorCssAt, expandVars, loadDTCG, parseBoxShadow, resolveStanceSlots, stanceSlotNames, tokenPx };
263
281
  //# sourceMappingURL=index.js.map
264
282
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/tokenPx.ts","../src/boxShadow.ts","../src/dtcg/flatten.ts","../src/loadDTCG.ts","../src/appearance.ts","../src/panel.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import { TOKEN_MANIFEST } from './generated/manifest';\nimport type { ResolvedTheme } from './resolveTheme';\nimport type { TokenName } from './generated/themes';\n\nconst DEFAULTS = new Map<string, string>(TOKEN_MANIFEST.map((t) => [t.name, t.defaultValue]));\n\n/**\n * A px-valued token as a number, for code that draws rather than styles —\n * SVG geometry attributes, canvas, WebGL. Pass `resolved` (from\n * `useTheme().resolved`) where a live theme override must reach the drawing;\n * without it the built-in theme's value is used, which is static and costs no\n * style resolution.\n *\n * Throws rather than guessing: a token that is not a plain px length has no\n * number, and silently returning 0 collapses whatever it sized.\n */\nexport function tokenPx(name: TokenName, resolved?: ResolvedTheme): number {\n const raw = resolved?.[name] ?? DEFAULTS.get(name);\n const m = /^(-?\\d*\\.?\\d+)px$/.exec((raw ?? '').trim());\n if (!m) throw new Error(`tokenPx: ${name} is not a px length (${raw ?? 'unknown token'})`);\n return Number(m[1]);\n}\n","import { readCssNumber } from './cssNumber';\n\n/** One layer of a CSS `box-shadow`, lengths in px. */\nexport interface BoxShadow {\n inset: boolean;\n x: number;\n y: number;\n blur: number;\n spread: number;\n /** As written; `currentColor` when the layer names none. */\n color: string;\n}\n\n/** `css` split at each top-level `sep`, ignoring any inside parentheses. */\nfunction splitTop(css: string, sep: RegExp): string[] {\n const out: string[] = [];\n let depth = 0;\n let start = 0;\n for (let i = 0; i < css.length; i++) {\n const ch = css[i]!;\n if (ch === '(') depth++;\n else if (ch === ')') depth--;\n else if (depth === 0 && sep.test(ch)) {\n out.push(css.slice(start, i));\n start = i + 1;\n }\n }\n out.push(css.slice(start));\n return out.map((s) => s.trim()).filter((s) => s !== '');\n}\n\n/** The index of the `)` closing the `(` at `open`, or -1. */\nfunction closing(css: string, open: number): number {\n let depth = 0;\n for (let i = open; i < css.length; i++) {\n if (css[i] === '(') depth++;\n else if (css[i] === ')' && --depth === 0) return i;\n }\n return -1;\n}\n\n/**\n * `value` with every `var(--name)` and `var(--name, fallback)` replaced as a browser would: by\n * `tokens[name]`, expanded in turn, or by the fallback when the theme has no such token. A\n * resolved theme can hold references (a theme's bevel names its bevel colors), and a canvas\n * reading one has no cascade to substitute them. Throws on a reference with neither.\n */\nexport function expandVars(value: string, tokens: Readonly<Record<string, string>>, seen: readonly string[] = []): string {\n let out = '';\n let i = 0;\n for (;;) {\n const at = value.indexOf('var(', i);\n if (at < 0) return out + value.slice(i);\n const end = closing(value, at + 3);\n if (end < 0) throw new Error(`expandVars: unclosed var() in \"${value}\"`);\n const inner = value.slice(at + 4, end);\n const comma = inner.indexOf(',');\n const name = (comma < 0 ? inner : inner.slice(0, comma)).trim();\n const fallback = comma < 0 ? undefined : inner.slice(comma + 1).trim();\n if (seen.includes(name)) throw new Error(`expandVars: ${name} refers to itself`);\n const own = tokens[name];\n const raw = own ?? fallback;\n if (raw === undefined) throw new Error(`expandVars: ${name} is not in the theme and has no fallback`);\n out += value.slice(i, at) + expandVars(raw, tokens, own === undefined ? seen : [...seen, name]);\n i = end + 1;\n }\n}\n\n/** A `box-shadow` value's layers, first (topmost) first; `none` has none. Lengths must be px or a bare 0. */\nexport function parseBoxShadow(value: string): BoxShadow[] {\n if (value.trim() === 'none') return [];\n return splitTop(value, /,/).map((layer) => {\n let inset = false;\n const lengths: number[] = [];\n const color: string[] = [];\n for (const word of splitTop(layer, /\\s/)) {\n if (word === 'inset') { inset = true; continue; }\n const n = readCssNumber(word);\n if (n && (n.unit === 'px' || (n.unit === '' && n.value === 0))) { lengths.push(n.value); continue; }\n if (n) throw new Error(`parseBoxShadow: ${word} is not a px length`);\n color.push(word);\n }\n if (lengths.length < 2 || lengths.length > 4) throw new Error(`parseBoxShadow: cannot read \"${layer}\"`);\n const [x, y, blur = 0, spread = 0] = lengths as [number, number, number?, number?];\n return { inset, x, y, blur, spread, color: color.length ? color.join(' ') : 'currentColor' };\n });\n}\n","import { ALPHA_EXT, type FlatTokens, type RawToken, type TokenValue } from './types';\n\ninterface DtcgToken {\n $value: TokenValue;\n $type?: string;\n $description?: string;\n $extensions?: Record<string, unknown>;\n}\n\nconst isToken = (v: unknown): v is DtcgToken =>\n typeof v === 'object' && v !== null && '$value' in v;\n\n/**\n * Collapse a DTCG document into flat token names.\n *\n * Groups exist only to carry `$type`; they contribute nothing to the name, so\n * `color.fg-muted` becomes `fg-muted` and in turn `--wzl-fg-muted`. This shape\n * is forced by the token set: `--wzl-accent` and `--wzl-accent-base` are both\n * real tokens, and DTCG forbids a token that is also a group.\n */\nexport function flattenTokens(doc: Record<string, unknown>): FlatTokens {\n const out: FlatTokens = {};\n\n for (const [groupName, group] of Object.entries(doc)) {\n if (groupName.startsWith('$')) continue;\n if (typeof group !== 'object' || group === null) continue;\n\n const g = group as Record<string, unknown> & { $type?: string };\n const groupType = g.$type;\n\n for (const [leaf, node] of Object.entries(g)) {\n if (leaf.startsWith('$')) continue;\n if (!isToken(node)) continue;\n\n const type = node.$type ?? groupType;\n if (!type) {\n throw new Error(`Token \"${leaf}\" has no $type and its group \"${groupName}\" declares none`);\n }\n if (leaf in out) {\n throw new Error(`Duplicate token name \"${leaf}\" — leaf keys must be unique across type groups`);\n }\n\n const alphaRaw = node.$extensions?.[ALPHA_EXT];\n const token: RawToken = {\n type,\n value: node.$value,\n alpha: typeof alphaRaw === 'number' ? alphaRaw : undefined,\n description: node.$description,\n };\n out[leaf] = token;\n }\n }\n\n return out;\n}\n","import { isPlainObject } from '@weasel-js/registry';\nimport { mergeAxes, type AxisDef, type AxisDefs, type Selection, type Varying } from './axes';\nimport { AXES_EXT, overrideKey, type DtcgAxesExtension } from './dtcg/axesExtension';\nimport { flattenTokens } from './dtcg/flatten';\nimport type { FlatTokens, RawToken } from './dtcg/types';\nimport { themeAxes } from './resolveTheme';\nimport { weaselTheme, type Theme } from './theme';\n\n/** What `loadDTCG` reads: a `toDTCG` export, or a document shaped like one. */\nexport interface DtcgDocument {\n name?: unknown;\n defaultMode?: unknown;\n extends?: Theme | null;\n primitives?: Record<string, unknown>;\n modes?: Record<string, Record<string, unknown>>;\n $extensions?: Record<string, unknown>;\n}\n\ninterface Layer {\n readonly primitives: FlatTokens;\n readonly modes: Record<string, FlatTokens>;\n}\n\nconst isRecord = isPlainObject;\n\nfunction readLayer(src: { primitives?: unknown; modes?: unknown }): Layer {\n const modes = isRecord(src.modes) ? src.modes : {};\n return {\n primitives: flattenTokens(isRecord(src.primitives) ? src.primitives : {}),\n modes: Object.fromEntries(Object.entries(modes).map(([m, g]) => [m, flattenTokens(isRecord(g) ? g : {})])),\n };\n}\n\nfunction readAxesExtension(raw: unknown): DtcgAxesExtension | undefined {\n if (raw === undefined) return undefined;\n if (!isRecord(raw) || !isRecord(raw.axes)) throw new Error(`DTCG \"$extensions.${AXES_EXT}\" needs an \"axes\" object`);\n return {\n axes: raw.axes as AxisDefs,\n varies: (isRecord(raw.varies) ? raw.varies : {}) as DtcgAxesExtension['varies'],\n overrides: (isRecord(raw.overrides) ? raw.overrides : {}) as DtcgAxesExtension['overrides'],\n };\n}\n\n/**\n * Build a `Theme` from a DTCG document — the interchange path, for tokens\n * exported by a design tool rather than authored in TS. A token a mode leaves\n * out takes the document's primitive of the same name, or else the base theme's.\n * Axes besides mode come from `$extensions[\"com.weasel.axes\"]`, the encoding\n * `toDTCG` writes; a document without it loads with mode as its only axis.\n */\nexport function loadDTCG(doc: DtcgDocument): Theme {\n if (typeof doc.name !== 'string' || doc.name === '') {\n throw new Error('DTCG document needs a string \"name\"');\n }\n const base = doc.extends === undefined ? weaselTheme : doc.extends;\n const ext = readAxesExtension(doc.$extensions?.[AXES_EXT]);\n const plain = readLayer(doc);\n const overrides = Object.fromEntries(Object.entries(ext?.overrides ?? {}).map(([k, l]) => [k, readLayer(l)]));\n const modeNames = [...new Set([plain, ...Object.values(overrides)].flatMap((l) => Object.keys(l.modes)))];\n\n /** A token's value within one layer: varying by mode if any mode names it. */\n const tokenIn = (layer: Layer, name: string): Varying<RawToken> | undefined => {\n if (!modeNames.some((m) => layer.modes[m]?.[name])) return layer.primitives[name];\n const branch: Record<string, unknown> = { by: 'mode' };\n for (const m of modeNames) {\n const t = layer.modes[m]?.[name] ?? layer.primitives[name];\n if (t) branch[m] = t;\n }\n return branch as Varying<RawToken>;\n };\n\n const inherited = base ? themeAxes(base).mode?.default : undefined;\n const defaultMode = typeof doc.defaultMode === 'string' ? doc.defaultMode : (ext?.axes.mode?.default ?? inherited ?? 'dark');\n const modeAxis: AxisDef = {\n default: defaultMode,\n values: Object.fromEntries(modeNames.map((m) => [m, ext?.axes.mode?.values[m] ?? {}])),\n };\n const axes: Record<string, AxisDef> = {};\n for (const [name, def] of Object.entries(ext?.axes ?? { mode: modeAxis })) {\n if (name !== 'mode') axes[name] = def;\n else if (modeNames.length > 0) axes.mode = modeAxis;\n }\n if (modeNames.length > 0) axes.mode ??= modeAxis;\n const all = mergeAxes(base ? themeAxes(base) : {}, axes);\n\n /** Rebuild a token's tree over the axes it varies by, one override layer per leaf. */\n const nest = (name: string, vary: readonly string[], combo: Selection): Varying<RawToken> | undefined => {\n if (vary.length === 0) {\n const key = overrideKey(all, combo);\n const layer = key === '' ? plain : overrides[key];\n return layer && tokenIn(layer, name);\n }\n const [axis, ...rest] = vary;\n const out: Record<string, unknown> = { by: axis };\n let any = false;\n for (const value of Object.keys(all[axis].values)) {\n const v = nest(name, rest, { ...combo, [axis]: value });\n if (v !== undefined) {\n out[value] = v;\n any = true;\n }\n }\n return any ? (out as Varying<RawToken>) : undefined;\n };\n\n const tokens: Record<string, Varying<RawToken>> = {};\n const names = new Set([...Object.keys(plain.primitives), ...modeNames.flatMap((m) => Object.keys(plain.modes[m] ?? {}))]);\n for (const name of Object.keys(ext?.varies ?? {})) names.add(name);\n for (const name of names) {\n const vary = (ext?.varies[name] ?? []).filter((a) => a in all);\n const v = vary.length > 0 ? nest(name, vary, {}) : tokenIn(plain, name);\n if (v !== undefined) tokens[name] = v;\n }\n\n return { name: doc.name, extends: base, axes, tokens };\n}\n","/** The angle a component comes from: who it is for, how it speaks, what an action does. */\nexport const STANCES = ['clarify', 'aside', 'advanced', 'debug', 'preview', 'confirm', 'cancel'] as const;\n/** One stance. */\nexport type Stance = (typeof STANCES)[number];\n\n/** How serious, or how good. The only axis that paints red. */\nexport const GRADES = ['info', 'success', 'warn', 'danger'] as const;\n/** One grade. */\nexport type Grade = (typeof GRADES)[number];\n\n/** The token each grade paints with. */\nexport const GRADE_TOKENS: Readonly<Record<Grade, string>> = {\n info: '--wzl-info',\n success: '--wzl-success',\n warn: '--wzl-warning',\n danger: '--wzl-danger',\n};\n\n/** How loudly a component reads. Unset is normal. */\nexport const EMPHASES = ['high', 'low'] as const;\n/** One emphasis level; unset reads as normal. */\nexport type Emphasis = (typeof EMPHASES)[number];\n\n/** The text color an emphasis lends to everything inside it, as `--wzl-emphasis-fg`. */\nexport const EMPHASIS_FG: Readonly<Record<Emphasis, string>> = {\n high: 'var(--wzl-accent-fg)',\n low: 'var(--wzl-fg-muted)',\n};\n\n/** The surface slots an emphasis repaints, beyond the text color it hands down. */\nexport const EMPHASIS_SLOTS: Readonly<Record<Emphasis, Partial<Record<'border-color' | 'title-color', string>>>> = {\n high: { 'border-color': 'var(--wzl-accent-fg)', 'title-color': 'var(--wzl-accent-fg)' },\n low: { 'title-color': 'var(--wzl-fg-muted)' },\n};\n\n/** The surface slots a grade repaints in its color. */\nexport const GRADE_SLOTS = ['tint', 'border-color', 'title-color'] as const;\n","/**\n * The slots a theme styles a stanced surface with. A stance is the angle a\n * surface comes from, not a class of content.\n *\n * A stance looks the same on every surface that takes one. A surface reads\n * `--wzl-stance-<stance>-<slot>` first — a nested panel\n * `--wzl-stance-<stance>-nested-<slot>` before that — and falls back to its\n * own base look, so a theme declares only the slots where a stance differs and\n * every other name here is read, with its fallback, and declared by nothing.\n * A panel's base look is itself theme slots, `--wzl-panel-<slot>`.\n */\nimport { type Stance, STANCES } from './appearance';\n\n/** One styleable property of a stanced surface. */\nexport interface StanceSlot {\n readonly name: string;\n /** What it drives, for tooling. */\n readonly drives: string;\n}\n\n/** Every slot a theme can set per stance, as `--wzl-stance-<stance>-<slot>`. */\nexport const STANCE_SLOTS: readonly StanceSlot[] = [\n { name: 'surface', drives: 'background' },\n { name: 'border-color', drives: 'border-color' },\n { name: 'border-style', drives: 'border-style' },\n { name: 'border-width', drives: 'border-width' },\n { name: 'radius', drives: 'border-radius' },\n { name: 'pad', drives: 'padding' },\n { name: 'blur', drives: 'backdrop-filter' },\n { name: 'tint-mix', drives: 'how much of the tint mixes into the surface' },\n { name: 'tint', drives: 'the tint a surface takes when it names none' },\n // Only a surface that names its own tint or grade recolors its controls.\n { name: 'accent', drives: 'the accent the controls inside a tinted or graded surface take; unset, the tint' },\n { name: 'title-font', drives: 'font-family' },\n { name: 'title-weight', drives: 'font-weight' },\n { name: 'title-size', drives: 'font-size' },\n { name: 'title-case', drives: 'text-transform' },\n { name: 'title-tracking', drives: 'letter-spacing' },\n { name: 'title-color', drives: 'color' },\n { name: 'title-inset', drives: 'the title’s padding' },\n];\n\n/** Every stance-slot name, `--wzl-`-prefixed, nested variants included. */\nexport function stanceSlotNames(): string[] {\n return STANCES.flatMap((stance) =>\n STANCE_SLOTS.flatMap((slot) => [`--wzl-stance-${stance}-${slot.name}`, `--wzl-stance-${stance}-nested-${slot.name}`]),\n );\n}\n\n/** What `resolveStanceSlots` resolves a surface against, besides its tokens. */\nexport interface StanceLookup<S extends string> {\n readonly stance?: Stance;\n /** The surface sits inside one of its own kind, and reads `-nested-<slot>` first. */\n readonly nested?: boolean;\n /** A stanced surface's fallback, where it differs from `base`. */\n readonly stanced?: Partial<Readonly<Record<S, string>>>;\n}\n\n/**\n * A stanced surface's look, for one drawn without the cascade — a canvas\n * surface reading a resolved theme. The same lookup the generated CSS makes:\n * `--wzl-stance-<stance>-<slot>`, then the stanced fallback, then `base`.\n * `base` holds final values, one per slot the surface draws.\n *\n * The tint is the caller's: a surface that names one mixes it into\n * `surface` at `tint-mix`; one that names none takes the `tint` slot, which\n * falls back to `surface` so mixing it changes nothing.\n */\nexport function resolveStanceSlots<S extends string>(\n tokens: Readonly<Record<string, string>>,\n base: Readonly<Record<S, string>>,\n { stance, nested, stanced }: StanceLookup<S> = {},\n): Record<S, string> {\n const out: Record<S, string> = { ...base };\n if (stance === undefined) return out;\n for (const slot of Object.keys(base) as S[]) {\n const own = tokens[`--wzl-stance-${stance}-${slot}`];\n const inner = nested ? tokens[`--wzl-stance-${stance}-nested-${slot}`] : undefined;\n // A stance's own tint falls back to the surface, never to the surface's base tint.\n const fallback = slot === 'tint' ? (base as Record<string, string>).surface ?? base[slot] : stanced?.[slot] ?? base[slot];\n out[slot] = inner ?? own ?? fallback;\n }\n return out;\n}\n"]}
1
+ {"version":3,"sources":["../src/tokenPx.ts","../src/boxShadow.ts","../src/dtcg/flatten.ts","../src/loadDTCG.ts","../src/colorList.ts","../src/appearance.ts","../src/panel.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import { TOKEN_MANIFEST } from './generated/manifest';\nimport type { ResolvedTheme } from './resolveTheme';\nimport type { TokenName } from './generated/themes';\n\nconst DEFAULTS = new Map<string, string>(TOKEN_MANIFEST.map((t) => [t.name, t.defaultValue]));\n\n/**\n * A px-valued token as a number, for code that draws rather than styles —\n * SVG geometry attributes, canvas, WebGL. Pass `resolved` (from\n * `useTheme().resolved`) where a live theme override must reach the drawing;\n * without it the built-in theme's value is used, which is static and costs no\n * style resolution.\n *\n * Throws rather than guessing: a token that is not a plain px length has no\n * number, and silently returning 0 collapses whatever it sized.\n */\nexport function tokenPx(name: TokenName, resolved?: ResolvedTheme): number {\n const raw = resolved?.[name] ?? DEFAULTS.get(name);\n const m = /^(-?\\d*\\.?\\d+)px$/.exec((raw ?? '').trim());\n if (!m) throw new Error(`tokenPx: ${name} is not a px length (${raw ?? 'unknown token'})`);\n return Number(m[1]);\n}\n","import { readCssNumber } from './cssNumber';\n\n/** One layer of a CSS `box-shadow`, lengths in px. */\nexport interface BoxShadow {\n inset: boolean;\n x: number;\n y: number;\n blur: number;\n spread: number;\n /** As written; `currentColor` when the layer names none. */\n color: string;\n}\n\n/** `css` split at each top-level `sep`, ignoring any inside parentheses. */\nfunction splitTop(css: string, sep: RegExp): string[] {\n const out: string[] = [];\n let depth = 0;\n let start = 0;\n for (let i = 0; i < css.length; i++) {\n const ch = css[i]!;\n if (ch === '(') depth++;\n else if (ch === ')') depth--;\n else if (depth === 0 && sep.test(ch)) {\n out.push(css.slice(start, i));\n start = i + 1;\n }\n }\n out.push(css.slice(start));\n return out.map((s) => s.trim()).filter((s) => s !== '');\n}\n\n/** The index of the `)` closing the `(` at `open`, or -1. */\nfunction closing(css: string, open: number): number {\n let depth = 0;\n for (let i = open; i < css.length; i++) {\n if (css[i] === '(') depth++;\n else if (css[i] === ')' && --depth === 0) return i;\n }\n return -1;\n}\n\n/**\n * `value` with every `var(--name)` and `var(--name, fallback)` replaced as a browser would: by\n * `tokens[name]`, expanded in turn, or by the fallback when the theme has no such token. A\n * resolved theme can hold references (a theme's bevel names its bevel colors), and a canvas\n * reading one has no cascade to substitute them. Throws on a reference with neither.\n */\nexport function expandVars(value: string, tokens: Readonly<Record<string, string>>, seen: readonly string[] = []): string {\n let out = '';\n let i = 0;\n for (;;) {\n const at = value.indexOf('var(', i);\n if (at < 0) return out + value.slice(i);\n const end = closing(value, at + 3);\n if (end < 0) throw new Error(`expandVars: unclosed var() in \"${value}\"`);\n const inner = value.slice(at + 4, end);\n const comma = inner.indexOf(',');\n const name = (comma < 0 ? inner : inner.slice(0, comma)).trim();\n const fallback = comma < 0 ? undefined : inner.slice(comma + 1).trim();\n if (seen.includes(name)) throw new Error(`expandVars: ${name} refers to itself`);\n const own = tokens[name];\n const raw = own ?? fallback;\n if (raw === undefined) throw new Error(`expandVars: ${name} is not in the theme and has no fallback`);\n out += value.slice(i, at) + expandVars(raw, tokens, own === undefined ? seen : [...seen, name]);\n i = end + 1;\n }\n}\n\n/** A `box-shadow` value's layers, first (topmost) first; `none` has none. Lengths must be px or a bare 0. */\nexport function parseBoxShadow(value: string): BoxShadow[] {\n if (value.trim() === 'none') return [];\n return splitTop(value, /,/).map((layer) => {\n let inset = false;\n const lengths: number[] = [];\n const color: string[] = [];\n for (const word of splitTop(layer, /\\s/)) {\n if (word === 'inset') { inset = true; continue; }\n const n = readCssNumber(word);\n if (n && (n.unit === 'px' || (n.unit === '' && n.value === 0))) { lengths.push(n.value); continue; }\n if (n) throw new Error(`parseBoxShadow: ${word} is not a px length`);\n color.push(word);\n }\n if (lengths.length < 2 || lengths.length > 4) throw new Error(`parseBoxShadow: cannot read \"${layer}\"`);\n const [x, y, blur = 0, spread = 0] = lengths as [number, number, number?, number?];\n return { inset, x, y, blur, spread, color: color.length ? color.join(' ') : 'currentColor' };\n });\n}\n","import { ALPHA_EXT, type FlatTokens, type RawToken, type TokenValue } from './types';\n\ninterface DtcgToken {\n $value: TokenValue;\n $type?: string;\n $description?: string;\n $extensions?: Record<string, unknown>;\n}\n\nconst isToken = (v: unknown): v is DtcgToken =>\n typeof v === 'object' && v !== null && '$value' in v;\n\n/**\n * Collapse a DTCG document into flat token names.\n *\n * Groups exist only to carry `$type`; they contribute nothing to the name, so\n * `color.fg-muted` becomes `fg-muted` and in turn `--wzl-fg-muted`. This shape\n * is forced by the token set: `--wzl-accent` and `--wzl-accent-base` are both\n * real tokens, and DTCG forbids a token that is also a group.\n */\nexport function flattenTokens(doc: Record<string, unknown>): FlatTokens {\n const out: FlatTokens = {};\n\n for (const [groupName, group] of Object.entries(doc)) {\n if (groupName.startsWith('$')) continue;\n if (typeof group !== 'object' || group === null) continue;\n\n const g = group as Record<string, unknown> & { $type?: string };\n const groupType = g.$type;\n\n for (const [leaf, node] of Object.entries(g)) {\n if (leaf.startsWith('$')) continue;\n if (!isToken(node)) continue;\n\n const type = node.$type ?? groupType;\n if (!type) {\n throw new Error(`Token \"${leaf}\" has no $type and its group \"${groupName}\" declares none`);\n }\n if (leaf in out) {\n throw new Error(`Duplicate token name \"${leaf}\" — leaf keys must be unique across type groups`);\n }\n\n const alphaRaw = node.$extensions?.[ALPHA_EXT];\n const token: RawToken = {\n type,\n value: node.$value,\n alpha: typeof alphaRaw === 'number' ? alphaRaw : undefined,\n description: node.$description,\n };\n out[leaf] = token;\n }\n }\n\n return out;\n}\n","import { isPlainObject } from '@weasel-js/registry';\nimport { mergeAxes, type AxisDef, type AxisDefs, type Selection, type Varying } from './axes';\nimport { AXES_EXT, overrideKey, type DtcgAxesExtension } from './dtcg/axesExtension';\nimport { flattenTokens } from './dtcg/flatten';\nimport type { FlatTokens, RawToken } from './dtcg/types';\nimport { themeAxes } from './resolveTheme';\nimport { weaselTheme, type Theme } from './theme';\n\n/** What `loadDTCG` reads: a `toDTCG` export, or a document shaped like one. */\nexport interface DtcgDocument {\n name?: unknown;\n defaultMode?: unknown;\n extends?: Theme | null;\n primitives?: Record<string, unknown>;\n modes?: Record<string, Record<string, unknown>>;\n $extensions?: Record<string, unknown>;\n}\n\ninterface Layer {\n readonly primitives: FlatTokens;\n readonly modes: Record<string, FlatTokens>;\n}\n\nconst isRecord = isPlainObject;\n\nfunction readLayer(src: { primitives?: unknown; modes?: unknown }): Layer {\n const modes = isRecord(src.modes) ? src.modes : {};\n return {\n primitives: flattenTokens(isRecord(src.primitives) ? src.primitives : {}),\n modes: Object.fromEntries(Object.entries(modes).map(([m, g]) => [m, flattenTokens(isRecord(g) ? g : {})])),\n };\n}\n\nfunction readAxesExtension(raw: unknown): DtcgAxesExtension | undefined {\n if (raw === undefined) return undefined;\n if (!isRecord(raw) || !isRecord(raw.axes)) throw new Error(`DTCG \"$extensions.${AXES_EXT}\" needs an \"axes\" object`);\n return {\n axes: raw.axes as AxisDefs,\n varies: (isRecord(raw.varies) ? raw.varies : {}) as DtcgAxesExtension['varies'],\n overrides: (isRecord(raw.overrides) ? raw.overrides : {}) as DtcgAxesExtension['overrides'],\n };\n}\n\n/**\n * Build a `Theme` from a DTCG document — the interchange path, for tokens\n * exported by a design tool rather than authored in TS. A token a mode leaves\n * out takes the document's primitive of the same name, or else the base theme's.\n * Axes besides mode come from `$extensions[\"com.weasel.axes\"]`, the encoding\n * `toDTCG` writes; a document without it loads with mode as its only axis.\n */\nexport function loadDTCG(doc: DtcgDocument): Theme {\n if (typeof doc.name !== 'string' || doc.name === '') {\n throw new Error('DTCG document needs a string \"name\"');\n }\n const base = doc.extends === undefined ? weaselTheme : doc.extends;\n const ext = readAxesExtension(doc.$extensions?.[AXES_EXT]);\n const plain = readLayer(doc);\n const overrides = Object.fromEntries(Object.entries(ext?.overrides ?? {}).map(([k, l]) => [k, readLayer(l)]));\n const modeNames = [...new Set([plain, ...Object.values(overrides)].flatMap((l) => Object.keys(l.modes)))];\n\n /** A token's value within one layer: varying by mode if any mode names it. */\n const tokenIn = (layer: Layer, name: string): Varying<RawToken> | undefined => {\n if (!modeNames.some((m) => layer.modes[m]?.[name])) return layer.primitives[name];\n const branch: Record<string, unknown> = { by: 'mode' };\n for (const m of modeNames) {\n const t = layer.modes[m]?.[name] ?? layer.primitives[name];\n if (t) branch[m] = t;\n }\n return branch as Varying<RawToken>;\n };\n\n const inherited = base ? themeAxes(base).mode?.default : undefined;\n const defaultMode = typeof doc.defaultMode === 'string' ? doc.defaultMode : (ext?.axes.mode?.default ?? inherited ?? 'dark');\n const modeAxis: AxisDef = {\n default: defaultMode,\n values: Object.fromEntries(modeNames.map((m) => [m, ext?.axes.mode?.values[m] ?? {}])),\n };\n const axes: Record<string, AxisDef> = {};\n for (const [name, def] of Object.entries(ext?.axes ?? { mode: modeAxis })) {\n if (name !== 'mode') axes[name] = def;\n else if (modeNames.length > 0) axes.mode = modeAxis;\n }\n if (modeNames.length > 0) axes.mode ??= modeAxis;\n const all = mergeAxes(base ? themeAxes(base) : {}, axes);\n\n /** Rebuild a token's tree over the axes it varies by, one override layer per leaf. */\n const nest = (name: string, vary: readonly string[], combo: Selection): Varying<RawToken> | undefined => {\n if (vary.length === 0) {\n const key = overrideKey(all, combo);\n const layer = key === '' ? plain : overrides[key];\n return layer && tokenIn(layer, name);\n }\n const [axis, ...rest] = vary;\n const out: Record<string, unknown> = { by: axis };\n let any = false;\n for (const value of Object.keys(all[axis].values)) {\n const v = nest(name, rest, { ...combo, [axis]: value });\n if (v !== undefined) {\n out[value] = v;\n any = true;\n }\n }\n return any ? (out as Varying<RawToken>) : undefined;\n };\n\n const tokens: Record<string, Varying<RawToken>> = {};\n const names = new Set([...Object.keys(plain.primitives), ...modeNames.flatMap((m) => Object.keys(plain.modes[m] ?? {}))]);\n for (const name of Object.keys(ext?.varies ?? {})) names.add(name);\n for (const name of names) {\n const vary = (ext?.varies[name] ?? []).filter((a) => a in all);\n const v = vary.length > 0 ? nest(name, vary, {}) : tokenIn(plain, name);\n if (v !== undefined) tokens[name] = v;\n }\n\n return { name: doc.name, extends: base, axes, tokens };\n}\n","import { colorLiteralToCss } from '@weasel-js/paint';\nimport { colorItemAt, defaultContext, isRamp, rampProperty, type ColorList, type ColorSourceContext } from './colorListItems.ts';\nimport { colorSourceCss, colorSourceLiteral } from './colorSource.ts';\nimport type { ResolvedTheme } from './resolveTheme.ts';\n\nexport {\n colorCount,\n findRampSteps,\n rampSteps,\n themeTints,\n type ColorContext,\n type ColorList,\n type ColorListItem,\n type GeneratedColors,\n type RampColors,\n type SerializableColorList,\n} from './colorListItems.ts';\n\nfunction answered(css: string | null, i: number): string {\n if (css === null) throw new Error(`colorAt: nothing answers item ${i} of the color list`);\n return css;\n}\n\n/**\n * The `i`th color of `list`, wrapping. A ramp list reads the resolved theme, so\n * the answer follows its mode; a `ColorSource` item resolves against the\n * context's palette, then its theme. Throws on an item nothing answers.\n */\nexport function colorAt(list: ColorList, i: number, ctx: ColorSourceContext = defaultContext()): string {\n if (isRamp(list)) return ctx.resolved[rampProperty(list, i, ctx.theme) as keyof ResolvedTheme];\n const item = colorItemAt(list, i);\n if (typeof item === 'string') return item;\n const literal = colorSourceLiteral(item, ctx);\n return answered(literal && colorLiteralToCss(literal), i);\n}\n\n/**\n * As `colorAt`, but a ramp list, and an item that names the theme, answers\n * with its custom property (`var(--wzl-swatch-sky)`), so a color written into\n * CSS follows a mode change without re-rendering, provider or not.\n */\nexport function colorCssAt(list: ColorList, i: number, ctx: ColorSourceContext = defaultContext()): string {\n if (isRamp(list)) return `var(${rampProperty(list, i, ctx.theme)})`;\n const item = colorItemAt(list, i);\n return typeof item === 'string' ? item : answered(colorSourceCss(item, ctx), i);\n}\n","/** The angle a component comes from: who it is for, how it speaks, what an action does. */\nexport const STANCES = ['clarify', 'aside', 'advanced', 'debug', 'preview', 'confirm', 'cancel'] as const;\n/** One stance. */\nexport type Stance = (typeof STANCES)[number];\n\n/** How serious, or how good. The only axis that paints red. */\nexport const GRADES = ['info', 'success', 'warn', 'danger'] as const;\n/** One grade. */\nexport type Grade = (typeof GRADES)[number];\n\n/** The token each grade paints with. */\nexport const GRADE_TOKENS: Readonly<Record<Grade, string>> = {\n info: '--wzl-info',\n success: '--wzl-success',\n warn: '--wzl-warning',\n danger: '--wzl-danger',\n};\n\n/** How loudly a component reads. Unset is normal. */\nexport const EMPHASES = ['high', 'low'] as const;\n/** One emphasis level; unset reads as normal. */\nexport type Emphasis = (typeof EMPHASES)[number];\n\n/** The text color an emphasis lends to everything inside it, as `--wzl-emphasis-fg`. */\nexport const EMPHASIS_FG: Readonly<Record<Emphasis, string>> = {\n high: 'var(--wzl-accent-fg)',\n low: 'var(--wzl-fg-muted)',\n};\n\n/** The surface slots an emphasis repaints, beyond the text color it hands down. */\nexport const EMPHASIS_SLOTS: Readonly<Record<Emphasis, Partial<Record<'border-color' | 'title-color', string>>>> = {\n high: { 'border-color': 'var(--wzl-accent-fg)', 'title-color': 'var(--wzl-accent-fg)' },\n low: { 'title-color': 'var(--wzl-fg-muted)' },\n};\n\n/** The surface slots a grade repaints in its color. */\nexport const GRADE_SLOTS = ['tint', 'border-color', 'title-color'] as const;\n","/**\n * The slots a theme styles a stanced surface with. A stance is the angle a\n * surface comes from, not a class of content.\n *\n * A stance looks the same on every surface that takes one. A surface reads\n * `--wzl-stance-<stance>-<slot>` first — a nested panel\n * `--wzl-stance-<stance>-nested-<slot>` before that — and falls back to its\n * own base look, so a theme declares only the slots where a stance differs and\n * every other name here is read, with its fallback, and declared by nothing.\n * A panel's base look is itself theme slots, `--wzl-panel-<slot>`.\n */\nimport { type Stance, STANCES } from './appearance';\n\n/** One styleable property of a stanced surface. */\nexport interface StanceSlot {\n readonly name: string;\n /** What it drives, for tooling. */\n readonly drives: string;\n}\n\n/** Every slot a theme can set per stance, as `--wzl-stance-<stance>-<slot>`. */\nexport const STANCE_SLOTS: readonly StanceSlot[] = [\n { name: 'surface', drives: 'background' },\n { name: 'border-color', drives: 'border-color' },\n { name: 'border-style', drives: 'border-style' },\n { name: 'border-width', drives: 'border-width' },\n { name: 'radius', drives: 'border-radius' },\n { name: 'pad', drives: 'padding' },\n { name: 'blur', drives: 'backdrop-filter' },\n { name: 'tint-mix', drives: 'how much of the tint mixes into the surface' },\n { name: 'tint', drives: 'the tint a surface takes when it names none' },\n // Only a surface that names its own tint or grade recolors its controls.\n { name: 'accent', drives: 'the accent the controls inside a tinted or graded surface take; unset, the tint' },\n { name: 'title-font', drives: 'font-family' },\n { name: 'title-weight', drives: 'font-weight' },\n { name: 'title-size', drives: 'font-size' },\n { name: 'title-case', drives: 'text-transform' },\n { name: 'title-tracking', drives: 'letter-spacing' },\n { name: 'title-color', drives: 'color' },\n { name: 'title-inset', drives: 'the title’s padding' },\n];\n\n/** Every stance-slot name, `--wzl-`-prefixed, nested variants included. */\nexport function stanceSlotNames(): string[] {\n return STANCES.flatMap((stance) =>\n STANCE_SLOTS.flatMap((slot) => [`--wzl-stance-${stance}-${slot.name}`, `--wzl-stance-${stance}-nested-${slot.name}`]),\n );\n}\n\n/** What `resolveStanceSlots` resolves a surface against, besides its tokens. */\nexport interface StanceLookup<S extends string> {\n readonly stance?: Stance;\n /** The surface sits inside one of its own kind, and reads `-nested-<slot>` first. */\n readonly nested?: boolean;\n /** A stanced surface's fallback, where it differs from `base`. */\n readonly stanced?: Partial<Readonly<Record<S, string>>>;\n}\n\n/**\n * A stanced surface's look, for one drawn without the cascade — a canvas\n * surface reading a resolved theme. The same lookup the generated CSS makes:\n * `--wzl-stance-<stance>-<slot>`, then the stanced fallback, then `base`.\n * `base` holds final values, one per slot the surface draws.\n *\n * The tint is the caller's: a surface that names one mixes it into\n * `surface` at `tint-mix`; one that names none takes the `tint` slot, which\n * falls back to `surface` so mixing it changes nothing.\n */\nexport function resolveStanceSlots<S extends string>(\n tokens: Readonly<Record<string, string>>,\n base: Readonly<Record<S, string>>,\n { stance, nested, stanced }: StanceLookup<S> = {},\n): Record<S, string> {\n const out: Record<S, string> = { ...base };\n if (stance === undefined) return out;\n for (const slot of Object.keys(base) as S[]) {\n const own = tokens[`--wzl-stance-${stance}-${slot}`];\n const inner = nested ? tokens[`--wzl-stance-${stance}-nested-${slot}`] : undefined;\n // A stance's own tint falls back to the surface, never to the surface's base tint.\n const fallback = slot === 'tint' ? (base as Record<string, string>).surface ?? base[slot] : stanced?.[slot] ?? base[slot];\n out[slot] = inner ?? own ?? fallback;\n }\n return out;\n}\n"]}
package/dist/prefs.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { PrefGroup, PrefLocus } from '@weasel-js/prefs';
2
- import { a as Theme, V as Varying, e as PinValue, S as Selection } from './definition-nZbgRG7A.js';
1
+ import { PrefGroup, PrefScope } from '@weasel-js/prefs';
2
+ import { a as Theme, V as Varying, e as PinValue, S as Selection } from './definition-DfbYMDu0.js';
3
3
  import '@weasel-js/paint';
4
4
 
5
5
  /** The key of the group a theme's axes are chosen in: `axis.mode` is the leaf holding the mode. */
@@ -17,7 +17,7 @@ declare const themeTokenOf: (path: string) => string;
17
17
  * without its group's prefix: a
18
18
  * `color`, a `number` in the token's unit, or a `string` of CSS text for what
19
19
  * neither holds. A leaf is at `<group>.<token>`, the token named without
20
- * `--wzl-`, and may be split by every axis.
20
+ * `--wzl-`, and is scoped by the axes its value differs along.
21
21
  *
22
22
  * A leaf's default is what the theme resolves the token to, already split
23
23
  * along the axes it differs by, so a store nothing was written to reads the
@@ -42,7 +42,7 @@ declare function themePrefsReferences(schema: PrefGroup): (css: unknown) => Them
42
42
  interface ThemePrefsSource {
43
43
  schema: PrefGroup;
44
44
  get(path: string): unknown;
45
- locus(path: string): PrefLocus | undefined;
45
+ scope(path: string): PrefScope | undefined;
46
46
  isSet(path: string): boolean;
47
47
  }
48
48
  /** The value of each axis as the store has it set: the selection to resolve or apply its theme at. */
@@ -60,17 +60,17 @@ declare function themeFromPrefs(store: ThemePrefsSource, base: Theme, name?: str
60
60
  /** What {@link themePrefsValues} reads beside the pins. */
61
61
  interface ThemePrefsValuesSource extends ThemePrefsSource {
62
62
  values(): Record<string, unknown>;
63
- loci(): ReadonlyMap<string, PrefLocus>;
63
+ scopes(): ReadonlyMap<string, PrefScope>;
64
64
  }
65
65
  /**
66
- * The store's values and loci as a form shows them, with every leaf that
66
+ * The store's values and scopes as a form shows them, with every leaf that
67
67
  * follows its default read from the pinned theme, where the store reads it
68
68
  * from `base`. They differ for an alias of a token that was pinned: `accent`
69
- * after `accent-base` is set. Shaped as `store.values()` and `store.loci()`.
69
+ * after `accent-base` is set. Shaped as `store.values()` and `store.scopes()`.
70
70
  */
71
71
  declare function themePrefsValues(store: ThemePrefsValuesSource, base: Theme): {
72
72
  values: Record<string, unknown>;
73
- loci: ReadonlyMap<string, PrefLocus>;
73
+ scopes: ReadonlyMap<string, PrefScope>;
74
74
  };
75
75
 
76
76
  export { THEME_PREFS_AXIS, type ThemePrefsReference, type ThemePrefsSource, type ThemePrefsValuesSource, themeAxisOf, themeAxisPath, themeFromPrefs, themePrefsPins, themePrefsReferences, themePrefsSchema, themePrefsSelection, themePrefsValues, themeTokenOf };
package/dist/prefs.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import { TOKEN_MANIFEST } from './chunk-4PFMGV3U.js';
2
2
  import { readCssNumber } from './chunk-M3R5MV7Q.js';
3
3
  import { themeAxes, resolveTheme, themeChain } from './chunk-UCQC6GZR.js';
4
- import { weaselTheme, defineTheme } from './chunk-NCAQ54LO.js';
4
+ import { weaselTheme, defineTheme } from './chunk-X2KI4SSJ.js';
5
5
  import { selectionKey, enumerateSelections, isByAxis } from './chunk-P5F3GZV6.js';
6
- import { prefLeaves, isPrefLocus } from '@weasel-js/prefs';
6
+ import { prefLeaves, isPrefScope, prefScopeSelectors } from '@weasel-js/prefs';
7
7
  import { rgbaToHex, parseColor } from '@weasel-js/paint';
8
8
 
9
9
  var NUMERIC_TYPES = /* @__PURE__ */ new Set(["dimension", "number", "duration", "fontWeight"]);
@@ -52,7 +52,8 @@ function declared(theme) {
52
52
  const had = out.get(name);
53
53
  out.set(name, {
54
54
  type: had?.type ?? (token?.type !== "unknown" ? token?.type : void 0),
55
- description: had?.description || token?.description || ""
55
+ description: had?.description || token?.description || "",
56
+ scope: [.../* @__PURE__ */ new Set([...had?.scope ?? [], ...token?.scope ?? []])]
56
57
  });
57
58
  }
58
59
  }
@@ -80,7 +81,8 @@ function tokenTable(theme) {
80
81
  type: said?.type ?? listed?.type ?? "string",
81
82
  group: listed?.group ?? groupOf(name),
82
83
  description: said?.description || listed?.description || "",
83
- css
84
+ css,
85
+ ...said?.scope.length ? { scope: said.scope } : {}
84
86
  });
85
87
  }
86
88
  for (const [name, listed] of MANIFEST) {
@@ -109,22 +111,24 @@ var themeAxisOf = (path) => path.startsWith(`${THEME_PREFS_AXIS}.`) ? path.slice
109
111
  var themeTokenOf = (path) => path.slice(path.indexOf(".") + 1);
110
112
  var labeled = (text) => text === "" ? text : text[0].toUpperCase() + text.slice(1);
111
113
  var groupKey = (group) => group === THEME_PREFS_AXIS ? `${THEME_PREFS_AXIS}-tokens` : group;
112
- var locusByAxis = (axis, members) => ({ $by: themeAxisPath(axis), $of: members });
114
+ var scopeByAxis = (axis, members) => ({ $by: themeAxisPath(axis), $in: members });
113
115
  var shortName = (row) => row.name.startsWith(`${row.group}-`) ? row.name.slice(row.group.length + 1) : row.name;
114
- function tokenLeaf(row, table, splitBy) {
116
+ function tokenLeaf(row, table) {
115
117
  const name = shortName(row);
116
118
  const leaf = {
117
119
  ...tokenLeafKind(row),
118
120
  name,
119
121
  description: row.description,
120
122
  default: void 0,
121
- splitBy,
122
123
  ...name === row.name ? {} : { tags: [row.name] }
123
124
  };
124
125
  const fallback = row.css[selectionKey(table.axes, {})] ?? Object.values(row.css)[0];
125
- const held = foldAxes(table.axes, (selection) => prefOfCss(leaf, row.css[selectionKey(table.axes, selection)] ?? fallback), locusByAxis);
126
+ const held = foldAxes(table.axes, (selection) => prefOfCss(leaf, row.css[selectionKey(table.axes, selection)] ?? fallback), scopeByAxis);
126
127
  leaf.default = prefOfCss(leaf, fallback);
127
- if (isPrefLocus(held)) leaf.defaultLocus = held;
128
+ const differs = prefScopeSelectors(held);
129
+ const scopes = Object.keys(table.axes).filter((axis) => differs.has(themeAxisPath(axis)) || row.scope?.includes(axis)).map((axis) => ({ selector: themeAxisPath(axis) }));
130
+ if (scopes.length > 0) leaf.scopes = scopes;
131
+ if (isPrefScope(held)) leaf.defaultScope = held;
128
132
  return leaf;
129
133
  }
130
134
  function themePrefsSchema(theme = weaselTheme) {
@@ -139,12 +143,11 @@ function themePrefsSchema(theme = weaselTheme) {
139
143
  options: Object.keys(def.values).map((value) => ({ value, label: labeled(value) }))
140
144
  };
141
145
  }
142
- const splitBy = Object.keys(table.axes).map(themeAxisPath);
143
146
  const children = { [THEME_PREFS_AXIS]: { name: "Axes", children: axes } };
144
147
  for (const row of table.rows) {
145
148
  const key = groupKey(row.group);
146
149
  children[key] ??= { name: labeled(row.group), children: {} };
147
- children[key].children[row.name] = tokenLeaf(row, table, splitBy);
150
+ children[key].children[row.name] = tokenLeaf(row, table);
148
151
  }
149
152
  return { name: `${labeled(theme.name)} theme`, children };
150
153
  }
@@ -160,9 +163,9 @@ function themePrefsReferences(schema) {
160
163
  };
161
164
  }
162
165
  function pinOf(leaf, held) {
163
- if (!isPrefLocus(held)) return cssOfPref(leaf, held);
166
+ if (!isPrefScope(held)) return cssOfPref(leaf, held);
164
167
  const out = { by: themeAxisOf(held.$by) ?? held.$by };
165
- for (const [value, member] of Object.entries(held.$of)) out[value] = pinOf(leaf, member);
168
+ for (const [value, member] of Object.entries(held.$in)) out[value] = pinOf(leaf, member);
166
169
  return out;
167
170
  }
168
171
  function themePrefsSelection(store) {
@@ -177,7 +180,7 @@ function themePrefsPins(store) {
177
180
  const out = {};
178
181
  for (const [path, leaf] of prefLeaves(store.schema)) {
179
182
  if (themeAxisOf(path) !== void 0 || !store.isSet(path)) continue;
180
- out[themeTokenOf(path)] = pinOf(leaf, store.locus(path) ?? store.get(path));
183
+ out[themeTokenOf(path)] = pinOf(leaf, store.scope(path) ?? store.get(path));
181
184
  }
182
185
  return out;
183
186
  }
@@ -189,15 +192,15 @@ function themePrefsValues(store, base) {
189
192
  const css = new Map(rows.map((row) => [row.name, row.css]));
190
193
  const now = selectionKey(axes, themePrefsSelection(store));
191
194
  const values = { ...store.values() };
192
- const loci = new Map(store.loci());
195
+ const scopes = new Map(store.scopes());
193
196
  const copied = /* @__PURE__ */ new Set();
194
197
  for (const [path, leaf] of prefLeaves(store.schema)) {
195
198
  if (themeAxisOf(path) !== void 0 || store.isSet(path)) continue;
196
199
  const resolved = css.get(themeTokenOf(path));
197
200
  if (!resolved || Object.values(resolved).some((text) => prefOfCss(leaf, text) === void 0)) continue;
198
- const held = foldAxes(axes, (selection) => prefOfCss(leaf, resolved[selectionKey(axes, selection)]), locusByAxis);
199
- if (isPrefLocus(held)) loci.set(path, held);
200
- else loci.delete(path);
201
+ const held = foldAxes(axes, (selection) => prefOfCss(leaf, resolved[selectionKey(axes, selection)]), scopeByAxis);
202
+ if (isPrefScope(held)) scopes.set(path, held);
203
+ else scopes.delete(path);
201
204
  const group = path.slice(0, path.indexOf("."));
202
205
  if (!copied.has(group)) {
203
206
  copied.add(group);
@@ -205,7 +208,7 @@ function themePrefsValues(store, base) {
205
208
  }
206
209
  values[group][themeTokenOf(path)] = prefOfCss(leaf, resolved[now]);
207
210
  }
208
- return { values, loci };
211
+ return { values, scopes };
209
212
  }
210
213
 
211
214
  export { THEME_PREFS_AXIS, themeAxisOf, themeAxisPath, themeFromPrefs, themePrefsPins, themePrefsReferences, themePrefsSchema, themePrefsSelection, themePrefsValues, themeTokenOf };
package/dist/prefs.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/prefs/leaf.ts","../src/prefs/tokens.ts","../src/prefs/schema.ts","../src/prefs/pins.ts"],"names":["isPrefLocus","prefLeaves"],"mappings":"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","file":"prefs.js","sourcesContent":["// A token as a pref leaf: which kind edits it, and its CSS text to the leaf's value and back.\n\nimport { parseColor, rgbaToHex } from '@weasel-js/paint';\nimport type { PrefLeaf, PrefLinearUnit, PrefNumber } from '@weasel-js/prefs';\nimport { readCssNumber } from '../cssNumber.ts';\nimport type { TokenRow } from './tokens.ts';\n\nconst NUMERIC_TYPES: ReadonlySet<string> = new Set(['dimension', 'number', 'duration', 'fontWeight']);\n\nfunction hexOf(css: string): string | undefined {\n try {\n return rgbaToHex(parseColor(css));\n } catch {\n return undefined;\n }\n}\n\n/**\n * The leaf that edits `row`, less its default: a `color` where every value it\n * resolves to is a color this kit can parse, a `number` in the unit they share\n * where every one is a number, and otherwise a `string` holding the CSS text,\n * which is what a `var()`, a `calc()`, a font stack, or a shadow is edited as.\n */\nexport function tokenLeafKind(row: TokenRow): Pick<PrefNumber, 'kind' | 'unit'> | { kind: 'color'; alpha: true } | { kind: 'string' } {\n const values = Object.values(row.css);\n if (row.type === 'color' && values.every((css) => hexOf(css) !== undefined)) return { kind: 'color', alpha: true };\n if (NUMERIC_TYPES.has(row.type)) {\n const read = values.map(readCssNumber);\n const unit = read[0]?.unit;\n if (read.every((r) => r !== undefined && r.unit === unit)) {\n return unit ? { kind: 'number', unit: { scale: 1, suffix: unit } } : { kind: 'number' };\n }\n }\n return { kind: 'string' };\n}\n\nconst suffixOf = (leaf: PrefLeaf): string => ((leaf as PrefNumber).unit as PrefLinearUnit | undefined)?.suffix ?? '';\n\n/** What `css` reads as on `leaf`, or `undefined` for text its kind cannot hold. */\nexport function prefOfCss(leaf: PrefLeaf, css: string | undefined): unknown {\n if (css === undefined) return undefined;\n if (leaf.kind === 'color') return hexOf(css);\n if (leaf.kind !== 'number') return css;\n const read = readCssNumber(css);\n return read && read.unit === suffixOf(leaf) ? read.value : undefined;\n}\n\n/** The CSS text of a value `leaf` holds. */\nexport function cssOfPref(leaf: PrefLeaf, value: unknown): string {\n return leaf.kind === 'number' ? `${value as number}${suffixOf(leaf)}` : String(value);\n}\n","// Every token of a theme as the prefs bridge reads it: what it is, and the CSS it resolves to at each selection.\n\nimport { enumerateSelections, isByAxis, selectionKey, type AxisDefs, type Selection } from '../axes.ts';\nimport { TOKEN_MANIFEST, type TokenManifestEntry } from '../generated/manifest.ts';\nimport { resolveTheme, themeAxes, themeChain } from '../resolveTheme.ts';\nimport type { Theme } from '../theme.ts';\n\nconst PREFIX = '--wzl-';\n\n/** One token of a theme, named without `--wzl-`. */\nexport interface TokenRow {\n readonly name: string;\n readonly type: string;\n readonly group: string;\n readonly description: string;\n /** The CSS it resolves to, by `selectionKey`. */\n readonly css: Readonly<Record<string, string>>;\n}\n\n/** A theme's tokens and the axes they were resolved along. */\nexport interface TokenTable {\n readonly axes: AxisDefs;\n readonly rows: readonly TokenRow[];\n}\n\nconst MANIFEST = new Map<string, TokenManifestEntry>(TOKEN_MANIFEST.map((entry) => [entry.name.slice(PREFIX.length), entry]));\n\nconst groupOf = (name: string): string => (name.includes('-') ? name.slice(0, name.indexOf('-')) : name);\n\n/** The type and description each token was first declared with, root theme first. A pin's type is `unknown`. */\nfunction declared(theme: Theme): Map<string, { type: string | undefined; description: string }> {\n const out = new Map<string, { type: string | undefined; description: string }>();\n for (const link of themeChain(theme)) {\n for (const [name, varying] of Object.entries(link.tokens)) {\n let raw: unknown = varying;\n while (isByAxis(raw)) raw = Object.entries(raw).find(([key]) => key !== 'by')?.[1];\n const token = raw as { type?: string; description?: string } | undefined;\n const had = out.get(name);\n out.set(name, {\n type: had?.type ?? (token?.type !== 'unknown' ? token?.type : undefined),\n description: had?.description || token?.description || '',\n });\n }\n }\n return out;\n}\n\n/**\n * Every token `theme` resolves, then every override hook it leaves alone, each\n * with its CSS at every selection of the theme's axes. A hook reads as its\n * fallback at all of them.\n */\nexport function tokenTable(theme: Theme): TokenTable {\n const axes = themeAxes(theme);\n const resolved = enumerateSelections(axes).map(\n (selection): [string, Record<string, string>] => [selectionKey(axes, selection), resolveTheme(theme, selection)],\n );\n const own = declared(theme);\n const names = new Set<string>();\n for (const [, tokens] of resolved) for (const name of Object.keys(tokens)) names.add(name.slice(PREFIX.length));\n\n const rows: TokenRow[] = [];\n for (const name of names) {\n const listed = MANIFEST.get(name);\n const said = own.get(name);\n const css: Record<string, string> = {};\n for (const [key, tokens] of resolved) {\n const value = tokens[PREFIX + name];\n if (value !== undefined) css[key] = value;\n }\n rows.push({\n name,\n type: said?.type ?? listed?.type ?? 'string',\n group: listed?.group ?? groupOf(name),\n description: said?.description || listed?.description || '',\n css,\n });\n }\n for (const [name, listed] of MANIFEST) {\n if (!listed.hook || names.has(name)) continue;\n const css = Object.fromEntries(resolved.map(([key]) => [key, listed.defaultValue]));\n rows.push({ name, type: listed.type, group: listed.group, description: listed.description, css });\n }\n return { axes, rows };\n}\n\n/**\n * `at(selection)` over every selection of `axes`, as a value split only by\n * the axes it differs along, the first axis outermost. `split` builds one\n * level from an axis and what each of its values holds.\n */\nexport function foldAxes(\n axes: AxisDefs,\n at: (selection: Selection) => unknown,\n split: (axis: string, members: Record<string, unknown>) => unknown,\n): unknown {\n const names = Object.keys(axes);\n const walk = (i: number, selection: Selection): unknown => {\n if (i === names.length) return at(selection);\n const axis = names[i]!;\n const members = Object.keys(axes[axis]!.values).map((value): [string, unknown] => [value, walk(i + 1, { ...selection, [axis]: value })]);\n const first = JSON.stringify(members[0]![1]);\n return members.every(([, member]) => JSON.stringify(member) === first) ? members[0]![1] : split(axis, Object.fromEntries(members));\n };\n return walk(0, {});\n}\n","import { isPrefLocus, prefLeaves, type PrefGroup, type PrefLeaf, type PrefLocus } from '@weasel-js/prefs';\nimport { selectionKey } from '../axes.ts';\nimport { weaselTheme, type Theme } from '../theme.ts';\nimport { prefOfCss, tokenLeafKind } from './leaf.ts';\nimport { foldAxes, tokenTable, type TokenRow } from './tokens.ts';\n\n/** The key of the group a theme's axes are chosen in: `axis.mode` is the leaf holding the mode. */\nexport const THEME_PREFS_AXIS = 'axis';\n\n/** The path of the leaf that holds `axis`'s value. */\nexport const themeAxisPath = (axis: string): string => `${THEME_PREFS_AXIS}.${axis}`;\n\n/** The axis a leaf at `path` holds the value of, or `undefined` for a token's leaf. */\nexport const themeAxisOf = (path: string): string | undefined =>\n (path.startsWith(`${THEME_PREFS_AXIS}.`) ? path.slice(THEME_PREFS_AXIS.length + 1) : undefined);\n\n/** The token a leaf at `path` edits, named without `--wzl-`. */\nexport const themeTokenOf = (path: string): string => path.slice(path.indexOf('.') + 1);\n\nconst labeled = (text: string): string => (text === '' ? text : text[0]!.toUpperCase() + text.slice(1));\n\n// A token group named for the axes' own key takes another; no group's name holds a `-`.\nconst groupKey = (group: string): string => (group === THEME_PREFS_AXIS ? `${THEME_PREFS_AXIS}-tokens` : group);\n\n/** The locus of a value that differs along `axes`, each level keyed by its axis's leaf. */\nexport const locusByAxis = (axis: string, members: Record<string, unknown>): PrefLocus => ({ $by: themeAxisPath(axis), $of: members });\n\n// On its group's page a token's group prefix says nothing; its whole name stays a tag, so a filter still finds it.\nconst shortName = (row: TokenRow): string => (row.name.startsWith(`${row.group}-`) ? row.name.slice(row.group.length + 1) : row.name);\n\nfunction tokenLeaf(row: TokenRow, table: ReturnType<typeof tokenTable>, splitBy: readonly string[]): PrefLeaf {\n const name = shortName(row);\n const leaf = {\n ...tokenLeafKind(row), name, description: row.description, default: undefined as unknown, splitBy,\n ...(name === row.name ? {} : { tags: [row.name] }),\n } as PrefLeaf;\n const fallback = row.css[selectionKey(table.axes, {})] ?? Object.values(row.css)[0];\n const held = foldAxes(table.axes, (selection) => prefOfCss(leaf, row.css[selectionKey(table.axes, selection)] ?? fallback), locusByAxis);\n leaf.default = prefOfCss(leaf, fallback);\n if (isPrefLocus(held)) leaf.defaultLocus = held;\n return leaf;\n}\n\n/**\n * `theme` as a preferences schema. Under `axis`, an `enum` for each of the\n * theme's axes, set to its default. Then a page for each token group, holding\n * a leaf for every token the theme resolves and every override hook, named\n * without its group's prefix: a\n * `color`, a `number` in the token's unit, or a `string` of CSS text for what\n * neither holds. A leaf is at `<group>.<token>`, the token named without\n * `--wzl-`, and may be split by every axis.\n *\n * A leaf's default is what the theme resolves the token to, already split\n * along the axes it differs by, so a store nothing was written to reads the\n * theme as it is. {@link themeFromPrefs} turns what was written into a theme.\n */\nexport function themePrefsSchema(theme: Theme = weaselTheme): PrefGroup {\n const table = tokenTable(theme);\n const axes: Record<string, PrefLeaf> = {};\n for (const [axis, def] of Object.entries(table.axes)) {\n axes[axis] = {\n kind: 'enum',\n name: labeled(axis),\n description: '',\n default: def.default,\n options: Object.keys(def.values).map((value) => ({ value, label: labeled(value) })),\n };\n }\n const splitBy = Object.keys(table.axes).map(themeAxisPath);\n const children: Record<string, PrefGroup> = { [THEME_PREFS_AXIS]: { name: 'Axes', children: axes } };\n for (const row of table.rows) {\n const key = groupKey(row.group);\n children[key] ??= { name: labeled(row.group), children: {} };\n children[key].children[row.name] = tokenLeaf(row, table, splitBy);\n }\n return { name: `${labeled(theme.name)} theme`, children };\n}\n\n/** What a token's CSS refers to, as {@link themePrefsReferences} reads it. */\nexport interface ThemePrefsReference {\n /** The custom property referred to, `--` and all. */\n readonly property: string;\n /** The path of the leaf that edits it, where it is one of the schema's tokens. */\n readonly path?: string;\n}\n\nconst WHOLE_VAR = /^\\s*var\\(\\s*(--[\\w-]+)\\s*\\)\\s*$/;\n\n/**\n * Reads a token's CSS as a reference to another custom property where the whole of it is one `var()` with no\n * fallback, and finds the leaf of `schema` that edits that property. Anything else, a `calc()` or a shadow that\n * holds a `var()` among other text included, reads as no reference.\n */\nexport function themePrefsReferences(schema: PrefGroup): (css: unknown) => ThemePrefsReference | undefined {\n const paths = new Map<string, string>();\n for (const path of prefLeaves(schema).keys()) if (themeAxisOf(path) === undefined) paths.set(`--wzl-${themeTokenOf(path)}`, path);\n return (css) => {\n const property = typeof css === 'string' ? WHOLE_VAR.exec(css)?.[1] : undefined;\n if (property === undefined) return undefined;\n const path = paths.get(property);\n return path === undefined ? { property } : { property, path };\n };\n}\n","import { isPrefLocus, prefLeaves, type PrefGroup, type PrefLeaf, type PrefLocus } from '@weasel-js/prefs';\nimport { selectionKey, type Selection, type Varying } from '../axes.ts';\nimport type { PinValue } from '../definition.ts';\nimport { defineTheme, type Theme } from '../theme.ts';\nimport { cssOfPref, prefOfCss } from './leaf.ts';\nimport { locusByAxis, themeAxisOf, themeTokenOf } from './schema.ts';\nimport { foldAxes, tokenTable } from './tokens.ts';\n\n/** What the bridge reads of a store over a {@link themePrefsSchema}: any `PrefsStore` is one. */\nexport interface ThemePrefsSource {\n schema: PrefGroup;\n get(path: string): unknown;\n locus(path: string): PrefLocus | undefined;\n isSet(path: string): boolean;\n}\n\nfunction pinOf(leaf: PrefLeaf, held: unknown): Varying<PinValue> {\n if (!isPrefLocus(held)) return cssOfPref(leaf, held);\n const out: Record<string, unknown> = { by: themeAxisOf(held.$by) ?? held.$by };\n for (const [value, member] of Object.entries(held.$of)) out[value] = pinOf(leaf, member);\n return out as Varying<PinValue>;\n}\n\n/** The value of each axis as the store has it set: the selection to resolve or apply its theme at. */\nexport function themePrefsSelection(store: ThemePrefsSource): Selection {\n const out: Record<string, string> = {};\n for (const path of prefLeaves(store.schema).keys()) {\n const axis = themeAxisOf(path);\n if (axis !== undefined) out[axis] = store.get(path) as string;\n }\n return out;\n}\n\n/**\n * Every token leaf the store has a value of its own for, as `pins` for a\n * `ThemeDefinition`: a split value in theme's `{ by, … }` form, a color as\n * hex, a number in its unit, and a string as it is held. A leaf following its\n * default is no pin, so the token keeps its rule in the theme the pins go\n * over: an alias left alone still follows a primitive that was pinned.\n */\nexport function themePrefsPins(store: ThemePrefsSource): Record<string, Varying<PinValue>> {\n const out: Record<string, Varying<PinValue>> = {};\n for (const [path, leaf] of prefLeaves(store.schema)) {\n if (themeAxisOf(path) !== undefined || !store.isSet(path)) continue;\n out[themeTokenOf(path)] = pinOf(leaf, store.locus(path) ?? store.get(path));\n }\n return out;\n}\n\n/** `base` with the store's pins over it. `name` defaults to `base`'s with `-prefs` after it. */\nexport function themeFromPrefs(store: ThemePrefsSource, base: Theme, name = `${base.name}-prefs`): Theme {\n return defineTheme({ name, extends: base, pins: themePrefsPins(store) });\n}\n\n/** What {@link themePrefsValues} reads beside the pins. */\nexport interface ThemePrefsValuesSource extends ThemePrefsSource {\n values(): Record<string, unknown>;\n loci(): ReadonlyMap<string, PrefLocus>;\n}\n\n/**\n * The store's values and loci as a form shows them, with every leaf that\n * follows its default read from the pinned theme, where the store reads it\n * from `base`. They differ for an alias of a token that was pinned: `accent`\n * after `accent-base` is set. Shaped as `store.values()` and `store.loci()`.\n */\nexport function themePrefsValues(\n store: ThemePrefsValuesSource,\n base: Theme,\n): { values: Record<string, unknown>; loci: ReadonlyMap<string, PrefLocus> } {\n const { axes, rows } = tokenTable(themeFromPrefs(store, base));\n const css = new Map(rows.map((row) => [row.name, row.css]));\n const now = selectionKey(axes, themePrefsSelection(store));\n const values: Record<string, unknown> = { ...store.values() };\n const loci = new Map(store.loci());\n const copied = new Set<string>();\n for (const [path, leaf] of prefLeaves(store.schema)) {\n if (themeAxisOf(path) !== undefined || store.isSet(path)) continue;\n const resolved = css.get(themeTokenOf(path));\n if (!resolved || Object.values(resolved).some((text) => prefOfCss(leaf, text) === undefined)) continue;\n const held = foldAxes(axes, (selection) => prefOfCss(leaf, resolved[selectionKey(axes, selection)]), locusByAxis);\n if (isPrefLocus(held)) loci.set(path, held);\n else loci.delete(path);\n const group = path.slice(0, path.indexOf('.'));\n if (!copied.has(group)) {\n copied.add(group);\n values[group] = { ...(values[group] as Record<string, unknown>) };\n }\n (values[group] as Record<string, unknown>)[themeTokenOf(path)] = prefOfCss(leaf, resolved[now]);\n }\n return { values, loci };\n}\n"]}
1
+ {"version":3,"sources":["../src/prefs/leaf.ts","../src/prefs/tokens.ts","../src/prefs/schema.ts","../src/prefs/pins.ts"],"names":["isPrefScope","prefLeaves"],"mappings":"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","file":"prefs.js","sourcesContent":["// A token as a pref leaf: which kind edits it, and its CSS text to the leaf's value and back.\n\nimport { parseColor, rgbaToHex } from '@weasel-js/paint';\nimport type { PrefLeaf, PrefLinearUnit, PrefNumber } from '@weasel-js/prefs';\nimport { readCssNumber } from '../cssNumber.ts';\nimport type { TokenRow } from './tokens.ts';\n\nconst NUMERIC_TYPES: ReadonlySet<string> = new Set(['dimension', 'number', 'duration', 'fontWeight']);\n\nfunction hexOf(css: string): string | undefined {\n try {\n return rgbaToHex(parseColor(css));\n } catch {\n return undefined;\n }\n}\n\n/**\n * The leaf that edits `row`, less its default: a `color` where every value it\n * resolves to is a color this kit can parse, a `number` in the unit they share\n * where every one is a number, and otherwise a `string` holding the CSS text,\n * which is what a `var()`, a `calc()`, a font stack, or a shadow is edited as.\n */\nexport function tokenLeafKind(row: TokenRow): Pick<PrefNumber, 'kind' | 'unit'> | { kind: 'color'; alpha: true } | { kind: 'string' } {\n const values = Object.values(row.css);\n if (row.type === 'color' && values.every((css) => hexOf(css) !== undefined)) return { kind: 'color', alpha: true };\n if (NUMERIC_TYPES.has(row.type)) {\n const read = values.map(readCssNumber);\n const unit = read[0]?.unit;\n if (read.every((r) => r !== undefined && r.unit === unit)) {\n return unit ? { kind: 'number', unit: { scale: 1, suffix: unit } } : { kind: 'number' };\n }\n }\n return { kind: 'string' };\n}\n\nconst suffixOf = (leaf: PrefLeaf): string => ((leaf as PrefNumber).unit as PrefLinearUnit | undefined)?.suffix ?? '';\n\n/** What `css` reads as on `leaf`, or `undefined` for text its kind cannot hold. */\nexport function prefOfCss(leaf: PrefLeaf, css: string | undefined): unknown {\n if (css === undefined) return undefined;\n if (leaf.kind === 'color') return hexOf(css);\n if (leaf.kind !== 'number') return css;\n const read = readCssNumber(css);\n return read && read.unit === suffixOf(leaf) ? read.value : undefined;\n}\n\n/** The CSS text of a value `leaf` holds. */\nexport function cssOfPref(leaf: PrefLeaf, value: unknown): string {\n return leaf.kind === 'number' ? `${value as number}${suffixOf(leaf)}` : String(value);\n}\n","// Every token of a theme as the prefs bridge reads it: what it is, and the CSS it resolves to at each selection.\n\nimport { enumerateSelections, isByAxis, selectionKey, type AxisDefs, type Selection } from '../axes.ts';\nimport { TOKEN_MANIFEST, type TokenManifestEntry } from '../generated/manifest.ts';\nimport { resolveTheme, themeAxes, themeChain } from '../resolveTheme.ts';\nimport type { Theme } from '../theme.ts';\n\nconst PREFIX = '--wzl-';\n\n/** One token of a theme, named without `--wzl-`. */\nexport interface TokenRow {\n readonly name: string;\n readonly type: string;\n readonly group: string;\n readonly description: string;\n /** The CSS it resolves to, by `selectionKey`. */\n readonly css: Readonly<Record<string, string>>;\n /** Axes its pref is scoped by even where its CSS does not differ along them: every `scope` its definitions give. */\n readonly scope?: readonly string[];\n}\n\n/** A theme's tokens and the axes they were resolved along. */\nexport interface TokenTable {\n readonly axes: AxisDefs;\n readonly rows: readonly TokenRow[];\n}\n\nconst MANIFEST = new Map<string, TokenManifestEntry>(TOKEN_MANIFEST.map((entry) => [entry.name.slice(PREFIX.length), entry]));\n\nconst groupOf = (name: string): string => (name.includes('-') ? name.slice(0, name.indexOf('-')) : name);\n\n/** The type and description each token was first declared with, root theme first, and every axis any of its\n * definitions asks its pref be scoped by. A pin's type is `unknown`. */\nfunction declared(theme: Theme): Map<string, { type: string | undefined; description: string; scope: readonly string[] }> {\n const out = new Map<string, { type: string | undefined; description: string; scope: readonly string[] }>();\n for (const link of themeChain(theme)) {\n for (const [name, varying] of Object.entries(link.tokens)) {\n let raw: unknown = varying;\n while (isByAxis(raw)) raw = Object.entries(raw).find(([key]) => key !== 'by')?.[1];\n const token = raw as { type?: string; description?: string; scope?: readonly string[] } | undefined;\n const had = out.get(name);\n out.set(name, {\n type: had?.type ?? (token?.type !== 'unknown' ? token?.type : undefined),\n description: had?.description || token?.description || '',\n scope: [...new Set([...(had?.scope ?? []), ...(token?.scope ?? [])])],\n });\n }\n }\n return out;\n}\n\n/**\n * Every token `theme` resolves, then every override hook it leaves alone, each\n * with its CSS at every selection of the theme's axes. A hook reads as its\n * fallback at all of them.\n */\nexport function tokenTable(theme: Theme): TokenTable {\n const axes = themeAxes(theme);\n const resolved = enumerateSelections(axes).map(\n (selection): [string, Record<string, string>] => [selectionKey(axes, selection), resolveTheme(theme, selection)],\n );\n const own = declared(theme);\n const names = new Set<string>();\n for (const [, tokens] of resolved) for (const name of Object.keys(tokens)) names.add(name.slice(PREFIX.length));\n\n const rows: TokenRow[] = [];\n for (const name of names) {\n const listed = MANIFEST.get(name);\n const said = own.get(name);\n const css: Record<string, string> = {};\n for (const [key, tokens] of resolved) {\n const value = tokens[PREFIX + name];\n if (value !== undefined) css[key] = value;\n }\n rows.push({\n name,\n type: said?.type ?? listed?.type ?? 'string',\n group: listed?.group ?? groupOf(name),\n description: said?.description || listed?.description || '',\n css,\n ...(said?.scope.length ? { scope: said.scope } : {}),\n });\n }\n for (const [name, listed] of MANIFEST) {\n if (!listed.hook || names.has(name)) continue;\n const css = Object.fromEntries(resolved.map(([key]) => [key, listed.defaultValue]));\n rows.push({ name, type: listed.type, group: listed.group, description: listed.description, css });\n }\n return { axes, rows };\n}\n\n/**\n * `at(selection)` over every selection of `axes`, as a value split only by\n * the axes it differs along, the first axis outermost. `split` builds one\n * level from an axis and what each of its values holds.\n */\nexport function foldAxes(\n axes: AxisDefs,\n at: (selection: Selection) => unknown,\n split: (axis: string, members: Record<string, unknown>) => unknown,\n): unknown {\n const names = Object.keys(axes);\n const walk = (i: number, selection: Selection): unknown => {\n if (i === names.length) return at(selection);\n const axis = names[i]!;\n const members = Object.keys(axes[axis]!.values).map((value): [string, unknown] => [value, walk(i + 1, { ...selection, [axis]: value })]);\n const first = JSON.stringify(members[0]![1]);\n return members.every(([, member]) => JSON.stringify(member) === first) ? members[0]![1] : split(axis, Object.fromEntries(members));\n };\n return walk(0, {});\n}\n","import { isPrefScope, prefLeaves, prefScopeSelectors, type PrefGroup, type PrefLeaf, type PrefScope, type PrefScopeSpec } from '@weasel-js/prefs';\nimport { selectionKey } from '../axes.ts';\nimport { weaselTheme, type Theme } from '../theme.ts';\nimport { prefOfCss, tokenLeafKind } from './leaf.ts';\nimport { foldAxes, tokenTable, type TokenRow } from './tokens.ts';\n\n/** The key of the group a theme's axes are chosen in: `axis.mode` is the leaf holding the mode. */\nexport const THEME_PREFS_AXIS = 'axis';\n\n/** The path of the leaf that holds `axis`'s value. */\nexport const themeAxisPath = (axis: string): string => `${THEME_PREFS_AXIS}.${axis}`;\n\n/** The axis a leaf at `path` holds the value of, or `undefined` for a token's leaf. */\nexport const themeAxisOf = (path: string): string | undefined =>\n (path.startsWith(`${THEME_PREFS_AXIS}.`) ? path.slice(THEME_PREFS_AXIS.length + 1) : undefined);\n\n/** The token a leaf at `path` edits, named without `--wzl-`. */\nexport const themeTokenOf = (path: string): string => path.slice(path.indexOf('.') + 1);\n\nconst labeled = (text: string): string => (text === '' ? text : text[0]!.toUpperCase() + text.slice(1));\n\n// A token group named for the axes' own key takes another; no group's name holds a `-`.\nconst groupKey = (group: string): string => (group === THEME_PREFS_AXIS ? `${THEME_PREFS_AXIS}-tokens` : group);\n\n/** The scope of a value that differs along `axes`, each level keyed by its axis's leaf. */\nexport const scopeByAxis = (axis: string, members: Record<string, unknown>): PrefScope => ({ $by: themeAxisPath(axis), $in: members });\n\n// On its group's page a token's group prefix says nothing; its whole name stays a tag, so a filter still finds it.\nconst shortName = (row: TokenRow): string => (row.name.startsWith(`${row.group}-`) ? row.name.slice(row.group.length + 1) : row.name);\n\n/**\n * A token's pref. Its scopes are the axes its CSS differs along anywhere, and\n * any its definitions ask for, each open and in the theme's axis order; a\n * token that differs along none is one plain value. Its default is the CSS\n * folded along those axes, so a store nothing was written to reads the theme.\n */\nfunction tokenLeaf(row: TokenRow, table: ReturnType<typeof tokenTable>): PrefLeaf {\n const name = shortName(row);\n const leaf = {\n ...tokenLeafKind(row), name, description: row.description, default: undefined as unknown,\n ...(name === row.name ? {} : { tags: [row.name] }),\n } as PrefLeaf;\n const fallback = row.css[selectionKey(table.axes, {})] ?? Object.values(row.css)[0];\n const held = foldAxes(table.axes, (selection) => prefOfCss(leaf, row.css[selectionKey(table.axes, selection)] ?? fallback), scopeByAxis);\n leaf.default = prefOfCss(leaf, fallback);\n const differs = prefScopeSelectors(held);\n const scopes = Object.keys(table.axes)\n .filter((axis) => differs.has(themeAxisPath(axis)) || row.scope?.includes(axis))\n .map((axis): PrefScopeSpec => ({ selector: themeAxisPath(axis) }));\n if (scopes.length > 0) leaf.scopes = scopes;\n if (isPrefScope(held)) leaf.defaultScope = held;\n return leaf;\n}\n\n/**\n * `theme` as a preferences schema. Under `axis`, an `enum` for each of the\n * theme's axes, set to its default. Then a page for each token group, holding\n * a leaf for every token the theme resolves and every override hook, named\n * without its group's prefix: a\n * `color`, a `number` in the token's unit, or a `string` of CSS text for what\n * neither holds. A leaf is at `<group>.<token>`, the token named without\n * `--wzl-`, and is scoped by the axes its value differs along.\n *\n * A leaf's default is what the theme resolves the token to, already split\n * along the axes it differs by, so a store nothing was written to reads the\n * theme as it is. {@link themeFromPrefs} turns what was written into a theme.\n */\nexport function themePrefsSchema(theme: Theme = weaselTheme): PrefGroup {\n const table = tokenTable(theme);\n const axes: Record<string, PrefLeaf> = {};\n for (const [axis, def] of Object.entries(table.axes)) {\n axes[axis] = {\n kind: 'enum',\n name: labeled(axis),\n description: '',\n default: def.default,\n options: Object.keys(def.values).map((value) => ({ value, label: labeled(value) })),\n };\n }\n const children: Record<string, PrefGroup> = { [THEME_PREFS_AXIS]: { name: 'Axes', children: axes } };\n for (const row of table.rows) {\n const key = groupKey(row.group);\n children[key] ??= { name: labeled(row.group), children: {} };\n children[key].children[row.name] = tokenLeaf(row, table);\n }\n return { name: `${labeled(theme.name)} theme`, children };\n}\n\n/** What a token's CSS refers to, as {@link themePrefsReferences} reads it. */\nexport interface ThemePrefsReference {\n /** The custom property referred to, `--` and all. */\n readonly property: string;\n /** The path of the leaf that edits it, where it is one of the schema's tokens. */\n readonly path?: string;\n}\n\nconst WHOLE_VAR = /^\\s*var\\(\\s*(--[\\w-]+)\\s*\\)\\s*$/;\n\n/**\n * Reads a token's CSS as a reference to another custom property where the whole of it is one `var()` with no\n * fallback, and finds the leaf of `schema` that edits that property. Anything else, a `calc()` or a shadow that\n * holds a `var()` among other text included, reads as no reference.\n */\nexport function themePrefsReferences(schema: PrefGroup): (css: unknown) => ThemePrefsReference | undefined {\n const paths = new Map<string, string>();\n for (const path of prefLeaves(schema).keys()) if (themeAxisOf(path) === undefined) paths.set(`--wzl-${themeTokenOf(path)}`, path);\n return (css) => {\n const property = typeof css === 'string' ? WHOLE_VAR.exec(css)?.[1] : undefined;\n if (property === undefined) return undefined;\n const path = paths.get(property);\n return path === undefined ? { property } : { property, path };\n };\n}\n","import { isPrefScope, prefLeaves, type PrefGroup, type PrefLeaf, type PrefScope } from '@weasel-js/prefs';\nimport { selectionKey, type Selection, type Varying } from '../axes.ts';\nimport type { PinValue } from '../definition.ts';\nimport { defineTheme, type Theme } from '../theme.ts';\nimport { cssOfPref, prefOfCss } from './leaf.ts';\nimport { scopeByAxis, themeAxisOf, themeTokenOf } from './schema.ts';\nimport { foldAxes, tokenTable } from './tokens.ts';\n\n/** What the bridge reads of a store over a {@link themePrefsSchema}: any `PrefsStore` is one. */\nexport interface ThemePrefsSource {\n schema: PrefGroup;\n get(path: string): unknown;\n scope(path: string): PrefScope | undefined;\n isSet(path: string): boolean;\n}\n\nfunction pinOf(leaf: PrefLeaf, held: unknown): Varying<PinValue> {\n if (!isPrefScope(held)) return cssOfPref(leaf, held);\n const out: Record<string, unknown> = { by: themeAxisOf(held.$by) ?? held.$by };\n for (const [value, member] of Object.entries(held.$in)) out[value] = pinOf(leaf, member);\n return out as Varying<PinValue>;\n}\n\n/** The value of each axis as the store has it set: the selection to resolve or apply its theme at. */\nexport function themePrefsSelection(store: ThemePrefsSource): Selection {\n const out: Record<string, string> = {};\n for (const path of prefLeaves(store.schema).keys()) {\n const axis = themeAxisOf(path);\n if (axis !== undefined) out[axis] = store.get(path) as string;\n }\n return out;\n}\n\n/**\n * Every token leaf the store has a value of its own for, as `pins` for a\n * `ThemeDefinition`: a split value in theme's `{ by, … }` form, a color as\n * hex, a number in its unit, and a string as it is held. A leaf following its\n * default is no pin, so the token keeps its rule in the theme the pins go\n * over: an alias left alone still follows a primitive that was pinned.\n */\nexport function themePrefsPins(store: ThemePrefsSource): Record<string, Varying<PinValue>> {\n const out: Record<string, Varying<PinValue>> = {};\n for (const [path, leaf] of prefLeaves(store.schema)) {\n if (themeAxisOf(path) !== undefined || !store.isSet(path)) continue;\n out[themeTokenOf(path)] = pinOf(leaf, store.scope(path) ?? store.get(path));\n }\n return out;\n}\n\n/** `base` with the store's pins over it. `name` defaults to `base`'s with `-prefs` after it. */\nexport function themeFromPrefs(store: ThemePrefsSource, base: Theme, name = `${base.name}-prefs`): Theme {\n return defineTheme({ name, extends: base, pins: themePrefsPins(store) });\n}\n\n/** What {@link themePrefsValues} reads beside the pins. */\nexport interface ThemePrefsValuesSource extends ThemePrefsSource {\n values(): Record<string, unknown>;\n scopes(): ReadonlyMap<string, PrefScope>;\n}\n\n/**\n * The store's values and scopes as a form shows them, with every leaf that\n * follows its default read from the pinned theme, where the store reads it\n * from `base`. They differ for an alias of a token that was pinned: `accent`\n * after `accent-base` is set. Shaped as `store.values()` and `store.scopes()`.\n */\nexport function themePrefsValues(\n store: ThemePrefsValuesSource,\n base: Theme,\n): { values: Record<string, unknown>; scopes: ReadonlyMap<string, PrefScope> } {\n const { axes, rows } = tokenTable(themeFromPrefs(store, base));\n const css = new Map(rows.map((row) => [row.name, row.css]));\n const now = selectionKey(axes, themePrefsSelection(store));\n const values: Record<string, unknown> = { ...store.values() };\n const scopes = new Map(store.scopes());\n const copied = new Set<string>();\n for (const [path, leaf] of prefLeaves(store.schema)) {\n if (themeAxisOf(path) !== undefined || store.isSet(path)) continue;\n const resolved = css.get(themeTokenOf(path));\n if (!resolved || Object.values(resolved).some((text) => prefOfCss(leaf, text) === undefined)) continue;\n const held = foldAxes(axes, (selection) => prefOfCss(leaf, resolved[selectionKey(axes, selection)]), scopeByAxis);\n if (isPrefScope(held)) scopes.set(path, held);\n else scopes.delete(path);\n const group = path.slice(0, path.indexOf('.'));\n if (!copied.has(group)) {\n copied.add(group);\n values[group] = { ...(values[group] as Record<string, unknown>) };\n }\n (values[group] as Record<string, unknown>)[themeTokenOf(path)] = prefOfCss(leaf, resolved[now]);\n }\n return { values, scopes };\n}\n"]}
package/dist/react.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Palette, ColorSource } from '@weasel-js/paint';
2
2
  import React from 'react';
3
- import { a as Theme, S as Selection, r as ResolvedTheme, o as ColorList } from './definition-nZbgRG7A.js';
3
+ import { a as Theme, S as Selection, p as ResolvedTheme, r as ColorList } from './definition-DfbYMDu0.js';
4
4
  import { a as ColorModePreference, C as ColorMode } from './colorMode-CoklZomJ.js';
5
5
  export { i as isColorModePreference } from './colorMode-CoklZomJ.js';
6
6
 
package/dist/react.js CHANGED
@@ -1,9 +1,9 @@
1
- import { isColorModePreference, themeTints, applyTheme, colorSourceCss, colorSourceLiteral } from './chunk-TG3EV42T.js';
2
- export { isColorModePreference } from './chunk-TG3EV42T.js';
1
+ import { isColorModePreference, themeTints, applyTheme, colorSourceCss, colorSourceLiteral } from './chunk-SFVRMAMW.js';
2
+ export { isColorModePreference } from './chunk-SFVRMAMW.js';
3
3
  import './chunk-44CG54ZK.js';
4
4
  import './chunk-M3R5MV7Q.js';
5
5
  import { themeAxes, resolveTheme } from './chunk-UCQC6GZR.js';
6
- import { weaselTheme } from './chunk-NCAQ54LO.js';
6
+ import { weaselTheme } from './chunk-X2KI4SSJ.js';
7
7
  import { fullSelection, selectionKey } from './chunk-P5F3GZV6.js';
8
8
  import { colorLiteralToHex } from '@weasel-js/paint';
9
9
  import { createContext, useState, useCallback, useRef, useMemo, useLayoutEffect, useContext } from 'react';