@takazudo/zdtp 0.1.0-next.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 (130) hide show
  1. package/CHANGELOG.md +107 -0
  2. package/LICENSE +21 -0
  3. package/README.md +1044 -0
  4. package/dist/apply/apply-token-overrides.d.ts +81 -0
  5. package/dist/apply/apply-token-overrides.d.ts.map +1 -0
  6. package/dist/apply/build-apply-overrides.d.ts +71 -0
  7. package/dist/apply/build-apply-overrides.d.ts.map +1 -0
  8. package/dist/apply/route-tokens-to-files.d.ts +65 -0
  9. package/dist/apply/route-tokens-to-files.d.ts.map +1 -0
  10. package/dist/apply/tier-resolver.d.ts +75 -0
  11. package/dist/apply/tier-resolver.d.ts.map +1 -0
  12. package/dist/apply-modal.d.ts +49 -0
  13. package/dist/apply-modal.d.ts.map +1 -0
  14. package/dist/astro/DesignTokenPanelHost.astro +76 -0
  15. package/dist/astro/host-adapter.d.ts +47 -0
  16. package/dist/astro/host-adapter.d.ts.map +1 -0
  17. package/dist/astro/host-adapter.js +81 -0
  18. package/dist/astro/index.d.ts +30 -0
  19. package/dist/astro/index.d.ts.map +1 -0
  20. package/dist/astro/index.js +54 -0
  21. package/dist/bin/cors.d.ts +24 -0
  22. package/dist/bin/cors.d.ts.map +1 -0
  23. package/dist/bin/parse-args.d.ts +38 -0
  24. package/dist/bin/parse-args.d.ts.map +1 -0
  25. package/dist/bin/server.d.ts +23 -0
  26. package/dist/bin/server.d.ts.map +1 -0
  27. package/dist/bin/server.js +283 -0
  28. package/dist/color-schemes-CgzOBqGO.js +85 -0
  29. package/dist/components/color-picker/color-picker.d.ts +64 -0
  30. package/dist/components/color-picker/color-picker.d.ts.map +1 -0
  31. package/dist/components/color-picker/custom-slider.d.ts +25 -0
  32. package/dist/components/color-picker/custom-slider.d.ts.map +1 -0
  33. package/dist/components/color-picker/index.d.ts +3 -0
  34. package/dist/components/color-picker/index.d.ts.map +1 -0
  35. package/dist/config/cluster-config.d.ts +135 -0
  36. package/dist/config/cluster-config.d.ts.map +1 -0
  37. package/dist/config/color-scheme-utils.d.ts +105 -0
  38. package/dist/config/color-scheme-utils.d.ts.map +1 -0
  39. package/dist/config/color-schemes.d.ts +83 -0
  40. package/dist/config/color-schemes.d.ts.map +1 -0
  41. package/dist/config/panel-config.d.ts +258 -0
  42. package/dist/config/panel-config.d.ts.map +1 -0
  43. package/dist/controls/pill-slider-row.d.ts +37 -0
  44. package/dist/controls/pill-slider-row.d.ts.map +1 -0
  45. package/dist/controls/role-button.d.ts +18 -0
  46. package/dist/controls/role-button.d.ts.map +1 -0
  47. package/dist/controls/sanitize-css-value.d.ts +22 -0
  48. package/dist/controls/sanitize-css-value.d.ts.map +1 -0
  49. package/dist/controls/select-row.d.ts +26 -0
  50. package/dist/controls/select-row.d.ts.map +1 -0
  51. package/dist/controls/slider-row.d.ts +34 -0
  52. package/dist/controls/slider-row.d.ts.map +1 -0
  53. package/dist/controls/text-row.d.ts +28 -0
  54. package/dist/controls/text-row.d.ts.map +1 -0
  55. package/dist/controls/tier-ref-selector.d.ts +33 -0
  56. package/dist/controls/tier-ref-selector.d.ts.map +1 -0
  57. package/dist/controls/tooltip.d.ts +44 -0
  58. package/dist/controls/tooltip.d.ts.map +1 -0
  59. package/dist/export-modal.d.ts +33 -0
  60. package/dist/export-modal.d.ts.map +1 -0
  61. package/dist/highlight/find-elements.d.ts +113 -0
  62. package/dist/highlight/find-elements.d.ts.map +1 -0
  63. package/dist/highlight/highlight-orchestrator.d.ts +24 -0
  64. package/dist/highlight/highlight-orchestrator.d.ts.map +1 -0
  65. package/dist/highlight/highlight-overlay.d.ts +43 -0
  66. package/dist/highlight/highlight-overlay.d.ts.map +1 -0
  67. package/dist/highlight/highlight-settings-popover.d.ts +25 -0
  68. package/dist/highlight/highlight-settings-popover.d.ts.map +1 -0
  69. package/dist/highlight/highlight-state.d.ts +87 -0
  70. package/dist/highlight/highlight-state.d.ts.map +1 -0
  71. package/dist/highlight/highlight-toggle-button.d.ts +34 -0
  72. package/dist/highlight/highlight-toggle-button.d.ts.map +1 -0
  73. package/dist/import-modal.d.ts +33 -0
  74. package/dist/import-modal.d.ts.map +1 -0
  75. package/dist/index.d.ts +105 -0
  76. package/dist/index.d.ts.map +1 -0
  77. package/dist/index.js +5480 -0
  78. package/dist/load-routing-XyKgftpe.js +353 -0
  79. package/dist/manifest-DCReQE0k.js +24 -0
  80. package/dist/panel-config-DP2_P7dD.js +332 -0
  81. package/dist/panel.d.ts +3 -0
  82. package/dist/panel.d.ts.map +1 -0
  83. package/dist/route-tokens-to-files-1DvmWBdj.js +41 -0
  84. package/dist/server/create-apply-handler.d.ts +48 -0
  85. package/dist/server/create-apply-handler.d.ts.map +1 -0
  86. package/dist/server/index.d.ts +24 -0
  87. package/dist/server/index.d.ts.map +1 -0
  88. package/dist/server/index.js +10 -0
  89. package/dist/server/load-routing.d.ts +39 -0
  90. package/dist/server/load-routing.d.ts.map +1 -0
  91. package/dist/server/path-safety.d.ts +36 -0
  92. package/dist/server/path-safety.d.ts.map +1 -0
  93. package/dist/server/serialize-write.d.ts +7 -0
  94. package/dist/server/serialize-write.d.ts.map +1 -0
  95. package/dist/state/persist.d.ts +39 -0
  96. package/dist/state/persist.d.ts.map +1 -0
  97. package/dist/state/tweak-state.d.ts +344 -0
  98. package/dist/state/tweak-state.d.ts.map +1 -0
  99. package/dist/tabs/_generic-item-editor.d.ts +23 -0
  100. package/dist/tabs/_generic-item-editor.d.ts.map +1 -0
  101. package/dist/tabs/color-tab.d.ts +55 -0
  102. package/dist/tabs/color-tab.d.ts.map +1 -0
  103. package/dist/tabs/font-tab.d.ts +22 -0
  104. package/dist/tabs/font-tab.d.ts.map +1 -0
  105. package/dist/tabs/generic-tab.d.ts +43 -0
  106. package/dist/tabs/generic-tab.d.ts.map +1 -0
  107. package/dist/tabs/size-tab.d.ts +20 -0
  108. package/dist/tabs/size-tab.d.ts.map +1 -0
  109. package/dist/tabs/spacing-tab.d.ts +23 -0
  110. package/dist/tabs/spacing-tab.d.ts.map +1 -0
  111. package/dist/testing.d.ts +81 -0
  112. package/dist/testing.d.ts.map +1 -0
  113. package/dist/testing.js +23 -0
  114. package/dist/tokens/manifest.d.ts +148 -0
  115. package/dist/tokens/manifest.d.ts.map +1 -0
  116. package/dist/tokens/tier-model.d.ts +89 -0
  117. package/dist/tokens/tier-model.d.ts.map +1 -0
  118. package/dist/tweak-state-DSJa5csL.js +624 -0
  119. package/dist/utils/color-convert.d.ts +7 -0
  120. package/dist/utils/color-convert.d.ts.map +1 -0
  121. package/dist/utils/color-hsla.d.ts +9 -0
  122. package/dist/utils/color-hsla.d.ts.map +1 -0
  123. package/dist/utils/color-oklch.d.ts +51 -0
  124. package/dist/utils/color-oklch.d.ts.map +1 -0
  125. package/dist/utils/design-token-serde.d.ts +193 -0
  126. package/dist/utils/design-token-serde.d.ts.map +1 -0
  127. package/dist/utils/structural-equal.d.ts +22 -0
  128. package/dist/utils/structural-equal.d.ts.map +1 -0
  129. package/dist/zdtp.css +1 -0
  130. package/package.json +102 -0
