@takazudo/zdtp 0.4.3 → 0.4.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,56 +1,56 @@
1
- import { c as h, g as u, a as g, b as w, d as y, e as P } from "../panel-config-3tBEHjvZ.js";
2
- import { g as d, Z as b } from "../tweak-state-BEx1SHu7.js";
3
- import { s as _, l as A, a as c, c as k, b as I } from "../autoload-state-B1MWY_Pp.js";
4
- const l = "tokenpanel-config";
5
- function E() {
1
+ import { c as w, g as u, a as g, b as y, d as P, e as b, f as _ } from "../panel-config-CipeKMTz.js";
2
+ import { g as d, Z as A } from "../tweak-state-xt-tSQ_t.js";
3
+ import { s as k, l as I, a as c, c as E, b as C } from "../autoload-state-DF7TsTgY.js";
4
+ const i = "tokenpanel-config";
5
+ function S() {
6
6
  if (typeof document > "u")
7
7
  throw new Error(
8
8
  "[design-token-panel] host-adapter loaded without a document; expected to run in a browser context."
9
9
  );
10
- const n = document.getElementById(l);
10
+ const n = document.getElementById(i);
11
11
  if (!n)
12
12
  throw new Error(
13
- `[design-token-panel] Inline config script #${l} not found. Ensure <DesignTokenPanelHost config={...} /> is rendered on this page before the host script runs.`
13
+ `[design-token-panel] Inline config script #${i} not found. Ensure <DesignTokenPanelHost config={...} /> is rendered on this page before the host script runs.`
14
14
  );
15
- const o = n.textContent ?? "";
15
+ const a = n.textContent ?? "";
16
16
  let e;
17
17
  try {
18
- e = JSON.parse(o);
19
- } catch (a) {
18
+ e = JSON.parse(a);
19
+ } catch (o) {
20
20
  throw new Error(
21
- `[design-token-panel] Failed to parse inline config from #${l}: ${a.message}`
21
+ `[design-token-panel] Failed to parse inline config from #${i}: ${o.message}`
22
22
  );
23
23
  }
24
- return P(e), e;
24
+ return _(e), e;
25
25
  }
26
- function C(n) {
26
+ function T(n) {
27
27
  return n.__zudoDesignTokenPanelAdapter || (n.__zudoDesignTokenPanelAdapter = {}), n.__zudoDesignTokenPanelAdapter;
28
28
  }
29
- function S(n, o) {
30
- const e = C(n);
31
- let a = e[o];
32
- return a || (a = { bound: !1, modulePromise: null }, e[o] = a), a;
29
+ function V(n, a) {
30
+ const e = T(n);
31
+ let o = e[a];
32
+ return o || (o = { bound: !1, modulePromise: null }, e[a] = o), o;
33
33
  }
34
- function T(n) {
34
+ function v(n) {
35
35
  try {
36
36
  return window.localStorage.getItem(n) === "1";
37
37
  } catch {
38
38
  return !1;
39
39
  }
40
40
  }
41
- function v(n, o) {
41
+ function D(n, a, e) {
42
42
  try {
43
- const e = window.localStorage;
44
- return e.getItem(o) !== null || e.getItem(n) !== null;
43
+ const o = window.localStorage;
44
+ return o.getItem(e) !== null || o.getItem(a) !== null || o.getItem(n) !== null;
45
45
  } catch {
46
46
  return !1;
47
47
  }
48
48
  }
49
- async function i(n) {
50
- return n.modulePromise === null && (n.modulePromise = import("@takazudo/zdtp").then((o) => {
49
+ async function l(n) {
50
+ return n.modulePromise === null && (n.modulePromise = import("@takazudo/zdtp").then((a) => {
51
51
  try {
52
- const e = u(), a = o.__panelConfigForTest();
53
- e !== a && console.warn(
52
+ const e = u(), o = a.__panelConfigForTest();
53
+ e !== o && console.warn(
54
54
  "[design-token-panel] Singleton-sharing check failed: the host adapter and the panel module observed different PanelConfig singletons. This indicates the package's `config/panel-config` module is no longer code-split into a single shared chunk. The panel may behave correctly today, but storage keys / namespaces / branding could diverge between the two surfaces in future bundles."
55
55
  );
56
56
  } catch (e) {
@@ -58,17 +58,17 @@ async function i(n) {
58
58
  "[design-token-panel] Singleton-sharing check could not run (likely an older dist without the __panelConfigForTest accessor): " + e.message
59
59
  );
60
60
  }
61
- return o;
61
+ return a;
62
62
  })), n.modulePromise;
63
63
  }
64
- function D(n, o, e, a, t) {
65
- const s = n[o] ?? {};
64
+ function K(n, a, e, o, t) {
65
+ const s = n[a] ?? {};
66
66
  s.showDesignPanel = async () => {
67
- c(t, !0), await i(e), a.open();
67
+ c(t, !0), await l(e), o.open();
68
68
  }, s.hideDesignPanel = async () => {
69
- await i(e), a.close();
69
+ await l(e), o.close();
70
70
  }, s.toggleDesignPanel = async () => {
71
- await i(e), a.toggle();
71
+ await l(e), o.toggle();
72
72
  let r = !1;
73
73
  try {
74
74
  r = window.localStorage.getItem(d(t)) === "1";
@@ -76,13 +76,13 @@ function D(n, o, e, a, t) {
76
76
  }
77
77
  r && c(t, !0);
78
78
  }, s.enableAutoload = async () => {
79
- (await i(e)).enableAutoload(t);
79
+ (await l(e)).enableAutoload(t);
80
80
  }, s.disableAutoload = async () => {
81
81
  if (e.modulePromise !== null) {
82
- (await i(e)).disableAutoload(t);
82
+ (await l(e)).disableAutoload(t);
83
83
  return;
84
84
  }
85
- k(t), I(!1, t);
85
+ E(t), C(!1, t);
86
86
  try {
87
87
  window.localStorage.setItem(g(t), "0");
88
88
  } catch {
@@ -91,12 +91,12 @@ function D(n, o, e, a, t) {
91
91
  window.localStorage.removeItem(d(t));
92
92
  } catch {
93
93
  }
94
- }, n[o] = s;
94
+ }, n[a] = s;
95
95
  }
96
96
  (function() {
97
- const o = E(), e = o.legacyIdRenameMap ? o : { ...o, legacyIdRenameMap: { ...b } }, a = h(e), t = u(), s = window, r = S(s, t.storagePrefix);
98
- if (D(s, t.consoleNamespace, r, a, t), r.bound) return;
97
+ const a = S(), e = a.legacyIdRenameMap ? a : { ...a, legacyIdRenameMap: { ...A } }, o = w(e), t = u(), s = window, r = V(s, t.storagePrefix);
98
+ if (K(s, t.consoleNamespace, r, o, t), r.bound) return;
99
99
  r.bound = !0;
100
- const f = g(t), p = w(t), m = y(t);
101
- (T(f) || v(p, m) || _(t) || A(t)) && i(r);
100
+ const f = g(t), m = y(t), p = P(t), h = b(t);
101
+ (v(f) || D(m, p, h) || k(t) || I(t)) && l(r);
102
102
  })();
@@ -1,4 +1,4 @@
1
- import { s as t } from "../panel-config-3tBEHjvZ.js";
1
+ import { s as t } from "../panel-config-CipeKMTz.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-DCReQE0k.js";
4
4
  const e = {
@@ -1,4 +1,4 @@
1
- import { g as a, j as o } from "./panel-config-3tBEHjvZ.js";
1
+ import { g as a, k as o } from "./panel-config-CipeKMTz.js";
2
2
  function n(e = a()) {
3
3
  return `${e.storagePrefix}-elpath-enabled`;
4
4
  }
@@ -1,20 +1,20 @@
1
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-DtNTKoLW.js";
6
- function g(t, e) {
7
- return typeof t != "string" || t.length === 0 || e.length === 0 ? !1 : e.includes(t);
2
+ import { realpathSync as E } from "node:fs";
3
+ import { createServer as H } from "node:http";
4
+ import { resolve as p } from "node:path";
5
+ import { l as $, c as x } from "../load-routing-LJ72261l.js";
6
+ function g(o, t) {
7
+ return typeof o != "string" || o.length === 0 || t.length === 0 ? !1 : t.includes(o);
8
8
  }
9
- function w(t) {
9
+ function w(o) {
10
10
  return {
11
- "Access-Control-Allow-Origin": t,
11
+ "Access-Control-Allow-Origin": o,
12
12
  "Access-Control-Allow-Methods": "POST, OPTIONS",
13
13
  "Access-Control-Allow-Headers": "content-type",
14
14
  "Access-Control-Max-Age": "600"
15
15
  };
16
16
  }
17
- const k = 24681, b = "127.0.0.1", $ = `Usage: zdtp-server [options]
17
+ const k = 24681, b = "127.0.0.1", N = `Usage: zdtp-server [options]
18
18
 
19
19
  Run a small Node http server that wraps the design-token apply handler.
20
20
 
@@ -39,8 +39,8 @@ Examples:
39
39
  --routing ./my.routing.json \\
40
40
  --allow-origin http://localhost:34434
41
41
  `;
42
- function v(t) {
43
- const e = {
42
+ function v(o) {
43
+ const t = {
44
44
  root: null,
45
45
  writeRoot: null,
46
46
  routing: null,
@@ -50,144 +50,148 @@ function v(t) {
50
50
  quiet: !1,
51
51
  help: !1
52
52
  };
53
- let o = 0;
54
- for (; o < t.length; ) {
55
- const n = t[o];
53
+ let e = 0;
54
+ for (; e < o.length; ) {
55
+ const n = o[e];
56
56
  switch (n) {
57
57
  case "--help":
58
58
  case "-h":
59
- e.help = !0, o += 1;
59
+ t.help = !0, e += 1;
60
60
  break;
61
61
  case "--quiet":
62
- e.quiet = !0, o += 1;
62
+ t.quiet = !0, e += 1;
63
63
  break;
64
64
  case "--root":
65
- e.root = c(t, o, "--root"), o += 2;
65
+ t.root = c(o, e, "--root"), e += 2;
66
66
  break;
67
67
  case "--write-root":
68
- e.writeRoot = c(t, o, "--write-root"), o += 2;
68
+ t.writeRoot = c(o, e, "--write-root"), e += 2;
69
69
  break;
70
70
  case "--routing":
71
- e.routing = c(t, o, "--routing"), o += 2;
71
+ t.routing = c(o, e, "--routing"), e += 2;
72
72
  break;
73
73
  case "--host":
74
- e.host = c(t, o, "--host"), o += 2;
74
+ t.host = c(o, e, "--host"), e += 2;
75
75
  break;
76
76
  case "--port": {
77
- const s = c(t, o, "--port"), r = Number(s);
77
+ const s = c(o, e, "--port"), r = Number(s);
78
78
  if (!Number.isInteger(r) || r < 0 || r > 65535)
79
79
  throw new Error(`--port must be an integer in 0..65535 (got ${JSON.stringify(s)})`);
80
- e.port = r, o += 2;
80
+ t.port = r, e += 2;
81
81
  break;
82
82
  }
83
83
  case "--allow-origin": {
84
- const s = c(t, o, "--allow-origin");
85
- e.allowOrigins.push(s), o += 2;
84
+ const s = c(o, e, "--allow-origin");
85
+ t.allowOrigins.push(s), e += 2;
86
86
  break;
87
87
  }
88
88
  default:
89
89
  throw new Error(`Unknown option: ${n}`);
90
90
  }
91
91
  }
92
- if (e.help) return e;
93
- if (!e.writeRoot)
92
+ if (t.help) return t;
93
+ if (!t.writeRoot)
94
94
  throw new Error("--write-root is required (the only directory the bin will write into)");
95
- if (!e.routing)
95
+ if (!t.routing)
96
96
  throw new Error("--routing is required (path to the routing JSON file)");
97
- return e;
97
+ return t;
98
98
  }
99
- function c(t, e, o) {
100
- const n = t[e + 1];
99
+ function c(o, t, e) {
100
+ const n = o[t + 1];
101
101
  if (typeof n != "string" || n.startsWith("--"))
102
- throw new Error(`${o} requires a value`);
102
+ throw new Error(`${e} requires a value`);
103
103
  return n;
104
104
  }
105
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);
106
+ function L(o) {
107
+ const t = p(o.root ?? process.cwd()), e = p(t, o.writeRoot), n = p(t, o.routing);
108
108
  return {
109
- rootDir: e,
110
- writeRoot: o,
109
+ rootDir: t,
110
+ writeRoot: e,
111
111
  routingPath: n,
112
- port: t.port,
113
- host: t.host,
114
- allowOrigins: t.allowOrigins,
115
- quiet: t.quiet
112
+ port: o.port,
113
+ host: o.host,
114
+ allowOrigins: o.allowOrigins,
115
+ quiet: o.quiet
116
116
  };
117
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);
118
+ function a(o, t, e) {
119
+ const n = JSON.stringify(e);
120
+ o.statusCode = t, o.setHeader("Content-Type", "application/json"), o.setHeader("Content-Length", Buffer.byteLength(n).toString()), o.end(n);
121
121
  }
122
122
  const O = 1048576;
123
- function U(t) {
124
- return new Promise((e, o) => {
123
+ function j(o) {
124
+ return new Promise((t, e) => {
125
125
  const n = [];
126
126
  let s = 0;
127
- t.on("data", (r) => {
127
+ o.on("data", (r) => {
128
128
  if (s += r.byteLength, s > O) {
129
- e(413), t.destroy();
129
+ t(413), o.destroy();
130
130
  return;
131
131
  }
132
132
  n.push(r);
133
- }), t.on("end", () => e(Buffer.concat(n).toString("utf-8"))), t.on("error", o);
133
+ }), o.on("end", () => t(Buffer.concat(n).toString("utf-8"))), o.on("error", e);
134
134
  });
135
135
  }
136
- function I(t) {
137
- const e = new Headers();
138
- for (const [o, n] of Object.entries(t.headers))
136
+ function U(o) {
137
+ const t = new Headers();
138
+ for (const [e, n] of Object.entries(o.headers))
139
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;
140
+ for (const s of n) t.append(e, s);
141
+ else typeof n == "string" && t.set(e, n);
142
+ return t;
143
143
  }
144
- async function j(t, e, o) {
145
- t.statusCode = e.status, e.headers.forEach((s, r) => {
146
- t.setHeader(r, s);
144
+ async function I(o, t, e) {
145
+ o.statusCode = t.status, t.headers.forEach((s, r) => {
146
+ o.setHeader(r, s);
147
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);
148
+ for (const [s, r] of Object.entries(e))
149
+ o.setHeader(s, r);
150
+ const n = await t.text();
151
+ o.end(n);
152
152
  }
153
- function q(t, e) {
154
- if (!t)
153
+ function V(o, t) {
154
+ if (!o)
155
155
  try {
156
- const o = JSON.parse(e);
157
- if (!o.ok || !Array.isArray(o.updated)) return;
158
- const n = o.updated.reduce(
156
+ const e = JSON.parse(t);
157
+ if (!e.ok || !Array.isArray(e.updated)) return;
158
+ const n = e.updated.reduce(
159
159
  (i, l) => i + (Array.isArray(l.changed) ? l.changed.length : 0),
160
160
  0
161
- ), s = o.updated.length, r = o.updated.filter((i) => Array.isArray(i.changed) && i.changed.length > 0).map((i) => i.file);
161
+ ), s = e.updated.length, r = e.updated.filter((i) => Array.isArray(i.changed) && i.changed.length > 0).map((i) => i.file);
162
162
  console.log(
163
163
  `[design-token-panel] applied ${n} tokens to ${s} files (changed: ${r.length > 0 ? r.join(", ") : "none"})`
164
+ ), Array.isArray(e.unknownCssVars) && e.unknownCssVars.length > 0 && console.log(
165
+ `[design-token-panel] unknown: ${e.unknownCssVars.length} cssVar(s) not found (${e.unknownCssVars.join(", ")})`
166
+ ), Array.isArray(e.unknownOutsideBlockCssVars) && e.unknownOutsideBlockCssVars.length > 0 && console.log(
167
+ `[design-token-panel] outside scanned block: ${e.unknownOutsideBlockCssVars.length} of those cssVar(s) are declared in the file but outside the scanned :root/@theme block(s), so they were not rewritable (${e.unknownOutsideBlockCssVars.join(", ")})`
164
168
  );
165
169
  } catch {
166
170
  }
167
171
  }
168
- function F(t) {
169
- const { applyHandler: e, config: o } = t;
172
+ function B(o) {
173
+ const { applyHandler: t, config: e } = o;
170
174
  return async function(s, r) {
171
175
  const i = s.url ?? "/", l = (s.method ?? "GET").toUpperCase(), u = typeof s.headers.origin == "string" ? s.headers.origin : null;
172
176
  try {
173
177
  if (i === D && l === "GET") {
174
178
  a(r, 200, {
175
179
  ok: !0,
176
- writeRoot: o.writeRoot,
177
- routing: o.routingPath,
178
- port: o.port
180
+ writeRoot: e.writeRoot,
181
+ routing: e.routingPath,
182
+ port: e.port
179
183
  });
180
184
  return;
181
185
  }
182
186
  if (i === y) {
183
187
  if (l === "OPTIONS") {
184
- if (!g(u, o.allowOrigins)) {
188
+ if (!g(u, e.allowOrigins)) {
185
189
  a(r, 403, { ok: !1, error: "Origin not allowed" });
186
190
  return;
187
191
  }
188
192
  const S = w(u);
189
- for (const [P, E] of Object.entries(S))
190
- r.setHeader(P, E);
193
+ for (const [C, P] of Object.entries(S))
194
+ r.setHeader(C, P);
191
195
  r.statusCode = 204, r.end();
192
196
  return;
193
197
  }
@@ -195,16 +199,16 @@ function F(t) {
195
199
  r.setHeader("Allow", "POST, OPTIONS"), a(r, 405, { ok: !1, error: "Method not allowed" });
196
200
  return;
197
201
  }
198
- const p = s.headers["content-type"];
199
- if (typeof p != "string" || !p.toLowerCase().includes("application/json")) {
202
+ const d = s.headers["content-type"];
203
+ if (typeof d != "string" || !d.toLowerCase().includes("application/json")) {
200
204
  a(r, 415, { ok: !1, error: "Content-Type must be application/json" });
201
205
  return;
202
206
  }
203
- if (!g(u, o.allowOrigins)) {
207
+ if (!g(u, e.allowOrigins)) {
204
208
  a(r, 403, { ok: !1, error: "Origin not allowed" });
205
209
  return;
206
210
  }
207
- const f = await U(s);
211
+ const f = await j(s);
208
212
  if (f === 413) {
209
213
  a(r, 413, {
210
214
  ok: !1,
@@ -213,71 +217,71 @@ function F(t) {
213
217
  });
214
218
  return;
215
219
  }
216
- const m = f, A = new Request(`http://localhost${y}`, {
220
+ const A = f, m = new Request(`http://localhost${y}`, {
217
221
  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
+ headers: U(s),
223
+ body: A
224
+ }), h = await t(m), R = await h.clone().text(), T = w(u);
225
+ await I(r, h, T), V(e.quiet, R);
222
226
  return;
223
227
  }
224
228
  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" });
229
+ } catch (d) {
230
+ console.error("[design-token-panel] Unhandled error:", d), r.headersSent ? r.end() : a(r, 500, { ok: !1, error: "Internal server error" });
227
231
  }
228
232
  };
229
233
  }
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);
234
+ function q(o, t) {
235
+ o.on("error", (n) => {
236
+ n.code === "EADDRINUSE" && (console.error(`[design-token-panel] port ${t} already in use`), process.exit(1)), console.error("[design-token-panel] Server error:", n), process.exit(1);
233
237
  });
234
- const o = (n) => {
235
- t.close(() => {
238
+ const e = (n) => {
239
+ o.close(() => {
236
240
  process.exit(0);
237
241
  }), setTimeout(() => {
238
242
  console.error(`[design-token-panel] force-exiting after ${n}`), process.exit(0);
239
243
  }, 5e3).unref();
240
244
  };
241
- process.on("SIGINT", o), process.on("SIGTERM", o);
245
+ process.on("SIGINT", e), process.on("SIGTERM", e);
242
246
  }
243
- function B() {
244
- let t;
247
+ function F() {
248
+ let o;
245
249
  try {
246
- t = v(process.argv.slice(2));
250
+ o = v(process.argv.slice(2));
247
251
  } catch (r) {
248
252
  console.error(`[design-token-panel] ${r.message}`), console.error(""), console.error("Run --help for usage."), process.exit(1);
249
253
  }
250
- t.help && (process.stdout.write($), process.exit(0));
251
- const e = L(t);
252
- let o;
254
+ o.help && (process.stdout.write(N), process.exit(0));
255
+ const t = L(o);
256
+ let e;
253
257
  try {
254
- o = x(e.routingPath);
258
+ e = $(t.routingPath);
255
259
  } catch (r) {
256
260
  console.error(`[design-token-panel] Failed to load routing: ${r.message}`), process.exit(1);
257
261
  }
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;
262
+ const n = x({
263
+ rootDir: t.rootDir,
264
+ writeRoot: t.writeRoot,
265
+ routing: e
266
+ }), s = H(B({ applyHandler: n, config: t }));
267
+ q(s, t.port), s.listen(t.port, t.host, () => {
268
+ if (!t.quiet) {
269
+ const r = s.address(), i = typeof r == "object" && r ? r.port : t.port;
266
270
  console.log(
267
- `[design-token-panel] listening on http://${e.host}:${i} (writeRoot: ${e.writeRoot})`
268
- ), e.allowOrigins.length === 0 && console.log(
271
+ `[design-token-panel] listening on http://${t.host}:${i} (writeRoot: ${t.writeRoot})`
272
+ ), t.allowOrigins.length === 0 && console.log(
269
273
  "[design-token-panel] WARNING: no --allow-origin set; browser POST /apply will be rejected."
270
274
  );
271
275
  }
272
276
  });
273
277
  }
274
- const G = (() => {
278
+ const _ = (() => {
275
279
  if (typeof process.argv[1] != "string") return !1;
276
280
  try {
277
- const t = H(process.argv[1]), e = new URL(`file://${d(t)}`).href, o = import.meta.url;
278
- return e === o;
281
+ const o = E(process.argv[1]), t = new URL(`file://${p(o)}`).href, e = import.meta.url;
282
+ return t === e;
279
283
  } catch {
280
284
  return !1;
281
285
  }
282
286
  })();
283
- G && B();
287
+ _ && F();
@@ -21,6 +21,8 @@
21
21
  * `panelConfig.colorCluster`.
22
22
  */
23
23
  import type { ColorScheme } from './color-schemes';
24
+ import type { SemanticValue } from '../tokens/tier-model';
25
+ export type { SemanticValue } from '../tokens/tier-model';
24
26
  /**
25
27
  * Base-role keys that a cluster may declare. Subset is allowed (a cluster may
26
28
  * ship zero base roles when its design system doesn't expose them as tokens).
@@ -76,8 +78,16 @@ export interface ColorClusterDataConfig {
76
78
  * `--brand-p{n}`, `--demo-palette-{n}`.
77
79
  */
78
80
  paletteCssVarTemplate: string;
79
- /** Semantic token name → default palette index. */
80
- semanticDefaults: Record<string, number>;
81
+ /**
82
+ * Semantic token name → default mapping. Historically always a palette
83
+ * index (`number`); widened to `SemanticValue` (#459) so a default can also
84
+ * be a literal color or a cross-tab ramp reference. `resolveColorClusterFromTab`
85
+ * now derives the `{ literal }` / best-effort `{ ref }` variants too (#463)
86
+ * for a `semantic: true` tier; actually resolving a `{ ref }` against the
87
+ * ramp tier it names (rendering + apply) is still downstream work
88
+ * (#467/#469).
89
+ */
90
+ semanticDefaults: Record<string, SemanticValue>;
81
91
  /** Semantic token name → CSS custom-property name. */
82
92
  semanticCssNames: Record<string, string>;
83
93
  /** Fallback indices used when a scheme doesn't declare a base role. */
@@ -104,23 +114,36 @@ import type { TabConfig } from '../tokens/tier-model';
104
114
  /**
105
115
  * Derive a `ColorClusterDataConfig` from a color `TabConfig`.
106
116
  *
107
- * - Palette items: the first tier whose items all have `kind: 'color'`.
108
- * Each item's `cssVar` becomes a palette slot; `paletteCssVarTemplate` is
109
- * synthesised as `"{item.cssVar}"` with `{n}` replaced by the slot index.
110
- * Because item cssVars are explicit (e.g. `--zfb-palette-0`) rather
111
- * than template-based, we derive the template from the first item by
112
- * replacing the terminal digit sequence with `{n}`.
117
+ * - Palette items: the first tier whose items all have `kind: 'color'` and
118
+ * are not `semantic: true`. Each item's `cssVar` becomes a palette slot;
119
+ * `paletteCssVarTemplate` is synthesised as `"{item.cssVar}"` with `{n}`
120
+ * replaced by the slot index. Because item cssVars are explicit (e.g.
121
+ * `--zfb-palette-0`) rather than template-based, we derive the template
122
+ * from the first item by replacing the terminal digit sequence with `{n}`.
113
123
  *
114
- * - Semantic items: the first tier with `referencesTier` set pointing at the
115
- * palette tier. Each item's `id` → `cssVar` mapping becomes `semanticCssNames`;
116
- * the item's `default` (a palette item id) is looked up to produce the index
117
- * for `semanticDefaults`.
124
+ * - Semantic items: either the first tier with `referencesTier` set pointing
125
+ * at the palette tier (legacy shape), or a tier explicitly marked
126
+ * `semantic: true` (#461) — the latter may have no palette sibling at all.
127
+ * Each item's `id` → `cssVar` mapping becomes `semanticCssNames`; the
128
+ * item's `default` is resolved to a `SemanticValue` by
129
+ * `deriveSemanticValue` (palette index / literal / ramp-ref — see there).
130
+ *
131
+ * - A tab with a semantic tier but NO palette tier still produces a usable
132
+ * cluster: `paletteSize` is `0` (the palette-driven UI has nothing to
133
+ * render) but `semanticDefaults`/`semanticCssNames` are populated from the
134
+ * semantic tier so the Semantic Tokens section isn't left empty (#463).
118
135
  *
119
136
  * - Metadata comes from `tab.colorExtras` (required on a color tab).
120
137
  *
138
+ * `tabs` is the panel config's full tabs array, used to resolve a semantic
139
+ * tier's cross-tab `{ ref }` mappings against a ramp tier living in ANOTHER
140
+ * tab (typically the grouped Palette tab). It defaults to `[tab]` so an
141
+ * existing single-argument call still works — intra-tab refs resolve, and a
142
+ * cross-tab ramp declaration falls back to its best-effort shape (#467).
143
+ *
121
144
  * Returns `undefined` when the tab has no `colorExtras` (not a color tab).
122
145
  */
123
- export declare function resolveColorClusterFromTab(tab: TabConfig): ColorClusterDataConfig | undefined;
146
+ export declare function resolveColorClusterFromTab(tab: TabConfig, tabs?: readonly TabConfig[]): ColorClusterDataConfig | undefined;
124
147
  /**
125
148
  * Find the primary color tab (id 'color') in the host's tabs array and
126
149
  * derive its `ColorClusterDataConfig`. Returns `undefined` when no color tab