@takazudo/zdtp 0.5.1 → 0.6.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.
Files changed (109) hide show
  1. package/CHANGELOG.md +55 -1
  2. package/PORTABLE-CONTRACT.md +84 -1
  3. package/dist/apply/build-apply-overrides.d.ts +2 -2
  4. package/dist/apply/last-applied.d.ts +1 -1
  5. package/dist/apply/reconcile-applied.d.ts +2 -2
  6. package/dist/apply/route-tokens-to-files.d.ts +1 -1
  7. package/dist/apply/tier-resolver.d.ts +1 -1
  8. package/dist/apply-modal.d.ts +2 -2
  9. package/dist/astro/host-adapter.js +3 -3
  10. package/dist/astro/index.d.ts +8 -8
  11. package/dist/astro/index.js +1 -1
  12. package/dist/{autoload-state-BI4-9A58.js → autoload-state-CGnis85c.js} +1 -1
  13. package/dist/bulk/bulk-actions.d.ts +3 -3
  14. package/dist/bulk/index.d.ts +2 -2
  15. package/dist/chain/index.d.ts +2 -2
  16. package/dist/chain/token-chain-context.d.ts +3 -3
  17. package/dist/chain/token-chain-popover.d.ts +2 -2
  18. package/dist/changed/contribution.d.ts +5 -5
  19. package/dist/changed/footer-content.d.ts +4 -4
  20. package/dist/changed/index.d.ts +4 -4
  21. package/dist/components/color-picker/color-field.d.ts +1 -1
  22. package/dist/components/color-picker/index.d.ts +2 -2
  23. package/dist/components/palette-chart/index.d.ts +2 -2
  24. package/dist/components/palette-chart/palette-chart.d.ts +4 -4
  25. package/dist/config/cluster-config.d.ts +4 -4
  26. package/dist/config/color-scheme-utils.d.ts +1 -1
  27. package/dist/config/panel-config.d.ts +5 -5
  28. package/dist/controls/actions-menu-popover.d.ts +4 -0
  29. package/dist/controls/role-button.d.ts +4 -1
  30. package/dist/controls/tier-ref-selector.d.ts +1 -1
  31. package/dist/dom-tweaker/dom-tweaker-diff-action-link.d.ts +1 -1
  32. package/dist/dom-tweaker/dom-tweaker-orchestrator.d.ts +1 -1
  33. package/dist/dom-tweaker/dom-tweaker-state.d.ts +1 -1
  34. package/dist/dom-tweaker/lazy/class-editor-popup.d.ts +1 -1
  35. package/dist/dom-tweaker/lazy/diff-export-modal.d.ts +1 -1
  36. package/dist/dom-tweaker/lazy/index.d.ts +2 -2
  37. package/dist/element-inspect/element-inspect-context.d.ts +1 -1
  38. package/dist/element-inspect/element-inspect-orchestrator.d.ts +3 -3
  39. package/dist/element-inspect/element-inspect-overlay.d.ts +1 -1
  40. package/dist/element-inspect/find-tokens-for-element.d.ts +1 -1
  41. package/dist/element-inspect/index.d.ts +8 -8
  42. package/dist/element-path/element-path-state.d.ts +1 -1
  43. package/dist/element-path/index.d.ts +7 -7
  44. package/dist/export-modal.d.ts +2 -2
  45. package/dist/highlight/highlight-orchestrator.d.ts +2 -2
  46. package/dist/highlight/highlight-state.d.ts +1 -1
  47. package/dist/highlight/highlight-toggle-button.d.ts +2 -2
  48. package/dist/history/buttons.d.ts +1 -1
  49. package/dist/history/index.d.ts +3 -3
  50. package/dist/history/rail.d.ts +2 -2
  51. package/dist/history/snapshots.d.ts +2 -2
  52. package/dist/import-modal.d.ts +2 -2
  53. package/dist/{index-D4NR_eYT.js → index-DWs1XPfy.js} +1250 -1245
  54. package/dist/{index-RLAXfjv2.js → index-LYsbHWcy.js} +2 -2
  55. package/dist/index.d.ts +14 -14
  56. package/dist/index.js +14 -13
  57. package/dist/{panel-config-CqbuB0nh.js → panel-config-Crn5QJGy.js} +243 -208
  58. package/dist/panel.d.ts +2 -2
  59. package/dist/picker/index.d.ts +4 -4
  60. package/dist/search/command-palette.d.ts +3 -3
  61. package/dist/search/contribution.d.ts +1 -1
  62. package/dist/search/index.d.ts +4 -4
  63. package/dist/search/match-bar.d.ts +1 -1
  64. package/dist/search/token-search.d.ts +3 -3
  65. package/dist/server/create-apply-handler.d.ts +2 -2
  66. package/dist/server/index.d.ts +6 -6
  67. package/dist/shell/dock-mode-switch.d.ts +1 -1
  68. package/dist/shell/regions.d.ts +1 -1
  69. package/dist/shell/tab-bar.d.ts +1 -1
  70. package/dist/shell/tab-overflow-popover.d.ts +1 -1
  71. package/dist/specimen/on-page-specimen.d.ts +3 -3
  72. package/dist/specimen/preview-glyphs.d.ts +1 -1
  73. package/dist/specimen/specimen-state.d.ts +1 -1
  74. package/dist/specimen/specimen-tab-body.d.ts +5 -5
  75. package/dist/specimen/specimen-toolbar.d.ts +1 -1
  76. package/dist/specimen/specimen-values.d.ts +1 -1
  77. package/dist/state/autoload-state.d.ts +1 -1
  78. package/dist/state/history.d.ts +1 -1
  79. package/dist/state/persist.d.ts +3 -3
  80. package/dist/state/transaction.d.ts +3 -3
  81. package/dist/state/tweak-state.d.ts +12 -12
  82. package/dist/tabs/_generic-item-editor.d.ts +1 -1
  83. package/dist/tabs/color-tab.d.ts +6 -6
  84. package/dist/tabs/flat/flat-tab.d.ts +5 -5
  85. package/dist/tabs/flat/index.d.ts +8 -8
  86. package/dist/tabs/flat/scroll-to-token-row.d.ts +1 -1
  87. package/dist/tabs/flat/tier-section.d.ts +3 -3
  88. package/dist/tabs/flat/token-controller.d.ts +1 -1
  89. package/dist/tabs/flat/token-row.d.ts +2 -2
  90. package/dist/tabs/flat/types.d.ts +1 -1
  91. package/dist/tabs/font-tab.d.ts +6 -6
  92. package/dist/tabs/generic-tab.d.ts +4 -4
  93. package/dist/tabs/notes-tab.d.ts +1 -1
  94. package/dist/tabs/palette/palette-check-view.d.ts +3 -3
  95. package/dist/tabs/palette/palette-edit-view.d.ts +3 -3
  96. package/dist/tabs/palette/palette-readout.d.ts +1 -1
  97. package/dist/tabs/palette/palette-tab.d.ts +3 -3
  98. package/dist/tabs/size-tab.d.ts +5 -5
  99. package/dist/tabs/spacing-tab.d.ts +5 -5
  100. package/dist/testing.d.ts +6 -6
  101. package/dist/testing.js +16 -15
  102. package/dist/tokens/tier-model.d.ts +2 -2
  103. package/dist/{tweak-state-c53KtLHq.js → tweak-state-Dzr5kDhX.js} +210 -207
  104. package/dist/utils/color-oklch.d.ts +2 -2
  105. package/dist/utils/design-token-serde.d.ts +2 -2
  106. package/dist/utils/token-diff.d.ts +3 -3
  107. package/dist/utils/token-graph.d.ts +4 -4
  108. package/dist/utils/token-index.d.ts +2 -2
  109. package/package.json +5 -5
