@takazudo/zdtp 0.4.4 → 0.4.6
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 +46 -0
- package/README.md +159 -12
- package/dist/apply/apply-token-overrides.d.ts +139 -32
- package/dist/astro/host-adapter.js +71 -58
- package/dist/astro/index.js +1 -1
- package/dist/{autoload-state-CmhI7q9j.js → autoload-state-D26ML6sW.js} +1 -1
- package/dist/bin/server.js +116 -112
- package/dist/config/panel-config.d.ts +68 -1
- package/dist/controls/actions-menu-popover.d.ts +26 -0
- package/dist/controls/help-icon.d.ts +43 -0
- package/dist/controls/tooltip.d.ts +20 -2
- package/dist/export-modal.d.ts +5 -3
- package/dist/import-modal.d.ts +9 -9
- package/dist/index.d.ts +2 -1
- package/dist/index.js +3383 -3012
- package/dist/load-routing-LJ72261l.js +421 -0
- package/dist/{panel-config-CXTCcYQs.js → panel-config-Bw7D-25C.js} +381 -271
- package/dist/server/create-apply-handler.d.ts +6 -0
- package/dist/server/index.js +1 -1
- package/dist/state/tweak-state.d.ts +137 -14
- package/dist/tabs/notes-tab.d.ts +25 -0
- package/dist/testing.js +7 -7
- package/dist/tokens/manifest.d.ts +8 -0
- package/dist/tokens/tier-model.d.ts +36 -0
- package/dist/tweak-state-CD1y56zR.js +1958 -0
- package/dist/utils/design-token-serde.d.ts +20 -12
- package/dist/utils/sanitize-html.d.ts +27 -0
- package/dist/utils/unit-cycle.d.ts +61 -0
- package/dist/zdtp.css +1 -1
- package/package.json +1 -1
- package/dist/load-routing-DtNTKoLW.js +0 -353
- package/dist/tweak-state-BeXkzoj8.js +0 -1858
|
@@ -86,7 +86,12 @@ export interface PanelConfig {
|
|
|
86
86
|
consoleNamespace: string;
|
|
87
87
|
/** BEM-style prefix used by every modal in the panel (export / import / apply). */
|
|
88
88
|
modalClassPrefix: string;
|
|
89
|
-
/**
|
|
89
|
+
/**
|
|
90
|
+
* Schema label surfaced in the Import modal's hint/placeholder/error text
|
|
91
|
+
* and the Export modal's copy. NOT enforced: `serialize()`/`deserialize()`
|
|
92
|
+
* always use the fixed `SCHEMA_V1`/`SCHEMA_V2`/`SCHEMA_V3` constants
|
|
93
|
+
* regardless of this value (#498).
|
|
94
|
+
*/
|
|
90
95
|
schemaId: string;
|
|
91
96
|
/** Default filename base — exports save as `${exportFilenameBase}.json`. */
|
|
92
97
|
exportFilenameBase: string;
|
|
@@ -364,6 +369,24 @@ export declare function getPanelConfigByPrefix(prefix: string): PanelConfig | nu
|
|
|
364
369
|
* instance, parked presets, and parked pre-configure hooks.
|
|
365
370
|
*/
|
|
366
371
|
export declare function __resetPanelConfigForTests(): void;
|
|
372
|
+
/**
|
|
373
|
+
* #501 — record that the panel instance keyed by `prefix` wrote `color-scheme`
|
|
374
|
+
* to its apply target. Called from the apply path (`applyColorState`) wherever
|
|
375
|
+
* a per-mode literal forces `color-scheme: light dark`.
|
|
376
|
+
*/
|
|
377
|
+
export declare function markColorSchemeWritten(prefix: string): void;
|
|
378
|
+
/**
|
|
379
|
+
* #501 — drop the color-scheme ownership claim for `prefix`. Called from the
|
|
380
|
+
* clear paths after a panel-written `color-scheme` is removed (or found to have
|
|
381
|
+
* been overwritten by the host — the stale-ownership case).
|
|
382
|
+
*/
|
|
383
|
+
export declare function clearColorSchemeOwnership(prefix: string): void;
|
|
384
|
+
/**
|
|
385
|
+
* #501 — true when the panel instance keyed by `prefix` is the recorded writer
|
|
386
|
+
* of the current inline `color-scheme`. Gates the clear paths so the panel
|
|
387
|
+
* never removes a `color-scheme` it did not write.
|
|
388
|
+
*/
|
|
389
|
+
export declare function ownsColorScheme(prefix: string): boolean;
|
|
367
390
|
export { resolvePrimaryColorCluster, resolveSecondaryColorClusterFromTabs, } from './cluster-config';
|
|
368
391
|
import type { ColorClusterDataConfig } from './cluster-config';
|
|
369
392
|
/**
|
|
@@ -391,6 +414,18 @@ export declare function storageKey_stateV2(cfg: PanelConfig): string;
|
|
|
391
414
|
* this key, then deletes the v2 key.
|
|
392
415
|
*/
|
|
393
416
|
export declare function storageKey_stateV3(cfg: PanelConfig): string;
|
|
417
|
+
/**
|
|
418
|
+
* Storage key for the v4 unified envelope. Upgrades the "global tweak model" to
|
|
419
|
+
* per-scheme color persistence (#500/#509): the `color` and `secondary` slices
|
|
420
|
+
* become identity-keyed sub-objects (one slot per resolved scheme/mode), so a
|
|
421
|
+
* per-scheme color tweak survives a scheme toggle round-trip instead of being
|
|
422
|
+
* clobbered by the next unrelated edit. Non-color slices stay global. Kept a
|
|
423
|
+
* SINGLE storage key (not one key per scheme) because the Astro bootstrap must
|
|
424
|
+
* existence-check persistence before cluster config loads — a per-scheme key
|
|
425
|
+
* would hit a chicken-and-egg there. v1/v2/v3 migrate into this key on first
|
|
426
|
+
* load; v4 takes precedence on every subsequent load.
|
|
427
|
+
*/
|
|
428
|
+
export declare function storageKey_stateV4(cfg: PanelConfig): string;
|
|
394
429
|
/** Legacy v1 key (Color-only flat state). Migrated into v2 on first load, then deleted. */
|
|
395
430
|
export declare function storageKey_stateV1(cfg: PanelConfig): string;
|
|
396
431
|
/** Mirror of the panel's `open` boolean (synchronous mount-time read). */
|
|
@@ -455,6 +490,38 @@ export declare function openStateChangedEventName(cfg: PanelConfig): string;
|
|
|
455
490
|
export declare function modalClass(cfg: PanelConfig, suffix: string): string;
|
|
456
491
|
/** Default download filename for export. */
|
|
457
492
|
export declare function exportFilename(cfg: PanelConfig): string;
|
|
493
|
+
/** Shape of the fixed-name global alias installed at `window.zdtp`. */
|
|
494
|
+
export interface ZdtpGlobalApi {
|
|
495
|
+
show: () => void | Promise<void>;
|
|
496
|
+
hide: () => void | Promise<void>;
|
|
497
|
+
toggle: () => void | Promise<void>;
|
|
498
|
+
}
|
|
499
|
+
/**
|
|
500
|
+
* Install `window.zdtp = { show, hide, toggle }`, the fixed-name console
|
|
501
|
+
* sugar for the common single-panel case (issue #523).
|
|
502
|
+
*
|
|
503
|
+
* Guard rules:
|
|
504
|
+
* - A pre-existing `window.zdtp` WITHOUT this package's marker is assumed to
|
|
505
|
+
* be host-defined — never overwritten. Logs a `console.warn` so the host
|
|
506
|
+
* can see why `zdtp.show()` did not appear.
|
|
507
|
+
* - A pre-existing `window.zdtp` WITH the marker means this package already
|
|
508
|
+
* installed the alias (from the other call site, or an earlier run of this
|
|
509
|
+
* same one). First install wins — the call is a silent no-op. In the Astro
|
|
510
|
+
* flow this manifests as "the adapter wins": its bootstrap script always
|
|
511
|
+
* runs (and installs the alias) before the panel module's lazy dynamic
|
|
512
|
+
* import can resolve and reach the package-root install site.
|
|
513
|
+
*
|
|
514
|
+
* `show` / `hide` / `toggle` are caller-supplied closures, so which instance
|
|
515
|
+
* they target is up to the caller — the package-root install site (below,
|
|
516
|
+
* `index.tsx`) wraps `showDesignTokenPanel()` etc., which re-resolve
|
|
517
|
+
* `getPanelConfig()` (the CURRENT default instance) on every call; the Astro
|
|
518
|
+
* host-adapter install site instead binds to the specific `PanelInstanceHandle`
|
|
519
|
+
* captured at its own install time, which does NOT track a later change of
|
|
520
|
+
* default (see PORTABLE-CONTRACT.md §6.5 for the full nuance). Either way,
|
|
521
|
+
* for a multi-instance page use `configurePanel(cfg).open()` etc. on the
|
|
522
|
+
* specific instance's own handle instead of relying on this alias.
|
|
523
|
+
*/
|
|
524
|
+
export declare function installZdtpGlobalAlias(api: ZdtpGlobalApi): void;
|
|
458
525
|
/**
|
|
459
526
|
* Runtime validation at the host-adapter trust boundary. The Astro inline
|
|
460
527
|
* `<script type="application/json">` payload is untrusted-by-the-types:
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ActionsMenuPopover — narrow-panel replacement for the header action links
|
|
3
|
+
* (Export / Load from JSON… / Apply / Reset), collapsed behind the kebab
|
|
4
|
+
* trigger below the panel's <480px container-query breakpoint (#518).
|
|
5
|
+
*
|
|
6
|
+
* A PLAIN popover of ordinary action RoleButtons, NOT an ARIA menu:
|
|
7
|
+
* role="menu"/menuitem demands arrow-key navigation and focus management,
|
|
8
|
+
* and RoleButton hardcodes role="button" — so this follows the existing
|
|
9
|
+
* gear-settings popover's dialog + outside-click/Escape wiring instead
|
|
10
|
+
* (usePopoverClose, shared with highlight/highlight-settings-popover.tsx).
|
|
11
|
+
*/
|
|
12
|
+
import type { JSX } from 'preact';
|
|
13
|
+
export interface ActionsMenuAction {
|
|
14
|
+
label: string;
|
|
15
|
+
onSelect: () => void;
|
|
16
|
+
}
|
|
17
|
+
interface ActionsMenuPopoverProps {
|
|
18
|
+
/** The kebab trigger element — excluded from the outside-click close so its
|
|
19
|
+
* own click-to-toggle isn't raced by the popover's pointerdown listener
|
|
20
|
+
* (mirrors the gear button / HighlightSettingsPopover pairing). */
|
|
21
|
+
anchorRef: React.RefObject<HTMLElement | null>;
|
|
22
|
+
actions: readonly ActionsMenuAction[];
|
|
23
|
+
onClose: () => void;
|
|
24
|
+
}
|
|
25
|
+
export declare function ActionsMenuPopover({ anchorRef, actions, onClose, }: ActionsMenuPopoverProps): JSX.Element;
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HelpIcon — small round "?" badge that explains a nearby control via the
|
|
3
|
+
* shared `.tokenpanel-tooltip--help` variant (issue #520).
|
|
4
|
+
*
|
|
5
|
+
* Chrome-button policy (CLAUDE.md): implemented as
|
|
6
|
+
* `<div role="button" tabIndex={0}>` with explicit Enter/Space handling —
|
|
7
|
+
* never a native `<button>`.
|
|
8
|
+
*
|
|
9
|
+
* Behavior:
|
|
10
|
+
* - Hover / focus shows the help tooltip transiently, same as any other
|
|
11
|
+
* `useTooltip` trigger.
|
|
12
|
+
* - Click (or Enter/Space) PINS the tooltip open — touch devices have no
|
|
13
|
+
* hover, so a tap must be able to reveal and hold the tip. A second
|
|
14
|
+
* activation, or pressing Escape anywhere on the page, unpins it.
|
|
15
|
+
*
|
|
16
|
+
* Callers place this as a SIBLING of the control it explains (e.g. after a
|
|
17
|
+
* `<select>`, or after a `<label>` wrapping a checkbox) — never nested
|
|
18
|
+
* inside a `<label>`, where a click would also toggle the label's own
|
|
19
|
+
* control.
|
|
20
|
+
*
|
|
21
|
+
* Known trade-off: `tooltip.tsx` renders a single shared tooltip DOM node,
|
|
22
|
+
* so pinning icon A then hovering/pinning icon B silently replaces A's
|
|
23
|
+
* visible content with B's — A's `pinned`/`is-pinned` state persists until
|
|
24
|
+
* A is next clicked or Escape is pressed, even though its tooltip is no
|
|
25
|
+
* longer the one on screen. Acceptable for this panel's single-tooltip
|
|
26
|
+
* architecture; not worth a cross-instance pin registry for a "?" hint.
|
|
27
|
+
* The same applies to a panel/window resize: `tooltip.tsx` hides the shared
|
|
28
|
+
* tooltip on resize (its ResizeObserver + window-resize handlers), but this
|
|
29
|
+
* component's local `pinned` state only clears on click/Escape — so after a
|
|
30
|
+
* resize the icon may briefly keep `is-pinned`/`aria-pressed` with no tooltip
|
|
31
|
+
* visible until the next activation. Same accepted single-tooltip trade-off.
|
|
32
|
+
*/
|
|
33
|
+
import type { JSX } from 'preact';
|
|
34
|
+
export declare const LITERAL_HELP_TEXT = "Literal sets a fixed color just for this token \u2014 it won't update if you edit a palette/ramp swatch later. Pick a ramp option to keep it linked live.";
|
|
35
|
+
export declare const PER_MODE_HELP_TEXT = "Per-mode gives this token two colors \u2014 one for light mode, one for dark. The browser picks the right one automatically via CSS light-dark().";
|
|
36
|
+
export interface HelpIconProps {
|
|
37
|
+
/** The help text shown in the tooltip (wrapped, multi-line). */
|
|
38
|
+
text: string;
|
|
39
|
+
/** Accessible name for the icon itself (e.g. "Literal help", "Surface per-mode help"). */
|
|
40
|
+
ariaLabel: string;
|
|
41
|
+
}
|
|
42
|
+
export declare function HelpIcon({ text, ariaLabel }: HelpIconProps): JSX.Element;
|
|
43
|
+
export default HelpIcon;
|
|
@@ -16,6 +16,13 @@
|
|
|
16
16
|
* <div {...tooltipProps}>...</div>
|
|
17
17
|
*/
|
|
18
18
|
import type { ComponentChildren, JSX } from 'preact';
|
|
19
|
+
/**
|
|
20
|
+
* Opt-in tooltip presentation variant. `'help'` applies the wrapped,
|
|
21
|
+
* bounded-width `.tokenpanel-tooltip--help` class (see panel.css) instead of
|
|
22
|
+
* the default single-line `nowrap` tooltip — used by `controls/help-icon.tsx`
|
|
23
|
+
* for the multi-sentence Literal / Per-mode explainer tips.
|
|
24
|
+
*/
|
|
25
|
+
export type TooltipVariant = 'help';
|
|
19
26
|
interface TooltipProviderProps {
|
|
20
27
|
children: ComponentChildren;
|
|
21
28
|
}
|
|
@@ -27,17 +34,28 @@ interface TooltipProviderProps {
|
|
|
27
34
|
* tooltip globally.
|
|
28
35
|
*/
|
|
29
36
|
export declare function TooltipProvider({ children }: TooltipProviderProps): JSX.Element;
|
|
37
|
+
export interface UseTooltipOptions {
|
|
38
|
+
/** Opt into a presentation variant — see `TooltipVariant` above. Omit for
|
|
39
|
+
* the default single-line `nowrap` tooltip. */
|
|
40
|
+
variant?: TooltipVariant;
|
|
41
|
+
}
|
|
30
42
|
/**
|
|
31
43
|
* Returns event handler props to spread onto the tooltip trigger element.
|
|
32
44
|
*
|
|
33
45
|
* @param text - The full text to show in the tooltip.
|
|
46
|
+
* @param opts - Optional presentation variant (see `UseTooltipOptions`).
|
|
34
47
|
* @returns An object of `onMouseEnter`, `onMouseLeave`, `onFocusIn`, `onFocusOut`
|
|
35
|
-
* handlers to spread onto the trigger element
|
|
48
|
+
* handlers to spread onto the trigger element, plus imperative
|
|
49
|
+
* `show`/`hide` escape hatches for callers that need to
|
|
50
|
+
* show/keep-open the tooltip outside of a raw hover/focus event
|
|
51
|
+
* (e.g. `controls/help-icon.tsx`'s click-to-pin behavior).
|
|
36
52
|
*/
|
|
37
|
-
export declare function useTooltip(text: string): {
|
|
53
|
+
export declare function useTooltip(text: string, opts?: UseTooltipOptions): {
|
|
38
54
|
onMouseEnter: JSX.MouseEventHandler<HTMLElement>;
|
|
39
55
|
onMouseLeave: JSX.MouseEventHandler<HTMLElement>;
|
|
40
56
|
onFocusIn: JSX.FocusEventHandler<HTMLElement>;
|
|
41
57
|
onFocusOut: JSX.FocusEventHandler<HTMLElement>;
|
|
58
|
+
show: (el: HTMLElement) => void;
|
|
59
|
+
hide: (el: HTMLElement) => void;
|
|
42
60
|
};
|
|
43
61
|
export {};
|
package/dist/export-modal.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Export modal — renders the current `TweakState` as a design-tokens JSON
|
|
3
|
-
* document (
|
|
4
|
-
* `panelConfig.schemaId`
|
|
5
|
-
*
|
|
3
|
+
* document (`serialize()` emits `SCHEMA_V2` or opportunistically `SCHEMA_V3`
|
|
4
|
+
* — see `./utils/design-token-serde`; `panelConfig.schemaId` is not read
|
|
5
|
+
* here or anywhere else in this package — it is a UI-label-only field on
|
|
6
|
+
* `PanelConfig` that hosts may read via `getDesignTokenSchema()`, #498) with
|
|
7
|
+
* a diff-only toggle and a copy-to-clipboard button.
|
|
6
8
|
*
|
|
7
9
|
* Ported verbatim from zudo-doc's
|
|
8
10
|
* `src/components/design-token-tweak/export-modal.tsx`. Intentional deltas:
|
package/dist/import-modal.d.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Import modal — accepts a pasted design-tokens JSON document
|
|
3
|
-
* `
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
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.
|
|
7
9
|
*
|
|
8
10
|
* Ported verbatim from zudo-doc's
|
|
9
11
|
* `src/components/design-token-tweak/import-modal.tsx`. Intentional deltas:
|
|
10
|
-
* - `deserialize` / `DesignTokenSchemaError`
|
|
11
|
-
*
|
|
12
|
-
* id is read at render time from `panelConfig.schemaId` instead of
|
|
13
|
-
* being a module-level constant.
|
|
12
|
+
* - `deserialize` / `DesignTokenSchemaError` come from this package's serde
|
|
13
|
+
* (`./utils/design-token-serde`).
|
|
14
14
|
* - State types import from this package's state envelope.
|
|
15
15
|
* - Modal class names are derived from `panelConfig.modalClassPrefix` via
|
|
16
16
|
* `modalClass(...)` so a single config swap re-themes every dialog.
|
package/dist/index.d.ts
CHANGED
|
@@ -56,10 +56,11 @@ export type { ColorClusterConfig } from './state/tweak-state';
|
|
|
56
56
|
export { ZDTP_LEGACY_TYPOGRAPHY_RENAME_MAP } from './state/tweak-state';
|
|
57
57
|
export type { ColorScheme, ColorRef } from './config/color-schemes';
|
|
58
58
|
export type { TokenManifest, TokenDef } from './tokens/manifest';
|
|
59
|
-
export type { TierValueKind, PillSpec, TierItem, TierConfig, TabConfig, ColorClusterExtras, } from './tokens/tier-model';
|
|
59
|
+
export type { TierValueKind, PillSpec, TierItem, TierConfig, TabConfig, ColorClusterExtras, NotesExtras, } from './tokens/tier-model';
|
|
60
60
|
export { isLengthKind, isNumberKind, isSelectKind, isTextKind, isColorKind, isCursorKind, isContentKind, isMaskImageKind, } from './tokens/tier-model';
|
|
61
61
|
export type { TweakState } from './state/tweak-state';
|
|
62
62
|
export { emptyOverrides } from './state/tweak-state';
|
|
63
|
+
export { SCHEMA_V1, SCHEMA_V2, SCHEMA_V3, } from './utils/design-token-serde';
|
|
63
64
|
export { getClusterDefaultMode, resolvePerModeLiteral, resolveSemanticPreviewColor, } from './state/tweak-state';
|
|
64
65
|
export declare function showDesignTokenPanel(): void;
|
|
65
66
|
export declare function hideDesignTokenPanel(): void;
|