@takazudo/zdtp 0.7.0 → 0.8.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.
@@ -1,7 +1,9 @@
1
1
  import type { TabConfig } from "../tokens/tier-model.js";
2
- import type { DashboardMode, DashboardModel } from "./types.js";
2
+ import type { DashboardMode, DashboardModel, DashboardModelOptions } from "./types.js";
3
3
  /**
4
4
  * Normalize the authored inventory for a static dashboard. Named color schemes,
5
5
  * stored changes, editor fallback values and pill.customDefault are not inputs.
6
6
  */
7
+ export declare function buildDashboardModel(tabs: readonly TabConfig[], options?: DashboardModelOptions): DashboardModel;
8
+ /** Compatibility for consumers passing the declared mode positionally. */
7
9
  export declare function buildDashboardModel(tabs: readonly TabConfig[], mode?: DashboardMode): DashboardModel;
@@ -1,3 +1,41 @@
1
+ /*
2
+ * Public chrome inputs. Hosts may set these four variables on the dashboard or
3
+ * on an ancestor. The registered initial values keep the dashboard usable when
4
+ * no host value is supplied; the `inherit` declarations below preserve an
5
+ * ancestor override instead of shadowing it.
6
+ *
7
+ * --zdtp-dashboard-light-bg: light-mode page and shell background.
8
+ * --zdtp-dashboard-light-fg: light-mode primary text and foreground.
9
+ * --zdtp-dashboard-dark-bg: dark-mode page and shell background.
10
+ * --zdtp-dashboard-dark-fg: dark-mode primary text and foreground.
11
+ *
12
+ * All other chrome colors are derived from these inputs with light-dark() and
13
+ * color-mix().
14
+ */
15
+ @property --zdtp-dashboard-light-bg {
16
+ syntax: "<color>";
17
+ inherits: true;
18
+ initial-value: #f8fafc;
19
+ }
20
+
21
+ @property --zdtp-dashboard-light-fg {
22
+ syntax: "<color>";
23
+ inherits: true;
24
+ initial-value: #182131;
25
+ }
26
+
27
+ @property --zdtp-dashboard-dark-bg {
28
+ syntax: "<color>";
29
+ inherits: true;
30
+ initial-value: #151b24;
31
+ }
32
+
33
+ @property --zdtp-dashboard-dark-fg {
34
+ syntax: "<color>";
35
+ inherits: true;
36
+ initial-value: #edf2f7;
37
+ }
38
+
1
39
  /* Static dashboard chrome deliberately uses no inventory custom properties.
2
40
  The namespace and div/span markup protect documentation hosts from tag resets. */
3
41
  .zdtp-dashboard,
@@ -6,27 +44,60 @@
6
44
  }
7
45
 