@@ -0,0 +1,54 @@
1
+ import { default as t } from "./DesignTokenPanelHost.astro";
2
+ import { s as d } from "../panel-config-DP2_P7dD.js";
3
+ import { c as r } from "../color-schemes-CgzOBqGO.js";
4
+ import { F as g, G as f, a as l, S as z } from "../manifest-DCReQE0k.js";
5
+ const e = {
6
+ colorScheme: "Default Dark",
7
+ colorMode: !1
8
+ }, c = {
9
+ bg: 9,
10
+ fg: 11,
11
+ surface: 10,
12
+ muted: 8,
13
+ accent: 5,
14
+ accentHover: 14,
15
+ link: 4,
16
+ codeBg: 0,
17
+ codeFg: 7,
18
+ success: 2,
19
+ danger: 1,
20
+ warning: 3,
21
+ info: 4,
22
+ price: 12,
23
+ sold: 13,
24
+ active: 14
25
+ }, s = {
26
+ bg: "--zd-semantic-bg",
27
+ fg: "--zd-semantic-fg",
28
+ surface: "--zd-semantic-surface",
29
+ muted: "--zd-semantic-muted",
30
+ accent: "--zd-semantic-accent",
31
+ accentHover: "--zd-semantic-accent-hover",
32
+ link: "--zd-semantic-link",
33
+ codeBg: "--zd-semantic-code-bg",
34
+ codeFg: "--zd-semantic-code-fg",
35
+ success: "--zd-semantic-success",
36
+ danger: "--zd-semantic-danger",
37
+ warning: "--zd-semantic-warning",
38
+ info: "--zd-semantic-info",
39
+ price: "--zd-semantic-price",
40
+ sold: "--zd-semantic-sold",
41
+ active: "--zd-semantic-active"
42
+ };
43
+ export {
44
+ t as DesignTokenPanelHost,
45
+ g as FONT_GROUP_ORDER,
46
+ f as GROUP_ORDER,
47
+ l as GROUP_TITLES,
48
+ s as SEMANTIC_CSS_NAMES,
49
+ c as SEMANTIC_DEFAULTS_ZD,
50
+ z as SIZE_GROUP_ORDER,
51
+ r as colorSchemes,
52
+ e as panelSettings,
53
+ d as setPanelColorPresets
54
+ };
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Pure CORS helpers for the `zdtp-server` bin.
3
+ *
4
+ * Origin matching is **case-sensitive on the entire scheme + host + port**
5
+ * string — wildcards and pattern matching are intentionally not supported.
6
+ * The browser sends the origin verbatim; the bin operator declares the exact
7
+ * allowed origins via repeated `--allow-origin` flags.
8
+ */
9
+ /**
10
+ * @param origin The `Origin` header from the incoming request, or
11
+ * null/undefined if the header was absent.
12
+ * @param allowList The exact-match allow-list configured at bin startup.
13
+ * @returns true iff `origin` is a non-empty string present in `allowList`.
14
+ */
15
+ export declare function isOriginAllowed(origin: string | null | undefined, allowList: readonly string[]): boolean;
16
+ /**
17
+ * Build the four `Access-Control-Allow-*` headers for a successful CORS
18
+ * response (preflight 204 OR the wrapped POST /apply response). The caller
19
+ * is responsible for only calling this when `isOriginAllowed` returned true,
20
+ * so the echoed origin value is always one the operator has explicitly
21
+ * permitted.
22
+ */
23
+ export declare function buildCorsHeaders(origin: string): Record<string, string>;
24
+ //# sourceMappingURL=cors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cors.d.ts","sourceRoot":"","sources":["../../src/bin/cors.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACjC,SAAS,EAAE,SAAS,MAAM,EAAE,GAC3B,OAAO,CAIT;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAOvE"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Pure-function argv parser for the `zdtp-server` bin.
3
+ *
4
+ * No external dependencies — only standard JS/TS — so this module is trivially
5
+ * unit-testable and can be imported safely from non-Node contexts (although in
6
+ * practice the bin file is the only consumer).
7
+ *
8
+ * Surface (matches the parse-args contract):
9
+ *
10
+ * --root <dir> repo root; default: process.cwd() (parser leaves null)
11
+ * --write-root <path> REQUIRED; absolute or relative-to-root
12
+ * --routing <path> REQUIRED; routing JSON file path
13
+ * --port <number> default 24681
14
+ * --host <addr> default 127.0.0.1
15
+ * --allow-origin <origin> repeatable; required at least once for browser POST
16
+ * --quiet suppress per-request logs
17
+ * --help print usage and exit 0
18
+ *
19
+ * On invalid input, throws a descriptive `Error`. The bin entry catches it,
20
+ * writes the message to stderr, and exits 1.
21
+ */
22
+ export interface ParsedArgs {
23
+ root: string | null;
24
+ writeRoot: string | null;
25
+ routing: string | null;
26
+ port: number;
27
+ host: string;
28
+ allowOrigins: string[];
29
+ quiet: boolean;
30
+ help: boolean;
31
+ }
32
+ export declare const HELP_TEXT = "Usage: zdtp-server [options]\n\nRun a small Node http server that wraps the design-token apply handler.\n\nOptions:\n --root <dir> Repo root used as the CWD reference for routing\n paths. Defaults to the current working directory.\n --write-root <path> REQUIRED. Absolute or root-relative path to the\n single directory the bin is allowed to write into.\n --routing <path> REQUIRED. Path to the routing JSON file\n (prefix -> repo-relative CSS file path).\n --port <number> TCP port to bind. Default: 24681.\n --host <addr> Host/interface to bind. Default: 127.0.0.1.\n Use 0.0.0.0 to expose on the LAN (off by default).\n --allow-origin <origin> Origin allowed to POST to /apply. Repeatable.\n At least one is required for any browser to apply.\n --quiet Suppress per-request logs.\n --help Print this message and exit.\n\nExamples:\n zdtp-server \\\n --write-root tokens \\\n --routing ./my.routing.json \\\n --allow-origin http://localhost:34434\n";
33
+ /**
34
+ * Parse a raw argv array (typically `process.argv.slice(2)`) into a
35
+ * `ParsedArgs` record. Throws on malformed input — the bin handles the throw.
36
+ */
37
+ export declare function parseArgs(argv: readonly string[]): ParsedArgs;
38
+ //# sourceMappingURL=parse-args.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse-args.d.ts","sourceRoot":"","sources":["../../src/bin/parse-args.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAKH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,KAAK,EAAE,OAAO,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;CACf;AAED,eAAO,MAAM,SAAS,6qCAwBrB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,UAAU,CA4E7D"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * `zdtp-server` bin entry.
3
+ *
4
+ * The `#!/usr/bin/env node` shebang is intentionally NOT in this source file —
5
+ * Vite/Rollup re-injects it via `output.banner` (see vite.config.ts) onto the
6
+ * emitted `dist/bin/server.js`. That keeps the bundled file as the single
7
+ * source of truth for the executable header and avoids esbuild rejecting a
8
+ * double-shebang in the build output.
9
+ *
10
+ * Wraps the framework-agnostic `createApplyHandler` from `../server` in a tiny
11
+ * Node `http` server that:
12
+ *
13
+ * - parses argv via `parseArgs`
14
+ * - resolves --root / --write-root / --routing
15
+ * - loads the routing JSON via `loadRoutingFromFile`
16
+ * - serves OPTIONS/POST /apply with CORS gating, plus GET /healthz, plus
17
+ * 404/405 for everything else
18
+ * - logs apply outcomes (unless --quiet)
19
+ * - exits 1 with a friendly stderr message on EADDRINUSE
20
+ * - shuts down gracefully on SIGINT/SIGTERM
21
+ */
22
+ export {};
23
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/bin/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG"}
@@ -0,0 +1,283 @@
1
+ #!/usr/bin/env node
2
+ import { realpathSync as H } from "node:fs";
3
+ import { createServer as C } from "node:http";
4
+ import { resolve as d } from "node:path";
5
+ import { l as x, c as N } from "../load-routing-XyKgftpe.js";
6
+ function g(t, e) {
7
+ return typeof t != "string" || t.length === 0 || e.length === 0 ? !1 : e.includes(t);
8
+ }
9
+ function w(t) {
10
+ return {
11
+ "Access-Control-Allow-Origin": t,
12
+ "Access-Control-Allow-Methods": "POST, OPTIONS",
13
+ "Access-Control-Allow-Headers": "content-type",
14
+ "Access-Control-Max-Age": "600"
15
+ };
16
+ }
17
+ const k = 24681, b = "127.0.0.1", $ = `Usage: zdtp-server [options]
18
+
19
+ Run a small Node http server that wraps the design-token apply handler.
20
+
21
+ Options:
22
+ --root <dir> Repo root used as the CWD reference for routing
23
+ paths. Defaults to the current working directory.
24
+ --write-root <path> REQUIRED. Absolute or root-relative path to the
25
+ single directory the bin is allowed to write into.
26
+ --routing <path> REQUIRED. Path to the routing JSON file
27
+ (prefix -> repo-relative CSS file path).
28
+ --port <number> TCP port to bind. Default: ${k}.
29
+ --host <addr> Host/interface to bind. Default: ${b}.
30
+ Use 0.0.0.0 to expose on the LAN (off by default).
31
+ --allow-origin <origin> Origin allowed to POST to /apply. Repeatable.
32
+ At least one is required for any browser to apply.
33
+ --quiet Suppress per-request logs.
34
+ --help Print this message and exit.
35
+
36
+ Examples:
37
+ zdtp-server \\
38
+ --write-root tokens \\
39
+ --routing ./my.routing.json \\
40
+ --allow-origin http://localhost:34434
41
+ `;
42
+ function v(t) {
43
+ const e = {
44
+ root: null,
45
+ writeRoot: null,
46
+ routing: null,
47
+ port: k,
48
+ host: b,
49
+ allowOrigins: [],
50
+ quiet: !1,
51
+ help: !1
52
+ };
53
+ let o = 0;
54
+ for (; o < t.length; ) {
55
+ const n = t[o];
56
+ switch (n) {
57
+ case "--help":
58
+ case "-h":
59
+ e.help = !0, o += 1;
60
+ break;
61
+ case "--quiet":
62
+ e.quiet = !0, o += 1;
63
+ break;
64
+ case "--root":
65
+ e.root = c(t, o, "--root"), o += 2;
66
+ break;
67
+ case "--write-root":
68
+ e.writeRoot = c(t, o, "--write-root"), o += 2;
69
+ break;
70
+ case "--routing":
71
+ e.routing = c(t, o, "--routing"), o += 2;
72
+ break;
73
+ case "--host":
74
+ e.host = c(t, o, "--host"), o += 2;
75
+ break;
76
+ case "--port": {
77
+ const s = c(t, o, "--port"), r = Number(s);
78
+ if (!Number.isInteger(r) || r < 0 || r > 65535)
79
+ throw new Error(`--port must be an integer in 0..65535 (got ${JSON.stringify(s)})`);
80
+ e.port = r, o += 2;
81
+ break;
82
+ }
83
+ case "--allow-origin": {
84
+ const s = c(t, o, "--allow-origin");
85
+ e.allowOrigins.push(s), o += 2;
86
+ break;
87
+ }
88
+ default:
89
+ throw new Error(`Unknown option: ${n}`);
90
+ }
91
+ }
92
+ if (e.help) return e;
93
+ if (!e.writeRoot)
94
+ throw new Error("--write-root is required (the only directory the bin will write into)");
95
+ if (!e.routing)
96
+ throw new Error("--routing is required (path to the routing JSON file)");
97
+ return e;
98
+ }
99
+ function c(t, e, o) {
100
+ const n = t[e + 1];
101
+ if (typeof n != "string" || n.startsWith("--"))
102
+ throw new Error(`${o} requires a value`);
103
+ return n;
104
+ }
105
+ const y = "/apply", D = "/healthz";
106
+ function L(t) {
107
+ const e = d(t.root ?? process.cwd()), o = d(e, t.writeRoot), n = d(e, t.routing);
108
+ return {
109
+ rootDir: e,
110
+ writeRoot: o,
111
+ routingPath: n,
112
+ port: t.port,
113
+ host: t.host,
114
+ allowOrigins: t.allowOrigins,
115
+ quiet: t.quiet
116
+ };
117
+ }
118
+ function a(t, e, o) {
119
+ const n = JSON.stringify(o);
120
+ t.statusCode = e, t.setHeader("Content-Type", "application/json"), t.setHeader("Content-Length", Buffer.byteLength(n).toString()), t.end(n);
121
+ }
122
+ const O = 1048576;
123
+ function U(t) {
124
+ return new Promise((e, o) => {
125
+ const n = [];
126
+ let s = 0;
127
+ t.on("data", (r) => {
128
+ if (s += r.byteLength, s > O) {
129
+ e(413), t.destroy();
130
+ return;
131
+ }
132
+ n.push(r);
133
+ }), t.on("end", () => e(Buffer.concat(n).toString("utf-8"))), t.on("error", o);
134
+ });
135
+ }
136
+ function I(t) {
137
+ const e = new Headers();
138
+ for (const [o, n] of Object.entries(t.headers))
139
+ if (Array.isArray(n))
140
+ for (const s of n) e.append(o, s);
141
+ else typeof n == "string" && e.set(o, n);
142
+ return e;
143
+ }
144
+ async function j(t, e, o) {
145
+ t.statusCode = e.status, e.headers.forEach((s, r) => {
146
+ t.setHeader(r, s);
147
+ });
148
+ for (const [s, r] of Object.entries(o))
149
+ t.setHeader(s, r);
150
+ const n = await e.text();
151
+ t.end(n);
152
+ }
153
+ function q(t, e) {
154
+ if (!t)
155
+ try {
156
+ const o = JSON.parse(e);
157
+ if (!o.ok || !Array.isArray(o.updated)) return;
158
+ const n = o.updated.reduce(
159
+ (i, l) => i + (Array.isArray(l.changed) ? l.changed.length : 0),
160
+ 0
161
+ ), s = o.updated.length, r = o.updated.filter((i) => Array.isArray(i.changed) && i.changed.length > 0).map((i) => i.file);
162
+ console.log(
163
+ `[design-token-panel] applied ${n} tokens to ${s} files (changed: ${r.length > 0 ? r.join(", ") : "none"})`
164
+ );
165
+ } catch {
166
+ }
167
+ }
168
+ function F(t) {
169
+ const { applyHandler: e, config: o } = t;
170
+ return async function(s, r) {
171
+ const i = s.url ?? "/", l = (s.method ?? "GET").toUpperCase(), u = typeof s.headers.origin == "string" ? s.headers.origin : null;
172
+ try {
173
+ if (i === D && l === "GET") {
174
+ a(r, 200, {
175
+ ok: !0,
176
+ writeRoot: o.writeRoot,
177
+ routing: o.routingPath,
178
+ port: o.port
179
+ });
180
+ return;
181
+ }
182
+ if (i === y) {
183
+ if (l === "OPTIONS") {
184
+ if (!g(u, o.allowOrigins)) {
185
+ a(r, 403, { ok: !1, error: "Origin not allowed" });
186
+ return;
187
+ }
188
+ const S = w(u);
189
+ for (const [P, E] of Object.entries(S))
190
+ r.setHeader(P, E);
191
+ r.statusCode = 204, r.end();
192
+ return;
193
+ }
194
+ if (l !== "POST") {
195
+ r.setHeader("Allow", "POST, OPTIONS"), a(r, 405, { ok: !1, error: "Method not allowed" });
196
+ return;
197
+ }
198
+ const p = s.headers["content-type"];
199
+ if (typeof p != "string" || !p.toLowerCase().includes("application/json")) {
200
+ a(r, 415, { ok: !1, error: "Content-Type must be application/json" });
201
+ return;
202
+ }
203
+ if (!g(u, o.allowOrigins)) {
204
+ a(r, 403, { ok: !1, error: "Origin not allowed" });
205
+ return;
206
+ }
207
+ const f = await U(s);
208
+ if (f === 413) {
209
+ a(r, 413, {
210
+ ok: !1,
211
+ error: "Payload Too Large",
212
+ limit: O
213
+ });
214
+ return;
215
+ }
216
+ const m = f, A = new Request(`http://localhost${y}`, {
217
+ method: "POST",
218
+ headers: I(s),
219
+ body: m
220
+ }), h = await e(A), R = await h.clone().text(), T = w(u);
221
+ await j(r, h, T), q(o.quiet, R);
222
+ return;
223
+ }
224
+ a(r, 404, { ok: !1, error: "Not found" });
225
+ } catch (p) {
226
+ console.error("[design-token-panel] Unhandled error:", p), r.headersSent ? r.end() : a(r, 500, { ok: !1, error: "Internal server error" });
227
+ }
228
+ };
229
+ }
230
+ function _(t, e) {
231
+ t.on("error", (n) => {
232
+ n.code === "EADDRINUSE" && (console.error(`[design-token-panel] port ${e} already in use`), process.exit(1)), console.error("[design-token-panel] Server error:", n), process.exit(1);
233
+ });
234
+ const o = (n) => {
235
+ t.close(() => {
236
+ process.exit(0);
237
+ }), setTimeout(() => {
238
+ console.error(`[design-token-panel] force-exiting after ${n}`), process.exit(0);
239
+ }, 5e3).unref();
240
+ };
241
+ process.on("SIGINT", o), process.on("SIGTERM", o);
242
+ }
243
+ function B() {
244
+ let t;
245
+ try {
246
+ t = v(process.argv.slice(2));
247
+ } catch (r) {
248
+ console.error(`[design-token-panel] ${r.message}`), console.error(""), console.error("Run --help for usage."), process.exit(1);
249
+ }
250
+ t.help && (process.stdout.write($), process.exit(0));
251
+ const e = L(t);
252
+ let o;
253
+ try {
254
+ o = x(e.routingPath);
255
+ } catch (r) {
256
+ console.error(`[design-token-panel] Failed to load routing: ${r.message}`), process.exit(1);
257
+ }
258
+ const n = N({
259
+ rootDir: e.rootDir,
260
+ writeRoot: e.writeRoot,
261
+ routing: o
262
+ }), s = C(F({ applyHandler: n, config: e }));
263
+ _(s, e.port), s.listen(e.port, e.host, () => {
264
+ if (!e.quiet) {
265
+ const r = s.address(), i = typeof r == "object" && r ? r.port : e.port;
266
+ console.log(
267
+ `[design-token-panel] listening on http://${e.host}:${i} (writeRoot: ${e.writeRoot})`
268
+ ), e.allowOrigins.length === 0 && console.log(
269
+ "[design-token-panel] WARNING: no --allow-origin set; browser POST /apply will be rejected."
270
+ );
271
+ }
272
+ });
273
+ }
274
+ const G = (() => {
275
+ if (typeof process.argv[1] != "string") return !1;
276
+ try {
277
+ const t = H(process.argv[1]), e = new URL(`file://${d(t)}`).href, o = import.meta.url;
278
+ return e === o;
279
+ } catch {
280
+ return !1;
281
+ }
282
+ })();
283
+ G && B();
@@ -0,0 +1,85 @@
1
+ const e = {
2
+ "Default Light": {
3
+ background: 9,
4
+ foreground: 11,
5
+ cursor: 6,
6
+ selectionBg: 11,
7
+ selectionFg: 10,
8
+ palette: [
9
+ "#303030",
10
+ "#dd3131",
11
+ "#266538",
12
+ "#a83838",
13
+ "#3277c8",
14
+ "#a35e0f",
15
+ "#90a1b9",
16
+ "#7a5218",
17
+ "#6b6b6b",
18
+ "#e2ddda",
19
+ "#ece9e9",
20
+ "#303030",
21
+ "#5b99dc",
22
+ "#b89ee7",
23
+ "#8590a0",
24
+ "#b91c1c"
25
+ ],
26
+ shikiTheme: "catppuccin-latte",
27
+ semantic: {
28
+ surface: 10,
29
+ muted: 8,
30
+ accent: 5,
31
+ accentHover: 14,
32
+ codeBg: 10,
33
+ codeFg: 11,
34
+ success: 2,
35
+ danger: 1,
36
+ warning: 3,
37
+ info: 4
38
+ }
39
+ },
40
+ "Default Dark": {
41
+ background: 9,
42
+ // p11 (light gray) — not p15. The example palette repurposes p15 as a
43
+ // brand-red accent, so pinning `foreground` to p15 would paint the
44
+ // panel's fg swatch red and make every `fg`-mapped semantic resolve
45
+ // to red. p11 aligns with SEMANTIC_DEFAULTS_ZD.fg (also 11).
46
+ foreground: 11,
47
+ cursor: 6,
48
+ selectionBg: 10,
49
+ selectionFg: 11,
50
+ palette: [
51
+ "#1c1c1c",
52
+ "#da6871",
53
+ "#93bb77",
54
+ "#dfbb77",
55
+ "#5caae9",
56
+ "#c074d6",
57
+ "#90a1b9",
58
+ "#a0a0a0",
59
+ "#888888",
60
+ "18",
61
+ "#383838",
62
+ "#e0e0e0",
63
+ "#d69a66",
64
+ "#c074d6",
65
+ "#a7c0e3",
66
+ "#b91c1c"
67
+ ],
68
+ shikiTheme: "vitesse-dark",
69
+ semantic: {
70
+ surface: 0,
71
+ muted: 8,
72
+ accent: 12,
73
+ accentHover: 14,
74
+ codeBg: 10,
75
+ codeFg: 11,
76
+ success: 2,
77
+ danger: 1,
78
+ warning: 3,
79
+ info: 4
80
+ }
81
+ }
82
+ };
83
+ export {
84
+ e as c
85
+ };
@@ -0,0 +1,64 @@
1
+ /**
2
+ * ColorPicker — dual-mode (OKLCH | HSL) color picker for the design-token panel.
3
+ *
4
+ * Renders as a "popover body only" component — the parent is responsible for
5
+ * mounting/unmounting based on an open/closed boolean. No trigger swatch, no
6
+ * portal, no createPortal.
7
+ *
8
+ * Issue #175 (Wave 2 of the OKLCH Picker epic, issue #174-base).
9
+ *
10
+ * Design rules (see packages/zudo-design-token-panel/CLAUDE.md):
11
+ * - All interactive elements use <div role="button" tabIndex={0}> with
12
+ * explicit Enter/Space onKeyDown handlers. Native button and heading tags
13
+ * are not used (hostile-host policy).
14
+ * - BEM class names: tokenpanel-color-picker-* (locked external contract).
15
+ * - usePopoverClose: pointerdown + Escape only — NO scroll listener.
16
+ * - Mode persisted to localStorage under key tokenpanel.colorPicker.mode.
17
+ * - Alpha always shown; alpha ∈ [0, 100] scale throughout.
18
+ * - useSyncedHex: incoming color prop ignored while isDraggingRef.current.
19
+ */
20
+ import type { JSX } from 'preact';
21
+ export type ColorPickerMode = 'oklch' | 'hsl';
22
+ export interface ColorPickerProps {
23
+ /** Current hex color (#RRGGBB or #RRGGBBAA). Source of truth. */
24
+ color: string;
25
+ /** Called when the user commits a new color via any sub-control. */
26
+ onChange: (hex: string) => void;
27
+ /** Optional label rendered in the picker header. */
28
+ label?: string;
29
+ /**
30
+ * Initial mode. The runtime mode is uncontrolled inside the component
31
+ * and persisted via localStorage[LOCAL_STORAGE_KEY]. Defaults to 'oklch'.
32
+ */
33
+ defaultMode?: ColorPickerMode;
34
+ /** Element to anchor the popover against (popover sits below/above it). */
35
+ anchorRef: React.RefObject<HTMLElement | null>;
36
+ /** Called when the picker requests to close itself (Escape / outside click). */
37
+ onClose: () => void;
38
+ }
39
+ export declare const LOCAL_STORAGE_KEY = "tokenpanel.colorPicker.mode";
40
+ /**
41
+ * Compute a `position: fixed` style that places the popover below (or above,
42
+ * if flipped) the anchor element, then clamps all edges inside the viewport.
43
+ *
44
+ * When vertical space is scarce on both sides, the popover is pinned to the
45
+ * top edge (top = pad) and given a max-height + overflow: auto so it scrolls
46
+ * rather than clips.
47
+ */
48
+ export declare function getFixedPopoverStyle(anchor: HTMLElement | null, estW: number, estH: number): JSX.CSSProperties;
49
+ /**
50
+ * Close the popover on outside pointerdown or Escape key.
51
+ *
52
+ * Deliberately does NOT close on scroll — a scroll event on the host page
53
+ * should not dismiss an in-flight color edit.
54
+ */
55
+ export declare function usePopoverClose(containerRef: React.RefObject<HTMLElement | null>, onClose: () => void): void;
56
+ /**
57
+ * ColorPicker — popover body only.
58
+ *
59
+ * The parent renders `{isOpen && <ColorPicker ... />}`. This component does
60
+ * NOT render a trigger swatch and does NOT use createPortal.
61
+ */
62
+ export declare function ColorPicker({ color, onChange, label, defaultMode, anchorRef, onClose, }: ColorPickerProps): JSX.Element;
63
+ export default ColorPicker;
64
+ //# sourceMappingURL=color-picker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"color-picker.d.ts","sourceRoot":"","sources":["../../../src/components/color-picker/color-picker.tsx"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;;GAkBG;AAUH,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAiBlC,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,KAAK,CAAC;AAE9C,MAAM,WAAW,gBAAgB;IAC/B,iEAAiE;IACjE,KAAK,EAAE,MAAM,CAAC;IACd,oEAAoE;IACpE,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,oDAAoD;IACpD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,2EAA2E;IAC3E,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAC/C,gFAAgF;IAChF,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAID,eAAO,MAAM,iBAAiB,gCAAgC,CAAC;AAyJ/D;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,WAAW,GAAG,IAAI,EAC1B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,GACX,GAAG,CAAC,aAAa,CAuCnB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,YAAY,EAAE,KAAK,CAAC,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,EACjD,OAAO,EAAE,MAAM,IAAI,GAClB,IAAI,CA2BN;AAID;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,QAAQ,EACR,KAAK,EACL,WAAqB,EACrB,SAAS,EACT,OAAO,GACR,EAAE,gBAAgB,GAAG,GAAG,CAAC,OAAO,CAyehC;AAED,eAAe,WAAW,CAAC"}
@@ -0,0 +1,25 @@
1
+ import type { JSX } from 'preact';
2
+ export interface SliderConfig {
3
+ key: string;
4
+ /** Single-character label, e.g. 'L', 'H'. */
5
+ label: string;
6
+ /** Full accessible label, e.g. 'Lightness', 'Hue'. */
7
+ ariaLabel: string;
8
+ min: number;
9
+ max: number;
10
+ step: number;
11
+ /** Format the numeric value for display in the value span. */
12
+ format: (v: number) => string;
13
+ }
14
+ export interface CustomSliderProps {
15
+ config: SliderConfig;
16
+ value: number;
17
+ /** CSS gradient string applied to the track div's background. */
18
+ gradient: string;
19
+ onChange: (next: number) => void;
20
+ onDragStart: () => void;
21
+ onDragEnd: () => void;
22
+ }
23
+ export declare function CustomSlider({ config, value, gradient, onChange, onDragStart, onDragEnd, }: CustomSliderProps): JSX.Element;
24
+ export default CustomSlider;
25
+ //# sourceMappingURL=custom-slider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"custom-slider.d.ts","sourceRoot":"","sources":["../../../src/components/color-picker/custom-slider.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AAWlC,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,6CAA6C;IAC7C,KAAK,EAAE,MAAM,CAAC;IACd,sDAAsD;IACtD,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,8DAA8D;IAC9D,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,YAAY,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,iEAAiE;IACjE,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,SAAS,EAAE,MAAM,IAAI,CAAC;CACvB;AAoCD,wBAAgB,YAAY,CAAC,EAC3B,MAAM,EACN,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,WAAW,EACX,SAAS,GACV,EAAE,iBAAiB,GAAG,GAAG,CAAC,OAAO,CA+LjC;AAED,eAAe,YAAY,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { ColorPicker, type ColorPickerMode, type ColorPickerProps, LOCAL_STORAGE_KEY, getFixedPopoverStyle, usePopoverClose, } from './color-picker';
2
+ export { default } from './color-picker';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/color-picker/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,iBAAiB,EACjB,oBAAoB,EACpB,eAAe,GAChB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC"}