package/CHANGELOG.md CHANGED
@@ -4,10 +4,65 @@ All notable changes to `@takazudo/zdtp` are documented in this file.
4
4
 
5
5
  The format is based on Keep a Changelog, and release notes are generated from the changelog MDX pages.
6
6
 
7
+ ## [0.6.0] - 2026-09-08
8
+
9
+ ### Breaking Changes
10
+
11
+ - fix: validate reserved palette tab configuration (73e70f9). The reserved `palette` tab now rejects `colorExtras`, empty or non-color tiers, and inconsistent CSS-variable families. This also affects Astro host configuration validation. **Migration**: remove `colorExtras` from the `palette` tab; give each tier non-empty color items using either consecutive numbered CSS variables with one prefix or unique named variables with one prefix. Move mixed-kind generic tiers to a differently named tab and update any `referencesRamps` tab references.
12
+
13
+ ### Features
14
+
15
+ - feat(minimal): teach grouped palette and semantic colors (5dcbe12)
16
+ - feat(playground): use grouped OKLCH palette and semantic colors (42c7c86)
17
+
18
+ ### Fixed
19
+
20
+ - fix: preserve host color-scheme on per-mode apply (90c30c6)
21
+ - fix: render specimen fonts from instance values (7d18952)
22
+ - fix: normalize emitted declaration module specifiers (8f858c0)
23
+ - fix: expose panel config validator through public entrypoints (5335713)
24
+
25
+ ### Other Changes
26
+
27
+ - docs: explain grouped palettes and per-mode semantic colors (3d1d114)
28
+ - Restructure playground colors into grouped semantic ramps (2076abe)
29
+ - test: verify specimen instance isolation in Chromium (6ff7ed6)
30
+ - test: guard packed declarations across TypeScript resolution modes (f1e5e21)
31
+
32
+ ## [0.5.2] - 2026-09-08
33
+
34
+ ### Features
35
+
36
+ - Header actions now carry a stable `data-zdtp-action` attribute on both affordances — the inline header link and the compact kebab popover — with the ids `export`, `import`, `apply`, and `reset`. The ids are stable across releases; the display labels are not. This gives consumer tests a selector that survives a label change, which is what broke in [#831](https://github.com/Takazudo/zudo-design-token-panel/issues/831). The hook removes the dependence on the label; it does **not** remove the responsive collapse, so a locator still needs to be visibility-qualified and panel-scoped — see the recipe [Reaching header actions](https://zdtp.zudolab.dev/docs/recipes/reaching-header-actions/) and `PORTABLE-CONTRACT.md` §7.6. (91916b4, [#840](https://github.com/Takazudo/zudo-design-token-panel/issues/840))
37
+
38
+ ### Fixed
39
+
40
+ - The popover action items and the header region items are now keyed by their stable action id rather than by their display label. Two actions sharing a label previously produced duplicate keys, so reconciliation could reuse the wrong node and leave an item with a stale handler or `aria-disabled` state. (c3384ae)
41
+ - The 0.5.1 changelog said the old header-action selector "worked through 0.4.14". It worked through **0.5.0** — `v0.4.15` and `v0.5.0` both shipped before the collapse landed. (c3384ae)
42
+
43
+ ### Other Changes
44
+
45
+ - The documentation site moved to `https://zdtp.zudolab.dev/`, and the playground and minimal example to `https://zdtp-playground.zudolab.dev/` and `https://zdtp-minimal.zudolab.dev/`. The package `homepage` field follows. (0b9e596, ef41bf2, [#835](https://github.com/Takazudo/zudo-design-token-panel/issues/835))
46
+ - The 0.5.1 release notes now flag the header-action collapse as consumer-affecting, with the exact `1135px` container-query threshold and the fact that it measures the shell's content-box inline size rather than the viewport. (6215888, [#841](https://github.com/Takazudo/zudo-design-token-panel/issues/841))
47
+ - New bilingual recipe, [Reaching header actions](https://zdtp.zudolab.dev/docs/recipes/reaching-header-actions/), covering both a label-based pattern for existing releases and the id-based pattern from this one. (c701369, [#842](https://github.com/Takazudo/zudo-design-token-panel/issues/842))
48
+ - Twenty dead `*.pages.dev` example-demo links on the Examples page were repointed to their live `zudolab.dev` hosts. (c83ffa3, [#836](https://github.com/Takazudo/zudo-design-token-panel/issues/836))
49
+
7
50
  ## [0.5.1] - 2026-09-06
8
51
 
9
52
  The panel now fits its token grids, card controls, and header controls at the minimum panel width instead of overflowing. Multiple panels keep stable spawn positions: spawn ordinals are persisted and survive Astro client-side navigation. Eager loading is bounded to state keys the panel can actually read, and the specimen stylesheet gained the boundaries the docs-adoption check required.
10
53
 
54
+ ### Breaking Changes
55
+
56
+ - **Narrowed the accepted-key set of `EAGER_LOAD_GATE_STATE_FAMILY.matchesKey`, a public exported API.** 0.5.0 accepted `${storagePrefix}-state` optionally followed by `-v` and one or more digits. 0.5.1 accepts only exact matches against the new `READABLE_STATE_KEY_SUFFIXES` registry — `-state`, `-state-v2`, `-state-v3`, `-state-v4`. So `${storagePrefix}-state` and `${storagePrefix}-state-v2` still match, while `${storagePrefix}-state-v1`, `${storagePrefix}-state-v0`, `${storagePrefix}-state-v01`, and `${storagePrefix}-state-v123` matched in 0.5.0 and do not in 0.5.1. The narrowing is deliberate — the synchronous eager gate must probe only the key versions the loader can actually read — but it is consumer-observable, the TypeScript signature is unchanged so a type check will not surface it, and it should have ridden a minor release rather than this patch. **Migration**: hosts asserting on `-state-vN` keys should derive them from the new `READABLE_STATE_KEY_SUFFIXES` export instead of matching a numeric pattern, so their assertions self-update at the next storage-format bump. (bcc55fd, [#790](https://github.com/Takazudo/zudo-design-token-panel/issues/790), [#793](https://github.com/Takazudo/zudo-design-token-panel/issues/793), [#814](https://github.com/Takazudo/zudo-design-token-panel/issues/814))
57
+
58
+ - **Header action links now collapse behind the kebab menu at a panel content width of 1135px and below, making previously-clickable controls unreachable by their old selectors.** _(Retroactive correction added 2026-09-08. This behaviour shipped in 0.5.1 but was recorded only under **Fixed**, as `fix(panel): yield header controls before floating panel overflow`; it belongs here.)_ The header action links — Export, Load from JSON…, Apply, Reset — are hidden and served instead from the kebab trigger `.tokenpanel-actions-menu-btn` (`aria-label="Panel actions"`), which opens `.tokenpanel-actions-popover`. The rule is `@container tokenpanel (max-width: 1135px)` against `.tokenpanel-shell` (`container: tokenpanel / inline-size`). Two properties of that threshold matter: it engages at **1135px and below** — exactly 1135px collapses, 1136px does not — and it measures the **shell's own content-box inline size, not the viewport**, so the panel's borders count against the measured width. 1135px is wide enough that an ordinary desktop panel is already past it; a shell at 1024px is not a narrow or mobile case. The surprise is not that a responsive collapse exists but that it engages at a width most people would call desktop. Collapsed links are `display: none` and therefore leave the accessibility tree, so a query that worked through 0.5.0 times out on 0.5.1:
59
+
60
+ ```js
61
+ await page.getByRole('button', { name: 'Reset', exact: true }).click();
62
+ ```
63
+
64
+ Like the `matchesKey` narrowing above, this is consumer-observable, the TypeScript signature is unchanged so a type check will not surface it, and it should have ridden a minor release rather than this patch. **Migration**: open the kebab menu before reaching for an action, or drive the panel at a content width above the threshold — the recipe [Reaching header actions](https://zdtp.zudolab.dev/docs/recipes/reaching-header-actions/) covers both, with the boundary arithmetic. A stable `data-zdtp-action` attribute for these controls landed in 0.5.2; it does not exist in 0.5.1. (06cbb0e, [#787](https://github.com/Takazudo/zudo-design-token-panel/issues/787), [#831](https://github.com/Takazudo/zudo-design-token-panel/issues/831))
65
+
11
66
  ### Fixed
12
67
 
13
68
  - fix: fit token grids and card controls at minimum panel width (8db4235)
@@ -25,7 +80,6 @@ The panel now fits its token grids, card controls, and header controls at the mi
25
80
  - Merge branch 'topic/790-storage-bootstrap-confirm' into base/sweep-260906-2-storage-bootstrap (aca17d0)
26
81
  - Confirm storage bootstrap regressions (1fdb75e)
27
82
  - Merge branch 'topic/790-readable-gate-probe' into base/sweep-260906-2-storage-bootstrap (be49753)
28
- - Bound eager loading to readable state keys (bcc55fd)
29
83
  - Merge branch 'topic/790-astro-ordinal-lifecycle' into base/sweep-260906-2-storage-bootstrap (48a76ab)
30
84
  - Keep spawn positions stable across Astro navigation (2a6672b)
31
85
  - Merge branch 'topic/790-persisted-spawn-ordinal' into base/sweep-260906-2-storage-bootstrap (03deeaa)
@@ -191,6 +191,24 @@ export function setPanelColorPresets(presets: Record<string, ColorScheme>): void
191
191
  export function assertValidPanelConfig(value: unknown): asserts value is PanelConfig;
192
192
  ```
193
193
 
194
+ `assertValidPanelConfig` and its `PanelConfig` type are public exports from both
195
+ `@takazudo/zdtp` and `@takazudo/zdtp/testing`; no deep import is needed.
196
+ Run the assertion against your host config in a CI test, for example:
197
+
198
+ ```ts
199
+ import { assertValidPanelConfig } from '@takazudo/zdtp/testing';
200
+ import { panelConfig } from './panel-config';
201
+
202
+ // An invalid manifest throws and fails the test/CI run.
203
+ assertValidPanelConfig(panelConfig);
204
+ ```
205
+
206
+ The assertion accepts `unknown` and narrows it to `PanelConfig` on success.
207
+ Validation is explicit: `configurePanel` does not call this assertion. A host
208
+ that wants configure-time validation can import both functions from
209
+ `@takazudo/zdtp` and call `assertValidPanelConfig(config)` before
210
+ `configurePanel(config)`.
211
+
194
212
  Required behaviours:
195
213
 
196
214
  - **Multi-instance.** Calling `configurePanel` with a **distinct**
@@ -515,7 +533,7 @@ export interface TierConfig {
515
533
  }
516
534
 
517
535
  For the full `SemanticValue` mapping and emission behavior, see the maintained
518
- [Color-cluster reference](https://zudo-design-token-panel.takazudomodular.com/docs/reference/color-cluster/).
536
+ [Color-cluster reference](https://zdtp.zudolab.dev/docs/reference/color-cluster/).
519
537
 
520
538
  /**
521
539
  * Color-cluster extras — the non-tier fields required for the color tab.
@@ -1515,6 +1533,47 @@ pipeline:
1515
1533
  </script>
1516
1534
  ```
1517
1535
 
1536
+ ### 7.6 `data-zdtp-action` — stable header-action DOM hook
1537
+
1538
+ The four header actions carry a stable per-action attribute so a consumer test
1539
+ can select one without matching its display label:
1540
+
1541
+ ```html
1542
+ <div role="button" class="tokenpanel-action-link" data-zdtp-action="export">Export</div>
1543
+ ```
1544
+
1545
+ | Action label | `data-zdtp-action` |
1546
+ | ----------------- | ------------------ |
1547
+ | `Export` | `export` |
1548
+ | `Load from JSON…` | `import` |
1549
+ | `Apply` | `apply` |
1550
+ | `Reset` | `reset` |
1551
+
1552
+ **The ids are stable; the labels are not.** Labels are display strings and may
1553
+ change at any minor version (note the ellipsis in `Load from JSON…`, which is
1554
+ `…` U+2026, not three periods). Select on the attribute, never on the text.
1555
+
1556
+ Both affordances emit it with identical values: the header row and the compact
1557
+ kebab popover that takes over visually below the header's container-query
1558
+ threshold.
1559
+
1560
+ **The hook does not remove the visibility branch.** `ShellHeader` *always*
1561
+ renders the header action row; the container query only hides it with
1562
+ `display: none`. So while the compact popover is open, `[data-zdtp-action="reset"]`
1563
+ matches **two** elements — the hidden header control and the popover item. A
1564
+ bare attribute selector is therefore not unambiguous at narrow widths; qualify
1565
+ it by visibility (Playwright's `:visible` / `.filter({ visible: true })`, or a
1566
+ non-zero bounding box) to land on exactly one.
1567
+
1568
+ Scope — this hook covers the header actions and their compact popover only,
1569
+ which means every layout sharing `ShellHeader`: floating, right-docked, and
1570
+ bottom-docked. Deliberately **not** covered:
1571
+
1572
+ - The **command palette**, which renders its own Export / Import / Apply entries
1573
+ and whose reset entries are per-tab (`Reset {tab.label}`), not the header's
1574
+ reset-all.
1575
+ - **Mini mode**, which renders Apply and has no header.
1576
+
1518
1577
  ---
1519
1578
 
1520
1579
  ## 8. Storage-key continuity & migration paths
@@ -1660,6 +1719,28 @@ Items this contract deliberately does NOT pin down:
1660
1719
 
1661
1720
  ---
1662
1721
 
1722
+ ## 11. Versioning & compatibility
1723
+
1724
+ The package is pre-1.0 (`0.x`). This section states what a consumer may rely
1725
+ on across a release bump.
1726
+
1727
+ - **The versioning promise.** On 0.x, patch releases preserve documented
1728
+ public contracts and accepted consumer inputs. Consumer-breaking contract
1729
+ changes, including input narrowing, require a minor release. Patches remain
1730
+ free to fix bugs, and a bug fix can change observable behavior; the promise
1731
+ only bounds what a patch may take *away* from a consumer.
1732
+ - **How breaking changes are signalled.** A consumer-breaking contract change
1733
+ gets its own heading in the release notes, with a migration pointer naming
1734
+ the new adoption path.
1735
+ - **What consumers should do.** A host mirroring the eager-load gate should
1736
+ derive its checks from the exported registries
1737
+ (`READABLE_STATE_KEY_SUFFIXES`, `EAGER_LOAD_GATE_KEY_SUFFIXES`) documented
1738
+ in §6.2, rather than matching a pattern of its own — that way the host's
1739
+ assertions self-update on the next storage-format bump instead of silently
1740
+ drifting from the package's actual behavior.
1741
+
1742
+ ---
1743
+
1663
1744
  ## Appendix A — section index
1664
1745
 
1665
1746
  Cross-reference table — what each section pins down.
@@ -1688,7 +1769,9 @@ Cross-reference table — what each section pins down.
1688
1769
  | Modal class prefix and `data-design-token-panel-modal` selector contract | §7.3 |
1689
1770
  | Self-contained panel chrome palette (no host theme reads) | §7.4 |
1690
1771
  | Host-adapter side-effect import (paired-unit obligation) | §7.5 |
1772
+ | `data-zdtp-action` stable header-action hook (ids stable, labels not; two matches while the compact popover is open) | §7.6 |
1691
1773
  | v4 envelope precedence, v1/v2/v3 storage migration, and typography-id rename map | §2, §8.3, §8.4 |
1692
1774
  | JSON export/import schemas v1/v2/v3 (serde) | §9 |
1693
1775
  | Out-of-scope / deferred concerns | §10 |
1776
+ | Versioning promise, breaking-change signalling, and consumer guidance for mirroring the eager-load gate registries | §11 |
1694
1777
  | Feature walkthrough and shortcut table | [Panel UX tour](/docs/recipes/panel-ux-tour) |
@@ -60,8 +60,8 @@
60
60
  *
61
61
  * Pure / no IO — safe to import anywhere (browser, Node, tests).
62
62
  */
63
- import type { ColorTweakState, TweakState, ColorClusterConfig } from '../state/tweak-state';
64
- import type { TabConfig } from '../tokens/tier-model';
63
+ import type { ColorTweakState, TweakState, ColorClusterConfig } from "../state/tweak-state.js";
64
+ import type { TabConfig } from "../tokens/tier-model.js";
65
65
  /**
66
66
  * Produce the flat cssVar → value map for the dev-API handler.
67
67
  *
@@ -1,4 +1,4 @@
1
- import type { PanelConfig } from '../config/panel-config';
1
+ import type { PanelConfig } from "../config/panel-config.js";
2
2
  export type FlatOverrides = Record<string, string>;
3
3
  export declare function loadLastApplied(cfg: PanelConfig): FlatOverrides;
4
4
  export declare function saveLastApplied(overrides: FlatOverrides, cfg: PanelConfig): void;
@@ -1,5 +1,5 @@
1
- import type { PanelConfig } from '../config/panel-config';
2
- import type { ColorTweakState, TweakState } from '../state/tweak-state';
1
+ import type { PanelConfig } from "../config/panel-config.js";
2
+ import type { ColorTweakState, TweakState } from "../state/tweak-state.js";
3
3
  /**
4
4
  * Remove only overrides the server confirms it wrote. CSS variables are
5
5
  * resolved through the manifest token index so color, secondary-color,
@@ -14,7 +14,7 @@
14
14
  *
15
15
  * No IO, no DOM, no Node-specific imports — safe to bundle for the browser.
16
16
  */
17
- import type { ApplyRoutingMap } from '../config/panel-config';
17
+ import type { ApplyRoutingMap } from "../config/panel-config.js";
18
18
  /**
19
19
  * Prefix-family identifier. Plain string — the routing map is host-supplied.
20
20
  */
@@ -19,7 +19,7 @@
19
19
  * For a reference tier (referencesTier is set) the value is the id of a target
20
20
  * item in the named tier.
21
21
  */
22
- import type { TabConfig } from '../tokens/tier-model';
22
+ import type { TabConfig } from "../tokens/tier-model.js";
23
23
  export type TabOverrides = Readonly<Record<string, Readonly<Record<string, string>>>>;
24
24
  export declare class TierResolverError extends Error {
25
25
  constructor(message: string);
@@ -1,5 +1,5 @@
1
- import { type PanelConfig } from './config/panel-config';
2
- import { type ColorTweakState, type TweakState } from './state/tweak-state';
1
+ import { type PanelConfig } from "./config/panel-config.js";
2
+ import { type ColorTweakState, type TweakState } from "./state/tweak-state.js";
3
3
  export interface ApplyModalProps {
4
4
  state: TweakState;
5
5
  open: boolean;
@@ -1,6 +1,6 @@
1
- import { c as y, g as m, a as w, b, i as P } from "../panel-config-CqbuB0nh.js";
2
- import { g, Z as A } from "../tweak-state-c53KtLHq.js";
3
- import { s as D, l as E, a as _, i as c, r as f, c as k, b as S, d } from "../autoload-state-BI4-9A58.js";
1
+ import { c as y, g as m, a as w, b, i as P } from "../panel-config-Crn5QJGy.js";
2
+ import { g, Z as A } from "../tweak-state-Dzr5kDhX.js";
3
+ import { s as D, l as E, a as _, i as c, r as f, c as k, b as S, d } from "../autoload-state-CGnis85c.js";
4
4
  import { READABLE_STATE_KEY_SUFFIXES as T } from "../constants.js";
5
5
  const u = "tokenpanel-config";
6
6
  function I() {
@@ -22,11 +22,11 @@
22
22
  * callers don't need a deep `@takazudo/zdtp/dist/config/panel-config`
23
23
  * import to type their config object.
24
24
  */
25
- export type { PanelConfig } from '../config/panel-config';
26
- export type { ColorScheme, ColorRef } from '../config/color-schemes';
27
- export type { ColorClusterConfig } from '../state/tweak-state';
28
- export { setPanelColorPresets } from '../config/panel-config';
29
- export { colorSchemes } from '../config/color-schemes';
30
- export { panelSettings, SEMANTIC_CSS_NAMES, SEMANTIC_DEFAULTS_ZD } from '../config/color-scheme-utils';
31
- export { GROUP_ORDER, FONT_GROUP_ORDER, SIZE_GROUP_ORDER, GROUP_TITLES } from '../tokens/manifest';
32
- export type { TokenDef, TokenManifest } from '../tokens/manifest';
25
+ export type { PanelConfig } from "../config/panel-config.js";
26
+ export type { ColorScheme, ColorRef } from "../config/color-schemes.js";
27
+ export type { ColorClusterConfig } from "../state/tweak-state.js";
28
+ export { setPanelColorPresets } from "../config/panel-config.js";
29
+ export { colorSchemes } from "../config/color-schemes.js";
30
+ export { panelSettings, SEMANTIC_CSS_NAMES, SEMANTIC_DEFAULTS_ZD } from "../config/color-scheme-utils.js";
31
+ export { GROUP_ORDER, FONT_GROUP_ORDER, SIZE_GROUP_ORDER, GROUP_TITLES } from "../tokens/manifest.js";
32
+ export type { TokenDef, TokenManifest } from "../tokens/manifest.js";
@@ -1,4 +1,4 @@
1
- import { s as t } from "../panel-config-CqbuB0nh.js";
1
+ import { s as t } from "../panel-config-Crn5QJGy.js";
2
2
  import { c as d } from "../color-schemes-CgzOBqGO.js";
3
3
  import { F as r, G as m, a as g, S as z } from "../manifest-DvuKi7I4.js";
4
4
  const e = {
@@ -1,4 +1,4 @@
1
- import { g as n, j as o } from "./panel-config-CqbuB0nh.js";
1
+ import { g as n, j as o } from "./panel-config-Crn5QJGy.js";
2
2
  function c() {
3
3
  return typeof document < "u" && document !== null && typeof document.getElementById == "function";
4
4
  }
@@ -1,7 +1,7 @@
1
1
  import type { ComponentChildren } from 'preact';
2
- import type { TierConfig } from '../tokens/tier-model';
3
- import { type NumericValue } from '../utils/numeric-transform';
4
- import type { FlatTabEntry, RowContribution, TokenAddress } from '../tabs/flat/types';
2
+ import type { TierConfig } from "../tokens/tier-model.js";
3
+ import { type NumericValue } from "../utils/numeric-transform.js";
4
+ import type { FlatTabEntry, RowContribution, TokenAddress } from "../tabs/flat/types.js";
5
5
  export interface BulkOperations {
6
6
  multiply: string;
7
7
  add: string;
@@ -1,2 +1,2 @@
1
- export { BulkActionBar, DEFAULT_BULK_OPERATIONS, createBulkContribution, isBulkSelectable, isSelectable, numericEntryUnit, numericValueForEntry, transformBulkEntry, } from './bulk-actions';
2
- export type { BulkActionBarProps, BulkContributionOptions, BulkOperations, BulkPatchEntry, } from './bulk-actions';
1
+ export { BulkActionBar, DEFAULT_BULK_OPERATIONS, createBulkContribution, isBulkSelectable, isSelectable, numericEntryUnit, numericValueForEntry, transformBulkEntry, } from "./bulk-actions.js";
2
+ export type { BulkActionBarProps, BulkContributionOptions, BulkOperations, BulkPatchEntry, } from "./bulk-actions.js";
@@ -1,2 +1,2 @@
1
- export { ChainButton, ChainPopover, TOKEN_CHAIN_CONTRIBUTION, TokenChainButton, TokenChainPopover, type TokenChainButtonProps, type TokenChainPopoverProps, } from './token-chain-popover';
2
- export { TokenChainProvider, useTokenChainContext, type TokenChainContextValue, type TokenChainProviderProps, } from './token-chain-context';
1
+ export { ChainButton, ChainPopover, TOKEN_CHAIN_CONTRIBUTION, TokenChainButton, TokenChainPopover, type TokenChainButtonProps, type TokenChainPopoverProps, } from "./token-chain-popover.js";
2
+ export { TokenChainProvider, useTokenChainContext, type TokenChainContextValue, type TokenChainProviderProps, } from "./token-chain-context.js";
@@ -1,7 +1,7 @@
1
1
  import type { ComponentChildren } from 'preact';
2
- import type { PanelConfig } from '../config/panel-config';
3
- import type { TweakState } from '../state/tweak-state';
4
- import { type TokenGraph } from '../utils/token-graph';
2
+ import type { PanelConfig } from "../config/panel-config.js";
3
+ import type { TweakState } from "../state/tweak-state.js";
4
+ import { type TokenGraph } from "../utils/token-graph.js";
5
5
  export interface TokenChainContextValue {
6
6
  graph: TokenGraph;
7
7
  }
@@ -1,6 +1,6 @@
1
1
  import type { JSX } from 'preact';
2
- import { type TokenAddress } from '../utils/token-index';
3
- import type { RowContribution } from '../tabs/flat/types';
2
+ import { type TokenAddress } from "../utils/token-index.js";
3
+ import type { RowContribution } from "../tabs/flat/types.js";
4
4
  export interface TokenChainPopoverProps {
5
5
  address: TokenAddress;
6
6
  anchorRef: React.RefObject<HTMLElement | null>;
@@ -5,11 +5,11 @@
5
5
  * row's visual state, Changed-only filtering, ghost value, and revert affordance
6
6
  * all consult the same `isChanged` result for the row's stable token address.
7
7
  */
8
- import type { PanelConfig } from '../config/panel-config';
9
- import type { TweakState } from '../state/tweak-state';
10
- import { revertEntry, type ColorBaseline } from '../utils/token-diff';
11
- import type { TokenIndex, TokenAddress } from '../utils/token-index';
12
- import type { RowContribution } from '../tabs/flat/types';
8
+ import type { PanelConfig } from "../config/panel-config.js";
9
+ import type { TweakState } from "../state/tweak-state.js";
10
+ import { revertEntry, type ColorBaseline } from "../utils/token-diff.js";
11
+ import type { TokenIndex, TokenAddress } from "../utils/token-index.js";
12
+ import type { RowContribution } from "../tabs/flat/types.js";
13
13
  export interface ChangedContributionOptions {
14
14
  index: TokenIndex;
15
15
  state: TweakState;
@@ -1,8 +1,8 @@
1
1
  import type { JSX } from 'preact';
2
- import type { PanelConfig } from '../config/panel-config';
3
- import type { ColorBaseline } from '../utils/token-diff';
4
- import type { TweakState } from '../state/tweak-state';
5
- import type { TokenIndex } from '../utils/token-index';
2
+ import type { PanelConfig } from "../config/panel-config.js";
3
+ import type { ColorBaseline } from "../utils/token-diff.js";
4
+ import type { TweakState } from "../state/tweak-state.js";
5
+ import type { TokenIndex } from "../utils/token-index.js";
6
6
  export declare const COPY_REVERT_MS = 2000;
7
7
  export interface ChangedFooterContentProps {
8
8
  index: TokenIndex;
@@ -1,4 +1,4 @@
1
- export { changedContribution, changedStateContribution, createChangedContribution, revertEntry, } from './contribution';
2
- export { ChangedFooter, ChangedFooterContent, COPY_REVERT_MS } from './footer-content';
3
- export { ChangedOnlyToggle } from './tab-filter';
4
- export { ChangedTabBadge, TabChangedBadge } from './tab-badge';
1
+ export { changedContribution, changedStateContribution, createChangedContribution, revertEntry, } from "./contribution.js";
2
+ export { ChangedFooter, ChangedFooterContent, COPY_REVERT_MS } from "./footer-content.js";
3
+ export { ChangedOnlyToggle } from "./tab-filter.js";
4
+ export { ChangedTabBadge, TabChangedBadge } from "./tab-badge.js";
@@ -7,7 +7,7 @@
7
7
  * DOM-hygiene compliant: div-button with onClick + onKeyDown (Enter/Space);
8
8
  * no banned semantic tags — hostile-host policy (CLAUDE.md).
9
9
  */
10
- import type { ColorPickerValueFormat } from './color-picker';
10
+ import type { ColorPickerValueFormat } from "./color-picker.js";
11
11
  export interface ColorFieldProps {
12
12
  /** Current color value. Hex string in hex mode; `oklch(...)` string in oklch mode. */
13
13
  value: string;
@@ -1,2 +1,2 @@
1
- export { ColorPicker, type ColorPickerMode, type ColorPickerProps, LOCAL_STORAGE_KEY, getFixedPopoverStyle, usePopoverClose, } from './color-picker';
2
- export { default } from './color-picker';
1
+ export { ColorPicker, type ColorPickerMode, type ColorPickerProps, LOCAL_STORAGE_KEY, getFixedPopoverStyle, usePopoverClose, } from "./color-picker.js";
2
+ export { default } from "./color-picker.js";
@@ -1,2 +1,2 @@
1
- export { PaletteChart, type PaletteChartProps, type Oklcha, type Channel, } from './palette-chart';
2
- export { default } from './palette-chart';
1
+ export { PaletteChart, type PaletteChartProps, type Oklcha, type Channel, } from "./palette-chart.js";
2
+ export { default } from "./palette-chart.js";
@@ -1,6 +1,6 @@
1
1
  import type { JSX } from 'preact';
2
- import { type Channel } from '../../utils/palette-curve';
3
- import { type Oklcha } from '../../utils/color-oklch';
2
+ import { type Channel } from "../../utils/palette-curve.js";
3
+ import { type Oklcha } from "../../utils/color-oklch.js";
4
4
  /**
5
5
  * PaletteChart — controlled, presentational OKLCH L/C/H curve editor.
6
6
  *
@@ -32,8 +32,8 @@ import { type Oklcha } from '../../utils/color-oklch';
32
32
  * within the same SVG, so a pointer-down on a node hits the circle (DOM order
33
33
  * within an SVG determines paint/hit precedence).
34
34
  */
35
- export type { Oklcha } from '../../utils/color-oklch';
36
- export type { Channel } from '../../utils/palette-curve';
35
+ export type { Oklcha } from "../../utils/color-oklch.js";
36
+ export type { Channel } from "../../utils/palette-curve.js";
37
37
  export interface PaletteChartProps {
38
38
  /**
39
39
  * Dense palette slots in OKLCH space. A null slot preserves its index/band,
@@ -20,9 +20,9 @@
20
20
  * everything the color tab needs to render is reachable from
21
21
  * `panelConfig.colorCluster`.
22
22
  */
23
- import type { ColorScheme } from './color-schemes';
24
- import type { SemanticValue } from '../tokens/tier-model';
25
- export type { SemanticValue } from '../tokens/tier-model';
23
+ import type { ColorScheme } from "./color-schemes.js";
24
+ import type { SemanticValue } from "../tokens/tier-model.js";
25
+ export type { SemanticValue } from "../tokens/tier-model.js";
26
26
  /**
27
27
  * Base-role keys that a cluster may declare. Subset is allowed (a cluster may
28
28
  * ship zero base roles when its design system doesn't expose them as tokens).
@@ -110,7 +110,7 @@ export interface ColorClusterDataConfig {
110
110
  export declare function resolvePaletteCssVar(cluster: {
111
111
  paletteCssVarTemplate: string;
112
112
  }, index: number): string;
113
- import type { TabConfig } from '../tokens/tier-model';
113
+ import type { TabConfig } from "../tokens/tier-model.js";
114
114
  /**
115
115
  * Derive a `ColorClusterDataConfig` from a color `TabConfig`.
116
116
  *
@@ -14,7 +14,7 @@
14
14
  * mappings in the bundled tokens, so the panel's defaults on first open
15
15
  * match the example CSS exactly.
16
16
  */
17
- import { type ColorScheme, type ColorRef } from './color-schemes';
17
+ import { type ColorScheme, type ColorRef } from "./color-schemes.js";
18
18
  /**
19
19
  * Minimal local replacement for the upstream `settings` object. The panel only
20
20
  * ever reads `colorScheme` and `colorMode`; the rest of the upstream settings
@@ -45,9 +45,9 @@
45
45
  * arbitrary host-irrelevant data. Hosts MUST call `configurePanel(...)` to
46
46
  * see useful behaviour.
47
47
  */
48
- import type { ColorScheme } from './color-schemes';
49
- import type { TabConfig } from '../tokens/tier-model';
50
- export { DEFAULT_STORAGE_PREFIX, DEFAULT_TOGGLE_EVENT } from '../constants';
48
+ import type { ColorScheme } from "./color-schemes.js";
49
+ import type { TabConfig } from "../tokens/tier-model.js";
50
+ export { DEFAULT_STORAGE_PREFIX, DEFAULT_TOGGLE_EVENT } from "../constants.js";
51
51
  /**
52
52
  * Apply-routing map.
53
53
  *
@@ -430,8 +430,8 @@ export declare function clearColorSchemeOwnership(prefix: string): void;
430
430
  * never removes a `color-scheme` it did not write.
431
431
  */
432
432
  export declare function ownsColorScheme(prefix: string): boolean;
433
- export { resolvePrimaryColorCluster, resolveSecondaryColorClusterFromTabs, } from './cluster-config';
434
- import type { ColorClusterDataConfig } from './cluster-config';
433
+ export { resolvePrimaryColorCluster, resolveSecondaryColorClusterFromTabs, } from "./cluster-config.js";
434
+ import type { ColorClusterDataConfig } from "./cluster-config.js";
435
435
  /**
436
436
  * Resolve the active primary color cluster from the panel config's tabs array.
437
437
  *
@@ -11,6 +11,10 @@
11
11
  */
12
12
  import type { ComponentChildren, JSX } from 'preact';
13
13
  export interface ActionsMenuAction {
14
+ /** Stable action id, emitted as `data-zdtp-action` on the rendered item.
15
+ * Required so the DOM hook can never silently go missing; labels are
16
+ * display strings and must not be used as the key (PORTABLE-CONTRACT §7.6). */
17
+ id: string;
14
18
  label: string;
15
19
  onSelect: () => void;
16
20
  disabled?: boolean;
@@ -16,5 +16,8 @@ export interface RoleButtonProps {
16
16
  title?: string;
17
17
  'aria-label'?: string;
18
18
  'data-testid'?: string;
19
+ /** Stable per-action DOM hook for consumer tests (see PORTABLE-CONTRACT §7.6).
20
+ * Keyed on an action id, never on the display label. */
21
+ 'data-zdtp-action'?: string;
19
22
  }
20
- export declare function RoleButton({ children, onClick, className, 'aria-disabled': ariaDisabled, ariaProps, tabIndex, elementRef, id, title, 'aria-label': ariaLabel, 'data-testid': testId, }: RoleButtonProps): JSX.Element;
23
+ export declare function RoleButton({ children, onClick, className, 'aria-disabled': ariaDisabled, ariaProps, tabIndex, elementRef, id, title, 'aria-label': ariaLabel, 'data-testid': testId, 'data-zdtp-action': zdtpAction, }: RoleButtonProps): JSX.Element;
@@ -1,4 +1,4 @@
1
- import type { TabConfig } from '../tokens/tier-model';
1
+ import type { TabConfig } from "../tokens/tier-model.js";
2
2
  /**
3
3
  * Names one item in a (possibly cross-tab) tier. `tab` omitted means "the tab
4
4
  * `TierRefSelector` itself renders in" — the intra-tab case used by the
@@ -1,5 +1,5 @@
1
1
  import type { JSX } from 'preact';
2
- import type { PanelConfig } from '../config/panel-config';
2
+ import type { PanelConfig } from "../config/panel-config.js";
3
3
  export interface DomTweakerDiffActionLinkProps {
4
4
  instanceConfig: PanelConfig;
5
5
  onSelected?: () => void;
@@ -10,7 +10,7 @@
10
10
  * explicit scalar config values into that boundary.
11
11
  */
12
12
  import type { ComponentChildren, JSX } from 'preact';
13
- import type { PanelConfig } from '../config/panel-config';
13
+ import type { PanelConfig } from "../config/panel-config.js";
14
14
  export declare function DomTweakerOrchestrator({ children, instanceConfig, }: {
15
15
  children: ComponentChildren;
16
16
  instanceConfig: PanelConfig;
@@ -6,7 +6,7 @@
6
6
  * time (never at module init), so a late `configurePanel({ storagePrefix })`
7
7
  * is respected by no-arg callers.
8
8
  */
9
- import { type PanelConfig } from '../config/panel-config';
9
+ import { type PanelConfig } from "../config/panel-config.js";
10
10
  export declare function storageKey_domTweakerEnabled(cfg?: PanelConfig): string;
11
11
  /**
12
12
  * Load the persisted enabled flag from localStorage. Defaults to `false` on
@@ -1,5 +1,5 @@
1
1
  import type { JSX } from 'preact';
2
- import { type TrackedElementRect } from './pinned-selection-overlay';
2
+ import { type TrackedElementRect } from "./pinned-selection-overlay.js";
3
3
  export interface ClassEditorPopupProps {
4
4
  target: Element | null;
5
5
  selectorSummary: string;
@@ -1,5 +1,5 @@
1
1
  import type { JSX } from 'preact';
2
- import { type PanelConfig } from '../../config/panel-config';
2
+ import { type PanelConfig } from "../../config/panel-config.js";
3
3
  export interface DiffExportModalProps {
4
4
  diffText: string;
5
5
  onClose: () => void;
@@ -8,8 +8,8 @@
8
8
  * lazy boundary does not read global panel config.
9
9
  */
10
10
  import type { JSX } from 'preact';
11
- import type { DomTweakerRuntimeStatus } from '../dom-tweaker-context';
12
- export { buildStaticSuggestions, buildSuggestions, buildThemeSuggestions, filterSuggestions, STATIC_SUGGESTIONS, } from './suggestions';
11
+ import type { DomTweakerRuntimeStatus } from "../dom-tweaker-context.js";
12
+ export { buildStaticSuggestions, buildSuggestions, buildThemeSuggestions, filterSuggestions, STATIC_SUGGESTIONS, } from "./suggestions.js";
13
13
  export interface DomTweakerLazyBoundaryProps {
14
14
  enabled: boolean;
15
15
  storagePrefix: string;
@@ -1,4 +1,4 @@
1
- import type { FindTokensForElementResult } from './find-tokens-for-element';
1
+ import type { FindTokensForElementResult } from "./find-tokens-for-element.js";
2
2
  /** The synthetic tab id used by the transient element-inspect view. */
3
3
  export declare const ELEMENT_INSPECT_TAB_ID = "inspect";
4
4
  export interface ElementInspectContextValue {
@@ -1,7 +1,7 @@
1
1
  import type { ComponentChildren } from 'preact';
2
- import type { PanelConfig } from '../config/panel-config';
3
- import type { TweakState } from '../state/tweak-state';
4
- import type { CommitTweakStateOptions, TweakStateUpdater } from '../state/transaction';
2
+ import type { PanelConfig } from "../config/panel-config.js";
3
+ import type { TweakState } from "../state/tweak-state.js";
4
+ import type { CommitTweakStateOptions, TweakStateUpdater } from "../state/transaction.js";
5
5
  type CommitTweakState = (reason: string, next: TweakStateUpdater, options?: CommitTweakStateOptions) => void;
6
6
  export interface ElementInspectOrchestratorProps {
7
7
  children: ComponentChildren;