@projectwallace/css-design-tokens 0.6.0 → 0.7.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.
package/dist/colors.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { ColorToken, UnparsedToken } from './types.js';
2
- export declare function color_to_token(color: string): ColorToken | UnparsedToken | null;
1
+ import { ColorValue } from './types.js';
2
+ export declare function color_to_token(color: string): ColorValue | null;
@@ -1,46 +1,39 @@
1
- import { cssKeywords as A, colorKeywords as D, namedColors as I, systemColors as R, colorFunctions as X, analyze as F } from "@projectwallace/css-analyzer";
2
- import { convert as H } from "css-time-sort";
3
- import { convert as Y } from "color-sorter";
4
- import { parse as g } from "css-tree";
5
- import { ColorSpace as o, sRGB as B, XYZ_D65 as P, XYZ_D50 as k, XYZ_ABS_D65 as G, Lab_D65 as K, Lab as M, LCH as W, sRGB_Linear as Z, HSL as T, HWB as U, HSV as V, P3_Linear as J, P3 as Q, A98RGB_Linear as ee, A98RGB as te, ProPhoto_Linear as re, ProPhoto as ne, REC_2020_Linear as le, REC_2020 as ie, OKLab as se, OKLCH as oe, OKLrab as ue, parse as ae } from "colorjs.io/fn";
6
- const x = 0, w = 1, L = 2, d = 3, O = 4, S = 5, N = 6, q = 7, z = 8, C = 9, E = 10, h = 11, ce = /* @__PURE__ */ new Map([
7
- [x, "white"],
8
- [w, "black"],
9
- [L, "grey"],
10
- [d, "red"],
11
- [O, "orange"],
12
- [S, "yellow"],
13
- [N, "green"],
14
- [q, "cyan"],
15
- [z, "blue"],
16
- [C, "magenta"],
17
- [E, "pink"],
18
- [h, "unknown"]
1
+ import { cssKeywords as Y, colorKeywords as F, namedColors as B, systemColors as G, colorFunctions as T, analyze as W } from "@projectwallace/css-analyzer";
2
+ import { convert as k } from "css-time-sort";
3
+ import { convert as K } from "color-sorter";
4
+ import { parse as d } from "css-tree";
5
+ import { ColorSpace as o, sRGB as M, XYZ_D65 as Z, XYZ_D50 as U, XYZ_ABS_D65 as V, Lab_D65 as J, Lab as Q, LCH as ee, sRGB_Linear as te, HSL as re, HWB as ne, HSV as le, P3_Linear as ie, P3 as se, A98RGB_Linear as oe, A98RGB as ue, ProPhoto_Linear as ae, ProPhoto as ce, REC_2020_Linear as fe, REC_2020 as pe, OKLab as me, OKLCH as he, OKLrab as ge, parse as _e } from "colorjs.io/fn";
6
+ const N = 0, L = 1, E = 2, b = 3, q = 4, C = 5, j = 6, z = 7, A = 8, I = 9, R = 10, _ = 11, de = /* @__PURE__ */ new Map([
7
+ [N, "white"],
8
+ [L, "black"],
9
+ [E, "grey"],
10
+ [b, "red"],
11
+ [q, "orange"],
12
+ [C, "yellow"],
13
+ [j, "green"],
14
+ [z, "cyan"],
15
+ [A, "blue"],
16
+ [I, "magenta"],
17
+ [R, "pink"],
18
+ [_, "unknown"]
19
19
  ]);
20
- function fe(r) {
20
+ function ve(n) {
21
21
  let t = /* @__PURE__ */ new Map();
22
- for (let l in r) {
23
- let e = h;
24
- if (!l.includes("var(") && !l.includes("calc(")) {
25
- let s = Y(l), { hue: n, saturation: i, lightness: p } = s;
26
- i < 10 && p === 100 ? e = x : i < 10 && p === 0 ? e = w : i < 5 ? e = L : n < 22 ? e = d : n < 50 ? e = O : n < 72 ? e = S : n < 144 ? e = N : n < 180 ? e = q : n < 250 ? e = z : n < 300 ? e = C : n < 350 ? e = E : e = d;
22
+ for (let r in n) {
23
+ let e = _;
24
+ if (!r.includes("var(") && !r.includes("calc(")) {
25
+ let s = K(r), { hue: l, saturation: i, lightness: m } = s;
26
+ i < 10 && m === 100 ? e = N : i < 10 && m === 0 ? e = L : i < 5 ? e = E : l < 22 ? e = b : l < 50 ? e = q : l < 72 ? e = C : l < 144 ? e = j : l < 180 ? e = z : l < 250 ? e = A : l < 300 ? e = I : l < 350 ? e = R : e = b;
27
27
  }
28
- t.has(e) ? t.get(e).push(l) : t.set(e, [l]);
28
+ t.has(e) ? t.get(e).push(r) : t.set(e, [r]);
29
29
  }
30
30
  return Array.from(t).sort(
31
- (l, e) => l[0] === h || e[0] === h ? -1 : e[1].length - l[1].length
31
+ (r, e) => r[0] === _ || e[0] === _ ? -1 : e[1].length - r[1].length
32
32
  );
33
33
  }
34
- const u = "com.projectwallace.css-authored-as";
35
- o.register(B);
36
- o.register(P);
37
- o.register(k);
38
- o.register(G);
39
- o.register(K);
34
+ const u = "com.projectwallace.css-authored-as", a = "com.projectwallace.usage-count", be = "com.projectwallace.css-properties";
40
35
  o.register(M);
41
- o.register(W);
42
36
  o.register(Z);
43
- o.register(T);
44
37
  o.register(U);
45
38
  o.register(V);
46
39
  o.register(J);
@@ -54,49 +47,39 @@ o.register(ie);
54
47
  o.register(se);
55
48
  o.register(oe);
56
49
  o.register(ue);
57
- function f(r) {
58
- let t = r.toLowerCase();
50
+ o.register(ae);
51
+ o.register(ce);
52
+ o.register(fe);
53
+ o.register(pe);
54
+ o.register(me);
55
+ o.register(he);
56
+ o.register(ge);
57
+ function h(n) {
58
+ let t = n.toLowerCase();
59
59
  if (t === "transparent")
60
60
  return {
61
- $type: "color",
62
- $value: {
63
- colorSpace: "srgb",
64
- components: [0, 0, 0],
65
- alpha: 0
66
- },
67
- $extensions: {
68
- [u]: r
69
- }
61
+ colorSpace: "srgb",
62
+ components: [0, 0, 0],
63
+ alpha: 0
70
64
  };
71
- if (A.has(t) || D.has(t) || t.includes("var("))
65
+ if (Y.has(t) || F.has(t) || t.includes("var("))
72
66
  return null;
73
67
  try {
74
- let l = ae(r), [e, s, n] = l.coords;
68
+ let r = _e(n), [e, s, l] = r.coords;
75
69
  return {
76
- $type: "color",
77
- $value: {
78
- colorSpace: l.spaceId,
79
- components: [
80
- e ?? "none",
81
- s ?? "none",
82
- n ?? "none"
83
- ],
84
- alpha: l.alpha ?? 0
85
- },
86
- $extensions: {
87
- [u]: r
88
- }
70
+ colorSpace: r.spaceId,
71
+ components: [
72
+ e ?? "none",
73
+ s ?? "none",
74
+ l ?? "none"
75
+ ],
76
+ alpha: r.alpha ?? 0
89
77
  };
90
78
  } catch {
91
- return {
92
- $value: r,
93
- $extensions: {
94
- [u]: r
95
- }
96
- };
79
+ return null;
97
80
  }
98
81
  }
99
- function v() {
82
+ function x() {
100
83
  return {
101
84
  color: void 0,
102
85
  offsetX: void 0,
@@ -106,131 +89,134 @@ function v() {
106
89
  inset: !1
107
90
  };
108
91
  }
109
- function pe(r) {
110
- let t = g(r, {
92
+ function $e(n) {
93
+ let t = d(n, {
111
94
  context: "value",
112
95
  positions: !0
113
96
  });
114
- function l(n) {
115
- return n.loc ? r.slice(n.loc.start.offset, n.loc.end.offset) : "";
97
+ function r(l) {
98
+ return l.loc ? n.slice(l.loc.start.offset, l.loc.end.offset) : "";
116
99
  }
117
- let e = v(), s = [e];
118
- return t.children.size < 2 ? null : (t.children.forEach((n) => {
119
- if (n.type === "Identifier") {
120
- if (n.name.toLowerCase() === "inset")
100
+ let e = x(), s = [e];
101
+ return t.children.size < 2 ? null : (t.children.forEach((l) => {
102
+ if (l.type === "Identifier") {
103
+ if (l.name.toLowerCase() === "inset")
121
104
  e.inset = !0;
122
- else if (I.has(n.name) || R.has(n.name)) {
123
- let i = f(n.name);
124
- if (i === null || i.$type !== "color")
105
+ else if (B.has(l.name) || G.has(l.name)) {
106
+ let i = h(l.name);
107
+ if (i === null)
125
108
  return;
126
- e.color = i.$value;
109
+ e.color = i;
127
110
  }
128
- } else if (n.type === "Dimension" || n.type === "Number" && n.value === "0") {
129
- let i = n.type === "Dimension" ? {
130
- value: Number(n.value),
131
- unit: n.unit
111
+ } else if (l.type === "Dimension" || l.type === "Number" && l.value === "0") {
112
+ let i = l.type === "Dimension" ? {
113
+ value: Number(l.value),
114
+ unit: l.unit
132
115
  } : {
133
116
  value: 0,
134
117
  unit: "px"
135
118
  };
136
119
  e.offsetX ? e.offsetY ? e.blur ? e.spread || (e.spread = i) : e.blur = i : e.offsetY = i : e.offsetX = i;
137
- } else if (n.type === "Function") {
138
- if (X.has(n.name)) {
139
- let i = f(l(n));
140
- if (i === null || i.$type !== "color")
120
+ } else if (l.type === "Function") {
121
+ if (T.has(l.name)) {
122
+ let i = h(r(l));
123
+ if (i === null)
141
124
  return;
142
- e.color = i.$value;
143
- } else if (n.name.toLowerCase() === "var" && !e.color) {
144
- let i = f(l(n));
145
- if (i === null || i.$type !== "color")
125
+ e.color = i;
126
+ } else if (l.name.toLowerCase() === "var" && !e.color) {
127
+ let i = h(r(l));
128
+ if (i === null)
146
129
  return;
147
- e.color = i.$value;
130
+ e.color = i;
148
131
  }
149
- } else if (n.type === "Hash") {
150
- let i = f(l(n));
151
- if (i === null || i.$type !== "color")
132
+ } else if (l.type === "Hash") {
133
+ let i = h(r(l));
134
+ if (i === null)
152
135
  return;
153
- e.color = i.$value;
154
- } else n.type === "Operator" && n.value === "," && (_(e), e = v(), s.push(e));
155
- }), _(e), s);
136
+ e.color = i;
137
+ } else l.type === "Operator" && l.value === "," && (y(e), e = x(), s.push(e));
138
+ }), y(e), s);
156
139
  }
157
- const m = {
140
+ const g = {
158
141
  value: 0,
159
142
  unit: "px"
160
143
  };
161
- function _(r) {
162
- return r.offsetX || (r.offsetX = m), r.offsetY || (r.offsetY = m), r.blur || (r.blur = m), r.spread || (r.spread = m), r.color || (r.color = f("#000")?.$value), r;
144
+ function y(n) {
145
+ return n.offsetX || (n.offsetX = g), n.offsetY || (n.offsetY = g), n.blur || (n.blur = g), n.spread || (n.spread = g), n.color || (n.color = h("#000")), n;
163
146
  }
164
- const $ = /* @__PURE__ */ new Map([
147
+ const w = /* @__PURE__ */ new Map([
165
148
  ["linear", [0, 0, 1, 1]],
166
149
  ["ease", [0.25, 0.1, 0.25, 1]],
167
150
  ["ease-in", [0.42, 0, 1, 1]],
168
151
  ["ease-out", [0, 0, 0.58, 1]],
169
152
  ["ease-in-out", [0.42, 0, 0.58, 1]]
170
153
  ]);
171
- function me(r) {
172
- if (r = r.trim().toLowerCase(), $.has(r))
173
- return $.get(r);
174
- if (!r.includes("var(") && r.startsWith("cubic-bezier(")) {
175
- let t = r.replace("cubic-bezier(", "").replace(")", "").split(",").map((l) => Number(l.trim()));
176
- if (t.length === 4 && t.every((l) => Number.isFinite(l)))
154
+ function xe(n) {
155
+ if (n = n.trim().toLowerCase(), w.has(n))
156
+ return w.get(n);
157
+ if (n.includes("var("))
158
+ return null;
159
+ if (n.startsWith("cubic-bezier(")) {
160
+ let t = n.replace("cubic-bezier(", "").replace(")", "").split(",").map((r) => Number(r.trim()));
161
+ if (t.length === 4 && t.every((r) => Number.isFinite(r)))
177
162
  return t;
178
163
  }
164
+ return null;
179
165
  }
180
- function b(r) {
181
- return r.replaceAll(/^['"]|['"]$/g, "");
166
+ function S(n) {
167
+ return n.replaceAll(/^['"]|['"]$/g, "");
182
168
  }
183
- function he(r) {
184
- let t = g(r, {
169
+ function ye(n) {
170
+ let t = d(n, {
185
171
  context: "value",
186
172
  positions: !0
187
173
  });
188
- function l(i) {
189
- return i.loc ? r.slice(i.loc.start.offset, i.loc.end.offset) : "";
174
+ function r(i) {
175
+ return i.loc ? n.slice(i.loc.start.offset, i.loc.end.offset) : "";
190
176
  }
191
177
  let e = [];
192
178
  if (!t.children || t.children.size === 0)
193
179
  return e;
194
- let s = "", n;
180
+ let s = "", l;
195
181
  for (let i of t.children) {
196
182
  if (i.type === "Operator" && i.value === ",") {
197
- e.push(b(s)), s = "", n = i.type;
183
+ e.push(S(s)), s = "", l = i.type;
198
184
  continue;
199
185
  }
200
- n === "Identifier" && i.type === "Identifier" && (s += " "), s += l(i), n = i.type;
186
+ l === "Identifier" && i.type === "Identifier" && (s += " "), s += r(i), l = i.type;
201
187
  }
202
- return e.push(b(s)), e;
188
+ return e.push(S(s)), e;
203
189
  }
204
- function a(r) {
205
- if (r === void 0 || typeof r == "number" && isNaN(r))
190
+ function c(n) {
191
+ if (n === void 0 || typeof n == "number" && isNaN(n))
206
192
  return "0";
207
- typeof r != "string" && (r = r.toString());
193
+ typeof n != "string" && (n = n.toString());
208
194
  let t = 0;
209
- for (let l of r)
210
- t = (t << 5) - t + l.charCodeAt(0), t |= 0;
195
+ for (let r of n)
196
+ t = (t << 5) - t + r.charCodeAt(0), t |= 0;
211
197
  return (t >>> 0).toString(16);
212
198
  }
213
- function ge(r) {
214
- let t = g(r, { context: "value" });
199
+ function we(n) {
200
+ let t = d(n, { context: "value" });
215
201
  if (t.children === null || t.children.size !== 1) return null;
216
- let l = t.children.first;
217
- switch (l.type) {
202
+ let r = t.children.first;
203
+ switch (r.type) {
218
204
  case "Dimension":
219
205
  return {
220
- value: Number(l.value),
221
- unit: l.unit
206
+ value: Number(r.value),
207
+ unit: r.unit
222
208
  };
223
209
  case "Number":
224
- return Number(l.value);
210
+ return Number(r.value);
225
211
  case "Percentage":
226
- return Number(l.value) / 100;
212
+ return Number(r.value) / 100;
227
213
  case "Identifier":
228
- if (l.name === "normal")
214
+ if (r.name === "normal")
229
215
  return 1.2;
230
216
  }
231
217
  return null;
232
218
  }
233
- let y = /* @__PURE__ */ new Map([
219
+ let O = /* @__PURE__ */ new Map([
234
220
  ["xx-small", 0.6],
235
221
  ["x-small", 0.75],
236
222
  ["small", 0.89],
@@ -240,188 +226,199 @@ let y = /* @__PURE__ */ new Map([
240
226
  ["xx-large", 2],
241
227
  ["xxx-large", 3]
242
228
  ]);
243
- function de(r) {
244
- let t = g(r, { context: "value" });
229
+ function Se(n) {
230
+ let t = d(n, { context: "value" });
245
231
  if (t.children === null || t.children.size !== 1) return null;
246
- let l = t.children.first;
247
- switch (l.type) {
232
+ let r = t.children.first;
233
+ switch (r.type) {
248
234
  case "Dimension": {
249
- if (l.unit === "px" || l.unit === "rem")
235
+ if (r.unit === "px" || r.unit === "rem")
250
236
  return {
251
- value: Number(l.value),
252
- unit: l.unit
237
+ value: Number(r.value),
238
+ unit: r.unit
253
239
  };
254
240
  break;
255
241
  }
256
242
  case "Identifier": {
257
- let e = l.name.toLowerCase();
258
- if (y.has(e))
243
+ let e = r.name.toLowerCase();
244
+ if (O.has(e))
259
245
  return {
260
- value: y.get(e),
246
+ value: O.get(e),
261
247
  unit: "rem"
262
248
  };
263
249
  }
264
250
  }
265
251
  return null;
266
252
  }
267
- function we(r) {
268
- let t = F(r);
269
- return ve(t);
253
+ function je(n) {
254
+ let t = W(n);
255
+ return Oe(t);
270
256
  }
271
- function c(r) {
272
- return "uniqueWithLocations" in r ? r.uniqueWithLocations : r.unique;
257
+ function f(n) {
258
+ return "uniqueWithLocations" in n ? n.uniqueWithLocations : n.unique;
273
259
  }
274
- function ve(r) {
260
+ function p(n) {
261
+ return Array.isArray(n) ? n.length : n;
262
+ }
263
+ function Oe(n) {
275
264
  return {
276
265
  color: (() => {
277
- let t = /* @__PURE__ */ Object.create(null), l = c(r.values.colors), e = fe(l);
278
- for (let [s, n] of e)
279
- for (let i of n) {
280
- let p = f(i);
281
- if (p !== null) {
282
- let j = `${ce.get(s)}-${a(i)}`;
283
- t[j] = p;
266
+ let t = /* @__PURE__ */ Object.create(null), r = f(n.values.colors), e = ve(r);
267
+ for (let [s, l] of e)
268
+ for (let i of l) {
269
+ let m = h(i);
270
+ if (m !== null) {
271
+ let X = `${de.get(s)}-${c(i)}`, D = n.values.colors.itemsPerContext, P = Object.entries(D).reduce(($, [H, v]) => ((i in v.unique || v.uniqueWithLocations && i in v.uniqueWithLocations) && $.push(H), $), []);
272
+ t[X] = {
273
+ $type: "color",
274
+ $value: m,
275
+ $extensions: {
276
+ [u]: i,
277
+ [a]: p(r[i]),
278
+ [be]: P
279
+ }
280
+ };
284
281
  }
285
282
  }
286
283
  return t;
287
284
  })(),
288
285
  font_size: (() => {
289
- let t = /* @__PURE__ */ Object.create(null), l = c(r.values.fontSizes);
290
- for (let e in l) {
291
- let s = `fontSize-${a(e)}`, n = de(e);
292
- n === null ? t[s] = {
286
+ let t = /* @__PURE__ */ Object.create(null), r = f(n.values.fontSizes);
287
+ for (let e in r) {
288
+ let s = `fontSize-${c(e)}`, l = Se(e), i = {
289
+ [u]: e,
290
+ [a]: p(r[e])
291
+ };
292
+ l === null ? t[s] = {
293
293
  $value: e,
294
- $extensions: {
295
- [u]: e
296
- }
294
+ $extensions: i
297
295
  } : t[s] = {
298
296
  $type: "dimension",
299
- $value: n,
300
- $extensions: {
301
- [u]: e
302
- }
297
+ $value: l,
298
+ $extensions: i
303
299
  };
304
300
  }
305
301
  return t;
306
302
  })(),
307
303
  font_family: (() => {
308
- let t = /* @__PURE__ */ Object.create(null), l = c(r.values.fontFamilies);
309
- for (let e in l) {
310
- let s = he(e), n = `fontFamily-${a(e)}`;
311
- t[n] = {
304
+ let t = /* @__PURE__ */ Object.create(null), r = f(n.values.fontFamilies);
305
+ for (let e in r) {
306
+ let s = ye(e), l = `fontFamily-${c(e)}`;
307
+ t[l] = {
312
308
  $type: "fontFamily",
313
309
  $value: s,
314
310
  $extensions: {
315
- [u]: e
311
+ [u]: e,
312
+ [a]: p(r[e])
316
313
  }
317
314
  };
318
315
  }
319
316
  return t;
320
317
  })(),
321
318
  line_height: (() => {
322
- let t = /* @__PURE__ */ Object.create(null), l = c(r.values.lineHeights);
323
- for (let e in l) {
324
- let s = `lineHeight-${a(e)}`, n = ge(e);
325
- n === null ? t[s] = {
319
+ let t = /* @__PURE__ */ Object.create(null), r = f(n.values.lineHeights);
320
+ for (let e in r) {
321
+ let s = `lineHeight-${c(e)}`, l = we(e), i = {
322
+ [u]: e,
323
+ [a]: p(r[e])
324
+ };
325
+ l === null ? t[s] = {
326
326
  $value: e,
327
- $extensions: {
328
- [u]: e
329
- }
330
- } : typeof n == "number" ? t[s] = {
327
+ $extensions: i
328
+ } : typeof l == "number" ? t[s] = {
331
329
  $type: "number",
332
- $value: n,
333
- $extensions: {
334
- [u]: e
335
- }
336
- } : typeof n == "object" && (n.unit === "px" || n.unit === "rem" ? t[s] = {
330
+ $value: l,
331
+ $extensions: i
332
+ } : typeof l == "object" && (l.unit === "px" || l.unit === "rem" ? t[s] = {
337
333
  $type: "dimension",
338
- $value: n,
339
- $extensions: {
340
- [u]: e
341
- }
334
+ $value: l,
335
+ $extensions: i
342
336
  } : t[s] = {
343
337
  $value: e,
344
- $extensions: {
345
- [u]: e
346
- }
338
+ $extensions: i
347
339
  });
348
340
  }
349
341
  return t;
350
342
  })(),
351
343
  gradient: (() => {
352
- let t = /* @__PURE__ */ Object.create(null), l = c(r.values.gradients);
353
- for (let e in l)
354
- t[`gradient-${a(e)}`] = {
355
- $value: e
344
+ let t = /* @__PURE__ */ Object.create(null), r = f(n.values.gradients);
345
+ for (let e in r)
346
+ t[`gradient-${c(e)}`] = {
347
+ $value: e,
348
+ $extensions: {
349
+ [u]: e,
350
+ [a]: p(r[e])
351
+ }
356
352
  };
357
353
  return t;
358
354
  })(),
359
355
  box_shadow: (() => {
360
- let t = /* @__PURE__ */ Object.create(null), l = c(r.values.boxShadows);
361
- for (let e in l) {
362
- let s = `boxShadow-${a(e)}`, n = pe(e);
363
- n === null ? t[s] = {
356
+ let t = /* @__PURE__ */ Object.create(null), r = f(n.values.boxShadows);
357
+ for (let e in r) {
358
+ let s = `boxShadow-${c(e)}`, l = $e(e), i = {
359
+ [u]: e,
360
+ [a]: p(r[e])
361
+ };
362
+ l === null ? t[s] = {
364
363
  $value: e,
365
- $extensions: {
366
- [u]: e
367
- }
364
+ $extensions: i
368
365
  } : t[s] = {
369
366
  $type: "shadow",
370
- $value: n.length === 1 ? n[0] : n,
371
- $extensions: {
372
- [u]: e
373
- }
367
+ $value: l.length === 1 ? l[0] : l,
368
+ $extensions: i
374
369
  };
375
370
  }
376
371
  return t;
377
372
  })(),
378
373
  radius: (() => {
379
- let t = /* @__PURE__ */ Object.create(null), l = c(r.values.borderRadiuses);
380
- for (let e in l) {
381
- let s = `radius-${a(e)}`;
374
+ let t = /* @__PURE__ */ Object.create(null), r = f(n.values.borderRadiuses);
375
+ for (let e in r) {
376
+ let s = `radius-${c(e)}`;
382
377
  t[s] = {
383
- $value: e
378
+ $value: e,
379
+ $extensions: {
380
+ [u]: e,
381
+ [a]: p(r[e])
382
+ }
384
383
  };
385
384
  }
386
385
  return t;
387
386
  })(),
388
387
  duration: (() => {
389
- let t = /* @__PURE__ */ Object.create(null), l = c(r.values.animations.durations);
390
- for (let e in l) {
391
- let s = H(e), n = s < Number.MAX_SAFE_INTEGER - 1, i = a(s.toString());
392
- n ? t[`duration-${i}`] = {
388
+ let t = /* @__PURE__ */ Object.create(null), r = f(n.values.animations.durations);
389
+ for (let e in r) {
390
+ let s = k(e), l = s < Number.MAX_SAFE_INTEGER - 1, i = c(s.toString()), m = {
391
+ [u]: e,
392
+ [a]: p(r[e])
393
+ };
394
+ l ? t[`duration-${i}`] = {
393
395
  $type: "duration",
394
396
  $value: {
395
397
  value: s,
396
398
  unit: "ms"
397
399
  },
398
- $extensions: {
399
- [u]: e
400
- }
400
+ $extensions: m
401
401
  } : t[`duration-${i}`] = {
402
402
  $value: e,
403
- $extensions: {
404
- [u]: e
405
- }
403
+ $extensions: m
406
404
  };
407
405
  }
408
406
  return t;
409
407
  })(),
410
408
  easing: (() => {
411
- let t = /* @__PURE__ */ Object.create(null), l = c(r.values.animations.timingFunctions);
412
- for (let e in l) {
413
- let s = `easing-${a(e)}`, n = me(e);
414
- n ? t[s] = {
415
- $value: n,
409
+ let t = /* @__PURE__ */ Object.create(null), r = f(n.values.animations.timingFunctions);
410
+ for (let e in r) {
411
+ let s = `easing-${c(e)}`, l = xe(e), i = {
412
+ [u]: e,
413
+ [a]: p(r[e])
414
+ };
415
+ l !== null ? t[s] = {
416
+ $value: l,
416
417
  $type: "cubicBezier",
417
- $extensions: {
418
- [u]: e
419
- }
418
+ $extensions: i
420
419
  } : t[s] = {
421
420
  $value: e,
422
- $extensions: {
423
- [u]: e
424
- }
421
+ $extensions: i
425
422
  };
426
423
  }
427
424
  return t;
@@ -429,6 +426,6 @@ function ve(r) {
429
426
  };
430
427
  }
431
428
  export {
432
- ve as analysis_to_tokens,
433
- we as css_to_tokens
429
+ Oe as analysis_to_tokens,
430
+ je as css_to_tokens
434
431
  };
@@ -1,2 +1,2 @@
1
1
  import { Easing } from './types.js';
2
- export declare function destructure_easing(easing: string): Easing | undefined;
2
+ export declare function destructure_easing(easing: string): Easing | null;
package/dist/types.d.ts CHANGED
@@ -2,18 +2,22 @@ import { analyze } from '@projectwallace/css-analyzer';
2
2
  import { DestructuredShadow } from './destructure-box-shadow';
3
3
  export type CssAnalysis = ReturnType<typeof analyze>;
4
4
  export declare const EXTENSION_AUTHORED_AS = "com.projectwallace.css-authored-as";
5
+ export declare const EXTENSION_USAGE_COUNT = "com.projectwallace.usage-count";
6
+ export declare const EXTENSION_CSS_PROPERTIES = "com.projectwallace.css-properties";
5
7
  export type Easing = [number, number, number, number];
6
8
  export type BaseToken = {
7
- $extensions?: {
9
+ $extensions: {
8
10
  [EXTENSION_AUTHORED_AS]: string;
11
+ [EXTENSION_USAGE_COUNT]: number;
9
12
  };
10
13
  };
14
+ type DurationValue = {
15
+ value: number;
16
+ unit: 'ms';
17
+ };
11
18
  export type DurationToken = BaseToken & {
12
19
  $type: 'duration';
13
- $value: {
14
- value: number;
15
- unit: 'ms';
16
- };
20
+ $value: DurationValue;
17
21
  };
18
22
  export type UnparsedToken = BaseToken & {
19
23
  $value: string;
@@ -31,7 +35,7 @@ export type ColorToken = BaseToken & {
31
35
  $type: 'color';
32
36
  $value: ColorValue;
33
37
  $extensions: {
34
- [EXTENSION_AUTHORED_AS]: string;
38
+ [EXTENSION_CSS_PROPERTIES]: Array<string>;
35
39
  };
36
40
  };
37
41
  export type DimensionValue = {
@@ -52,7 +56,7 @@ export type CubicBezierToken = BaseToken & {
52
56
  };
53
57
  export type FontFamilyToken = BaseToken & {
54
58
  $type: 'fontFamily';
55
- $value: string[] | string;
59
+ $value: string[];
56
60
  };
57
61
  export type ShadowToken = BaseToken & {
58
62
  $type: 'shadow';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@projectwallace/css-design-tokens",
3
3
  "description": "Generate spec-compliant Design Tokens from CSS.",
4
- "version": "0.6.0",
4
+ "version": "0.7.0",
5
5
  "license": "EUPL-1.2",
6
6
  "author": "Bart Veneman <bart@projectwallace.com>",
7
7
  "repository": {
package/readme.md CHANGED
@@ -2,6 +2,23 @@
2
2
 
3
3
  Create Design Tokens by going through CSS to find colors, font-sizes, gradients etcetera and turn them into a [Design Tokens spec](https://tr.designtokens.org/)-compliant token format.
4
4
 
5
+ ## Table of contents
6
+
7
+ - [Installation](#installation)
8
+ - [Usage](#usage)
9
+ - [Token types](#token-types)
10
+ - [Color](#color)
11
+ - [Font-size](#font-size)
12
+ - [Font-family](#font-family)
13
+ - [Line-height](#line-height)
14
+ - [Gradient](#gradient)
15
+ - [Box-shadow](#box-shadow)
16
+ - [Radius](#radius)
17
+ - [Duration](#duration)
18
+ - [Easing](#easing)
19
+ - [Extensions](#extensions)
20
+ - [Acknowledgements](#acknowledgements)
21
+
5
22
  ## Installation
6
23
 
7
24
  ```sh
@@ -59,9 +76,397 @@ let { color } = css_to_tokens(
59
76
  // }
60
77
  ```
61
78
 
62
- ### Getting authored values
79
+ ## Token types
80
+
81
+ ### Color
82
+
83
+ ['Color' Design Token format](https://www.designtokens.org/tr/third-editors-draft/color/#format)
84
+
85
+ Only fully compliant colors are listed. Colors that can't be parsed by [colorjs.io](https://colorjs.io/) are ignored, like `rgb(var(--red) var(--green) var(--blue))` or CSS system colors like `ButtonText`.
86
+
87
+ - The optional `alpha` property is _always_ present.
88
+ - The optional `hex` fallback property is _never_ present.
89
+ - In addition to other tokens all colors have a `com.projectwallace.css-properties` extension that contains all the CSS properties that a specific color was used for.
90
+
91
+ ```js
92
+ let { color } = css_to_tokens(`.my-design-system { color: green; }`)
93
+
94
+ let color = {
95
+ 'green-5e0cf03': {
96
+ $type: 'color',
97
+ $value: {
98
+ colorSpace: 'srgb',
99
+ components: [0, 0.5019607843137255, 0],
100
+ alpha: 1,
101
+ },
102
+ $extensions: {
103
+ 'com.projectwallace.css-authored-as': 'green',
104
+ 'com.projectwallace.usage-count': 2,
105
+ 'com.projectwallace.css-properties': ['color', 'border-color'],
106
+ }
107
+ }
108
+ }
109
+ ```
110
+
111
+ ### Font-size
112
+
113
+ ['Dimension' Design Token format](https://www.designtokens.org/tr/third-editors-draft/format/#dimension)
114
+
115
+ Font-sizes are listed as `$type: 'dimension'` types if the font-size is declared with either `px` or `rem` or as plain type-less tokens otherwise.
116
+
117
+ ```js
118
+ let { font_size } = css_to_tokens(`.my-design-system {
119
+ .my-design-system {
120
+ font-size: 16px;
121
+ font-size: 1rem;
122
+ font-size: 20vmin;
123
+ }
124
+ }`)
125
+
126
+ let font_size = {
127
+ 'fontSize-171eed': {
128
+ $type: 'dimension',
129
+ $value: {
130
+ value: 16,
131
+ unit: 'px'
132
+ },
133
+ $extensions: {
134
+ 'com.projectwallace.css-authored-as': '16px',
135
+ 'com.projectwallace.usage-count': 1,
136
+ }
137
+ },
138
+ 'fontSize-582e015a': {
139
+ $value: '20vmin',
140
+ $extensions: {
141
+ 'com.projectwallace.css-authored-as': '20vmin',
142
+ 'com.projectwallace.usage-count': 1,
143
+ }
144
+ },
145
+ }
146
+ ```
147
+
148
+ ### Font-family
149
+
150
+ ['fontFamily' Design Token format](https://www.designtokens.org/tr/third-editors-draft/format/#font-family)
151
+
152
+ Font-families are _always_ listed as `$type: 'fontFamily'`.
153
+
154
+ ```js
155
+ let { font_family } = css_to_tokens(`.my-design-system {
156
+ .my-design-system {
157
+ font-family: 'Inter';
158
+ font-family: Arial Black, sans-serif;
159
+ }
160
+ }`)
161
+
162
+ let font_family = {
163
+ 'fontFamily-3375cf09': {
164
+ $type: 'fontFamily',
165
+ $value: ['\'Inter\''],
166
+ $extensions: {
167
+ 'com.projectwallace.css-authored-as': '\'Inter\'',
168
+ 'com.projectwallace.usage-count': 1,
169
+ }
170
+ },
171
+ 'fontFamily-582e015a': {
172
+ $value: ['Arial Black', 'sans-serif'],
173
+ $extensions: {
174
+ 'com.projectwallace.css-authored-as': 'Arial Black, sans-serif',
175
+ 'com.projectwallace.usage-count': 1,
176
+ }
177
+ },
178
+ }
179
+ ```
180
+
181
+ ### Line-height
182
+
183
+ Line heights can either be `dimension` or `number` types, or a plain type-less token. This depends on how well the value can be mapped to a valid token.
184
+
185
+ ```ts
186
+ let { line_height } = css_to_tokens(`
187
+ .my-design-system {
188
+ line-height: 1.5rem; /* rem -> type=dimension */
189
+ line-height: 1.5; /* no unit -> type=number */
190
+ line-height: 20vmin; /* can not be mapped to valid token type */
191
+ }
192
+ `)
193
+
194
+ let line_height = {
195
+ 'lineHeight-563f7fe2': {
196
+ $type: 'dimension',
197
+ $value: {
198
+ value: 1.5,
199
+ unit: 'rem'
200
+ },
201
+ $extensions: {
202
+ 'com.projectwallace.css-authored-as': '1.5rem',
203
+ 'com.projectwallace.usage-count': 1,
204
+ }
205
+ },
206
+ 'lineHeight-bdb8': {
207
+ $type: 'number',
208
+ $value: 1.5,
209
+ $extensions: {
210
+ 'com.projectwallace.css-authored-as': '1.5',
211
+ 'com.projectwallace.usage-count': 1,
212
+ }
213
+ },
214
+ 'lineHeight-582e015a': {
215
+ $value: '20vmin',
216
+ $extensions: {
217
+ 'com.projectwallace.css-authored-as': '20vmin',
218
+ 'com.projectwallace.usage-count': 1,
219
+ }
220
+ }
221
+ }
222
+ ```
223
+
224
+ ### Gradient
225
+
226
+ Gradients are passed as-is, no mapping is done. This is because the spec is currently too limited in expressing a CSS gradient.
227
+
228
+ ```ts
229
+ let { gradient } = css_to_tokens(`
230
+ .my-design-system {
231
+ background: linear-gradient(to right, red, blue);
232
+ }
233
+ `)
234
+
235
+ let gradient = {
236
+ 'gradient-2aec04e5': {
237
+ $value: 'linear-gradient(to right, red, blue)',
238
+ $extensions: {
239
+ 'com.projectwallace.css-authored-as': 'linear-gradient(to right, red, blue)',
240
+ 'com.projectwallace.usage-count': 1,
241
+ }
242
+ }
243
+ }
244
+ ```
245
+
246
+ ### Box-shadow
247
+
248
+ ['Shadow' Design Token type](https://www.designtokens.org/tr/third-editors-draft/format/#shadow)
249
+
250
+ - Multiple shadows can be mapped, so beware that `$value` van either be a single object or an array.
251
+ - Only if a box-shadow has a valid `color` type it will be mapped as a `box-shadow` type
252
+
253
+ ```ts
254
+ let { box_shadow } = css_to_tokens(`
255
+ .my-design-system {
256
+ box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.5);
257
+ box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.5), 0 0 10px 0 rgba(0, 0, 0, 0.5);
258
+ box-shadow: 0 0 0 0 var(--red);
259
+ }
260
+ `)
261
+
262
+ let box_shadow = {
263
+ 'boxShadow-6f90da6b': {
264
+ $type: 'shadow',
265
+ $value: {
266
+ offsetX: {
267
+ value: 0,
268
+ unit: 'px'
269
+ },
270
+ offsetY: {
271
+ value: 0,
272
+ unit: 'px'
273
+ },
274
+ blur: {
275
+ value: 10,
276
+ unit: 'px'
277
+ },
278
+ spread: {
279
+ value: 0,
280
+ unit: 'px'
281
+ },
282
+ inset: false,
283
+ color: {
284
+ colorSpace: 'srgb',
285
+ components: [0, 0, 0],
286
+ alpha: 0.5,
287
+ },
288
+ },
289
+ $extensions: {
290
+ 'com.projectwallace.css-authored-as': '0 0 10px 0 rgba(0, 0, 0, 0.5)',
291
+ 'com.projectwwallace.usage-count': 1,
292
+ }
293
+ },
294
+ 'boxShadow-be2751ac': {
295
+ $type: 'shadow',
296
+ $value: [
297
+ {
298
+ offsetX: {
299
+ value: 0,
300
+ unit: 'px'
301
+ },
302
+ offsetY: {
303
+ value: 0,
304
+ unit: 'px'
305
+ },
306
+ blur: {
307
+ value: 10,
308
+ unit: 'px'
309
+ },
310
+ spread: {
311
+ value: 0,
312
+ unit: 'px'
313
+ },
314
+ inset: false,
315
+ color: {
316
+ colorSpace: 'srgb',
317
+ components: [0, 0, 0],
318
+ alpha: 0.5,
319
+ },
320
+ },
321
+ {
322
+ offsetX: {
323
+ value: 0,
324
+ unit: 'px'
325
+ },
326
+ offsetY: {
327
+ value: 0,
328
+ unit: 'px'
329
+ },
330
+ blur: {
331
+ value: 10,
332
+ unit: 'px'
333
+ },
334
+ spread: {
335
+ value: 0,
336
+ unit: 'px'
337
+ },
338
+ inset: false,
339
+ color: {
340
+ colorSpace: 'srgb',
341
+ components: [0, 0, 0],
342
+ alpha: 0.5,
343
+ },
344
+ }
345
+ ],
346
+ $extensions: {
347
+ 'com.projectwwallace.css-authored-as': '0 0 10px 0 rgba(0, 0, 0, 0.5), 0 0 10px 0 rgba(0, 0, 0, 0.5)',
348
+ 'com.projectwwallace.usage-count': 1,
349
+ }
350
+ },
351
+ 'boxShadow-j4h5gas5h': {
352
+ $value: '0 0 0 0 var(--red)',
353
+ $extensions: {
354
+ 'com.projectwwallace.css-authored-as': '0 0 0 0 var(--red)',
355
+ 'com.projectwwallace.usage-count': 1,
356
+ }
357
+ }
358
+ }
359
+ ```
360
+
361
+ ### Radius
362
+
363
+ Radii are passed as-is, no mapping is done.
364
+
365
+ ```ts
366
+ let { radius } = css_to_tokens(`
367
+ .my-design-system {
368
+ border-radius: 10px;
369
+ }
370
+ `)
371
+
372
+ let radius = {
373
+ 'radius-170867': {
374
+ $value: '10px',
375
+ $extensions: {
376
+ 'com.projectwwallace.css-authored-as': '10px',
377
+ 'com.projectwwallace.usage-count': 1,
378
+ }
379
+ }
380
+ }
381
+ ```
382
+
383
+ ### Duration
384
+
385
+ ['Duration' Design Token type](https://www.designtokens.org/tr/third-editors-draft/format/#duration)
63
386
 
64
- The tokens output parses most CSS into Design Tokens but in most cases it also provides a way to get the authored CSS via the `$extensions` property. The custom identifier for this project is `com.projectwallace` and the authored values can be found with `com.projectwallace.css-authored-as` on the `$extensions` object.
387
+ Durations can either be animation- or transition-durations or -delays. Even though `s` is a valid unit we _always_ map to `ms`.
388
+
389
+ ```ts
390
+ let { duration } = css_to_tokens(`
391
+ .my-design-system {
392
+ animation-duration: 1s;
393
+ }
394
+ `)
395
+
396
+ let duration = {
397
+ 'duration-17005f': {
398
+ $type: 'duration',
399
+ $value: {
400
+ value: 1000,
401
+ unit: 'ms'
402
+ },
403
+ $extensions: {
404
+ 'com.projectwwallace.css-authored-as': '1s',
405
+ 'com.projectwwallace.usage-count': 1,
406
+ }
407
+ }
408
+ }
409
+ ```
410
+
411
+ ### Easing
412
+
413
+ ['Cubic Bézier' Design Token type](https://www.designtokens.org/tr/third-editors-draft/format/#cubic-bezier)
414
+
415
+ Easings are mapped to cubic béziers when possible or represented as plain type-less tokens otherwise. [CSS Easing keywords](https://developer.mozilla.org/en-US/docs/Web/CSS/easing-function) are also converted to cubic béziers.
416
+
417
+ ```ts
418
+ let actual = css_to_tokens(`
419
+ .my-design-system {
420
+ animation-timing-function: ease-in-out;
421
+ animation-timing-function: cubic-bezier(0, 0, 0.5, .8);
422
+ animation-timing-function: var(--test);
423
+ }
424
+ `)
425
+
426
+ let easing = {
427
+ 'easing-ea6c7565': {
428
+ $type: 'cubicBezier',
429
+ $value: [
430
+ 0.42,
431
+ 0,
432
+ 0.58,
433
+ 1
434
+ ],
435
+ $extensions: {
436
+ 'com.projectwwallace.css-authored-as': 'ease-in-out',
437
+ 'com.projectwwallace.usage-count': 1,
438
+ }
439
+ },
440
+ 'easing-90111eba': {
441
+ $type: 'cubicBezier',
442
+ $value: [
443
+ 0,
444
+ 0,
445
+ 0.5,
446
+ 0.8
447
+ ],
448
+ $extensions: {
449
+ 'com.projectwwallace.css-authored-as': 'cubic-bezier(0, 0, 0.5, .8)',
450
+ 'com.projectwwallace.usage-count': 1,
451
+ }
452
+ },
453
+ 'easing-12bb7f36': {
454
+ $value: 'var(--test)',
455
+ $extensions: {
456
+ 'com.projectwwallace.css-authored-as': 'var(--test)',
457
+ 'com.projectwwallace.usage-count': 1,
458
+ }
459
+ }
460
+ }
461
+ ```
462
+
463
+ ## Extensions
464
+
465
+ This library adds a couple of potentially extensions to the design token values via the `com.projectwallace` namespace on the `$extensions` property of all generated design tokens.
466
+
467
+ ### Authored CSS values
468
+
469
+ This package parses CSS into Design Tokens but also provides a way to get the authored CSS via the `$extensions['com.projectwallace.css-authored-as']` property on any of the tokens:
65
470
 
66
471
  ```ts
67
472
  let { color } = css_to_tokens(`.my-design-system { color: green; }`)
@@ -80,6 +485,50 @@ let authored_green = color['green-5e0cf03']['$extensions']['com.projectwallace.c
80
485
  // 'green'
81
486
  ```
82
487
 
488
+ ### Usage count
489
+
490
+ If you need to know how often a particalur design token was found in the CSS you can use the `$extensions['com.projectwallace.usage-count']` property on any of the tokens:
491
+
492
+ ```ts
493
+ let { color } = css_to_tokens(`.my-design-system { color: green; }`)
494
+
495
+ // {
496
+ // 'green-5e0cf03': {
497
+ // ...
498
+ // $extensions: {
499
+ // 'com.projectwallace.usage-count': 1
500
+ // }
501
+ // },
502
+ // }
503
+
504
+ let green_count = color['green-5e0cf03']['$extensions']['com.projectwallace.usage-count']
505
+
506
+ // 1
507
+ ```
508
+
509
+ ### CSS property usage
510
+
511
+ __For color tokens only__
512
+
513
+ You can read the `$extensions['com.projectwallace.css-properties']` property to see for which CSS properties a color was used:
514
+
515
+ ```ts
516
+ let { color } = css_to_tokens(`.my-design-system { color: green; }`)
517
+
518
+ // {
519
+ // 'green-5e0cf03': {
520
+ // ...
521
+ // $extensions: {
522
+ // 'com.projectwallace.css-properties': ['color']
523
+ // }
524
+ // },
525
+ // }
526
+
527
+ let properties = color['green-5e0cf03']['$extensions']['com.projectwallace.css-properties']
528
+
529
+ // ['color']
530
+ ```
531
+
83
532
  ## Acknowledgements
84
533
 
85
534
  - [CSSTree](https://github.com/csstree/csstree) does all the heavy lifting of parsing CSS
@@ -88,7 +537,7 @@ let authored_green = color['green-5e0cf03']['$extensions']['com.projectwallace.c
88
537
  ## Related projects
89
538
 
90
539
  - [Design Tokens analyzer](https://www.projectwallace.com/design-tokens) - Online CSS to Design Tokens convernter, uses this package
91
- - [CSS Analyzer](https://github.com/projectwallace/css-analyzer) - The best CSS analyzer that powers all analysis on [projectwallace.com](https://www.projectwallace.com?utm_source=github&utm_medium=wallace_format_css_related_projects)
540
+ - [CSS Analyzer](https://github.com/projectwallace/css-analyzer) - The best CSS analyzer that powers all analysis on [projectwallace.com](https://www.projectwallace.com?utm_source=github&utm_medium=wallace_css_design_tokens_related_projects)
92
541
  - [Color Sorter](https://github.com/projectwallace/color-sorter) - Sort CSS colors
93
542
  by hue, saturation, lightness and opacity
94
543
  - [CSS Time Sort](https://github.com/projectwallace/css-time-sort) - Sort an array of `<time>` values