@takazudo/zdtp 0.4.3 → 0.4.5
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/CHANGELOG.md +68 -0
- package/README.md +113 -12
- package/dist/apply/apply-token-overrides.d.ts +139 -32
- package/dist/apply/build-apply-overrides.d.ts +20 -4
- package/dist/apply/tier-resolver.d.ts +28 -0
- package/dist/astro/host-adapter.js +39 -39
- package/dist/astro/index.js +1 -1
- package/dist/{autoload-state-B1MWY_Pp.js → autoload-state-DF7TsTgY.js} +1 -1
- package/dist/bin/server.js +116 -112
- package/dist/config/cluster-config.d.ts +36 -13
- package/dist/config/panel-config.d.ts +36 -1
- package/dist/controls/tier-ref-selector.d.ts +65 -21
- package/dist/export-modal.d.ts +5 -3
- package/dist/import-modal.d.ts +9 -9
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3535 -2941
- package/dist/load-routing-LJ72261l.js +421 -0
- package/dist/panel-config-CipeKMTz.js +876 -0
- package/dist/server/create-apply-handler.d.ts +6 -0
- package/dist/server/index.js +1 -1
- package/dist/state/persist.d.ts +7 -0
- package/dist/state/tweak-state.d.ts +245 -9
- package/dist/tabs/color-tab.d.ts +13 -1
- package/dist/tabs/generic-tab.d.ts +4 -2
- package/dist/testing.js +5 -5
- package/dist/tokens/tier-model.d.ts +62 -0
- package/dist/tweak-state-xt-tSQ_t.js +1958 -0
- package/dist/utils/design-token-serde.d.ts +93 -17
- package/dist/zdtp.css +1 -1
- package/package.json +1 -1
- package/dist/load-routing-DtNTKoLW.js +0 -353
- package/dist/panel-config-3tBEHjvZ.js +0 -493
- package/dist/tweak-state-BEx1SHu7.js +0 -1773
|
@@ -22,6 +22,12 @@ export interface PerFileResult {
|
|
|
22
22
|
changed: string[];
|
|
23
23
|
unchanged: string[];
|
|
24
24
|
unknown: string[];
|
|
25
|
+
/**
|
|
26
|
+
* Subset of `unknown` (#508): declared somewhere in the file but outside
|
|
27
|
+
* the scanned `:root`/`@theme` blocks — see `ApplyResult.unknownOutsideBlock`
|
|
28
|
+
* in `apply-token-overrides.ts` for the full classification rules.
|
|
29
|
+
*/
|
|
30
|
+
unknownOutsideBlock: string[];
|
|
25
31
|
}
|
|
26
32
|
/**
|
|
27
33
|
* Create a framework-agnostic Fetch API handler for the design-token apply
|
package/dist/server/index.js
CHANGED
package/dist/state/persist.d.ts
CHANGED
|
@@ -11,6 +11,13 @@
|
|
|
11
11
|
* Framework-agnostic wrt. the setState function: pass any
|
|
12
12
|
* `(updater) => void` that propagates `updater(prev)` to the caller's state.
|
|
13
13
|
* In practice the panel passes Preact's `setState` from `useState`.
|
|
14
|
+
*
|
|
15
|
+
* `persistColor`'s updater is `(prev: ColorTweakState) => ColorTweakState`, so
|
|
16
|
+
* the widened `ColorTweakState.semanticMappings: Record<string, SemanticValue>`
|
|
17
|
+
* (#459) — including the `{ literal }` / `{ ref }` object variants added for
|
|
18
|
+
* #462 — already flows through this hook's generic pass-through unchanged; the
|
|
19
|
+
* actual validating hydrate/round-trip logic for those variants lives in
|
|
20
|
+
* `tweak-state.ts` (`hydrateSemanticMappings` / `savePersistedState`), not here.
|
|
14
21
|
*/
|
|
15
22
|
import { type ColorTweakState, type TabOverrides, type TokenOverrides, type TweakState } from './tweak-state';
|
|
16
23
|
import type { PanelConfig } from '../config/panel-config';
|
|
@@ -42,8 +42,11 @@
|
|
|
42
42
|
import type { ColorRef, ColorScheme } from '../config/color-schemes';
|
|
43
43
|
import type { TokenDef } from '../tokens/manifest';
|
|
44
44
|
import { type ColorClusterDataConfig } from '../config/cluster-config';
|
|
45
|
+
import type { SemanticValue } from '../tokens/tier-model';
|
|
46
|
+
export type { SemanticValue } from '../tokens/tier-model';
|
|
45
47
|
import { type ApplySink, type PanelConfig } from '../config/panel-config';
|
|
46
48
|
export type { ApplySink } from '../config/panel-config';
|
|
49
|
+
import type { TabConfig } from '../tokens/tier-model';
|
|
47
50
|
import { type TabOverrides } from '../apply/tier-resolver';
|
|
48
51
|
export type { BaseRoleKey, ColorClusterDataConfig } from '../config/cluster-config';
|
|
49
52
|
export { resolvePaletteCssVar } from '../config/cluster-config';
|
|
@@ -77,6 +80,12 @@ export type { TabOverrides } from '../apply/tier-resolver';
|
|
|
77
80
|
export declare function getStorageKeyV1(cfg?: PanelConfig): string;
|
|
78
81
|
export declare function getStorageKeyV2(cfg?: PanelConfig): string;
|
|
79
82
|
export declare function getStorageKeyV3(cfg?: PanelConfig): string;
|
|
83
|
+
/**
|
|
84
|
+
* v4 unified envelope key — the per-scheme-keyed color format (#500/#509).
|
|
85
|
+
* See `storageKey_stateV4` for the shape rationale. Read first by
|
|
86
|
+
* `loadPersistedState`; v1/v2/v3 migrate into it on first load.
|
|
87
|
+
*/
|
|
88
|
+
export declare function getStorageKeyV4(cfg?: PanelConfig): string;
|
|
80
89
|
export declare function getOpenKey(cfg?: PanelConfig): string;
|
|
81
90
|
export declare function getPositionKey(cfg?: PanelConfig): string;
|
|
82
91
|
export declare function getSizeKey(cfg?: PanelConfig): string;
|
|
@@ -182,9 +191,47 @@ export interface ColorTweakState {
|
|
|
182
191
|
cursor: number;
|
|
183
192
|
selectionBg: number;
|
|
184
193
|
selectionFg: number;
|
|
185
|
-
|
|
194
|
+
/**
|
|
195
|
+
* Semantic token name → mapping. Widened from `Record<string, number | 'bg'
|
|
196
|
+
* | 'fg'>` to `Record<string, SemanticValue>` (#459 S1). This is additive
|
|
197
|
+
* for readers of the type (every legacy value is still a valid
|
|
198
|
+
* `SemanticValue`), but it BREAKS any exhaustive `switch`/equality check
|
|
199
|
+
* written against the old narrow union — callers that pattern-match on a
|
|
200
|
+
* mapping value must now also handle the new `{ literal }` / `{ ref }`
|
|
201
|
+
* object variants (see `isIndexMapping` / `isLiteralMapping` /
|
|
202
|
+
* `isPerModeLiteral` / `isRefMapping` below). `resolveMapping` (exported)
|
|
203
|
+
* still only resolves the legacy `number | 'bg' | 'fg'` shape — resolving
|
|
204
|
+
* the new variants is downstream work (#467/#469).
|
|
205
|
+
*/
|
|
206
|
+
semanticMappings: Record<string, SemanticValue>;
|
|
186
207
|
shikiTheme: string;
|
|
187
208
|
}
|
|
209
|
+
/** True when `v` is a legacy index-style mapping (palette index or bg/fg alias). */
|
|
210
|
+
export declare function isIndexMapping(v: SemanticValue): v is number | 'bg' | 'fg';
|
|
211
|
+
/** True when `v` is either literal-color variant (plain string or light/dark pair). */
|
|
212
|
+
export declare function isLiteralMapping(v: SemanticValue): v is {
|
|
213
|
+
literal: string;
|
|
214
|
+
} | {
|
|
215
|
+
literal: {
|
|
216
|
+
light: string;
|
|
217
|
+
dark: string;
|
|
218
|
+
};
|
|
219
|
+
};
|
|
220
|
+
/** True when `v` is specifically the light/dark literal-color variant. */
|
|
221
|
+
export declare function isPerModeLiteral(v: SemanticValue): v is {
|
|
222
|
+
literal: {
|
|
223
|
+
light: string;
|
|
224
|
+
dark: string;
|
|
225
|
+
};
|
|
226
|
+
};
|
|
227
|
+
/** True when `v` is a cross-tab/tier ramp-item reference. */
|
|
228
|
+
export declare function isRefMapping(v: SemanticValue): v is {
|
|
229
|
+
ref: {
|
|
230
|
+
tab?: string;
|
|
231
|
+
tier: string;
|
|
232
|
+
item: string;
|
|
233
|
+
};
|
|
234
|
+
};
|
|
188
235
|
/**
|
|
189
236
|
* Per-token override map. Keys are `TokenDef.id` (e.g. `hsp-sm`); values are
|
|
190
237
|
* raw CSS length strings (e.g. `0.75rem`). Only overridden tokens appear in
|
|
@@ -217,6 +264,32 @@ export interface TweakState {
|
|
|
217
264
|
/** Generic tab overrides keyed by tab id. Added in v3 envelope. */
|
|
218
265
|
tabs?: Record<string, TabOverrides>;
|
|
219
266
|
}
|
|
267
|
+
/**
|
|
268
|
+
* On-disk v4 persist envelope (#500/#509). Same top-level slices as the runtime
|
|
269
|
+
* `TweakState`, EXCEPT the `color` and `secondary` slices are identity-keyed
|
|
270
|
+
* sub-objects: one `ColorTweakState` slot per active-color IDENTITY (see
|
|
271
|
+
* `getActiveColorIdentity`). This is what lets a per-scheme color tweak survive
|
|
272
|
+
* a scheme toggle — editing under scheme A never touches scheme B's slot.
|
|
273
|
+
*
|
|
274
|
+
* The non-color slices (`spacing` / `typography` / `size` / `tabs`) stay global
|
|
275
|
+
* and unkeyed, exactly as in v1–v3: a light/dark toggle does not change them.
|
|
276
|
+
*
|
|
277
|
+
* `secondary` slots are keyed by the SAME primary identity — the secondary
|
|
278
|
+
* cluster has no scheme of its own but reseeds on the same `color-scheme-changed`
|
|
279
|
+
* event, so it follows the primary's identity.
|
|
280
|
+
*
|
|
281
|
+
* `loadPersistedState` selects the active identity's slots into a runtime
|
|
282
|
+
* `TweakState`; `savePersistedState` merge-saves the active slots while
|
|
283
|
+
* preserving every inactive identity's slot.
|
|
284
|
+
*/
|
|
285
|
+
export interface PersistedEnvelopeV4 {
|
|
286
|
+
color: Record<string, ColorTweakState>;
|
|
287
|
+
secondary?: Record<string, ColorTweakState>;
|
|
288
|
+
spacing: TokenOverrides;
|
|
289
|
+
typography: TokenOverrides;
|
|
290
|
+
size: TokenOverrides;
|
|
291
|
+
tabs?: Record<string, TabOverrides>;
|
|
292
|
+
}
|
|
220
293
|
/** Produce an empty overrides map — `TweakState` default for new tabs. */
|
|
221
294
|
export declare function emptyOverrides(): TokenOverrides;
|
|
222
295
|
/**
|
|
@@ -238,6 +311,10 @@ export declare function getActivePrimaryCluster(cfg?: PanelConfig): ColorCluster
|
|
|
238
311
|
* slots interpolate. Functional but visually flat; hosts wanting a
|
|
239
312
|
* designed seed should ship a scheme registry on the cluster and call
|
|
240
313
|
* `initColorFromScheme(cluster)` instead.
|
|
314
|
+
* - A cluster with `paletteSize: 0` (a lone `semantic: true` tier with no
|
|
315
|
+
* palette sibling, #458/#466) seeds an EMPTY palette — there is nothing
|
|
316
|
+
* to ramp. Forcing a 1-slot grayscale floor here produced a phantom
|
|
317
|
+
* `--zudo-stub-p0` swatch/token with no backing tier; see #466.
|
|
241
318
|
*
|
|
242
319
|
* The base-role indices are kept on the state shape for envelope-round-trip
|
|
243
320
|
* compatibility but are inert — `applyColorState` only writes a base role
|
|
@@ -315,6 +392,24 @@ export declare function getActiveSchemeName(cluster?: ColorClusterDataConfig, cf
|
|
|
315
392
|
* is the correct behavior for non-sink instances but wrong for sinks.
|
|
316
393
|
*/
|
|
317
394
|
export declare function initColorFromScheme(cluster?: ColorClusterDataConfig, cfg?: PanelConfig): ColorTweakState;
|
|
395
|
+
/**
|
|
396
|
+
* Derive the active-color IDENTITY — the key under which the v4 envelope files
|
|
397
|
+
* this instance's `color` / `secondary` slots (#500/#509).
|
|
398
|
+
*
|
|
399
|
+
* The identity is EXACTLY the active scheme name `initColorFromScheme` resolves
|
|
400
|
+
* for the primary cluster via `getActiveSchemeName` (the active scheme, with the
|
|
401
|
+
* light/dark mode already folded into the resolved name where the cluster
|
|
402
|
+
* `panelSettings.colorMode` distinguishes modes). This is deliberate: the same
|
|
403
|
+
* inputs whose change triggers a reseed today produce the identity, so the
|
|
404
|
+
* invariant holds — *the same identity that causes a reseed selects its own
|
|
405
|
+
* persisted slot*. A colorMode-less cluster resolves a constant identity (one
|
|
406
|
+
* slot); a light/dark cluster resolves distinct identities per side.
|
|
407
|
+
*
|
|
408
|
+
* The secondary cluster has no scheme concept of its own but reseeds on the same
|
|
409
|
+
* `color-scheme-changed` event, so its slots are keyed by this SAME primary
|
|
410
|
+
* identity — callers pass the PRIMARY cluster here for both slices.
|
|
411
|
+
*/
|
|
412
|
+
export declare function getActiveColorIdentity(cluster?: ColorClusterDataConfig, cfg?: PanelConfig): string;
|
|
318
413
|
/**
|
|
319
414
|
* Palette entry sanitiser. Raw `oklch(...)` values are preserved verbatim so
|
|
320
415
|
* wide-gamut chroma survives (and they never touch the canvas → no '#000000'
|
|
@@ -331,11 +426,79 @@ export declare function initColorFromScheme(cluster?: ColorClusterDataConfig, cf
|
|
|
331
426
|
*/
|
|
332
427
|
export declare function normalizeSchemePaletteEntry(value: string): string;
|
|
333
428
|
export declare function initColorFromSchemeData(scheme: ColorScheme, cluster?: ColorClusterDataConfig): ColorTweakState;
|
|
334
|
-
/**
|
|
429
|
+
/**
|
|
430
|
+
* Resolve a semantic mapping to an actual color (bounds-checked).
|
|
431
|
+
*
|
|
432
|
+
* Only handles the legacy `number | 'bg' | 'fg'` index shape — the narrower
|
|
433
|
+
* type this function accepted before `ColorTweakState.semanticMappings` /
|
|
434
|
+
* `ColorClusterDataConfig.semanticDefaults` were widened to `SemanticValue`
|
|
435
|
+
* (#459 S1). Callers holding a `SemanticValue` must narrow with
|
|
436
|
+
* `isIndexMapping()` first; resolving the `{ literal }` / `{ ref }` variants
|
|
437
|
+
* is downstream work (#467/#469), not this function's job today.
|
|
438
|
+
*/
|
|
335
439
|
export declare function resolveMapping(mapping: number | 'bg' | 'fg', palette: string[], bgIndex: number, fgIndex: number): string;
|
|
336
440
|
export declare function safeIndex(index: number, len: number): number;
|
|
337
|
-
/**
|
|
338
|
-
|
|
441
|
+
/**
|
|
442
|
+
* The cluster's configured default light/dark mode, or `'light'` when the
|
|
443
|
+
* cluster declares no `colorMode` (`colorMode === false`).
|
|
444
|
+
*
|
|
445
|
+
* This is the single runtime reader of `ClusterPanelSettings.colorMode.defaultMode`
|
|
446
|
+
* (#472). The field validates but was previously never read at runtime; this
|
|
447
|
+
* helper (consumed by `resolveSemanticPreviewColor`) gives it a real effect —
|
|
448
|
+
* it selects which side of a per-mode `{ literal: { light, dark } }` pair is the
|
|
449
|
+
* fallback when `light-dark()` cannot resolve.
|
|
450
|
+
*/
|
|
451
|
+
export declare function getClusterDefaultMode(cluster: ColorClusterDataConfig): 'light' | 'dark';
|
|
452
|
+
/**
|
|
453
|
+
* Resolve a per-mode literal to a single concrete CSS color for `mode`.
|
|
454
|
+
*
|
|
455
|
+
* Used wherever CSS `light-dark()` cannot be used — a preview swatch, an SSR
|
|
456
|
+
* seed, or any non-browser consumer that needs one flat value rather than a
|
|
457
|
+
* `light-dark(...)` function. The emitters (`applyColorState`,
|
|
458
|
+
* `buildApplyOverrides`) deliberately do NOT call this; they emit
|
|
459
|
+
* `light-dark()` and let the browser choose.
|
|
460
|
+
*/
|
|
461
|
+
export declare function resolvePerModeLiteral(value: {
|
|
462
|
+
literal: {
|
|
463
|
+
light: string;
|
|
464
|
+
dark: string;
|
|
465
|
+
};
|
|
466
|
+
}, mode: 'light' | 'dark'): string;
|
|
467
|
+
/**
|
|
468
|
+
* Resolve a semantic mapping to a single concrete CSS color suitable for a
|
|
469
|
+
* PREVIEW swatch — a flat value, never a `light-dark()` function. Mirrors the
|
|
470
|
+
* internal apply-path resolver, except a per-mode `{ literal: { light, dark } }`
|
|
471
|
+
* value collapses to `getClusterDefaultMode(cluster)`'s side (#472).
|
|
472
|
+
*
|
|
473
|
+
* This is the "preview/seed" consumer referenced by #472/#473: the per-mode
|
|
474
|
+
* editor UI (#473) renders its swatch from this so the user sees the cluster's
|
|
475
|
+
* default-mode color, while the applied CSS var still emits `light-dark()`.
|
|
476
|
+
*/
|
|
477
|
+
export declare function resolveSemanticPreviewColor(mapping: SemanticValue, state: ColorTweakState, cluster?: ColorClusterDataConfig, currentTab?: TabConfig, tabs?: readonly TabConfig[]): string;
|
|
478
|
+
/**
|
|
479
|
+
* Apply a single `ColorTweakState` to the DOM using the given cluster config.
|
|
480
|
+
*
|
|
481
|
+
* `currentTab` / `tabs` are optional and exist so a cross-tab/tier `{ ref }`
|
|
482
|
+
* semantic mapping (#468) can resolve: `currentTab` should be the color
|
|
483
|
+
* TabConfig this cluster was derived from (id `'color'` or
|
|
484
|
+
* `'color-secondary'`), and `tabs` the panel's full tabs array so a ref
|
|
485
|
+
* pointing into another tab (e.g. the grouped Palette tab) resolves. Callers
|
|
486
|
+
* that never hold `{ ref }` mappings (or have no tab context, e.g. most
|
|
487
|
+
* existing tests) can omit both — `resolveSemanticCssValue` returns `null`
|
|
488
|
+
* for an unresolvable ref rather than throwing, and this function skips a
|
|
489
|
+
* `null` (leaving the token at its stylesheet default) rather than painting
|
|
490
|
+
* a fallback color.
|
|
491
|
+
*
|
|
492
|
+
* `ownerPrefix` (#501) is the instance `storagePrefix` this apply belongs to.
|
|
493
|
+
* When supplied AND this cluster emits a per-mode `light-dark()` literal (so
|
|
494
|
+
* `color-scheme: light dark` is written to the apply target — either
|
|
495
|
+
* `document.documentElement` or the sink's root), the instance is recorded as
|
|
496
|
+
* the owner of that inline `color-scheme` so the clear paths can later remove
|
|
497
|
+
* it without ever wiping a host-owned `<html style="color-scheme">`. Omitting
|
|
498
|
+
* it (direct callers with no instance context, e.g. some tests) skips the
|
|
499
|
+
* bookkeeping only — the actual CSS write is unchanged.
|
|
500
|
+
*/
|
|
501
|
+
export declare function applyColorState(state: ColorTweakState, cluster?: ColorClusterDataConfig, sink?: ApplySink, currentTab?: TabConfig, tabs?: readonly TabConfig[], ownerPrefix?: string): void;
|
|
339
502
|
/**
|
|
340
503
|
* Apply a `TokenOverrides` map for a given manifest — writes inline
|
|
341
504
|
* `--css-var: value` on `:root` for every overridden token, and removes the
|
|
@@ -346,6 +509,31 @@ export declare function applyColorState(state: ColorTweakState, cluster?: ColorC
|
|
|
346
509
|
* in the UI and are never written to storage.
|
|
347
510
|
*/
|
|
348
511
|
export declare function applyTokenOverrides(tokens: readonly TokenDef[], overrides: TokenOverrides, sink?: ApplySink): void;
|
|
512
|
+
/**
|
|
513
|
+
* Apply ONLY the color slices — primary color cluster + optional secondary
|
|
514
|
+
* cluster + the aggregate `color-scheme` decision — leaving spacing / font /
|
|
515
|
+
* size / generic-tab vars untouched.
|
|
516
|
+
*
|
|
517
|
+
* Extracted from `applyFullState` (#500/#509) so the scheme-change handler can
|
|
518
|
+
* re-paint the new identity's persisted color overrides after
|
|
519
|
+
* `clearAppliedColorStyles` WITHOUT re-writing (or clearing) the scheme-
|
|
520
|
+
* independent non-color vars that must survive a light/dark toggle (#347).
|
|
521
|
+
*
|
|
522
|
+
* `color-scheme` is managed as an AGGREGATE across the primary + secondary
|
|
523
|
+
* clusters, not per-cluster (#482 D3): `applyColorState` only ever SETS
|
|
524
|
+
* `color-scheme: light dark` when its OWN cluster needs it, it never clears
|
|
525
|
+
* it, so demoting the last per-mode-literal row (in either cluster) would
|
|
526
|
+
* otherwise leave the previous apply's value stale. A naive per-cluster
|
|
527
|
+
* clear inside `applyColorState` would let a per-mode-free secondary undo
|
|
528
|
+
* what the primary just required (or vice versa), so the clear-when-neither-
|
|
529
|
+
* needs-it decision is made here, once, after both clusters have applied.
|
|
530
|
+
*
|
|
531
|
+
* #501 — the `document.documentElement` clear is scoped to a color-scheme THIS
|
|
532
|
+
* instance actually wrote (`clearOwnedColorSchemeFromDocument`) so a host that
|
|
533
|
+
* owns `<html style="color-scheme">` is never clobbered; the sink path stays
|
|
534
|
+
* unconditional (sink targets are panel-owned) but drops the ownership claim.
|
|
535
|
+
*/
|
|
536
|
+
export declare function applyColorSlices(color: ColorTweakState, secondary: ColorTweakState | undefined, cfg?: PanelConfig): void;
|
|
349
537
|
/**
|
|
350
538
|
* Apply the full unified `TweakState` — primary color cluster + token
|
|
351
539
|
* overrides + optional secondary cluster.
|
|
@@ -357,8 +545,27 @@ export declare function applyTokenOverrides(tokens: readonly TokenDef[], overrid
|
|
|
357
545
|
* When `cfg` is supplied its `applySink` (if any) is used to route all
|
|
358
546
|
* CSS-var writes for this instance. Omitting `cfg` uses the default active
|
|
359
547
|
* config (single-panel path, unchanged behavior).
|
|
548
|
+
*
|
|
549
|
+
* The color slices + aggregate `color-scheme` decision are delegated to
|
|
550
|
+
* `applyColorSlices`; this function adds the non-color (spacing / font / size /
|
|
551
|
+
* generic-tab) writes.
|
|
360
552
|
*/
|
|
361
553
|
export declare function applyFullState(state: TweakState, cfg?: PanelConfig): void;
|
|
554
|
+
/**
|
|
555
|
+
* Apply ONLY the non-color slices (spacing / typography / size / generic-tab
|
|
556
|
+
* overrides), leaving the color clusters and aggregate `color-scheme` decision
|
|
557
|
+
* untouched. Complement of `applyColorSlices`; together they compose
|
|
558
|
+
* `applyFullState`.
|
|
559
|
+
*
|
|
560
|
+
* Extracted (#509 audit) so the persisted-overrides reapply paths
|
|
561
|
+
* (`reapplyPersistedOverrides`, the panel first-open effect) can, when a v4
|
|
562
|
+
* envelope exists but the ACTIVE (scheme, mode) identity has no color slot,
|
|
563
|
+
* still apply the scheme-INDEPENDENT non-color tweaks while leaving the active
|
|
564
|
+
* scheme's own stylesheet colors to show through — instead of painting the
|
|
565
|
+
* synthesized config-default colors inline. This mirrors the scheme-change
|
|
566
|
+
* handler's missing-slot behavior (gated on `hasActiveColorSlot`).
|
|
567
|
+
*/
|
|
568
|
+
export declare function applyNonColorSlices(state: TweakState, cfg?: PanelConfig): void;
|
|
362
569
|
/**
|
|
363
570
|
* Strip the inline CSS variables written by the color cluster(s) only —
|
|
364
571
|
* palette slots, base roles, and semantic vars. Spacing / typography / size
|
|
@@ -382,6 +589,11 @@ export declare function applyFullState(state: TweakState, cfg?: PanelConfig): vo
|
|
|
382
589
|
* historical `(clusters, sink)` call shape (e.g. the scheme-change path before
|
|
383
590
|
* #357, and existing tests) is unchanged. Omitting all three preserves the
|
|
384
591
|
* single-panel default-instance behaviour.
|
|
592
|
+
*
|
|
593
|
+
* The color-scheme removal on the `document.documentElement` path is gated on
|
|
594
|
+
* this instance owning the inline value (#501) — see
|
|
595
|
+
* `clearOwnedColorSchemeFromDocument`. The owner is `cfg.storagePrefix` when a
|
|
596
|
+
* `cfg` is given, else the default instance's prefix.
|
|
385
597
|
*/
|
|
386
598
|
export declare function clearAppliedColorStyles(clusters?: readonly ColorClusterDataConfig[], sink?: ApplySink, cfg?: PanelConfig): void;
|
|
387
599
|
/**
|
|
@@ -447,17 +659,41 @@ export interface StorageLike {
|
|
|
447
659
|
* labels), so this migration only applies to the typography slice.
|
|
448
660
|
*/
|
|
449
661
|
export declare const ZDTP_LEGACY_TYPOGRAPHY_RENAME_MAP: Readonly<Record<string, string | null>>;
|
|
662
|
+
/**
|
|
663
|
+
* True when the v4 envelope holds a color slot for the CURRENTLY active
|
|
664
|
+
* identity. The scheme-change handler uses this to decide whether to hydrate +
|
|
665
|
+
* apply persisted overrides for the new scheme (slot present) or reseed from
|
|
666
|
+
* config defaults WITHOUT applying (slot absent — the pre-#500 behavior that
|
|
667
|
+
* lets the new scheme's stylesheet show through).
|
|
668
|
+
*/
|
|
669
|
+
export declare function hasActiveColorSlot(cfg?: PanelConfig, cluster?: ColorClusterDataConfig, storage?: StorageLike): boolean;
|
|
670
|
+
/**
|
|
671
|
+
* Load the active `TweakState`, preferring the v4 per-scheme envelope
|
|
672
|
+
* (#500/#509).
|
|
673
|
+
*
|
|
674
|
+
* Order:
|
|
675
|
+
* 1. v4 present → select the active identity's color/secondary slots.
|
|
676
|
+
* 2. else run the legacy v1/v2/v3 chain (unchanged) → migrate that state into
|
|
677
|
+
* a v4 envelope filed under the identity active at load, WITHOUT deleting
|
|
678
|
+
* the legacy key (v4 wins on every future load via step 1). This is why the
|
|
679
|
+
* pre-existing v1/v2/v3 migration tests keep passing: the legacy chain still
|
|
680
|
+
* writes/keeps the v3 key exactly as before; v4 is layered on top.
|
|
681
|
+
* 3. else null (caller cold-seeds).
|
|
682
|
+
*
|
|
683
|
+
* A present-but-malformed v4 blob falls through to steps 2/3, which overwrite it.
|
|
684
|
+
*/
|
|
450
685
|
export declare function loadPersistedState(storage?: StorageLike, colorDefaults?: ColorTweakState, cluster?: ColorClusterDataConfig, cfg?: PanelConfig): TweakState | null;
|
|
451
686
|
/**
|
|
452
|
-
*
|
|
687
|
+
* Merge-save the full `TweakState` into the v4 per-scheme envelope (#500/#509).
|
|
453
688
|
*
|
|
454
|
-
*
|
|
455
|
-
*
|
|
456
|
-
*
|
|
689
|
+
* The active identity's color/secondary slots are overwritten; every inactive
|
|
690
|
+
* identity's slot is preserved (read → merge → write). Global non-color slices
|
|
691
|
+
* are replaced wholesale. `cfg` scopes the storage key to a specific panel
|
|
692
|
+
* instance (multi-instance, #357).
|
|
457
693
|
*/
|
|
458
694
|
export declare function savePersistedState(state: TweakState, storage?: StorageLike, cfg?: PanelConfig): void;
|
|
459
695
|
/**
|
|
460
|
-
* Remove
|
|
696
|
+
* Remove the v4 key (and lingering v3/v2/v1 keys).
|
|
461
697
|
*
|
|
462
698
|
* `cfg` scopes the cleared keys to a specific panel instance (multi-instance,
|
|
463
699
|
* #357). Omitting it resolves the default instance via `getPanelConfig()`,
|
package/dist/tabs/color-tab.d.ts
CHANGED
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
* in the panel.
|
|
36
36
|
*/
|
|
37
37
|
import { type ColorTweakState } from '../state/tweak-state';
|
|
38
|
+
import { type PanelConfig } from '../config/panel-config';
|
|
38
39
|
import type { TabConfig } from '../tokens/tier-model';
|
|
39
40
|
import type { PersistColor, PersistSecondary } from '../state/persist';
|
|
40
41
|
interface ColorTabProps {
|
|
@@ -52,6 +53,17 @@ interface ColorTabProps {
|
|
|
52
53
|
secondaryTab: TabConfig | null;
|
|
53
54
|
secondaryState: ColorTweakState | null;
|
|
54
55
|
persistSecondary: PersistSecondary;
|
|
56
|
+
/**
|
|
57
|
+
* The mounted panel instance's config (multi-instance, #353/#357). When
|
|
58
|
+
* supplied, cross-tab cluster/ref resolution (cluster derivation, the
|
|
59
|
+
* grouped ref-or-literal picker's ramp groups, preview resolution, and the
|
|
60
|
+
* host preset list) reads THIS instance's `tabs` / `colorPresets` rather
|
|
61
|
+
* than the active default instance — matching the apply path, which
|
|
62
|
+
* already resolves against `cfg.tabs` via `usePersist` (`applyFullState`,
|
|
63
|
+
* `state/persist.ts`). Omitted (e.g. a direct test render) →
|
|
64
|
+
* `getPanelConfig()`, preserving the single-instance path.
|
|
65
|
+
*/
|
|
66
|
+
instanceConfig?: PanelConfig;
|
|
55
67
|
}
|
|
56
|
-
export default function ColorTab({ tab, state, persistColor, secondaryTab, secondaryState, persistSecondary, }: ColorTabProps): import("preact").JSX.Element;
|
|
68
|
+
export default function ColorTab({ tab, state, persistColor, secondaryTab, secondaryState, persistSecondary, instanceConfig, }: ColorTabProps): import("preact").JSX.Element;
|
|
57
69
|
export {};
|
|
@@ -28,8 +28,10 @@ export interface GenericTabProps {
|
|
|
28
28
|
* When an item has no override, its `TierItem.default` is used.
|
|
29
29
|
*/
|
|
30
30
|
overrides: TabOverrides;
|
|
31
|
-
/** Called when the user commits a change to any item.
|
|
32
|
-
|
|
31
|
+
/** Called when the user commits a change to any item. `next: undefined`
|
|
32
|
+
* (only reachable for ref-tier items) means "drop the stored override for
|
|
33
|
+
* this item" rather than writing a literal value. */
|
|
34
|
+
onChange: (tierId: string, itemId: string, next: string | undefined) => void;
|
|
33
35
|
}
|
|
34
36
|
/**
|
|
35
37
|
* Renders a non-reserved tab (any TabConfig whose id is not color/font/
|
package/dist/testing.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { _ as r, c as i,
|
|
2
|
-
import { a as
|
|
1
|
+
import { _ as r, c as i, h as _, i as n, j as g, b as R, a as p } from "./panel-config-CipeKMTz.js";
|
|
2
|
+
import { a as y, b as O, l as P } from "./tweak-state-xt-tSQ_t.js";
|
|
3
3
|
import { F as K, G as E, a as S, S as u } from "./manifest-DCReQE0k.js";
|
|
4
4
|
async function s(a, e) {
|
|
5
5
|
await a.fill(e), await a.dispatchEvent("input");
|
|
@@ -11,9 +11,9 @@ export {
|
|
|
11
11
|
u as SIZE_GROUP_ORDER,
|
|
12
12
|
r as __resetPanelConfigForTests,
|
|
13
13
|
i as configurePanel,
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
y as getStorageKeyV1,
|
|
15
|
+
O as getStorageKeyV2,
|
|
16
|
+
P as loadPersistedState,
|
|
17
17
|
s as setPanelInputValue,
|
|
18
18
|
_ as storageKey_open,
|
|
19
19
|
n as storageKey_position,
|
|
@@ -56,6 +56,33 @@ export interface PillSpec {
|
|
|
56
56
|
value: string;
|
|
57
57
|
customDefault: string;
|
|
58
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* A semantic token's mapping value.
|
|
61
|
+
*
|
|
62
|
+
* Legacy shape stays valid: a palette index (`number`) or the `'bg'` / `'fg'`
|
|
63
|
+
* sentinel aliases. New variants (added for #459) let a semantic tier point at
|
|
64
|
+
* an arbitrary literal color (optionally split light/dark) or reference a ramp
|
|
65
|
+
* item living in another tab/tier — both resolved downstream by #467/#469.
|
|
66
|
+
*
|
|
67
|
+
* Defined here (not in `state/tweak-state.ts`) because `config/cluster-config.ts`
|
|
68
|
+
* needs it for `ColorClusterDataConfig.semanticDefaults`, and cluster-config.ts
|
|
69
|
+
* already imports types from this module — keeping the definition here avoids
|
|
70
|
+
* a new type-only import cycle. `state/tweak-state.ts` re-exports it.
|
|
71
|
+
*/
|
|
72
|
+
export type SemanticValue = number | 'bg' | 'fg' | {
|
|
73
|
+
literal: string;
|
|
74
|
+
} | {
|
|
75
|
+
literal: {
|
|
76
|
+
light: string;
|
|
77
|
+
dark: string;
|
|
78
|
+
};
|
|
79
|
+
} | {
|
|
80
|
+
ref: {
|
|
81
|
+
tab?: string;
|
|
82
|
+
tier: string;
|
|
83
|
+
item: string;
|
|
84
|
+
};
|
|
85
|
+
};
|
|
59
86
|
export interface TierItem {
|
|
60
87
|
id: string;
|
|
61
88
|
cssVar: string;
|
|
@@ -73,6 +100,29 @@ export interface TierConfig {
|
|
|
73
100
|
* an item in the tier whose id matches referencesTier. The apply pipeline
|
|
74
101
|
* emits var(--tier1-cssvar). */
|
|
75
102
|
referencesTier?: string;
|
|
103
|
+
/**
|
|
104
|
+
* Marks this tier as a SEMANTIC tier (its items hold `SemanticValue`
|
|
105
|
+
* mappings, not raw palette entries) so the panel never mistakes it for
|
|
106
|
+
* the palette tier. Optional and additive — omitting it preserves today's
|
|
107
|
+
* behavior (palette-tier detection stays structural, via
|
|
108
|
+
* `resolveColorClusterFromTab`'s `kind: 'color'` check).
|
|
109
|
+
*/
|
|
110
|
+
semantic?: true;
|
|
111
|
+
/**
|
|
112
|
+
* Cross-tab ramp-source declaration for a semantic tier: the ramp tier(s)
|
|
113
|
+
* this tier's `{ ref }` mappings are allowed to point into. Each entry names
|
|
114
|
+
* a tier id and an optional tab id (omitted `tab` means "this tab").
|
|
115
|
+
* `assertValidPanelConfig` validates every declared source up front (the
|
|
116
|
+
* tab/tier must exist and share this tier's kind); `resolveColorClusterFromTab`
|
|
117
|
+
* (`config/cluster-config.ts`) uses the allow-list to derive each row's
|
|
118
|
+
* `SemanticValue`; the grouped `TierRefSelector` picker
|
|
119
|
+
* (`controls/tier-ref-selector.tsx`) renders one `<optgroup>` per declared
|
|
120
|
+
* source.
|
|
121
|
+
*/
|
|
122
|
+
referencesRamps?: readonly {
|
|
123
|
+
tab?: string;
|
|
124
|
+
tier: string;
|
|
125
|
+
}[];
|
|
76
126
|
}
|
|
77
127
|
export interface ColorClusterExtras {
|
|
78
128
|
id: string;
|
|
@@ -82,6 +132,18 @@ export interface ColorClusterExtras {
|
|
|
82
132
|
defaultShikiTheme: string;
|
|
83
133
|
colorSchemes: Record<string, ColorScheme>;
|
|
84
134
|
panelSettings: ClusterPanelSettings;
|
|
135
|
+
/**
|
|
136
|
+
* Config-time override map for a semantic tier's derived defaults (#499).
|
|
137
|
+
* Keyed by semantic item id; when a key is present here,
|
|
138
|
+
* `resolveColorClusterFromTab` uses its `SemanticValue` verbatim instead of
|
|
139
|
+
* running `deriveSemanticValue` on the item's plain-string `default` — this
|
|
140
|
+
* is the only way a host can ship a `{ literal: { light, dark } }` (or
|
|
141
|
+
* `{ ref }`) config-time default, since `TierItem.default` itself stays a
|
|
142
|
+
* plain string (Option B from #499, chosen over widening `TierItem.default`
|
|
143
|
+
* to `SemanticValue` — that field is consumed generically as a plain string
|
|
144
|
+
* by every tab kind, not just Color).
|
|
145
|
+
*/
|
|
146
|
+
semanticDefaults?: Record<string, SemanticValue>;
|
|
85
147
|
}
|
|
86
148
|
export interface TabConfig {
|
|
87
149
|
id: string;
|