8
46
  .zdtp-dashboard {
9
- --zdtp-dashboard-bg: light-dark(#f8fafc, #151b24);
10
- --zdtp-dashboard-fg: light-dark(#182131, #edf2f7);
11
- --zdtp-dashboard-muted: light-dark(#536174, #acb9cb);
12
- --zdtp-dashboard-border: light-dark(#dce1e8, #465367);
13
- --zdtp-dashboard-card-bg: light-dark(#fff, #202936);
47
+ /* Keep these inputs inheritable so a wrapper can theme the dashboard. */
48
+ --zdtp-dashboard-light-bg: inherit;
49
+ --zdtp-dashboard-light-fg: inherit;
50
+ --zdtp-dashboard-dark-bg: inherit;
51
+ --zdtp-dashboard-dark-fg: inherit;
52
+
53
+ --zdtp-dashboard-bg: light-dark(
54
+ color-mix(in oklab, var(--zdtp-dashboard-light-bg, #f8fafc), var(--zdtp-dashboard-light-fg, #182131) 0%),
55
+ color-mix(in oklab, var(--zdtp-dashboard-dark-bg, #151b24), var(--zdtp-dashboard-dark-fg, #edf2f7) 0%)
56
+ );
57
+ --zdtp-dashboard-fg: light-dark(
58
+ color-mix(in oklab, var(--zdtp-dashboard-light-bg, #f8fafc), var(--zdtp-dashboard-light-fg, #182131) 100%),
59
+ color-mix(in oklab, var(--zdtp-dashboard-dark-bg, #151b24), var(--zdtp-dashboard-dark-fg, #edf2f7) 100%)
60
+ );
61
+ --zdtp-dashboard-muted: light-dark(
62
+ color-mix(in oklab, var(--zdtp-dashboard-light-bg, #f8fafc), var(--zdtp-dashboard-light-fg, #182131) 58%),
63
+ color-mix(in oklab, var(--zdtp-dashboard-dark-bg, #151b24), var(--zdtp-dashboard-dark-fg, #edf2f7) 58%)
64
+ );
65
+ --zdtp-dashboard-border: light-dark(
66
+ color-mix(in oklab, var(--zdtp-dashboard-light-bg, #f8fafc), var(--zdtp-dashboard-light-fg, #182131) 16%),
67
+ color-mix(in oklab, var(--zdtp-dashboard-dark-bg, #151b24), var(--zdtp-dashboard-dark-fg, #edf2f7) 22%)
68
+ );
69
+ --zdtp-dashboard-card-bg: light-dark(
70
+ color-mix(in oklab, color-mix(in oklab, var(--zdtp-dashboard-light-bg, #f8fafc), var(--zdtp-dashboard-light-fg, #182131) 0%), white 20%),
71
+ color-mix(in oklab, color-mix(in oklab, var(--zdtp-dashboard-dark-bg, #151b24), var(--zdtp-dashboard-dark-fg, #edf2f7) 0%), black 8%)
72
+ );
14
73
  --zdtp-dashboard-diag-bg: light-dark(#fff5e6, #3b2c18);
15
74
  --zdtp-dashboard-diag-fg: light-dark(#704612, #ffdaa3);
16
75
  --zdtp-dashboard-diag-accent: light-dark(#9d641a, #e4ad5c);
17
76
  --zdtp-dashboard-focus: light-dark(#245caa, #6488b8);
18
- --zdtp-dashboard-ruler-major: light-dark(#8290a3, #a3b2c7);
19
- --zdtp-dashboard-ruler-minor: light-dark(#c4ccd7, #63748c);
77
+ --zdtp-dashboard-ruler-major: light-dark(
78
+ color-mix(in oklab, var(--zdtp-dashboard-light-bg, #f8fafc), var(--zdtp-dashboard-light-fg, #182131) 48%),
79
+ color-mix(in oklab, var(--zdtp-dashboard-dark-bg, #151b24), var(--zdtp-dashboard-dark-fg, #edf2f7) 52%)
80
+ );
81
+ --zdtp-dashboard-ruler-minor: light-dark(
82
+ color-mix(in oklab, var(--zdtp-dashboard-light-bg, #f8fafc), var(--zdtp-dashboard-light-fg, #182131) 22%),
83
+ color-mix(in oklab, var(--zdtp-dashboard-dark-bg, #151b24), var(--zdtp-dashboard-dark-fg, #edf2f7) 26%)
84
+ );
20
85
  --zdtp-dashboard-bar: light-dark(#526c92, #9dbbe6);
21
- --zdtp-dashboard-sample-bg: light-dark(#fff, #39475b);
22
- --zdtp-dashboard-sample-border: light-dark(#8290a3, #a3b2c7);
23
- --zdtp-dashboard-transparent: light-dark(transparent, transparent);
86
+ --zdtp-dashboard-sample-bg: light-dark(
87
+ color-mix(in oklab, var(--zdtp-dashboard-light-bg, #f8fafc), var(--zdtp-dashboard-light-fg, #182131) 4%),
88
+ color-mix(in oklab, var(--zdtp-dashboard-dark-bg, #151b24), var(--zdtp-dashboard-dark-fg, #edf2f7) 6%)
89
+ );
90
+ --zdtp-dashboard-sample-border: light-dark(
91
+ color-mix(in oklab, var(--zdtp-dashboard-light-bg, #f8fafc), var(--zdtp-dashboard-light-fg, #182131) 48%),
92
+ color-mix(in oklab, var(--zdtp-dashboard-dark-bg, #151b24), var(--zdtp-dashboard-dark-fg, #edf2f7) 52%)
93
+ );
94
+ --zdtp-dashboard-transparent: transparent;
24
95
  min-inline-size: 0;
25
96
  max-inline-size: 100%;
26
97
  border: 1px solid var(--zdtp-dashboard-border);
27
98
  border-radius: 10px;
28
- background: var(--zdtp-dashboard-bg);
29
- color: var(--zdtp-dashboard-fg);
99
+ background: transparent;
100
+ color: inherit;
30
101
  font: 400 14px/1.5 system-ui, sans-serif;
31
102
  letter-spacing: normal;
32
103
  text-align: start;
@@ -35,10 +106,15 @@
35
106
  overflow-wrap: anywhere;
36
107
  }
37
108
 
38
- .zdtp-dashboard[data-chrome='light'] { color-scheme: light; }
39
- .zdtp-dashboard[data-chrome='dark'] { color-scheme: dark; }
40
109
  .zdtp-dashboard[data-chrome='host'] { color-scheme: inherit; }
41
110
 
111
+ /* Shell chrome is scoped to the header and the mode-independent region. This
112
+ leaves a mode-dependent `data-scheme="host"` region able to inherit from the
113
+ page ancestor, even when the shell itself is fixed to light or dark. */
114
+ .zdtp-dashboard[data-chrome='light'] > .zdtp-dashboard__header { color-scheme: light; }
115
+ .zdtp-dashboard[data-chrome='dark'] > .zdtp-dashboard__header { color-scheme: dark; }
116
+ .zdtp-dashboard[data-chrome='host'] > .zdtp-dashboard__header { color-scheme: inherit; }
117
+
42
118
  .zdtp-dashboard :where(div, span) {
43
119
  min-inline-size: 0;
44
120
  margin: 0;
@@ -56,8 +132,21 @@
56
132
  gap: 8px;
57
133
  padding: 20px;
58
134
  border-block-end: 1px solid var(--zdtp-dashboard-border);
135
+ background: var(--zdtp-dashboard-bg);
136
+ color: var(--zdtp-dashboard-fg);
137
+ }
138
+
139
+ .zdtp-dashboard__region {
140
+ display: grid;
141
+ gap: 32px;
142
+ background: var(--zdtp-dashboard-bg);
143
+ color: var(--zdtp-dashboard-fg);
59
144
  }
60
145
 
146
+ .zdtp-dashboard__region[data-scheme='light'] { color-scheme: light; }
147
+ .zdtp-dashboard__region[data-scheme='dark'] { color-scheme: dark; }
148
+ .zdtp-dashboard__region[data-scheme='host'] { color-scheme: inherit; }
149
+
61
150
  .zdtp-dashboard__title {
62
151
  font-size: 22px;
63
152
  font-weight: 700;
@@ -185,16 +274,8 @@
185
274
  align-items: center;
186
275
  flex: 1;
187
276
  padding: 16px;
188
- }
189
-
190
- :where(.zdtp-dashboard[data-mode='light']) .zdtp-dashboard__preview > .zdtp-dashboard__specimen {
191
- background: #eef1f5;
192
- color: #182131;
193
- }
194
-
195
- .zdtp-dashboard[data-mode='dark'] .zdtp-dashboard__preview > .zdtp-dashboard__specimen {
196
- background: #222936;
197
- color: #f1f5f9;
277
+ background: light-dark(#eef1f5, #222936);
278
+ color: light-dark(#182131, #f1f5f9);
198
279
  }
199
280
 
200
281
  .zdtp-dashboard__sample {
@@ -205,14 +286,7 @@
205
286
 
206
287
  .zdtp-dashboard__preview--color > .zdtp-dashboard__specimen {
207
288
  padding: 0;
208
- }
209
-
210
- :where(.zdtp-dashboard[data-mode='light']) .zdtp-dashboard__preview--color > .zdtp-dashboard__specimen {
211
- background: repeating-conic-gradient(#e2e6eb 0% 25%, #fff 0% 50%) 0 / 16px 16px;
212
- }
213
-
214
- .zdtp-dashboard[data-mode='dark'] .zdtp-dashboard__preview--color > .zdtp-dashboard__specimen {
215
- background: repeating-conic-gradient(#3e4652 0% 25%, #252c37 0% 50%) 0 / 16px 16px;
289
+ background: repeating-conic-gradient(light-dark(#e2e6eb, #3e4652) 0% 25%, light-dark(#fff, #252c37) 0% 50%) 0 / 16px 16px;
216
290
  }
217
291
 
218
292
  .zdtp-dashboard__sample--color {
@@ -243,6 +317,7 @@
243
317
  }
244
318
 
245
319
  .zdtp-dashboard__empty {
320
+ background: var(--zdtp-dashboard-bg);
246
321
  color: var(--zdtp-dashboard-muted);
247
322
  }
248
323
 
@@ -1,14 +1,17 @@
1
1
  import type { JSX } from 'preact';
2
2
  import type { TabConfig, TierConfig } from "../tokens/tier-model.js";
3
- import type { DashboardChrome, DashboardMode } from "./types.js";
3
+ import type { DashboardChrome, DashboardInclude, DashboardMode } from "./types.js";
4
4
  /** Visual samples are independent from the panel's editor kind. */
5
5
  export type DashboardPreviewKind = NonNullable<TierConfig['preview']> | 'color' | 'shadow' | 'text';
6
6
  export interface TokenDashboardProps {
7
7
  tabs: readonly TabConfig[];
8
- /** Selects declared per-mode defaults. Does not read the host or panel mode. */
8
+ /** Selects declared per-mode defaults. 'host' follows the inherited CSS
9
+ * color-scheme without reading browser or panel state. Defaults to 'light'. */
9
10
  mode?: DashboardMode;
10
- /** Selects chrome appearance (shell, cards, labels, borders, diagnostics and
11
- * focus/scroll affordances), independently of mode's declared defaults.
11
+ /** Selects visible rows by mode dependence. Defaults to 'all'. */
12
+ include?: DashboardInclude;
13
+ /** Selects the shell and mode-independent region's appearance, including
14
+ * cards, labels, borders, diagnostics and focus/scroll affordances.
12
15
  * 'host' inherits the host's effective color-scheme. Defaults to 'light'. */
13
16
  chrome?: DashboardChrome;
14
17
  title?: string;
@@ -24,4 +27,4 @@ export interface TokenDashboardProps {
24
27
  * server renderer without hydration, browser globals, or panel configuration.
25
28
  * Include @takazudo/zdtp/dashboard/styles.css through the host's CSS pipeline.
26
29
  */
27
- export declare function TokenDashboard({ tabs, mode, chrome, title, id, previewOverrides, previewText, }: TokenDashboardProps): JSX.Element;
30
+ export declare function TokenDashboard({ tabs, mode, include, chrome, title, id, previewOverrides, previewText, }: TokenDashboardProps): JSX.Element;
@@ -1,6 +1,11 @@
1
1
  import type { TierConfig, TierValueKind } from "../tokens/tier-model.js";
2
2
  /** Internal, render-independent description of declared token defaults. */
3
- export type DashboardMode = 'light' | 'dark';
3
+ export type DashboardMode = 'light' | 'dark' | 'host';
4
+ export type DashboardInclude = 'all' | 'mode-dependent' | 'mode-independent';
5
+ export interface DashboardModelOptions {
6
+ mode?: DashboardMode;
7
+ include?: DashboardInclude;
8
+ }
4
9
  /** Appearance of the dashboard chrome, independent of declared token mode. */
5
10
  export type DashboardChrome = 'light' | 'dark' | 'host';
6
11
  export interface DashboardDiagnostic {
@@ -24,6 +29,13 @@ export interface DashboardRow {
24
29
  cssVar: string;
25
30
  kind: TierValueKind['kind'];
26
31
  source: 'item' | 'base-role';
32
+ modeDependent: boolean;
33
+ /** Direct authored pair; reference-derived dependence has no local pair. */
34
+ sides: {
35
+ light: string;
36
+ dark: string;
37
+ } | null;
38
+ origin: 'modes' | 'semantic' | 'default' | 'reference' | null;
27
39
  defaultValue: string;
28
40
  /** Human-readable selected-mode declaration, including explicit semantic overrides. */
29
41
  declaredValue: string;
@@ -31,8 +43,9 @@ export interface DashboardRow {
31
43
  cssValue: string | null;
32
44
  /**
33
45
  * Follows direct declared references only, never computes CSS. Expressions
34
- * remain expressions. Null means invalid or dependent on unknown context;
35
- * the renderer must not show a value preview in that case.
46
+ * remain expressions. Null means invalid or dependent on unknown context.
47
+ * In host mode, mode-dependent rows stay null while cssValue retains the
48
+ * declarations needed for the browser to resolve the inherited scheme.
36
49
  */
37
50
  resolvedValue: string | null;
38
51
  references: DashboardReference[];
@@ -56,7 +69,10 @@ export interface DashboardTab {
56
69
  }
57
70
  export interface DashboardModel {
58
71
  mode: DashboardMode;
72
+ include: DashboardInclude;
73
+ /** Visible inventory, with empty tiers and tabs omitted. */
59
74
  tabs: DashboardTab[];
75
+ /** Complete graph, including rows hidden by include. */
60
76
  rows: DashboardRow[];
61
77
  /** Declare these on each preview scope, never on :root or the document. */
62
78
  declarations: Readonly<Record<string, string>>;
@@ -1,40 +1,39 @@
1
1
  /**
2
- * Import modal — accepts a pasted design-tokens JSON document and lifts it
3
- * into a `TweakState` via `deserialize()`. `deserialize()` validates the
4
- * `$schema` key against the fixed `SCHEMA_V1`/`SCHEMA_V2`/`SCHEMA_V3`
5
- * constants exported by the serde — `panelConfig.schemaId` plays no part in
6
- * that validation; it is a UI-label-only field (#498). This component does
7
- * not read `schemaId` at all; the hint/placeholder/error copy below names
8
- * the actual accepted constants directly.
2
+ * Import modal — accepts a pasted design-tokens JSON document and guides the
3
+ * user through paste → analyze → scope → load.
9
4
  *
10
- * Ported verbatim from zudo-doc's
11
- * `src/components/design-token-tweak/import-modal.tsx`. Intentional deltas:
12
- * - `deserialize` / `DesignTokenSchemaError` come from this package's serde
13
- * (`./utils/design-token-serde`).
14
- * - State types import from this package's state envelope.
15
- * - Modal class names are derived from `panelConfig.modalClassPrefix` via
16
- * `modalClass(...)` so a single config swap re-themes every dialog.
5
+ * `analyzeDesignTokenJson()` is deliberately state-free, so the first step
6
+ * can inspect a document without applying values or touching storage. The
7
+ * selected tabs and mode/merge choices are passed to `deserialize()` only
8
+ * after the user explicitly chooses Load.
17
9
  *
18
10
  * Modal lifecycle uses the native `<dialog>` element via `showModal()` /
19
- * `close()`. Every dismissal path (× button, backdrop click, Escape key, the
20
- * programmatic "Close" button) routes through `dialog.close()` so the native
21
- * `close` event — and thus `onClose` — fires exactly once per dismissal.
11
+ * `close()`. Every dismissal path routes through `dialog.close()` so the
12
+ * native `close` event — and thus `onClose` — fires exactly once per
13
+ * dismissal.
22
14
  */
23
15
  import type { ColorTweakState, TweakState } from "./state/tweak-state.js";
24
16
  import { type PanelConfig } from "./config/panel-config.js";
25
17
  export interface ImportModalProps {
26
18
  onClose: () => void;
27
19
  /** Called with the parsed state when the user hits "Load". The caller is
28
- * responsible for applying it to the panel + persisting it. */
20
+ * responsible for applying it to the panel + persisting it. */
29
21
  onLoad: (state: TweakState) => void;
30
22
  /** Color baseline filled in for fields absent from the payload. */
31
23
  colorDefaults: ColorTweakState;
24
+ /**
25
+ * The mounted panel instance's live state. It is used by scoped merge and
26
+ * one-side imports to preserve values from the instance being edited.
27
+ * Omitted for backwards-compatible direct renders; serde then falls back to
28
+ * manifest/default values for those options.
29
+ */
30
+ current?: TweakState;
32
31
  /**
33
32
  * The mounted panel instance's config (multi-instance, #357). When supplied,
34
- * the modal derives its modal classes + title id from THIS instance rather
35
- * than the active default instance. Omitted (e.g. a direct test render) →
36
- * `getPanelConfig()`, preserving the single-panel path.
33
+ * the modal derives its modal classes + title id and serde lookups from THIS
34
+ * instance rather than the active default instance. Omitted (e.g. a direct
35
+ * test render) → `getPanelConfig()`, preserving the single-panel path.
37
36
  */
38
37
  instanceConfig?: PanelConfig;
39
38
  }
40
- export declare function ImportModal({ onClose, onLoad, colorDefaults, instanceConfig }: ImportModalProps): import("preact").JSX.Element;
39
+ export declare function ImportModal({ onClose, onLoad, colorDefaults, current, instanceConfig, }: ImportModalProps): import("preact").JSX.Element;
@@ -1,7 +1,7 @@
1
1
  import { jsx as y, jsxs as K, Fragment as kt } from "preact/jsx-runtime";
2
2
  import { useEffect as P, useState as Y, useRef as O, useMemo as J, useCallback as X } from "preact/hooks";
3
- import { b as ft, p as wt, u as ht, a as Ne, A as bt, Z as gt } from "./index-CUWkR-Gb.js";
4
- import { g as vt, m as j } from "./panel-config-Crn5QJGy.js";
3
+ import { b as ft, p as wt, u as ht, a as Ne, A as bt, Z as gt } from "./index-blRjSavc.js";
4
+ import { g as vt, m as j } from "./panel-config-DKfob-1r.js";
5
5
  const xt = (e, o) => {
6
6
  const t = new Array(e.length + o.length);
7
7
  for (let r = 0; r < e.length; r++)