@tokenami/node 0.0.96--canary.bootstrap.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/LICENSE +21 -0
- package/README.md +3 -0
- package/dist/index.d.ts +2977 -0
- package/dist/index.js +2031 -0
- package/dist/ts-plugin.cjs +1299 -0
- package/dist/ts-plugin.d.cts +24 -0
- package/package.json +64 -0
- package/stubs/tokenami.config.cjs +175 -0
- package/stubs/tokenami.config.js +175 -0
- package/stubs/tokenami.config.mjs +175 -0
- package/stubs/tokenami.config.ts +175 -0
- package/stubs/tokenami.env.d.ts +7 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,2031 @@
|
|
|
1
|
+
import { fileURLToPath } from 'url';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import * as Tokenami2 from '@tokenami/config';
|
|
4
|
+
import glob from 'fast-glob';
|
|
5
|
+
import * as fs from 'fs';
|
|
6
|
+
import * as acorn from 'acorn';
|
|
7
|
+
import * as acornWalk from 'acorn-walk';
|
|
8
|
+
import * as csstree from 'css-tree';
|
|
9
|
+
import { stringify } from '@stitches/stringify';
|
|
10
|
+
import * as lightning from 'lightningcss';
|
|
11
|
+
import createJiti from 'jiti';
|
|
12
|
+
import { transform } from 'sucrase';
|
|
13
|
+
import * as pathe from 'pathe';
|
|
14
|
+
import ts from 'typescript/lib/tsserverlibrary.js';
|
|
15
|
+
import * as culori2 from 'culori';
|
|
16
|
+
|
|
17
|
+
var __defProp = Object.defineProperty;
|
|
18
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
19
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
20
|
+
}) : x)(function(x) {
|
|
21
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
22
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
23
|
+
});
|
|
24
|
+
var __export = (target, all) => {
|
|
25
|
+
for (var name in all)
|
|
26
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
27
|
+
};
|
|
28
|
+
var getFilename = () => fileURLToPath(import.meta.url);
|
|
29
|
+
var getDirname = () => path.dirname(getFilename());
|
|
30
|
+
var __dirname = /* @__PURE__ */ getDirname();
|
|
31
|
+
var __filename = /* @__PURE__ */ getFilename();
|
|
32
|
+
|
|
33
|
+
// src/utils.ts
|
|
34
|
+
var utils_exports = {};
|
|
35
|
+
__export(utils_exports, {
|
|
36
|
+
generateConfig: () => generateConfig,
|
|
37
|
+
generateTypeDefs: () => generateTypeDefs,
|
|
38
|
+
getConfigAtPath: () => getConfigAtPath,
|
|
39
|
+
getConfigPath: () => getConfigPath,
|
|
40
|
+
getThemeFromConfig: () => getThemeFromConfig,
|
|
41
|
+
getThemeValuesByThemeMode: () => getThemeValuesByThemeMode,
|
|
42
|
+
getThemeValuesByTokenValues: () => getThemeValuesByTokenValues,
|
|
43
|
+
getTypeDefsPath: () => getTypeDefsPath,
|
|
44
|
+
getValidProperties: () => getValidProperties,
|
|
45
|
+
mergedConfigs: () => mergedConfigs,
|
|
46
|
+
unique: () => unique
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
// src/supports.ts
|
|
50
|
+
var supportedLogical = {
|
|
51
|
+
"block-overflow": 1,
|
|
52
|
+
"block-size": 1,
|
|
53
|
+
"border-block": 1,
|
|
54
|
+
"border-block-end": 1,
|
|
55
|
+
"border-block-start": 1,
|
|
56
|
+
"border-block-color": 1,
|
|
57
|
+
"border-block-end-color": 1,
|
|
58
|
+
"border-block-end-style": 1,
|
|
59
|
+
"border-block-end-width": 1,
|
|
60
|
+
"border-block-start-color": 1,
|
|
61
|
+
"border-block-start-style": 1,
|
|
62
|
+
"border-block-start-width": 1,
|
|
63
|
+
"border-block-style": 1,
|
|
64
|
+
"border-block-width": 1,
|
|
65
|
+
"border-inline": 1,
|
|
66
|
+
"border-inline-end": 1,
|
|
67
|
+
"border-inline-start": 1,
|
|
68
|
+
"border-inline-color": 1,
|
|
69
|
+
"border-inline-end-color": 1,
|
|
70
|
+
"border-inline-end-style": 1,
|
|
71
|
+
"border-inline-end-width": 1,
|
|
72
|
+
"border-inline-start-color": 1,
|
|
73
|
+
"border-inline-start-style": 1,
|
|
74
|
+
"border-inline-start-width": 1,
|
|
75
|
+
"border-inline-style": 1,
|
|
76
|
+
"border-inline-width": 1,
|
|
77
|
+
"contain-intrinsic-block-size": 1,
|
|
78
|
+
"contain-intrinsic-inline-size": 1,
|
|
79
|
+
"inline-size": 1,
|
|
80
|
+
"inset-block": 1,
|
|
81
|
+
"inset-block-end": 1,
|
|
82
|
+
"inset-block-start": 1,
|
|
83
|
+
"inset-inline": 1,
|
|
84
|
+
"inset-inline-end": 1,
|
|
85
|
+
"inset-inline-start": 1,
|
|
86
|
+
"margin-block": 1,
|
|
87
|
+
"margin-block-end": 1,
|
|
88
|
+
"margin-block-start": 1,
|
|
89
|
+
"margin-inline": 1,
|
|
90
|
+
"margin-inline-end": 1,
|
|
91
|
+
"margin-inline-start": 1,
|
|
92
|
+
"max-block-size": 1,
|
|
93
|
+
"max-inline-size": 1,
|
|
94
|
+
"min-block-size": 1,
|
|
95
|
+
"min-inline-size": 1,
|
|
96
|
+
"overflow-block": 1,
|
|
97
|
+
"overflow-inline": 1,
|
|
98
|
+
"overscroll-behavior-block": 1,
|
|
99
|
+
"overscroll-behavior-inline": 1,
|
|
100
|
+
"padding-block": 1,
|
|
101
|
+
"padding-block-end": 1,
|
|
102
|
+
"padding-block-start": 1,
|
|
103
|
+
"padding-inline": 1,
|
|
104
|
+
"padding-inline-end": 1,
|
|
105
|
+
"padding-inline-start": 1,
|
|
106
|
+
"scroll-margin-block": 1,
|
|
107
|
+
"scroll-margin-block-end": 1,
|
|
108
|
+
"scroll-margin-block-start": 1,
|
|
109
|
+
"scroll-margin-inline": 1,
|
|
110
|
+
"scroll-margin-inline-end": 1,
|
|
111
|
+
"scroll-margin-inline-start": 1,
|
|
112
|
+
"scroll-padding-block": 1,
|
|
113
|
+
"scroll-padding-block-end": 1,
|
|
114
|
+
"scroll-padding-block-start": 1,
|
|
115
|
+
"scroll-padding-inline": 1,
|
|
116
|
+
"scroll-padding-inline-end": 1,
|
|
117
|
+
"scroll-padding-inline-start": 1
|
|
118
|
+
};
|
|
119
|
+
var supported = {
|
|
120
|
+
all: 1,
|
|
121
|
+
animation: 1,
|
|
122
|
+
"animation-range": 1,
|
|
123
|
+
background: 1,
|
|
124
|
+
"background-position": 1,
|
|
125
|
+
border: 1,
|
|
126
|
+
"border-bottom": 1,
|
|
127
|
+
"border-color": 1,
|
|
128
|
+
"border-image": 1,
|
|
129
|
+
"border-left": 1,
|
|
130
|
+
"border-radius": 1,
|
|
131
|
+
"border-right": 1,
|
|
132
|
+
"border-style": 1,
|
|
133
|
+
"border-top": 1,
|
|
134
|
+
"border-width": 1,
|
|
135
|
+
caret: 1,
|
|
136
|
+
"column-rule": 1,
|
|
137
|
+
columns: 1,
|
|
138
|
+
"contain-intrinsic-size": 1,
|
|
139
|
+
container: 1,
|
|
140
|
+
flex: 1,
|
|
141
|
+
"flex-flow": 1,
|
|
142
|
+
font: 1,
|
|
143
|
+
gap: 1,
|
|
144
|
+
grid: 1,
|
|
145
|
+
"grid-area": 1,
|
|
146
|
+
"grid-column": 1,
|
|
147
|
+
"grid-row": 1,
|
|
148
|
+
"grid-template": 1,
|
|
149
|
+
inset: 1,
|
|
150
|
+
"line-clamp": 1,
|
|
151
|
+
"list-style": 1,
|
|
152
|
+
margin: 1,
|
|
153
|
+
mask: 1,
|
|
154
|
+
"mask-border": 1,
|
|
155
|
+
motion: 1,
|
|
156
|
+
offset: 1,
|
|
157
|
+
outline: 1,
|
|
158
|
+
overflow: 1,
|
|
159
|
+
"overscroll-behavior": 1,
|
|
160
|
+
padding: 1,
|
|
161
|
+
"place-content": 1,
|
|
162
|
+
"place-items": 1,
|
|
163
|
+
"place-self": 1,
|
|
164
|
+
"scroll-margin": 1,
|
|
165
|
+
"scroll-padding": 1,
|
|
166
|
+
"scroll-snap-margin": 1,
|
|
167
|
+
"scroll-timeline": 1,
|
|
168
|
+
"text-decoration": 1,
|
|
169
|
+
"text-emphasis": 1,
|
|
170
|
+
transition: 1,
|
|
171
|
+
"view-timeline": 1,
|
|
172
|
+
"accent-color": 1,
|
|
173
|
+
"align-content": 1,
|
|
174
|
+
"align-items": 1,
|
|
175
|
+
"align-self": 1,
|
|
176
|
+
"align-tracks": 1,
|
|
177
|
+
"animation-composition": 1,
|
|
178
|
+
"animation-delay": 1,
|
|
179
|
+
"animation-direction": 1,
|
|
180
|
+
"animation-duration": 1,
|
|
181
|
+
"animation-fill-mode": 1,
|
|
182
|
+
"animation-iteration-count": 1,
|
|
183
|
+
"animation-name": 1,
|
|
184
|
+
"animation-play-state": 1,
|
|
185
|
+
"animation-range-end": 1,
|
|
186
|
+
"animation-range-start": 1,
|
|
187
|
+
"animation-timeline": 1,
|
|
188
|
+
"animation-timing-function": 1,
|
|
189
|
+
appearance: 1,
|
|
190
|
+
"aspect-ratio": 1,
|
|
191
|
+
"backdrop-filter": 1,
|
|
192
|
+
"backface-visibility": 1,
|
|
193
|
+
"background-attachment": 1,
|
|
194
|
+
"background-blend-mode": 1,
|
|
195
|
+
"background-clip": 1,
|
|
196
|
+
"background-color": 1,
|
|
197
|
+
"background-image": 1,
|
|
198
|
+
"background-origin": 1,
|
|
199
|
+
"background-position-x": 1,
|
|
200
|
+
"background-position-y": 1,
|
|
201
|
+
"background-repeat": 1,
|
|
202
|
+
"background-size": 1,
|
|
203
|
+
"border-bottom-color": 1,
|
|
204
|
+
"border-bottom-left-radius": 1,
|
|
205
|
+
"border-bottom-right-radius": 1,
|
|
206
|
+
"border-bottom-style": 1,
|
|
207
|
+
"border-bottom-width": 1,
|
|
208
|
+
"border-collapse": 1,
|
|
209
|
+
"border-end-end-radius": 1,
|
|
210
|
+
"border-end-start-radius": 1,
|
|
211
|
+
"border-image-outset": 1,
|
|
212
|
+
"border-image-repeat": 1,
|
|
213
|
+
"border-image-slice": 1,
|
|
214
|
+
"border-image-source": 1,
|
|
215
|
+
"border-image-width": 1,
|
|
216
|
+
"border-left-color": 1,
|
|
217
|
+
"border-left-style": 1,
|
|
218
|
+
"border-left-width": 1,
|
|
219
|
+
"border-right-color": 1,
|
|
220
|
+
"border-right-style": 1,
|
|
221
|
+
"border-right-width": 1,
|
|
222
|
+
"border-spacing": 1,
|
|
223
|
+
"border-start-end-radius": 1,
|
|
224
|
+
"border-start-start-radius": 1,
|
|
225
|
+
"border-top-color": 1,
|
|
226
|
+
"border-top-left-radius": 1,
|
|
227
|
+
"border-top-right-radius": 1,
|
|
228
|
+
"border-top-style": 1,
|
|
229
|
+
"border-top-width": 1,
|
|
230
|
+
bottom: 1,
|
|
231
|
+
"box-decoration-break": 1,
|
|
232
|
+
"box-shadow": 1,
|
|
233
|
+
"box-sizing": 1,
|
|
234
|
+
"break-after": 1,
|
|
235
|
+
"break-before": 1,
|
|
236
|
+
"break-inside": 1,
|
|
237
|
+
"caption-side": 1,
|
|
238
|
+
"caret-color": 1,
|
|
239
|
+
"caret-shape": 1,
|
|
240
|
+
clear: 1,
|
|
241
|
+
"clip-path": 1,
|
|
242
|
+
color: 1,
|
|
243
|
+
"color-adjust": 1,
|
|
244
|
+
"color-scheme": 1,
|
|
245
|
+
"column-count": 1,
|
|
246
|
+
"column-fill": 1,
|
|
247
|
+
"column-gap": 1,
|
|
248
|
+
"column-rule-color": 1,
|
|
249
|
+
"column-rule-style": 1,
|
|
250
|
+
"column-rule-width": 1,
|
|
251
|
+
"column-span": 1,
|
|
252
|
+
"column-width": 1,
|
|
253
|
+
contain: 1,
|
|
254
|
+
"contain-intrinsic-height": 1,
|
|
255
|
+
"contain-intrinsic-width": 1,
|
|
256
|
+
"container-name": 1,
|
|
257
|
+
"container-type": 1,
|
|
258
|
+
content: 1,
|
|
259
|
+
"content-visibility": 1,
|
|
260
|
+
"counter-increment": 1,
|
|
261
|
+
"counter-reset": 1,
|
|
262
|
+
"counter-set": 1,
|
|
263
|
+
cursor: 1,
|
|
264
|
+
direction: 1,
|
|
265
|
+
display: 1,
|
|
266
|
+
"empty-cells": 1,
|
|
267
|
+
filter: 1,
|
|
268
|
+
"flex-basis": 1,
|
|
269
|
+
"flex-direction": 1,
|
|
270
|
+
"flex-grow": 1,
|
|
271
|
+
"flex-shrink": 1,
|
|
272
|
+
"flex-wrap": 1,
|
|
273
|
+
float: 1,
|
|
274
|
+
"font-family": 1,
|
|
275
|
+
"font-feature-settings": 1,
|
|
276
|
+
"font-kerning": 1,
|
|
277
|
+
"font-language-override": 1,
|
|
278
|
+
"font-optical-sizing": 1,
|
|
279
|
+
"font-palette": 1,
|
|
280
|
+
"font-size": 1,
|
|
281
|
+
"font-size-adjust": 1,
|
|
282
|
+
"font-smooth": 1,
|
|
283
|
+
"font-stretch": 1,
|
|
284
|
+
"font-style": 1,
|
|
285
|
+
"font-synthesis": 1,
|
|
286
|
+
"font-synthesis-position": 1,
|
|
287
|
+
"font-synthesis-small-caps": 1,
|
|
288
|
+
"font-synthesis-style": 1,
|
|
289
|
+
"font-synthesis-weight": 1,
|
|
290
|
+
"font-variant": 1,
|
|
291
|
+
"font-variant-alternates": 1,
|
|
292
|
+
"font-variant-caps": 1,
|
|
293
|
+
"font-variant-east-asian": 1,
|
|
294
|
+
"font-variant-emoji": 1,
|
|
295
|
+
"font-variant-ligatures": 1,
|
|
296
|
+
"font-variant-numeric": 1,
|
|
297
|
+
"font-variant-position": 1,
|
|
298
|
+
"font-variation-settings": 1,
|
|
299
|
+
"font-weight": 1,
|
|
300
|
+
"forced-color-adjust": 1,
|
|
301
|
+
"grid-auto-columns": 1,
|
|
302
|
+
"grid-auto-flow": 1,
|
|
303
|
+
"grid-auto-rows": 1,
|
|
304
|
+
"grid-column-end": 1,
|
|
305
|
+
"grid-column-start": 1,
|
|
306
|
+
"grid-row-end": 1,
|
|
307
|
+
"grid-row-start": 1,
|
|
308
|
+
"grid-template-areas": 1,
|
|
309
|
+
"grid-template-columns": 1,
|
|
310
|
+
"grid-template-rows": 1,
|
|
311
|
+
"hanging-punctuation": 1,
|
|
312
|
+
height: 1,
|
|
313
|
+
"hyphenate-character": 1,
|
|
314
|
+
"hyphenate-limit-chars": 1,
|
|
315
|
+
hyphens: 1,
|
|
316
|
+
"image-orientation": 1,
|
|
317
|
+
"image-rendering": 1,
|
|
318
|
+
"image-resolution": 1,
|
|
319
|
+
"initial-letter": 1,
|
|
320
|
+
"input-security": 1,
|
|
321
|
+
isolation: 1,
|
|
322
|
+
"justify-content": 1,
|
|
323
|
+
"justify-items": 1,
|
|
324
|
+
"justify-self": 1,
|
|
325
|
+
"justify-tracks": 1,
|
|
326
|
+
left: 1,
|
|
327
|
+
"letter-spacing": 1,
|
|
328
|
+
"line-break": 1,
|
|
329
|
+
"line-height": 1,
|
|
330
|
+
"line-height-step": 1,
|
|
331
|
+
"list-style-image": 1,
|
|
332
|
+
"list-style-position": 1,
|
|
333
|
+
"list-style-type": 1,
|
|
334
|
+
"margin-bottom": 1,
|
|
335
|
+
"margin-left": 1,
|
|
336
|
+
"margin-right": 1,
|
|
337
|
+
"margin-top": 1,
|
|
338
|
+
"margin-trim": 1,
|
|
339
|
+
"mask-border-mode": 1,
|
|
340
|
+
"mask-border-outset": 1,
|
|
341
|
+
"mask-border-repeat": 1,
|
|
342
|
+
"mask-border-slice": 1,
|
|
343
|
+
"mask-border-source": 1,
|
|
344
|
+
"mask-border-width": 1,
|
|
345
|
+
"mask-clip": 1,
|
|
346
|
+
"mask-composite": 1,
|
|
347
|
+
"mask-image": 1,
|
|
348
|
+
"mask-mode": 1,
|
|
349
|
+
"mask-origin": 1,
|
|
350
|
+
"mask-position": 1,
|
|
351
|
+
"mask-repeat": 1,
|
|
352
|
+
"mask-size": 1,
|
|
353
|
+
"mask-type": 1,
|
|
354
|
+
"masonry-auto-flow": 1,
|
|
355
|
+
"math-depth": 1,
|
|
356
|
+
"math-shift": 1,
|
|
357
|
+
"math-style": 1,
|
|
358
|
+
"max-height": 1,
|
|
359
|
+
"max-lines": 1,
|
|
360
|
+
"max-width": 1,
|
|
361
|
+
"min-height": 1,
|
|
362
|
+
"min-width": 1,
|
|
363
|
+
"mix-blend-mode": 1,
|
|
364
|
+
"motion-distance": 1,
|
|
365
|
+
"motion-path": 1,
|
|
366
|
+
"motion-rotation": 1,
|
|
367
|
+
"object-fit": 1,
|
|
368
|
+
"object-position": 1,
|
|
369
|
+
"offset-anchor": 1,
|
|
370
|
+
"offset-distance": 1,
|
|
371
|
+
"offset-path": 1,
|
|
372
|
+
"offset-position": 1,
|
|
373
|
+
"offset-rotate": 1,
|
|
374
|
+
"offset-rotation": 1,
|
|
375
|
+
opacity: 1,
|
|
376
|
+
order: 1,
|
|
377
|
+
orphans: 1,
|
|
378
|
+
"outline-color": 1,
|
|
379
|
+
"outline-offset": 1,
|
|
380
|
+
"outline-style": 1,
|
|
381
|
+
"outline-width": 1,
|
|
382
|
+
"overflow-anchor": 1,
|
|
383
|
+
"overflow-clip-box": 1,
|
|
384
|
+
"overflow-clip-margin": 1,
|
|
385
|
+
"overflow-wrap": 1,
|
|
386
|
+
"overflow-x": 1,
|
|
387
|
+
"overflow-y": 1,
|
|
388
|
+
overlay: 1,
|
|
389
|
+
"overscroll-behavior-x": 1,
|
|
390
|
+
"overscroll-behavior-y": 1,
|
|
391
|
+
"padding-bottom": 1,
|
|
392
|
+
"padding-left": 1,
|
|
393
|
+
"padding-right": 1,
|
|
394
|
+
"padding-top": 1,
|
|
395
|
+
page: 1,
|
|
396
|
+
"page-break-after": 1,
|
|
397
|
+
"page-break-before": 1,
|
|
398
|
+
"page-break-inside": 1,
|
|
399
|
+
"paint-order": 1,
|
|
400
|
+
perspective: 1,
|
|
401
|
+
"perspective-origin": 1,
|
|
402
|
+
"pointer-events": 1,
|
|
403
|
+
position: 1,
|
|
404
|
+
"print-color-adjust": 1,
|
|
405
|
+
quotes: 1,
|
|
406
|
+
resize: 1,
|
|
407
|
+
right: 1,
|
|
408
|
+
rotate: 1,
|
|
409
|
+
"row-gap": 1,
|
|
410
|
+
"ruby-align": 1,
|
|
411
|
+
"ruby-merge": 1,
|
|
412
|
+
"ruby-position": 1,
|
|
413
|
+
scale: 1,
|
|
414
|
+
"scroll-behavior": 1,
|
|
415
|
+
"scroll-margin-bottom": 1,
|
|
416
|
+
"scroll-margin-left": 1,
|
|
417
|
+
"scroll-margin-right": 1,
|
|
418
|
+
"scroll-margin-top": 1,
|
|
419
|
+
"scroll-padding-bottom": 1,
|
|
420
|
+
"scroll-padding-left": 1,
|
|
421
|
+
"scroll-padding-right": 1,
|
|
422
|
+
"scroll-padding-top": 1,
|
|
423
|
+
"scroll-snap-align": 1,
|
|
424
|
+
"scroll-snap-margin-bottom": 1,
|
|
425
|
+
"scroll-snap-margin-left": 1,
|
|
426
|
+
"scroll-snap-margin-right": 1,
|
|
427
|
+
"scroll-snap-margin-top": 1,
|
|
428
|
+
"scroll-snap-stop": 1,
|
|
429
|
+
"scroll-snap-type": 1,
|
|
430
|
+
"scroll-timeline-axis": 1,
|
|
431
|
+
"scroll-timeline-name": 1,
|
|
432
|
+
"scrollbar-color": 1,
|
|
433
|
+
"scrollbar-gutter": 1,
|
|
434
|
+
"scrollbar-width": 1,
|
|
435
|
+
"shape-image-threshold": 1,
|
|
436
|
+
"shape-margin": 1,
|
|
437
|
+
"shape-outside": 1,
|
|
438
|
+
"tab-size": 1,
|
|
439
|
+
"table-layout": 1,
|
|
440
|
+
"text-align": 1,
|
|
441
|
+
"text-align-last": 1,
|
|
442
|
+
"text-combine-upright": 1,
|
|
443
|
+
"text-decoration-color": 1,
|
|
444
|
+
"text-decoration-line": 1,
|
|
445
|
+
"text-decoration-skip": 1,
|
|
446
|
+
"text-decoration-skip-ink": 1,
|
|
447
|
+
"text-decoration-style": 1,
|
|
448
|
+
"text-decoration-thickness": 1,
|
|
449
|
+
"text-emphasis-color": 1,
|
|
450
|
+
"text-emphasis-position": 1,
|
|
451
|
+
"text-emphasis-style": 1,
|
|
452
|
+
"text-indent": 1,
|
|
453
|
+
"text-justify": 1,
|
|
454
|
+
"text-orientation": 1,
|
|
455
|
+
"text-overflow": 1,
|
|
456
|
+
"text-rendering": 1,
|
|
457
|
+
"text-shadow": 1,
|
|
458
|
+
"text-size-adjust": 1,
|
|
459
|
+
"text-transform": 1,
|
|
460
|
+
"text-underline-offset": 1,
|
|
461
|
+
"text-underline-position": 1,
|
|
462
|
+
"text-wrap": 1,
|
|
463
|
+
"timeline-scope": 1,
|
|
464
|
+
top: 1,
|
|
465
|
+
"touch-action": 1,
|
|
466
|
+
transform: 1,
|
|
467
|
+
"transform-box": 1,
|
|
468
|
+
"transform-origin": 1,
|
|
469
|
+
"transform-style": 1,
|
|
470
|
+
"transition-behavior": 1,
|
|
471
|
+
"transition-delay": 1,
|
|
472
|
+
"transition-duration": 1,
|
|
473
|
+
"transition-property": 1,
|
|
474
|
+
"transition-timing-function": 1,
|
|
475
|
+
translate: 1,
|
|
476
|
+
"unicode-bidi": 1,
|
|
477
|
+
"user-select": 1,
|
|
478
|
+
"vertical-align": 1,
|
|
479
|
+
"view-timeline-axis": 1,
|
|
480
|
+
"view-timeline-inset": 1,
|
|
481
|
+
"view-timeline-name": 1,
|
|
482
|
+
"view-transition-name": 1,
|
|
483
|
+
visibility: 1,
|
|
484
|
+
"white-space": 1,
|
|
485
|
+
"white-space-collapse": 1,
|
|
486
|
+
"white-space-trim": 1,
|
|
487
|
+
widows: 1,
|
|
488
|
+
width: 1,
|
|
489
|
+
"will-change": 1,
|
|
490
|
+
"word-break": 1,
|
|
491
|
+
"word-spacing": 1,
|
|
492
|
+
"word-wrap": 1,
|
|
493
|
+
"writing-mode": 1,
|
|
494
|
+
"z-index": 1,
|
|
495
|
+
zoom: 1,
|
|
496
|
+
"alignment-baseline": 1,
|
|
497
|
+
"baseline-shift": 1,
|
|
498
|
+
clip: 1,
|
|
499
|
+
"clip-rule": 1,
|
|
500
|
+
"color-interpolation": 1,
|
|
501
|
+
"color-rendering": 1,
|
|
502
|
+
"dominant-baseline": 1,
|
|
503
|
+
fill: 1,
|
|
504
|
+
"fill-opacity": 1,
|
|
505
|
+
"fill-rule": 1,
|
|
506
|
+
"flood-color": 1,
|
|
507
|
+
"flood-opacity": 1,
|
|
508
|
+
"glyph-orientation-vertical": 1,
|
|
509
|
+
"lighting-color": 1,
|
|
510
|
+
marker: 1,
|
|
511
|
+
"marker-end": 1,
|
|
512
|
+
"marker-mid": 1,
|
|
513
|
+
"marker-start": 1,
|
|
514
|
+
"shape-rendering": 1,
|
|
515
|
+
"stop-color": 1,
|
|
516
|
+
"stop-opacity": 1,
|
|
517
|
+
stroke: 1,
|
|
518
|
+
"stroke-dasharray": 1,
|
|
519
|
+
"stroke-dashoffset": 1,
|
|
520
|
+
"stroke-linecap": 1,
|
|
521
|
+
"stroke-linejoin": 1,
|
|
522
|
+
"stroke-miterlimit": 1,
|
|
523
|
+
"stroke-opacity": 1,
|
|
524
|
+
"stroke-width": 1,
|
|
525
|
+
"text-anchor": 1,
|
|
526
|
+
"vector-effect": 1,
|
|
527
|
+
...supportedLogical
|
|
528
|
+
};
|
|
529
|
+
var inheritedProperties = /* @__PURE__ */ new Set([
|
|
530
|
+
"azimuth",
|
|
531
|
+
"border-collapse",
|
|
532
|
+
"border-spacing",
|
|
533
|
+
"caption-side",
|
|
534
|
+
"color",
|
|
535
|
+
"cursor",
|
|
536
|
+
"direction",
|
|
537
|
+
"empty-cells",
|
|
538
|
+
"font-family",
|
|
539
|
+
"font-size",
|
|
540
|
+
"font-style",
|
|
541
|
+
"font-variant",
|
|
542
|
+
"font-weight",
|
|
543
|
+
"font-stretch",
|
|
544
|
+
"font",
|
|
545
|
+
"letter-spacing",
|
|
546
|
+
"line-height",
|
|
547
|
+
"list-style-image",
|
|
548
|
+
"list-style-position",
|
|
549
|
+
"list-style-type",
|
|
550
|
+
"list-style",
|
|
551
|
+
"orphans",
|
|
552
|
+
"quotes",
|
|
553
|
+
"text-align",
|
|
554
|
+
"text-indent",
|
|
555
|
+
"text-transform",
|
|
556
|
+
"visibility",
|
|
557
|
+
"white-space",
|
|
558
|
+
"widows",
|
|
559
|
+
"word-spacing"
|
|
560
|
+
]);
|
|
561
|
+
var supportedProperties = new Set(Object.keys(supported));
|
|
562
|
+
var supportedLogicalProperties = new Set(Object.keys(supportedLogical));
|
|
563
|
+
|
|
564
|
+
// src/utils.ts
|
|
565
|
+
var DEFAULT_PATHS = {
|
|
566
|
+
js: "./.tokenami/tokenami.config.js",
|
|
567
|
+
ts: "./.tokenami/tokenami.config.ts",
|
|
568
|
+
cjs: "./.tokenami/tokenami.config.cjs",
|
|
569
|
+
mjs: "./.tokenami/tokenami.config.mjs"
|
|
570
|
+
};
|
|
571
|
+
function getConfigPath(cwd, path2, type) {
|
|
572
|
+
path2 = path2 || getConfigDefaultPath(cwd, type);
|
|
573
|
+
return pathe.join(cwd, path2);
|
|
574
|
+
}
|
|
575
|
+
function getConfigAtPath(path2, opts = { cache: true }) {
|
|
576
|
+
const config = (() => {
|
|
577
|
+
try {
|
|
578
|
+
if (!opts.cache) delete __require.cache[__require.resolve(path2)];
|
|
579
|
+
return __require(path2);
|
|
580
|
+
} catch {
|
|
581
|
+
return lazyJiti({ cache: opts.cache })(path2);
|
|
582
|
+
}
|
|
583
|
+
})();
|
|
584
|
+
return mergedConfigs(config.default ?? config);
|
|
585
|
+
}
|
|
586
|
+
function getConfigDefaultPath(cwd, type) {
|
|
587
|
+
const existingConfig = Object.values(DEFAULT_PATHS).find((path2) => {
|
|
588
|
+
return fs.existsSync(pathe.join(cwd, path2));
|
|
589
|
+
});
|
|
590
|
+
return existingConfig || DEFAULT_PATHS[type || "js"];
|
|
591
|
+
}
|
|
592
|
+
function getTypeDefsPath(configPath) {
|
|
593
|
+
const dirname2 = pathe.dirname(configPath);
|
|
594
|
+
return `${dirname2}/tokenami.env.d.ts`;
|
|
595
|
+
}
|
|
596
|
+
function getThemeValuesByTokenValues(tokenValues, theme) {
|
|
597
|
+
const entries = getThemeValueByTokenValueEntries(tokenValues, theme);
|
|
598
|
+
return Object.fromEntries(entries);
|
|
599
|
+
}
|
|
600
|
+
function getThemeValueByTokenValueEntries(tokenValues, theme) {
|
|
601
|
+
const sorted = [...tokenValues].sort();
|
|
602
|
+
return sorted.flatMap((tokenValue2) => {
|
|
603
|
+
const parts = Tokenami2.getTokenValueParts(tokenValue2);
|
|
604
|
+
const value = theme[parts.themeKey]?.[parts.token];
|
|
605
|
+
if (value == null) return [];
|
|
606
|
+
const valueString = String(value);
|
|
607
|
+
const tokenValues2 = findTokenValuesInThemeValue(valueString);
|
|
608
|
+
const themeValuesEntries = getThemeValueByTokenValueEntries(tokenValues2, theme);
|
|
609
|
+
return [[parts.property, valueString], ...themeValuesEntries];
|
|
610
|
+
});
|
|
611
|
+
}
|
|
612
|
+
function findTokenValuesInThemeValue(themeValue) {
|
|
613
|
+
const cssVariables = themeValue.match(/var\([\w-_]+\)/g) || [];
|
|
614
|
+
const tokenValues = cssVariables.filter((v) => Tokenami2.TokenValue.safeParse(v).success);
|
|
615
|
+
return tokenValues;
|
|
616
|
+
}
|
|
617
|
+
function getThemeFromConfig(themeConfig) {
|
|
618
|
+
const { modes = {}, root, ...base } = themeConfig;
|
|
619
|
+
if ("modes" in themeConfig) {
|
|
620
|
+
const config = themeConfig;
|
|
621
|
+
return { modes: config.modes, root: config.root };
|
|
622
|
+
}
|
|
623
|
+
return { modes: {}, root: base };
|
|
624
|
+
}
|
|
625
|
+
function getThemeValuesByThemeMode(tokenValue2, themeConfig) {
|
|
626
|
+
const theme = getThemeFromConfig(themeConfig);
|
|
627
|
+
const parts = Tokenami2.getTokenValueParts(tokenValue2);
|
|
628
|
+
const modeThemeEntries = Object.entries(theme.modes);
|
|
629
|
+
const modeValues = modeThemeEntries.concat([["root", theme.root]]).flatMap(([mode, theme2]) => {
|
|
630
|
+
const value = theme2[parts.themeKey]?.[parts.token];
|
|
631
|
+
return value == null ? [] : [[mode, String(value)]];
|
|
632
|
+
});
|
|
633
|
+
return Object.fromEntries(modeValues);
|
|
634
|
+
}
|
|
635
|
+
function generateConfig(include, configPath) {
|
|
636
|
+
const filename = pathe.basename(configPath);
|
|
637
|
+
const configStubPath = pathe.resolve(__dirname, `../stubs/${filename}`);
|
|
638
|
+
const configStub = fs.readFileSync(configStubPath, "utf8");
|
|
639
|
+
return configStub.replace("include: []", `include: [${include}]`);
|
|
640
|
+
}
|
|
641
|
+
function mergedConfigs(theirs) {
|
|
642
|
+
return theirs;
|
|
643
|
+
}
|
|
644
|
+
function generateTypeDefs(configPath, stubPath = "../stubs/tokenami.env.d.ts") {
|
|
645
|
+
const parsed = pathe.parse(configPath);
|
|
646
|
+
const typeDefStubPath = pathe.resolve(__dirname, stubPath);
|
|
647
|
+
const typeDefStub = fs.readFileSync(typeDefStubPath, "utf8");
|
|
648
|
+
return typeDefStub.replace("tokenami.config", parsed.name);
|
|
649
|
+
}
|
|
650
|
+
function getValidProperties(config) {
|
|
651
|
+
return /* @__PURE__ */ new Set([
|
|
652
|
+
...supportedProperties,
|
|
653
|
+
...Object.keys(config.properties || {}),
|
|
654
|
+
...Object.keys(config.customProperties || {}),
|
|
655
|
+
...Object.keys(config.aliases || {})
|
|
656
|
+
]);
|
|
657
|
+
}
|
|
658
|
+
function unique(items) {
|
|
659
|
+
return Array.from(new Set(items));
|
|
660
|
+
}
|
|
661
|
+
var jitiCache = {};
|
|
662
|
+
function lazyJiti(options = {}) {
|
|
663
|
+
const cacheId = JSON.stringify(options);
|
|
664
|
+
return jitiCache[cacheId] ??= createJiti(__filename, {
|
|
665
|
+
transform: (opts) => transform(opts.source, { transforms: ["typescript", "imports"] }),
|
|
666
|
+
interopDefault: true,
|
|
667
|
+
requireCache: options.cache
|
|
668
|
+
});
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
// src/log.ts
|
|
672
|
+
var log_exports = {};
|
|
673
|
+
__export(log_exports, {
|
|
674
|
+
debug: () => debug,
|
|
675
|
+
error: () => error
|
|
676
|
+
});
|
|
677
|
+
var ANSI = {
|
|
678
|
+
red: "\x1B[31m",
|
|
679
|
+
bgRed: "\x1B[41m",
|
|
680
|
+
yellow: "\x1B[33m",
|
|
681
|
+
bgYellow: "\x1B[43m",
|
|
682
|
+
reset: "\x1B[0m"
|
|
683
|
+
};
|
|
684
|
+
function color(code, str) {
|
|
685
|
+
return `${code}${str}${ANSI.reset}`;
|
|
686
|
+
}
|
|
687
|
+
function error(str) {
|
|
688
|
+
console.error(`${color(ANSI.bgRed, " tokenami ")} ${color(ANSI.red, str)}`);
|
|
689
|
+
process.exit(1);
|
|
690
|
+
}
|
|
691
|
+
function debug(str) {
|
|
692
|
+
console.debug(`${color(ANSI.bgYellow, " tokenami ")} ${color(ANSI.yellow, str)}`);
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
// src/sheet.ts
|
|
696
|
+
var UNUSED_LAYERS_REGEX = /[\n\s]*@layer[^;{]+;/g;
|
|
697
|
+
var DEFAULT_SELECTOR = "[style]";
|
|
698
|
+
var CUSTOM_PROP_PREFIX = "--_";
|
|
699
|
+
var LAYERS = {
|
|
700
|
+
BASE: "tk",
|
|
701
|
+
LOGICAL: "tkl",
|
|
702
|
+
SELECTORS: "tks",
|
|
703
|
+
SELECTORS_LOGICAL: "tksl",
|
|
704
|
+
COMPONENTS: "tkc"
|
|
705
|
+
};
|
|
706
|
+
function generate(params) {
|
|
707
|
+
try {
|
|
708
|
+
const sheet = createSheet(params);
|
|
709
|
+
const transformed = lightning.transform({
|
|
710
|
+
code: Buffer.from(sheet),
|
|
711
|
+
filename: params.output,
|
|
712
|
+
minify: params.minify,
|
|
713
|
+
targets: params.targets
|
|
714
|
+
});
|
|
715
|
+
return transformed.code.toString().replace(UNUSED_LAYERS_REGEX, "");
|
|
716
|
+
} catch (e) {
|
|
717
|
+
const message = e instanceof Error ? e.message : "Unknown error";
|
|
718
|
+
const escapedMessage = message.replace(/(['"])/g, "\\$1");
|
|
719
|
+
debug(`Error generating stylesheet: ${message}`);
|
|
720
|
+
return `body::after { content: 'Error generating stylesheet: ${escapedMessage}'; position: fixed; inset: 0; background: #ec6142; color: white; padding: 20px; font-family: sans-serif; z-index: 9999; }`;
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
function createSheet(params) {
|
|
724
|
+
if (!params.tokens.properties.length) return "";
|
|
725
|
+
const sheet = new Sheet(params.tokens.values, params.config);
|
|
726
|
+
const composeBlocks = parseComposeBlocks(params.tokens.composeBlocks, params.config);
|
|
727
|
+
const propertyConfigsByCSSProperty = getPropertyConfigs(params.tokens.properties, params.config);
|
|
728
|
+
for (const [cssProperty, propertyConfigs] of propertyConfigsByCSSProperty) {
|
|
729
|
+
const isInheritable = inheritedProperties.has(cssProperty);
|
|
730
|
+
const elementConfigs = propertyConfigs.filter((c) => {
|
|
731
|
+
const selectorConfig = getSelectorFromConfig(c.selector, params.config);
|
|
732
|
+
return !selectorConfig.some(isPseudoElementSelector);
|
|
733
|
+
});
|
|
734
|
+
for (const prop of propertyConfigs) {
|
|
735
|
+
const baseProperty = prop.isCustom ? CUSTOM_PROP_PREFIX + cssProperty : cssProperty;
|
|
736
|
+
const gridProperty3 = hashVariantProperty("grid", prop.tokenProperty);
|
|
737
|
+
const gridToggleValue = createGridToggleValue(prop.tokenProperty);
|
|
738
|
+
const selectorConfig = getSelectorFromConfig(prop.selector, params.config);
|
|
739
|
+
const parsedSelectors = getPropertySelectors(composeBlocks, prop, selectorConfig);
|
|
740
|
+
const configs = selectorConfig.some(isPseudoElementSelector) ? propertyConfigs.filter((c) => c.selector === prop.selector) : elementConfigs;
|
|
741
|
+
sheet.addThemeTokenSelectors(parsedSelectors.elements);
|
|
742
|
+
if (!isInheritable && !selectorConfig.some(isChildSelector)) {
|
|
743
|
+
sheet.addReset(prop.tokenProperty);
|
|
744
|
+
if (prop.isGrid) sheet.addReset(Tokenami2.calcProperty(prop.tokenProperty));
|
|
745
|
+
}
|
|
746
|
+
if (prop.variant) {
|
|
747
|
+
const responsiveConfig = getResponsiveSelectorFromConfig(prop.responsive, params.config);
|
|
748
|
+
const hashedProperty = hashVariantProperty(prop.variant, cssProperty);
|
|
749
|
+
const toggleProperty = Tokenami2.parsedTokenProperty(prop.variant);
|
|
750
|
+
const variantValue = createVariantValue(cssProperty, prop, configs);
|
|
751
|
+
const variantToggleValue = prop.isGrid ? createGridVariantToggleValue(toggleProperty, prop.tokenProperty) : createVariantToggleValue(toggleProperty, prop.tokenProperty);
|
|
752
|
+
sheet.addReset(toggleProperty);
|
|
753
|
+
sheet.addReset(hashedProperty);
|
|
754
|
+
for (const selector of parsedSelectors.all) {
|
|
755
|
+
sheet.addToggleFlagDeclaration(responsiveConfig, selector, toggleProperty);
|
|
756
|
+
}
|
|
757
|
+
for (const selector of parsedSelectors.elements) {
|
|
758
|
+
const pseudoOwnerSelector = removePseudoElementSelector(selector);
|
|
759
|
+
const baseSelector = prop.isCustom ? pseudoOwnerSelector : selector;
|
|
760
|
+
sheet.addDeclaration(prop.layer, baseSelector, baseProperty, variantValue);
|
|
761
|
+
sheet.addDeclaration(prop.layer, pseudoOwnerSelector, hashedProperty, variantToggleValue);
|
|
762
|
+
if (prop.isGrid) {
|
|
763
|
+
sheet.addDeclaration(prop.layer, pseudoOwnerSelector, gridProperty3, gridToggleValue);
|
|
764
|
+
}
|
|
765
|
+
}
|
|
766
|
+
} else {
|
|
767
|
+
const propertyValue = prop.isGrid ? createGridPropertyValue(prop.tokenProperty, "revert-layer") : createBasePropertyValue(prop.tokenProperty, "revert-layer");
|
|
768
|
+
for (const selector of parsedSelectors.elements) {
|
|
769
|
+
sheet.addDeclaration(prop.layer, selector, baseProperty, propertyValue);
|
|
770
|
+
if (prop.isGrid) {
|
|
771
|
+
sheet.addDeclaration(prop.layer, selector, gridProperty3, gridToggleValue);
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
const composeEntries = Object.entries(composeBlocks);
|
|
778
|
+
for (const [selector, tokenamiProperties] of composeEntries) {
|
|
779
|
+
const propertyEntries = Object.entries(tokenamiProperties);
|
|
780
|
+
for (let [key, value] of propertyEntries) {
|
|
781
|
+
sheet.addDeclaration(LAYERS.COMPONENTS, selector, key, value);
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
return sheet.toString();
|
|
785
|
+
}
|
|
786
|
+
var SELECTOR_TAG = "<selector>";
|
|
787
|
+
var CUSTOM_PROP_REGEX = /\(--[^-][\w-]+/g;
|
|
788
|
+
var Sheet = class {
|
|
789
|
+
config;
|
|
790
|
+
tokenValues;
|
|
791
|
+
themeTokenSelectors = [];
|
|
792
|
+
reset = /* @__PURE__ */ new Set();
|
|
793
|
+
toggles = {};
|
|
794
|
+
layers = {};
|
|
795
|
+
constructor(tokenValues, config) {
|
|
796
|
+
this.tokenValues = tokenValues;
|
|
797
|
+
this.config = config;
|
|
798
|
+
}
|
|
799
|
+
addReset(property) {
|
|
800
|
+
this.reset.add(`${property}: initial;`);
|
|
801
|
+
}
|
|
802
|
+
addThemeTokenSelectors(baseSelectors) {
|
|
803
|
+
this.themeTokenSelectors.push(...baseSelectors.map(removePseudoElementSelector));
|
|
804
|
+
}
|
|
805
|
+
addDeclaration(layer, selector, property, value) {
|
|
806
|
+
const declaration = `${property}: ${value}`;
|
|
807
|
+
const template = `@layer ${layer} { ${SELECTOR_TAG} { ${declaration} } }`;
|
|
808
|
+
this.layers[template] ??= /* @__PURE__ */ new Set();
|
|
809
|
+
this.layers[template].add(selector);
|
|
810
|
+
}
|
|
811
|
+
addToggleFlagDeclaration(responsiveConfig, selector, toggleProperty) {
|
|
812
|
+
let toggle = `${toggleProperty}: ;`;
|
|
813
|
+
const toggleKey = responsiveConfig || selector.join();
|
|
814
|
+
const responsiveSelectors = [responsiveConfig, ...selector].reverse();
|
|
815
|
+
for (const selector2 of responsiveSelectors) {
|
|
816
|
+
if (!selector2) continue;
|
|
817
|
+
const elemSelector = removePseudoElementSelector(selector2);
|
|
818
|
+
toggle = `${elemSelector} { ${toggle} }`;
|
|
819
|
+
}
|
|
820
|
+
this.toggles[toggleKey] ??= /* @__PURE__ */ new Set();
|
|
821
|
+
this.toggles[toggleKey].add(toggle);
|
|
822
|
+
}
|
|
823
|
+
#generateGlobalStyles() {
|
|
824
|
+
if (!this.config.globalStyles) return "";
|
|
825
|
+
return `@layer global { ${stringify(this.config.globalStyles)} }`;
|
|
826
|
+
}
|
|
827
|
+
#generateTokenamiResets() {
|
|
828
|
+
const themeTokenSelectors = unique(this.themeTokenSelectors);
|
|
829
|
+
return `
|
|
830
|
+
@layer tkb {
|
|
831
|
+
${this.#generateKeyframeRules()}
|
|
832
|
+
${this.#generateThemeTokens(themeTokenSelectors)}
|
|
833
|
+
* { ${Array.from(this.reset).join(" ")} }
|
|
834
|
+
${Object.values(this.toggles).flatMap((set) => Array.from(set)).join(" ")}
|
|
835
|
+
}
|
|
836
|
+
`;
|
|
837
|
+
}
|
|
838
|
+
#generatePlaceholderLayers(prefix) {
|
|
839
|
+
return `@layer ${Array.from({ length: 20 }).map((_, layer) => `${prefix}${layer}`).join(", ")};`;
|
|
840
|
+
}
|
|
841
|
+
#generateLayerStyles() {
|
|
842
|
+
const entries = Object.entries(this.layers);
|
|
843
|
+
const groupedBySelectors = /* @__PURE__ */ new Map();
|
|
844
|
+
for (const [template, selectors] of entries) {
|
|
845
|
+
const { pseudoElements, otherSelectors } = this.#separateSelectors(selectors);
|
|
846
|
+
if (otherSelectors.length > 0) {
|
|
847
|
+
const groupedSelector = otherSelectors.sort().join(",");
|
|
848
|
+
const existingStyles = groupedBySelectors.get(groupedSelector) || "";
|
|
849
|
+
const newStyles = template.replace(SELECTOR_TAG, groupedSelector);
|
|
850
|
+
groupedBySelectors.set(groupedSelector, existingStyles + " " + newStyles);
|
|
851
|
+
}
|
|
852
|
+
for (const pseudoElement of pseudoElements) {
|
|
853
|
+
const existingStyles = groupedBySelectors.get(pseudoElement) || "";
|
|
854
|
+
const newStyles = template.replace(SELECTOR_TAG, pseudoElement);
|
|
855
|
+
groupedBySelectors.set(pseudoElement, existingStyles + " " + newStyles);
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
return Array.from(groupedBySelectors.values()).join(" ");
|
|
859
|
+
}
|
|
860
|
+
#separateSelectors(selectors) {
|
|
861
|
+
const pseudoElements = [];
|
|
862
|
+
const otherSelectors = [];
|
|
863
|
+
for (const selector of selectors) {
|
|
864
|
+
if (isPseudoElementSelector(selector)) {
|
|
865
|
+
pseudoElements.push(selector);
|
|
866
|
+
} else {
|
|
867
|
+
otherSelectors.push(selector);
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
return { pseudoElements, otherSelectors };
|
|
871
|
+
}
|
|
872
|
+
#generateKeyframeRules() {
|
|
873
|
+
const themeValues = this.tokenValues.flatMap((tokenValue2) => {
|
|
874
|
+
return Object.values(getThemeValuesByThemeMode(tokenValue2, this.config.theme));
|
|
875
|
+
});
|
|
876
|
+
const rules = Object.entries(this.config.keyframes || {}).flatMap(([name, styles]) => {
|
|
877
|
+
const nameRegex = new RegExp(`\\b${name}\\b`);
|
|
878
|
+
const isUsingKeyframeName = themeValues.some((value) => nameRegex.test(value));
|
|
879
|
+
if (!isUsingKeyframeName) return [];
|
|
880
|
+
return [[`@keyframes ${name} { ${stringify(styles)} }`]];
|
|
881
|
+
});
|
|
882
|
+
return rules.join(" ");
|
|
883
|
+
}
|
|
884
|
+
#generateThemeTokens(styleSelector) {
|
|
885
|
+
if (styleSelector.length === 0) return "";
|
|
886
|
+
const theme = getThemeFromConfig(this.config.theme);
|
|
887
|
+
const rootSelector = this.config.themeSelector("root");
|
|
888
|
+
const gridStyles = `${rootSelector} { ${Tokenami2.gridProperty()}: ${this.config.grid}; }`;
|
|
889
|
+
const rootStyles = this.#getThemeStyles(styleSelector, rootSelector, theme.root);
|
|
890
|
+
const themeToModes = {};
|
|
891
|
+
const modeEntries = Object.entries(theme.modes || {});
|
|
892
|
+
for (const [mode, theme2] of modeEntries) {
|
|
893
|
+
const themeKey = JSON.stringify(theme2);
|
|
894
|
+
if (themeKey in themeToModes) themeToModes[themeKey].push(mode);
|
|
895
|
+
else themeToModes[themeKey] = [mode];
|
|
896
|
+
}
|
|
897
|
+
const modeStyles = Object.entries(themeToModes).map(([theme2, modes]) => {
|
|
898
|
+
const selector = modes.map(this.config.themeSelector).join(", ");
|
|
899
|
+
return this.#getThemeStyles(styleSelector, selector, JSON.parse(theme2));
|
|
900
|
+
});
|
|
901
|
+
const themeTokens = [gridStyles, rootStyles, modeStyles.join(" ")];
|
|
902
|
+
return themeTokens.join(" ");
|
|
903
|
+
}
|
|
904
|
+
#getThemeStyles(styleSelector, selector, theme) {
|
|
905
|
+
const themeValues = getThemeValuesByTokenValues(this.tokenValues, theme);
|
|
906
|
+
const customPropertyThemeValues = this.#getCustomPropertyThemeValues(themeValues);
|
|
907
|
+
const customPropertyThemeKeys = Object.keys(customPropertyThemeValues);
|
|
908
|
+
const selectors = [selector].flat();
|
|
909
|
+
const elementSelector = selectors.at(-1);
|
|
910
|
+
const parentSelectors = selectors.slice(0, -1);
|
|
911
|
+
const elementThemeStyles = this.#getElementThemeStyles(
|
|
912
|
+
styleSelector,
|
|
913
|
+
elementSelector,
|
|
914
|
+
customPropertyThemeValues
|
|
915
|
+
);
|
|
916
|
+
for (const customKey of customPropertyThemeKeys) {
|
|
917
|
+
delete themeValues[customKey];
|
|
918
|
+
}
|
|
919
|
+
const themeStyles = selectors.reduceRight(
|
|
920
|
+
(declaration, selector2) => `${selector2} { ${declaration} }`,
|
|
921
|
+
stringify(themeValues)
|
|
922
|
+
);
|
|
923
|
+
const customPropertyThemeStyles = parentSelectors.reduceRight(
|
|
924
|
+
(declaration, selector2) => `${selector2} { ${declaration} }`,
|
|
925
|
+
elementThemeStyles
|
|
926
|
+
);
|
|
927
|
+
return themeStyles + " " + customPropertyThemeStyles;
|
|
928
|
+
}
|
|
929
|
+
#getCustomPropertyThemeValues(themeValues) {
|
|
930
|
+
const entries = Object.entries(themeValues).flatMap(([key, value]) => {
|
|
931
|
+
const valueWithCustomPrefixes = this.#getPrefixedCustomPropertyValues(value);
|
|
932
|
+
return valueWithCustomPrefixes ? [[key, valueWithCustomPrefixes]] : [];
|
|
933
|
+
});
|
|
934
|
+
return Object.fromEntries(entries);
|
|
935
|
+
}
|
|
936
|
+
#getPrefixedCustomPropertyValues(themeValue) {
|
|
937
|
+
const variables = themeValue.match(CUSTOM_PROP_REGEX);
|
|
938
|
+
if (!variables) return null;
|
|
939
|
+
return themeValue.replace(CUSTOM_PROP_REGEX, (m) => {
|
|
940
|
+
const match = m.replace("(", "");
|
|
941
|
+
const tokenProperty3 = Tokenami2.TokenProperty.safeParse(match);
|
|
942
|
+
if (!tokenProperty3.success) return m;
|
|
943
|
+
const parts = Tokenami2.getTokenPropertySplit(tokenProperty3.output);
|
|
944
|
+
const isCustom = Boolean(this.config.customProperties?.[parts.alias]);
|
|
945
|
+
if (!isCustom) return m;
|
|
946
|
+
const tokenPrefix = Tokenami2.tokenProperty("");
|
|
947
|
+
const customPrefixTokenValue = tokenProperty3.output.replace(tokenPrefix, CUSTOM_PROP_PREFIX);
|
|
948
|
+
return "(" + customPrefixTokenValue;
|
|
949
|
+
});
|
|
950
|
+
}
|
|
951
|
+
#getElementThemeStyles(styleSelector, selector, themeValues) {
|
|
952
|
+
const splitGroups = selector.split(",");
|
|
953
|
+
const themeStyles = splitGroups.map((selector2) => {
|
|
954
|
+
const elemSelector = [styleSelector].flat().map((s) => `${selector2} ${s}`);
|
|
955
|
+
return `${selector2}, ${elemSelector} { ${stringify(themeValues)} }`;
|
|
956
|
+
});
|
|
957
|
+
return themeStyles.join(" ");
|
|
958
|
+
}
|
|
959
|
+
toString() {
|
|
960
|
+
return `
|
|
961
|
+
${this.#generateGlobalStyles()}
|
|
962
|
+
${this.#generateTokenamiResets()}
|
|
963
|
+
${this.#generatePlaceholderLayers(LAYERS.BASE)}
|
|
964
|
+
${this.#generatePlaceholderLayers(LAYERS.LOGICAL)}
|
|
965
|
+
${this.#generatePlaceholderLayers(LAYERS.SELECTORS)}
|
|
966
|
+
${this.#generatePlaceholderLayers(LAYERS.SELECTORS_LOGICAL)}
|
|
967
|
+
${this.#generatePlaceholderLayers(LAYERS.COMPONENTS)}
|
|
968
|
+
${this.#generateLayerStyles()}
|
|
969
|
+
`;
|
|
970
|
+
}
|
|
971
|
+
};
|
|
972
|
+
function parseComposeBlocks(composeBlocks, config) {
|
|
973
|
+
let parsedComposeBlocks = {};
|
|
974
|
+
const entries = Object.entries(composeBlocks);
|
|
975
|
+
for (const [selector, tokenamiProperties] of entries) {
|
|
976
|
+
const entries2 = Object.entries(tokenamiProperties);
|
|
977
|
+
const aliasProperties = Tokenami2.iterateAliasProperties(entries2, config);
|
|
978
|
+
let styles = {};
|
|
979
|
+
for (let [key, value, propertyConfig] of aliasProperties) {
|
|
980
|
+
const tokenProperty3 = key;
|
|
981
|
+
for (const cssProperty of propertyConfig.cssProperties) {
|
|
982
|
+
const longProperty = Tokenami2.createLonghandProperty(tokenProperty3, cssProperty);
|
|
983
|
+
const parsedProperty = Tokenami2.parseProperty(longProperty);
|
|
984
|
+
const calcToggle = Tokenami2.calcProperty(parsedProperty);
|
|
985
|
+
styles[parsedProperty] = value;
|
|
986
|
+
if (propertyConfig.isCalc) styles[calcToggle] = "/**/";
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
parsedComposeBlocks[selector] = styles;
|
|
990
|
+
}
|
|
991
|
+
return parsedComposeBlocks;
|
|
992
|
+
}
|
|
993
|
+
function getPropertySelectors(composeBlocks, prop, selectorConfig) {
|
|
994
|
+
let selectors = [];
|
|
995
|
+
const baseSelectors = getBaseSelectors(composeBlocks, prop.tokenProperty);
|
|
996
|
+
const elemSelector = selectorConfig.find(isElementSelector);
|
|
997
|
+
if (elemSelector) {
|
|
998
|
+
const parsedSelectors = getParsedSelectors(prop.selector, [elemSelector], baseSelectors);
|
|
999
|
+
selectors.push(...parsedSelectors.flat());
|
|
1000
|
+
} else {
|
|
1001
|
+
selectors.push(...baseSelectors);
|
|
1002
|
+
}
|
|
1003
|
+
const elementSelectors = unique(selectors).map((selector) => {
|
|
1004
|
+
return isPseudoElementSelector(selector) ? selector : selector.replace(/:[^ ]+$/, "");
|
|
1005
|
+
});
|
|
1006
|
+
return {
|
|
1007
|
+
all: getParsedSelectors(prop.selector, selectorConfig, baseSelectors),
|
|
1008
|
+
elements: elementSelectors
|
|
1009
|
+
};
|
|
1010
|
+
}
|
|
1011
|
+
function getBaseSelectors(composeBlocks, property) {
|
|
1012
|
+
const composeSelectors = Object.entries(composeBlocks).flatMap(([selector, styles]) => {
|
|
1013
|
+
return styles[property] !== void 0 ? [selector] : [];
|
|
1014
|
+
});
|
|
1015
|
+
return [DEFAULT_SELECTOR, ...composeSelectors];
|
|
1016
|
+
}
|
|
1017
|
+
function createBasePropertyValue(property, fallback) {
|
|
1018
|
+
return `var(${property}${fallback ? ", " + fallback : ""})`;
|
|
1019
|
+
}
|
|
1020
|
+
function createGridPropertyValue(property, fallback) {
|
|
1021
|
+
const hashGridProperty = hashVariantProperty("grid", property);
|
|
1022
|
+
const baseProperty = createBasePropertyValue(property, fallback);
|
|
1023
|
+
return `var(${hashGridProperty}, ${baseProperty})`;
|
|
1024
|
+
}
|
|
1025
|
+
function createVariantValue(cssProperty, prop, propertyConfigs) {
|
|
1026
|
+
const customPropertyFallback = `var(${Tokenami2.tokenProperty(cssProperty)})`;
|
|
1027
|
+
let variantValue = prop.isCustom ? customPropertyFallback : "revert-layer";
|
|
1028
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1029
|
+
for (const propertyConfig of propertyConfigs) {
|
|
1030
|
+
if (!propertyConfig.variant) continue;
|
|
1031
|
+
if (seen.has(propertyConfig.variant)) continue;
|
|
1032
|
+
const hashedProperty = hashVariantProperty(propertyConfig.variant, cssProperty);
|
|
1033
|
+
variantValue = `var(${hashedProperty}, ${variantValue})`;
|
|
1034
|
+
seen.add(propertyConfig.variant);
|
|
1035
|
+
}
|
|
1036
|
+
return variantValue;
|
|
1037
|
+
}
|
|
1038
|
+
function createGridToggleValue(property) {
|
|
1039
|
+
const gridProperty3 = Tokenami2.gridProperty();
|
|
1040
|
+
const gridToggleProperty = Tokenami2.calcProperty(property);
|
|
1041
|
+
return `var(${gridToggleProperty}) calc(var(${property}) * var(${gridProperty3}))`;
|
|
1042
|
+
}
|
|
1043
|
+
function createVariantToggleValue(toggleProperty, tokenProperty3) {
|
|
1044
|
+
const basePropertyValue = createBasePropertyValue(tokenProperty3);
|
|
1045
|
+
return `var(${toggleProperty}) ${basePropertyValue};`;
|
|
1046
|
+
}
|
|
1047
|
+
function createGridVariantToggleValue(toggleProperty, tokenProperty3) {
|
|
1048
|
+
const basePropertyValue = createGridPropertyValue(tokenProperty3);
|
|
1049
|
+
return `var(${toggleProperty}) ${basePropertyValue};`;
|
|
1050
|
+
}
|
|
1051
|
+
function getPropertyConfigs(tokenProperties, config) {
|
|
1052
|
+
let propertyConfigs = /* @__PURE__ */ new Map();
|
|
1053
|
+
for (const property of tokenProperties) {
|
|
1054
|
+
const parts = Tokenami2.getTokenPropertyParts(property, config);
|
|
1055
|
+
if (!parts) continue;
|
|
1056
|
+
const properties = Tokenami2.getCSSPropertiesForAlias(parts.alias, config.aliases);
|
|
1057
|
+
const responsiveOrder = parts.responsive ? 1 : 0;
|
|
1058
|
+
const selectorOrder = parts.selector ? 2 : 0;
|
|
1059
|
+
const order = responsiveOrder + selectorOrder;
|
|
1060
|
+
for (const cssProperty of properties) {
|
|
1061
|
+
const layerIndex = getPropertyLayerIndex(cssProperty, config);
|
|
1062
|
+
if (layerIndex === -1) continue;
|
|
1063
|
+
const longhandProperty = Tokenami2.createLonghandProperty(property, cssProperty);
|
|
1064
|
+
const tokenProperty3 = Tokenami2.parseProperty(longhandProperty);
|
|
1065
|
+
const currentConfigs = propertyConfigs.get(cssProperty) || [];
|
|
1066
|
+
const customConfig = config.customProperties?.[cssProperty];
|
|
1067
|
+
const propertyConfig = config.properties?.[cssProperty];
|
|
1068
|
+
const isLogical = supportedLogicalProperties.has(cssProperty);
|
|
1069
|
+
const isGrid = customConfig?.includes("grid") ?? propertyConfig?.includes("grid") ?? false;
|
|
1070
|
+
const isCustom = Boolean(customConfig);
|
|
1071
|
+
const layer = parts.variant ? `${isLogical ? LAYERS.SELECTORS_LOGICAL : LAYERS.SELECTORS}${layerIndex}` : `${isLogical ? LAYERS.LOGICAL : LAYERS.BASE}${layerIndex}`;
|
|
1072
|
+
const nextConfig = { ...parts, tokenProperty: tokenProperty3, order, layer, isCustom, isGrid };
|
|
1073
|
+
const sortedConfigs = [...currentConfigs, nextConfig].sort((a, b) => a.order - b.order);
|
|
1074
|
+
propertyConfigs.set(cssProperty, sortedConfigs);
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
return propertyConfigs;
|
|
1078
|
+
}
|
|
1079
|
+
var SHORTHAND_TO_LONGHAND_ENTRIES = Array.from(Tokenami2.mapShorthandToLonghands.entries());
|
|
1080
|
+
function getPropertyLayerIndex(cssProperty, config) {
|
|
1081
|
+
const validProperties = getValidProperties(config);
|
|
1082
|
+
const isSupported = validProperties.has(cssProperty);
|
|
1083
|
+
const initialDepth = isSupported ? 1 : -1;
|
|
1084
|
+
if (cssProperty === "all") return 0;
|
|
1085
|
+
return SHORTHAND_TO_LONGHAND_ENTRIES.reduce((depth, [shorthand, longhands]) => {
|
|
1086
|
+
const isLonghand = longhands.includes(cssProperty);
|
|
1087
|
+
return isLonghand ? depth + getPropertyLayerIndex(shorthand, config) : depth;
|
|
1088
|
+
}, initialDepth);
|
|
1089
|
+
}
|
|
1090
|
+
function hashVariantProperty(variant, property) {
|
|
1091
|
+
return `--_${Tokenami2.hash(variant + property)}`;
|
|
1092
|
+
}
|
|
1093
|
+
function isElementSelector(selector = "") {
|
|
1094
|
+
return isCombinatorSelector(selector) || isPseudoElementSelector(selector) || selector === "&";
|
|
1095
|
+
}
|
|
1096
|
+
function isCombinatorSelector(selector = "") {
|
|
1097
|
+
const ampersandIndex = selector.indexOf("&");
|
|
1098
|
+
return isChildSelector(selector) || ampersandIndex > 1 && selector[ampersandIndex - 1] === " ";
|
|
1099
|
+
}
|
|
1100
|
+
function isPseudoElementSelector(selector = "") {
|
|
1101
|
+
return /::/.test(selector);
|
|
1102
|
+
}
|
|
1103
|
+
function removePseudoElementSelector(selector = "") {
|
|
1104
|
+
return selector.replace(/::[a-z-]+$/, "");
|
|
1105
|
+
}
|
|
1106
|
+
function isChildSelector(selector = "") {
|
|
1107
|
+
const ampersandIndex = selector.indexOf("&");
|
|
1108
|
+
return ampersandIndex !== -1 && selector.length > ampersandIndex + 2 && selector[ampersandIndex + 1] === " ";
|
|
1109
|
+
}
|
|
1110
|
+
function getResponsiveSelectorFromConfig(responsiveSelector, tokenamiConfig) {
|
|
1111
|
+
return responsiveSelector && tokenamiConfig.responsive?.[responsiveSelector];
|
|
1112
|
+
}
|
|
1113
|
+
function getSelectorFromConfig(propertySelector, tokenamiConfig) {
|
|
1114
|
+
const arbitrarySelector = Tokenami2.getArbitrarySelector(propertySelector);
|
|
1115
|
+
const configSelector = propertySelector && tokenamiConfig.selectors?.[propertySelector];
|
|
1116
|
+
const selector = arbitrarySelector?.replace(/_/g, " ") || configSelector;
|
|
1117
|
+
return selector ? Array.isArray(selector) ? selector : [selector] : ["&"];
|
|
1118
|
+
}
|
|
1119
|
+
var disableRevertSelectors = ["&::selection", "&::-webkit-scrollbar"];
|
|
1120
|
+
function getParsedSelectors(propertySelector, selectorConfig, elementSelectors) {
|
|
1121
|
+
const selectors = [];
|
|
1122
|
+
const selectorString = selectorConfig.toString();
|
|
1123
|
+
if (selectorString.indexOf("&") === -1) {
|
|
1124
|
+
throw new Error(`Selector '${propertySelector}' must include '&'`);
|
|
1125
|
+
}
|
|
1126
|
+
const isRevertDisabled = disableRevertSelectors.some((s) => selectorString.includes(s));
|
|
1127
|
+
for (const elementSelector of elementSelectors) {
|
|
1128
|
+
const isRevertDisabledSelector = isRevertDisabled && elementSelector === DEFAULT_SELECTOR;
|
|
1129
|
+
const tkSelector = isRevertDisabledSelector ? `[style*="${propertySelector}_"]` : elementSelector;
|
|
1130
|
+
const selectorConfigs = expandSelectorConfigs(selectorConfig);
|
|
1131
|
+
for (const selectorConfig2 of selectorConfigs) {
|
|
1132
|
+
const selector = selectorConfig2.map((selector2) => selector2.replace(/&/g, tkSelector));
|
|
1133
|
+
selectors.push(selector);
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
return selectors;
|
|
1137
|
+
}
|
|
1138
|
+
function expandSelectorConfigs(selectorConfig) {
|
|
1139
|
+
const parts = selectorConfig.map(parseSelectorList);
|
|
1140
|
+
let results = [[]];
|
|
1141
|
+
for (const group of parts) {
|
|
1142
|
+
const res = [];
|
|
1143
|
+
for (const existing of results) {
|
|
1144
|
+
for (const value of group) {
|
|
1145
|
+
res.push([...existing, value]);
|
|
1146
|
+
}
|
|
1147
|
+
}
|
|
1148
|
+
results = res;
|
|
1149
|
+
}
|
|
1150
|
+
return results;
|
|
1151
|
+
}
|
|
1152
|
+
function parseSelectorList(selector) {
|
|
1153
|
+
const selectors = [];
|
|
1154
|
+
let currentSelector = "";
|
|
1155
|
+
let depth = 0;
|
|
1156
|
+
for (const [index, char] of selector.split("").entries()) {
|
|
1157
|
+
if (char === "(") depth++;
|
|
1158
|
+
if (char === "[") depth++;
|
|
1159
|
+
if (char === ")") depth--;
|
|
1160
|
+
if (char === "]") depth--;
|
|
1161
|
+
const nextChar = selector[index + 1];
|
|
1162
|
+
if (!nextChar) {
|
|
1163
|
+
currentSelector += char;
|
|
1164
|
+
selectors.push(currentSelector.trim());
|
|
1165
|
+
currentSelector = "";
|
|
1166
|
+
} else if (char === "," && depth === 0) {
|
|
1167
|
+
selectors.push(currentSelector.trim());
|
|
1168
|
+
currentSelector = "";
|
|
1169
|
+
} else {
|
|
1170
|
+
currentSelector += char;
|
|
1171
|
+
}
|
|
1172
|
+
}
|
|
1173
|
+
return selectors;
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1176
|
+
// src/core.ts
|
|
1177
|
+
var COMPOSE_BLOCKS_REGEX = /(const|let|var)\s+(.+)\s*=\s*css\.compose\(\{[\s\S]*?\}\)/gm;
|
|
1178
|
+
var CSS_VARIABLE_REGEX = /--(?:[\w-]+|\{[^\{\}]*\})+/g;
|
|
1179
|
+
var TokenStore = class {
|
|
1180
|
+
#config;
|
|
1181
|
+
#tokensByFile = /* @__PURE__ */ new Map();
|
|
1182
|
+
constructor(config) {
|
|
1183
|
+
this.#config = config;
|
|
1184
|
+
}
|
|
1185
|
+
updateConfig(config) {
|
|
1186
|
+
this.#config = config;
|
|
1187
|
+
}
|
|
1188
|
+
getConfig() {
|
|
1189
|
+
return this.#config;
|
|
1190
|
+
}
|
|
1191
|
+
updateFile(filePath, content) {
|
|
1192
|
+
this.#tokensByFile.set(filePath, scanFileContent(content, this.#config.theme));
|
|
1193
|
+
}
|
|
1194
|
+
removeFile(filePath) {
|
|
1195
|
+
this.#tokensByFile.delete(filePath);
|
|
1196
|
+
}
|
|
1197
|
+
hasFile(filePath) {
|
|
1198
|
+
return this.#tokensByFile.has(filePath);
|
|
1199
|
+
}
|
|
1200
|
+
clear() {
|
|
1201
|
+
this.#tokensByFile.clear();
|
|
1202
|
+
}
|
|
1203
|
+
getFileCount() {
|
|
1204
|
+
return this.#tokensByFile.size;
|
|
1205
|
+
}
|
|
1206
|
+
getTokens() {
|
|
1207
|
+
let properties = [];
|
|
1208
|
+
let values = [];
|
|
1209
|
+
let composeBlocks = {};
|
|
1210
|
+
for (const fileTokens of this.#tokensByFile.values()) {
|
|
1211
|
+
properties = [...properties, ...fileTokens.properties];
|
|
1212
|
+
values = [...values, ...fileTokens.values];
|
|
1213
|
+
composeBlocks = { ...composeBlocks, ...fileTokens.composeBlocks };
|
|
1214
|
+
}
|
|
1215
|
+
return { properties, values, composeBlocks };
|
|
1216
|
+
}
|
|
1217
|
+
};
|
|
1218
|
+
function scanFileContent(content, theme) {
|
|
1219
|
+
const tokens = matchTokens(content, theme);
|
|
1220
|
+
const composeBlocksContents = content.match(COMPOSE_BLOCKS_REGEX) ?? [];
|
|
1221
|
+
let composeBlocks = {};
|
|
1222
|
+
for (const composeBlock of composeBlocksContents) {
|
|
1223
|
+
try {
|
|
1224
|
+
const ast = acorn.parse(composeBlock, { ecmaVersion: "latest" });
|
|
1225
|
+
const composeBlockStyles = matchBaseComposeBlocks(ast);
|
|
1226
|
+
composeBlocks = { ...composeBlocks, ...composeBlockStyles };
|
|
1227
|
+
} catch {
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
if (content.includes(LAYERS.COMPONENTS)) {
|
|
1231
|
+
const sheetComposeBlocks = findSheetComposeBlocks(content);
|
|
1232
|
+
composeBlocks = { ...composeBlocks, ...sheetComposeBlocks };
|
|
1233
|
+
}
|
|
1234
|
+
return { properties: tokens.properties, values: tokens.values, composeBlocks };
|
|
1235
|
+
}
|
|
1236
|
+
async function findUsedTokens(cwd, config) {
|
|
1237
|
+
const include = config.include;
|
|
1238
|
+
const exclude = config.exclude;
|
|
1239
|
+
const entries = await glob(include, { cwd, onlyFiles: true, stats: false, ignore: exclude });
|
|
1240
|
+
const store = new TokenStore(config);
|
|
1241
|
+
entries.forEach((entry) => {
|
|
1242
|
+
const fileContent = fs.readFileSync(entry, "utf8");
|
|
1243
|
+
store.updateFile(entry, fileContent);
|
|
1244
|
+
});
|
|
1245
|
+
return store.getTokens();
|
|
1246
|
+
}
|
|
1247
|
+
function matchBaseComposeBlocks(ast) {
|
|
1248
|
+
const composeBlocks = findComposeBlocks(ast);
|
|
1249
|
+
let result = {};
|
|
1250
|
+
if (!composeBlocks) return result;
|
|
1251
|
+
for (const node of composeBlocks) {
|
|
1252
|
+
let styles;
|
|
1253
|
+
for (const tokenProperty3 of node.properties) {
|
|
1254
|
+
if (tokenProperty3.type === "Property" && tokenProperty3.key.type === "Literal") {
|
|
1255
|
+
let valueExpression = tokenProperty3.value;
|
|
1256
|
+
let value;
|
|
1257
|
+
if (valueExpression.type === "UnaryExpression" && valueExpression.operator === "-" && valueExpression.argument.type === "Literal" && valueExpression.argument.value) {
|
|
1258
|
+
value = -valueExpression.argument.value;
|
|
1259
|
+
} else if (valueExpression.type === "Literal") {
|
|
1260
|
+
value = valueExpression.value;
|
|
1261
|
+
} else {
|
|
1262
|
+
continue;
|
|
1263
|
+
}
|
|
1264
|
+
styles ??= {};
|
|
1265
|
+
styles[tokenProperty3.key.value] = value;
|
|
1266
|
+
}
|
|
1267
|
+
}
|
|
1268
|
+
if (styles) {
|
|
1269
|
+
const className = Tokenami2.generateClassName(styles);
|
|
1270
|
+
result[`.${className}`] = styles;
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
return result;
|
|
1274
|
+
}
|
|
1275
|
+
function matchTokens(content, theme) {
|
|
1276
|
+
const matches = content.match(CSS_VARIABLE_REGEX) || [];
|
|
1277
|
+
const stringMatches = Array.from(matches).map(Tokenami2.stringifyProperty);
|
|
1278
|
+
const uniqueMatches = unique(stringMatches);
|
|
1279
|
+
const variableMatches = uniqueMatches.filter((match) => match !== Tokenami2.gridProperty());
|
|
1280
|
+
const values = variableMatches.flatMap((match) => {
|
|
1281
|
+
const valueProperty = Tokenami2.TokenValue.safeParse(`var(${match})`);
|
|
1282
|
+
if (!valueProperty.success) return [];
|
|
1283
|
+
const themeValues = getThemeValuesByThemeMode(valueProperty.output, theme);
|
|
1284
|
+
return Object.entries(themeValues).length ? [valueProperty.output] : [];
|
|
1285
|
+
});
|
|
1286
|
+
const properties = variableMatches.flatMap((match) => {
|
|
1287
|
+
const tokenProperty3 = Tokenami2.TokenProperty.safeParse(match);
|
|
1288
|
+
const isValue = values.includes(`var(${match})`);
|
|
1289
|
+
if (isValue || !tokenProperty3.success) return [];
|
|
1290
|
+
return tokenProperty3.output;
|
|
1291
|
+
});
|
|
1292
|
+
return { properties, values };
|
|
1293
|
+
}
|
|
1294
|
+
function findComposeBlocks(node) {
|
|
1295
|
+
let result;
|
|
1296
|
+
acornWalk.simple(node, {
|
|
1297
|
+
CallExpression(node2) {
|
|
1298
|
+
if (node2.callee.type === "MemberExpression" && node2.callee.object.type === "Identifier" && node2.callee.object.name === "css" && node2.callee.property.type === "Identifier" && node2.callee.property.name === "compose" && node2.arguments?.[0]?.type === "ObjectExpression") {
|
|
1299
|
+
result ??= [];
|
|
1300
|
+
result.push(node2.arguments[0]);
|
|
1301
|
+
}
|
|
1302
|
+
}
|
|
1303
|
+
});
|
|
1304
|
+
return result;
|
|
1305
|
+
}
|
|
1306
|
+
function findSheetComposeBlocks(fileContents) {
|
|
1307
|
+
const ast = csstree.parse(fileContents);
|
|
1308
|
+
let stylesObject;
|
|
1309
|
+
csstree.walk(ast, {
|
|
1310
|
+
visit: "Atrule",
|
|
1311
|
+
enter(node) {
|
|
1312
|
+
if (node.name === "layer" && node.prelude && csstree.generate(node.prelude) === LAYERS.COMPONENTS) {
|
|
1313
|
+
csstree.walk(node, {
|
|
1314
|
+
visit: "Rule",
|
|
1315
|
+
enter(ruleNode) {
|
|
1316
|
+
if (!ruleNode.prelude || !ruleNode.block) return;
|
|
1317
|
+
const selector = csstree.generate(ruleNode.prelude).trim();
|
|
1318
|
+
let styles = {};
|
|
1319
|
+
csstree.walk(ruleNode.block, {
|
|
1320
|
+
visit: "Declaration",
|
|
1321
|
+
enter(declNode) {
|
|
1322
|
+
const escapedProperty = declNode.property.trim();
|
|
1323
|
+
const property = Tokenami2.stringifyProperty(escapedProperty);
|
|
1324
|
+
const value = csstree.generate(declNode.value).trim();
|
|
1325
|
+
styles[property] = value;
|
|
1326
|
+
}
|
|
1327
|
+
});
|
|
1328
|
+
stylesObject ??= {};
|
|
1329
|
+
stylesObject[selector] = styles;
|
|
1330
|
+
}
|
|
1331
|
+
});
|
|
1332
|
+
}
|
|
1333
|
+
}
|
|
1334
|
+
});
|
|
1335
|
+
return stylesObject;
|
|
1336
|
+
}
|
|
1337
|
+
|
|
1338
|
+
// src/ts-plugin/error-codes.ts
|
|
1339
|
+
var INVALID_PROPERTY = 2353;
|
|
1340
|
+
var INVALID_VALUE = 2322;
|
|
1341
|
+
var EXPECT_EXTRACTABLE_COMPOSE = 2790;
|
|
1342
|
+
|
|
1343
|
+
// src/ts-plugin/diagnostics.ts
|
|
1344
|
+
var TokenamiDiagnostics = class {
|
|
1345
|
+
#config;
|
|
1346
|
+
constructor(config, context = {}) {
|
|
1347
|
+
this.#config = config;
|
|
1348
|
+
context.logger?.log("Setting up diagnostics");
|
|
1349
|
+
}
|
|
1350
|
+
getSemanticDiagnostics(sourceFile) {
|
|
1351
|
+
let diagnostics = [];
|
|
1352
|
+
if (sourceFile) {
|
|
1353
|
+
const processNode = this.#processNode.bind(this);
|
|
1354
|
+
ts.forEachChild(sourceFile, function nextNode(node) {
|
|
1355
|
+
const nodeDiagnostics = processNode(node, sourceFile);
|
|
1356
|
+
if (nodeDiagnostics) diagnostics.push(...nodeDiagnostics);
|
|
1357
|
+
ts.forEachChild(node, nextNode);
|
|
1358
|
+
});
|
|
1359
|
+
}
|
|
1360
|
+
return diagnostics;
|
|
1361
|
+
}
|
|
1362
|
+
#processNode(node, sourceFile) {
|
|
1363
|
+
const isDiagnosticPrevented = this.#shouldSuppressDiagnosticForNode(node, sourceFile);
|
|
1364
|
+
if (isDiagnosticPrevented) return;
|
|
1365
|
+
if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression) && ts.isIdentifier(node.expression.expression) && node.expression.expression.text === "css" && node.expression.name.text === "compose" && node.arguments[0] && ts.isObjectLiteralExpression(node.arguments[0])) {
|
|
1366
|
+
return this.#validateComposeConfig(node.arguments[0], sourceFile);
|
|
1367
|
+
}
|
|
1368
|
+
if (ts.isPropertyAssignment(node)) {
|
|
1369
|
+
const nodeProperty = ts.isStringLiteral(node.name) ? node.name.text : null;
|
|
1370
|
+
const property = Tokenami2.TokenProperty.safeParse(nodeProperty);
|
|
1371
|
+
if (!property.success) return;
|
|
1372
|
+
return this.#validateTokenamiProperty(property.output, node, sourceFile);
|
|
1373
|
+
}
|
|
1374
|
+
}
|
|
1375
|
+
#validateTokenamiProperty(property, node, sourceFile) {
|
|
1376
|
+
const { variants } = Tokenami2.getTokenPropertySplit(property);
|
|
1377
|
+
const parts = Tokenami2.getTokenPropertyParts(property, this.#config);
|
|
1378
|
+
const isArbitrarySelector = variants.some(Tokenami2.getArbitrarySelector);
|
|
1379
|
+
if (!variants.length || parts || isArbitrarySelector) return;
|
|
1380
|
+
const selector = variants.join("_");
|
|
1381
|
+
const isEmptyArbSelector = variants.includes("{}");
|
|
1382
|
+
const arbSuffix = isEmptyArbSelector ? ` Add an arbitrary selector or remove '${selector}'.` : "";
|
|
1383
|
+
return [
|
|
1384
|
+
{
|
|
1385
|
+
file: sourceFile,
|
|
1386
|
+
start: node.getStart(sourceFile),
|
|
1387
|
+
length: node.name.getWidth(sourceFile),
|
|
1388
|
+
messageText: `Selector '${selector}' does not exist in the Tokenami config.${arbSuffix}`,
|
|
1389
|
+
category: ts.DiagnosticCategory.Error,
|
|
1390
|
+
code: INVALID_PROPERTY
|
|
1391
|
+
}
|
|
1392
|
+
];
|
|
1393
|
+
}
|
|
1394
|
+
#validateComposeConfig(config, sourceFile) {
|
|
1395
|
+
const diagnostic = {
|
|
1396
|
+
file: sourceFile,
|
|
1397
|
+
messageText: `Compose styles must be statically extractable. Use 'includes' to reuse shared styles.`,
|
|
1398
|
+
category: ts.DiagnosticCategory.Error,
|
|
1399
|
+
code: EXPECT_EXTRACTABLE_COMPOSE
|
|
1400
|
+
};
|
|
1401
|
+
for (const prop of config.properties) {
|
|
1402
|
+
if (ts.isSpreadAssignment(prop)) {
|
|
1403
|
+
const start = prop.getStart(sourceFile);
|
|
1404
|
+
const length = prop.getWidth(sourceFile);
|
|
1405
|
+
return [{ ...diagnostic, start, length }];
|
|
1406
|
+
}
|
|
1407
|
+
if (!ts.isPropertyAssignment(prop)) continue;
|
|
1408
|
+
const key = prop.name;
|
|
1409
|
+
const value = prop.initializer;
|
|
1410
|
+
if (ts.isComputedPropertyName(key)) {
|
|
1411
|
+
const start = key.getStart(sourceFile);
|
|
1412
|
+
const length = key.getWidth(sourceFile);
|
|
1413
|
+
return [{ ...diagnostic, start, length }];
|
|
1414
|
+
}
|
|
1415
|
+
if (ts.isObjectLiteralExpression(value)) {
|
|
1416
|
+
return this.#validateComposeConfig(value, sourceFile);
|
|
1417
|
+
} else if (value.getText(sourceFile).length > 0 && !ts.isIdentifier(key) && !ts.isStringLiteral(value) && !ts.isNumericLiteral(value) && !(ts.isPrefixUnaryExpression(value) && value.operator === ts.SyntaxKind.MinusToken && ts.isNumericLiteral(value.operand))) {
|
|
1418
|
+
const start = value.getStart(sourceFile);
|
|
1419
|
+
const length = value.getWidth(sourceFile);
|
|
1420
|
+
return [{ ...diagnostic, start, length }];
|
|
1421
|
+
}
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1424
|
+
#shouldSuppressDiagnosticForNode(node, sourceFile) {
|
|
1425
|
+
if (!sourceFile) return false;
|
|
1426
|
+
const lineStarts = sourceFile.getLineStarts();
|
|
1427
|
+
const nodeStartPos = node.getStart(sourceFile);
|
|
1428
|
+
const nodeStartLine = sourceFile.getLineAndCharacterOfPosition(nodeStartPos).line;
|
|
1429
|
+
if (nodeStartLine > 0) {
|
|
1430
|
+
const previousLineStartPos = lineStarts[nodeStartLine - 1] || 0;
|
|
1431
|
+
const previousLineEndPos = lineStarts[nodeStartLine] || 0;
|
|
1432
|
+
const previousLineText = sourceFile.text.substring(previousLineStartPos, previousLineEndPos);
|
|
1433
|
+
return /\/\/ @ts-ignore/.test(previousLineText);
|
|
1434
|
+
}
|
|
1435
|
+
return false;
|
|
1436
|
+
}
|
|
1437
|
+
};
|
|
1438
|
+
function isColorValue(value) {
|
|
1439
|
+
if (!value) return false;
|
|
1440
|
+
try {
|
|
1441
|
+
const isString = isNaN(Number(value));
|
|
1442
|
+
return isString ? Boolean(culori2.parse(replaceCssVarsWithFallback(value))) : false;
|
|
1443
|
+
} catch {
|
|
1444
|
+
return false;
|
|
1445
|
+
}
|
|
1446
|
+
}
|
|
1447
|
+
function isColorThemeEntry(modeValues) {
|
|
1448
|
+
const firstValue = Object.values(modeValues)?.[0];
|
|
1449
|
+
return isColorValue(firstValue);
|
|
1450
|
+
}
|
|
1451
|
+
function replaceCssVarsWithFallback(value) {
|
|
1452
|
+
const regex = /var\([\w-_]+,\s*([\w-_]+)\)/g;
|
|
1453
|
+
return value.replace(regex, (_, fallback) => fallback);
|
|
1454
|
+
}
|
|
1455
|
+
|
|
1456
|
+
// src/ts-plugin/logger.ts
|
|
1457
|
+
var LanguageServiceLogger = class {
|
|
1458
|
+
#info;
|
|
1459
|
+
constructor(info) {
|
|
1460
|
+
this.#info = info;
|
|
1461
|
+
}
|
|
1462
|
+
log(message) {
|
|
1463
|
+
this.#info.project.projectService.logger.info(`Tokenami:: ${message}`);
|
|
1464
|
+
}
|
|
1465
|
+
error(message) {
|
|
1466
|
+
this.#info.project.projectService.logger.info(`Tokenami:: ${message}`);
|
|
1467
|
+
}
|
|
1468
|
+
};
|
|
1469
|
+
var TokenamiCompletions = class {
|
|
1470
|
+
#ctx;
|
|
1471
|
+
#config;
|
|
1472
|
+
#selectorEntries;
|
|
1473
|
+
#responsiveEntries;
|
|
1474
|
+
#base;
|
|
1475
|
+
#selectorSnippets;
|
|
1476
|
+
// lazily instantiate and cache these
|
|
1477
|
+
#_responsiveSelectorSnippets;
|
|
1478
|
+
#_validProperties;
|
|
1479
|
+
#_colorThemeKeys;
|
|
1480
|
+
constructor(config, context) {
|
|
1481
|
+
this.#config = config;
|
|
1482
|
+
this.#ctx = { ...context, insertFormatter: context.insertFormatter ?? ((name) => name) };
|
|
1483
|
+
this.#_validProperties = Array.from(getValidProperties(this.#config));
|
|
1484
|
+
this.#_colorThemeKeys = this.#computeColorThemeKeys();
|
|
1485
|
+
this.#selectorEntries = Object.entries(this.#config.selectors || {});
|
|
1486
|
+
this.#responsiveEntries = Object.entries(this.#config.responsive || {});
|
|
1487
|
+
this.#base = this.#getBaseCompletions();
|
|
1488
|
+
this.#selectorSnippets = this.#getSelectorSnippetCompletions();
|
|
1489
|
+
}
|
|
1490
|
+
get #responsiveSelectorSnippets() {
|
|
1491
|
+
if (this.#_responsiveSelectorSnippets) return this.#_responsiveSelectorSnippets;
|
|
1492
|
+
const selectorConfig = this.#getSelectorConfigEntries();
|
|
1493
|
+
const completions = this.#getResponsiveSelectorSnippetCompletions(selectorConfig);
|
|
1494
|
+
this.#_responsiveSelectorSnippets = completions;
|
|
1495
|
+
return completions;
|
|
1496
|
+
}
|
|
1497
|
+
propertySearch(input) {
|
|
1498
|
+
const variantResults = this.variantSearch(input);
|
|
1499
|
+
if (input.includes("_")) return variantResults;
|
|
1500
|
+
return { ...this.#base, ...variantResults };
|
|
1501
|
+
}
|
|
1502
|
+
valueSearch(original) {
|
|
1503
|
+
const result = {};
|
|
1504
|
+
for (const [index, entry] of original.entries()) {
|
|
1505
|
+
const entryName = entry.name.replace(/['"]/g, "");
|
|
1506
|
+
const tokenValue2 = Tokenami2.TokenValue.safeParse(entryName);
|
|
1507
|
+
if (!tokenValue2.success) continue;
|
|
1508
|
+
const { themeKey, token } = Tokenami2.getTokenValueParts(tokenValue2.output);
|
|
1509
|
+
const name = `$${token}`;
|
|
1510
|
+
const isColor = this.#_colorThemeKeys.has(themeKey);
|
|
1511
|
+
result[name] = {
|
|
1512
|
+
name,
|
|
1513
|
+
kind: ts.ScriptElementKind.string,
|
|
1514
|
+
kindModifiers: isColor ? "color" : themeKey,
|
|
1515
|
+
sortText: this.#createSortText(`${index}${entryName}`),
|
|
1516
|
+
insertText: this.#ctx.insertFormatter(entryName, { type: "value" }),
|
|
1517
|
+
labelDetails: { detail: "", description: entryName },
|
|
1518
|
+
details: { themeKey, token }
|
|
1519
|
+
};
|
|
1520
|
+
}
|
|
1521
|
+
return result;
|
|
1522
|
+
}
|
|
1523
|
+
variantSearch(input) {
|
|
1524
|
+
const parts = Tokenami2.getTokenPropertySplit(input);
|
|
1525
|
+
if (!parts.variants.length) {
|
|
1526
|
+
return this.#selectorSnippets;
|
|
1527
|
+
}
|
|
1528
|
+
if (parts.variants.length === 1) {
|
|
1529
|
+
const search = this.#selectorsSearch(input, parts.alias, parts.variants);
|
|
1530
|
+
return Object.assign(search, this.#responsiveSelectorSnippets);
|
|
1531
|
+
}
|
|
1532
|
+
return this.#responsiveSelectorsSearch(input, parts.alias, parts.variants);
|
|
1533
|
+
}
|
|
1534
|
+
#arbitrarySelectorRegex = /\{(.*)\}/;
|
|
1535
|
+
#getArbitrarySelector(input) {
|
|
1536
|
+
return input.match(this.#arbitrarySelectorRegex)?.[1];
|
|
1537
|
+
}
|
|
1538
|
+
#selectorsSearch(input, alias, variants) {
|
|
1539
|
+
const arbSelector = this.#getArbitrarySelector(input);
|
|
1540
|
+
return this.#getSelectorCompletions(alias, variants, arbSelector);
|
|
1541
|
+
}
|
|
1542
|
+
#responsiveSelectorsSearch(input, alias, variants) {
|
|
1543
|
+
const arbSelector = this.#getArbitrarySelector(input);
|
|
1544
|
+
const selectorConfig = this.#getSelectorConfigEntries(variants, arbSelector);
|
|
1545
|
+
return this.#getResponsiveSelectorCompletions(alias, variants, selectorConfig);
|
|
1546
|
+
}
|
|
1547
|
+
#matchSearch(input, entryName) {
|
|
1548
|
+
const searchEntryName = entryName.replaceAll("-", "");
|
|
1549
|
+
const searchInput = input.replaceAll("-", "");
|
|
1550
|
+
if (searchEntryName.startsWith(searchInput)) return true;
|
|
1551
|
+
const index = searchEntryName.indexOf(searchInput);
|
|
1552
|
+
return index > 0 && entryName[index] === "-";
|
|
1553
|
+
}
|
|
1554
|
+
#createSortText(name) {
|
|
1555
|
+
const sortText = name.replace(/[0-9]+/g, (m) => m.padStart(6, "0")).replaceAll("-", "");
|
|
1556
|
+
return `$${sortText}`;
|
|
1557
|
+
}
|
|
1558
|
+
#getBaseCompletions() {
|
|
1559
|
+
const result = {};
|
|
1560
|
+
for (const property of this.#_validProperties) {
|
|
1561
|
+
const name = Tokenami2.tokenProperty(property);
|
|
1562
|
+
const entry = this.#createPropertyEntry(name, this.#createSortText(`$${name}`));
|
|
1563
|
+
result[entry.name] = entry;
|
|
1564
|
+
}
|
|
1565
|
+
return result;
|
|
1566
|
+
}
|
|
1567
|
+
#getSelectorCompletions(alias, variants, arbSelector) {
|
|
1568
|
+
const responsiveConfig = this.#getResponsiveConfigEntries(variants);
|
|
1569
|
+
const selectorConfig = this.#getSelectorConfigEntries(variants, arbSelector);
|
|
1570
|
+
const result = {};
|
|
1571
|
+
for (const property of this.#_validProperties) {
|
|
1572
|
+
if (!this.#matchSearch(alias, property)) continue;
|
|
1573
|
+
const create = this.#createVariantPropertyEntry(property);
|
|
1574
|
+
for (const [selector, value] of selectorConfig) {
|
|
1575
|
+
const entry = create([selector, value]);
|
|
1576
|
+
result[entry.name] = entry;
|
|
1577
|
+
}
|
|
1578
|
+
for (const [selector, value] of responsiveConfig) {
|
|
1579
|
+
const entry = create([selector, value]);
|
|
1580
|
+
result[entry.name] = entry;
|
|
1581
|
+
}
|
|
1582
|
+
}
|
|
1583
|
+
return result;
|
|
1584
|
+
}
|
|
1585
|
+
#getResponsiveSelectorCompletions(alias, variants, selectorConfig) {
|
|
1586
|
+
const responsiveSelectors = this.#getResponsiveSelectorConfigEntries(selectorConfig, variants);
|
|
1587
|
+
const result = {};
|
|
1588
|
+
for (const property of this.#_validProperties) {
|
|
1589
|
+
if (!this.#matchSearch(alias, property)) continue;
|
|
1590
|
+
const create = this.#createVariantPropertyEntry(property);
|
|
1591
|
+
for (const [selector, value] of responsiveSelectors) {
|
|
1592
|
+
const entry = create([selector, value]);
|
|
1593
|
+
result[entry.name] = entry;
|
|
1594
|
+
}
|
|
1595
|
+
}
|
|
1596
|
+
return result;
|
|
1597
|
+
}
|
|
1598
|
+
#getSelectorSnippetCompletions() {
|
|
1599
|
+
const responsiveConfig = this.#getResponsiveConfigEntries();
|
|
1600
|
+
const selectorConfig = this.#getSelectorConfigEntries();
|
|
1601
|
+
const create = this.#createVariantPropertyEntry(null);
|
|
1602
|
+
const result = {};
|
|
1603
|
+
for (const [selector, value] of selectorConfig) {
|
|
1604
|
+
const entry = create([selector, value]);
|
|
1605
|
+
result[entry.name] = entry;
|
|
1606
|
+
}
|
|
1607
|
+
for (const [selector, value] of responsiveConfig) {
|
|
1608
|
+
const entry = create([selector, value]);
|
|
1609
|
+
result[entry.name] = entry;
|
|
1610
|
+
}
|
|
1611
|
+
return result;
|
|
1612
|
+
}
|
|
1613
|
+
#getResponsiveSelectorSnippetCompletions(selectorConfig) {
|
|
1614
|
+
const entries = this.#getResponsiveSelectorConfigEntries(selectorConfig);
|
|
1615
|
+
const create = this.#createVariantPropertyEntry(null);
|
|
1616
|
+
const result = {};
|
|
1617
|
+
for (const [selector, value] of entries) {
|
|
1618
|
+
const entry = create([selector, value]);
|
|
1619
|
+
result[entry.name] = entry;
|
|
1620
|
+
}
|
|
1621
|
+
return result;
|
|
1622
|
+
}
|
|
1623
|
+
#computeColorThemeKeys() {
|
|
1624
|
+
const colorKeys = /* @__PURE__ */ new Set();
|
|
1625
|
+
const theme = getThemeFromConfig(this.#config.theme);
|
|
1626
|
+
const themeModes = [theme.root, ...Object.values(theme.modes)];
|
|
1627
|
+
for (const theme2 of themeModes) {
|
|
1628
|
+
for (const [themeKey, values] of Object.entries(theme2)) {
|
|
1629
|
+
if (colorKeys.has(themeKey)) continue;
|
|
1630
|
+
const firstValue = Object.values(values)[0];
|
|
1631
|
+
if (typeof firstValue === "string" && isColorValue(firstValue)) {
|
|
1632
|
+
colorKeys.add(themeKey);
|
|
1633
|
+
}
|
|
1634
|
+
}
|
|
1635
|
+
}
|
|
1636
|
+
return colorKeys;
|
|
1637
|
+
}
|
|
1638
|
+
#getSelectorConfigEntries(variants, arbSelector = "") {
|
|
1639
|
+
const selectorConfig = this.#selectorEntries.concat([[`{${arbSelector}}`, ""]]);
|
|
1640
|
+
if (!variants) return selectorConfig;
|
|
1641
|
+
const variantSet = new Set(variants);
|
|
1642
|
+
return selectorConfig.filter(([k]) => variantSet.has(k));
|
|
1643
|
+
}
|
|
1644
|
+
#getResponsiveConfigEntries(variants) {
|
|
1645
|
+
if (!variants) return this.#responsiveEntries;
|
|
1646
|
+
const variantSet = new Set(variants);
|
|
1647
|
+
return this.#responsiveEntries.filter(([k]) => variantSet.has(k));
|
|
1648
|
+
}
|
|
1649
|
+
#getResponsiveSelectorConfigEntries(selectorConfig, variants) {
|
|
1650
|
+
const responsiveConfig = this.#getResponsiveConfigEntries(variants);
|
|
1651
|
+
const result = [];
|
|
1652
|
+
for (const [responsiveSelector, responsiveValue] of responsiveConfig) {
|
|
1653
|
+
for (const [selector, value] of selectorConfig) {
|
|
1654
|
+
result.push([`${responsiveSelector}_${selector}`, [responsiveValue].concat(value)]);
|
|
1655
|
+
}
|
|
1656
|
+
}
|
|
1657
|
+
return result;
|
|
1658
|
+
}
|
|
1659
|
+
#createVariantPropertyEntry(property) {
|
|
1660
|
+
return ([selectorName, selector]) => {
|
|
1661
|
+
const name = Tokenami2.variantProperty(selectorName, property ?? "");
|
|
1662
|
+
const isArbitrary = name.includes("{}");
|
|
1663
|
+
const propertyEntry = isArbitrary ? this.#createAribitraryPropertyEntry(name) : this.#createPropertyEntry(name);
|
|
1664
|
+
return { ...propertyEntry, details: { selector } };
|
|
1665
|
+
};
|
|
1666
|
+
}
|
|
1667
|
+
#createAribitraryPropertyEntry(name, sortText = this.#createSortText(name)) {
|
|
1668
|
+
const entry = this.#createPropertyEntry(name, sortText);
|
|
1669
|
+
const insertText = entry.name.replace("{}", "{${1}}");
|
|
1670
|
+
return { ...entry, insertText, isSnippet: true };
|
|
1671
|
+
}
|
|
1672
|
+
#createPropertyEntry(name, sortText = this.#createSortText(name)) {
|
|
1673
|
+
const kind = ts.ScriptElementKind.memberVariableElement;
|
|
1674
|
+
const kindModifiers = ts.ScriptElementKindModifier.optionalModifier;
|
|
1675
|
+
const isSelector = name.slice(-1) === "_";
|
|
1676
|
+
const filterText = isSelector ? name.slice(0, -1) : name;
|
|
1677
|
+
const insertText = this.#ctx.insertFormatter(name, { type: "property" });
|
|
1678
|
+
const isSnippet = insertText.includes("${");
|
|
1679
|
+
return {
|
|
1680
|
+
name,
|
|
1681
|
+
filterText,
|
|
1682
|
+
kind,
|
|
1683
|
+
kindModifiers,
|
|
1684
|
+
sortText,
|
|
1685
|
+
insertText,
|
|
1686
|
+
...isSnippet && { isSnippet }
|
|
1687
|
+
};
|
|
1688
|
+
}
|
|
1689
|
+
};
|
|
1690
|
+
|
|
1691
|
+
// src/ts-plugin/plugin.ts
|
|
1692
|
+
var createTSPlugin = (mod) => ({
|
|
1693
|
+
create(info) {
|
|
1694
|
+
const logger = new LanguageServiceLogger(info);
|
|
1695
|
+
const cwd = info.project.getCurrentDirectory();
|
|
1696
|
+
const configPath = getConfigPath(cwd, info.config.configPath);
|
|
1697
|
+
const configExists = mod.typescript.sys.fileExists(configPath);
|
|
1698
|
+
if (!configExists) {
|
|
1699
|
+
logger.log(`Config not found at ${configPath}`);
|
|
1700
|
+
return info.languageService;
|
|
1701
|
+
}
|
|
1702
|
+
const ctx = { ts: mod.typescript, info, logger };
|
|
1703
|
+
const plugin = new TokenamiPlugin(configPath, ctx);
|
|
1704
|
+
return createServiceProxy(info.languageService, plugin);
|
|
1705
|
+
}
|
|
1706
|
+
});
|
|
1707
|
+
var TokenamiPlugin = class {
|
|
1708
|
+
#diagnostics;
|
|
1709
|
+
#config;
|
|
1710
|
+
#ctx;
|
|
1711
|
+
#completions;
|
|
1712
|
+
#quotedCompletions;
|
|
1713
|
+
#completionsForPosition = null;
|
|
1714
|
+
constructor(configPath, context) {
|
|
1715
|
+
this.#config = getConfigAtPath(configPath);
|
|
1716
|
+
this.#diagnostics = new TokenamiDiagnostics(this.#config, context);
|
|
1717
|
+
this.#completions = new TokenamiCompletions(this.#config, context);
|
|
1718
|
+
this.#ctx = context;
|
|
1719
|
+
this.#quotedCompletions = new TokenamiCompletions(this.#config, {
|
|
1720
|
+
insertFormatter: quotedInsertFormatter,
|
|
1721
|
+
logger: context.logger
|
|
1722
|
+
});
|
|
1723
|
+
this.#watchConfig(configPath);
|
|
1724
|
+
context.logger.log(`Watching config at ${configPath}`);
|
|
1725
|
+
try {
|
|
1726
|
+
updateEnvFile(configPath);
|
|
1727
|
+
} catch (e) {
|
|
1728
|
+
context.logger.error(`Error updating typedefs: ${e}`);
|
|
1729
|
+
}
|
|
1730
|
+
}
|
|
1731
|
+
#watchConfig(configPath) {
|
|
1732
|
+
this.#ctx.ts.sys.watchFile?.(configPath, (_fileName, eventKind) => {
|
|
1733
|
+
if (eventKind !== this.#ctx.ts.FileWatcherEventKind.Changed) return;
|
|
1734
|
+
try {
|
|
1735
|
+
const reloadedConfig = getConfigAtPath(configPath, { cache: false });
|
|
1736
|
+
updateEnvFile(configPath);
|
|
1737
|
+
this.#ctx.logger.log(`Config changed at ${configPath}}`);
|
|
1738
|
+
this.#completions = new TokenamiCompletions(reloadedConfig, this.#ctx);
|
|
1739
|
+
this.#quotedCompletions = new TokenamiCompletions(reloadedConfig, {
|
|
1740
|
+
insertFormatter: quotedInsertFormatter,
|
|
1741
|
+
logger: this.#ctx.logger
|
|
1742
|
+
});
|
|
1743
|
+
this.#diagnostics = new TokenamiDiagnostics(reloadedConfig, this.#ctx);
|
|
1744
|
+
this.#ctx.info.project.refreshDiagnostics();
|
|
1745
|
+
this.#config = reloadedConfig;
|
|
1746
|
+
} catch (e) {
|
|
1747
|
+
this.#ctx.logger.error(`Error processing config at ${configPath}: ${e}`);
|
|
1748
|
+
}
|
|
1749
|
+
});
|
|
1750
|
+
this.#ctx.logger.log(`Watching config at ${configPath}`);
|
|
1751
|
+
}
|
|
1752
|
+
getSemanticDiagnostics(fileName) {
|
|
1753
|
+
const original = this.#ctx.info.languageService.getSemanticDiagnostics(fileName);
|
|
1754
|
+
const sourceFile = this.#ctx.info.languageService.getProgram()?.getSourceFile(fileName);
|
|
1755
|
+
if (!sourceFile) return original;
|
|
1756
|
+
return [...this.#diagnostics.getSemanticDiagnostics(sourceFile), ...original];
|
|
1757
|
+
}
|
|
1758
|
+
getCompletionsAtPosition(fileName, position, options) {
|
|
1759
|
+
const languageService = this.#ctx.info.languageService;
|
|
1760
|
+
const original = () => languageService.getCompletionsAtPosition(fileName, position, options);
|
|
1761
|
+
const program = languageService.getProgram();
|
|
1762
|
+
const sourceFile = program?.getSourceFile(fileName);
|
|
1763
|
+
if (!sourceFile) return original();
|
|
1764
|
+
const node = findNodeAtPosition(sourceFile, position);
|
|
1765
|
+
if (!node) return original();
|
|
1766
|
+
const input = this.#parseTokenamiCompletionsInput(node, fileName, position);
|
|
1767
|
+
if (!input) return original();
|
|
1768
|
+
const rawInput = removeQuotes(input.value);
|
|
1769
|
+
const hasQuotes = input.value.startsWith('"') || input.value.startsWith("'");
|
|
1770
|
+
const completions = hasQuotes ? this.#completions : this.#quotedCompletions;
|
|
1771
|
+
if (input.isTokenamiProperty) {
|
|
1772
|
+
const results = completions.propertySearch(rawInput);
|
|
1773
|
+
this.#completionsForPosition = results;
|
|
1774
|
+
return {
|
|
1775
|
+
entries: Object.values(results),
|
|
1776
|
+
isGlobalCompletion: false,
|
|
1777
|
+
isMemberCompletion: false,
|
|
1778
|
+
isNewIdentifierLocation: false,
|
|
1779
|
+
optionalReplacementSpan: {
|
|
1780
|
+
start: position - rawInput.length,
|
|
1781
|
+
length: rawInput.length
|
|
1782
|
+
}
|
|
1783
|
+
};
|
|
1784
|
+
} else {
|
|
1785
|
+
const result = original();
|
|
1786
|
+
const results = completions.valueSearch(result?.entries ?? []);
|
|
1787
|
+
if (Object.keys(results).length === 0) {
|
|
1788
|
+
this.#completionsForPosition = null;
|
|
1789
|
+
return result;
|
|
1790
|
+
}
|
|
1791
|
+
this.#completionsForPosition = results;
|
|
1792
|
+
return {
|
|
1793
|
+
entries: Object.values(results),
|
|
1794
|
+
isGlobalCompletion: false,
|
|
1795
|
+
isMemberCompletion: false,
|
|
1796
|
+
isNewIdentifierLocation: false,
|
|
1797
|
+
optionalReplacementSpan: {
|
|
1798
|
+
start: position - rawInput.length,
|
|
1799
|
+
length: rawInput.length
|
|
1800
|
+
}
|
|
1801
|
+
};
|
|
1802
|
+
}
|
|
1803
|
+
}
|
|
1804
|
+
getCompletionEntryDetails(fileName, position, entryName, formatOptions, source, preferences, data) {
|
|
1805
|
+
const original = this.#ctx.info.languageService.getCompletionEntryDetails(
|
|
1806
|
+
fileName,
|
|
1807
|
+
position,
|
|
1808
|
+
entryName,
|
|
1809
|
+
formatOptions,
|
|
1810
|
+
source,
|
|
1811
|
+
preferences,
|
|
1812
|
+
data
|
|
1813
|
+
);
|
|
1814
|
+
const entry = this.#completionsForPosition?.[entryName];
|
|
1815
|
+
if (!entry) return original;
|
|
1816
|
+
const selector = entry.details?.selector;
|
|
1817
|
+
if (selector) return createEntryDetails(original, entry, selector);
|
|
1818
|
+
const themeKey = entry.details?.themeKey;
|
|
1819
|
+
const token = entry.details?.token;
|
|
1820
|
+
if (!themeKey || !token) return original;
|
|
1821
|
+
const tokenValue2 = Tokenami2.tokenValue(themeKey, token);
|
|
1822
|
+
const modeValues = getThemeValuesByThemeMode(tokenValue2, this.#config.theme);
|
|
1823
|
+
const themeEntries = Object.entries(modeValues);
|
|
1824
|
+
const [mode, firstValue] = themeEntries[0] || [];
|
|
1825
|
+
if (!firstValue) return original;
|
|
1826
|
+
if (isColorValue(firstValue)) {
|
|
1827
|
+
const colorDescription = createColorTokenDescription(modeValues);
|
|
1828
|
+
const rgb2 = convertToRgb(replaceCssVarsWithFallback(firstValue), mode);
|
|
1829
|
+
return createEntryDetails(original, entry, `${rgb2}
|
|
1830
|
+
|
|
1831
|
+
${colorDescription}`);
|
|
1832
|
+
} else {
|
|
1833
|
+
const description = createTokenDescription(modeValues);
|
|
1834
|
+
return createEntryDetails(original, entry, description);
|
|
1835
|
+
}
|
|
1836
|
+
}
|
|
1837
|
+
getQuickInfoAtPosition(fileName, position) {
|
|
1838
|
+
const original = this.#ctx.info.languageService.getQuickInfoAtPosition(fileName, position);
|
|
1839
|
+
const sourceFile = this.#ctx.info.languageService.getProgram()?.getSourceFile(fileName);
|
|
1840
|
+
if (!original || !sourceFile) return;
|
|
1841
|
+
const node = findNodeAtPosition(sourceFile, position);
|
|
1842
|
+
if (!node || !node.parent || !ts.isPropertyAssignment(node.parent)) return original;
|
|
1843
|
+
const property = node.parent;
|
|
1844
|
+
const propertyName = property.name.getText(sourceFile);
|
|
1845
|
+
const propertyValue = property.initializer.getText();
|
|
1846
|
+
const tokenProperty3 = Tokenami2.TokenProperty.safeParse(propertyName);
|
|
1847
|
+
const tokenValue2 = Tokenami2.TokenValue.safeParse(propertyValue);
|
|
1848
|
+
if (!tokenProperty3.success || !tokenValue2.success) return original;
|
|
1849
|
+
const { variants } = Tokenami2.getTokenPropertySplit(tokenProperty3.output);
|
|
1850
|
+
const propertyParts = Tokenami2.getTokenPropertyParts(tokenProperty3.output, this.#config);
|
|
1851
|
+
if (!propertyParts && variants.length) return;
|
|
1852
|
+
const modeValues = getThemeValuesByThemeMode(tokenValue2.output, this.#config.theme);
|
|
1853
|
+
const text = isColorThemeEntry(modeValues) ? createColorTokenDescription(modeValues) : createTokenDescription(modeValues);
|
|
1854
|
+
return { ...original, documentation: [{ text, kind: "markdown" }] };
|
|
1855
|
+
}
|
|
1856
|
+
getCodeFixesAtPosition(fileName, start, end, errorCodes, formatOptions, preferences) {
|
|
1857
|
+
const original = this.#ctx.info.languageService.getCodeFixesAtPosition(
|
|
1858
|
+
fileName,
|
|
1859
|
+
start,
|
|
1860
|
+
end,
|
|
1861
|
+
errorCodes,
|
|
1862
|
+
formatOptions,
|
|
1863
|
+
preferences
|
|
1864
|
+
);
|
|
1865
|
+
const sourceFile = this.#ctx.info.languageService.getProgram()?.getSourceFile(fileName);
|
|
1866
|
+
if (!sourceFile || !errorCodes.includes(INVALID_VALUE)) return original;
|
|
1867
|
+
const node = findNodeAtPosition(sourceFile, start);
|
|
1868
|
+
if (!node?.parent || !ts.isPropertyAssignment(node.parent)) return original;
|
|
1869
|
+
const assignment = node.parent;
|
|
1870
|
+
const valueSpan = createTextSpanFromNode(assignment.initializer);
|
|
1871
|
+
const value = ts.isStringLiteral(assignment.initializer) && assignment.initializer.text;
|
|
1872
|
+
if (!value) return original;
|
|
1873
|
+
const quoteMark = assignment.initializer.getText().slice(-1);
|
|
1874
|
+
const arbitraryValue2 = Tokenami2.arbitraryValue(value);
|
|
1875
|
+
const arbitraryText = `${quoteMark}${arbitraryValue2}${quoteMark}`;
|
|
1876
|
+
return [
|
|
1877
|
+
{
|
|
1878
|
+
description: `Use ${arbitraryText} to mark as arbitrary`,
|
|
1879
|
+
fixName: "replaceWithArbitrary",
|
|
1880
|
+
changes: [{ fileName, textChanges: [{ span: valueSpan, newText: arbitraryText }] }]
|
|
1881
|
+
}
|
|
1882
|
+
];
|
|
1883
|
+
}
|
|
1884
|
+
#parseTokenamiCompletionsInput(node, fileName, position) {
|
|
1885
|
+
const objLit = ts.findAncestor(node, ts.isObjectLiteralExpression);
|
|
1886
|
+
if (!objLit) {
|
|
1887
|
+
if (!ts.isStringLiteral(node)) return null;
|
|
1888
|
+
if (!this.#isTokenValueContext(node)) return null;
|
|
1889
|
+
return { isTokenamiProperty: false, value: node.getText() };
|
|
1890
|
+
}
|
|
1891
|
+
const prop = objLit.properties.find((p) => p.getStart() <= position && position <= p.getEnd());
|
|
1892
|
+
if (!prop) return null;
|
|
1893
|
+
const isTokenamiObj = this.#isTokenamiObject(objLit, fileName);
|
|
1894
|
+
if (!ts.isPropertyAssignment(prop)) {
|
|
1895
|
+
return isTokenamiObj ? { isTokenamiProperty: true, value: prop.getText() } : null;
|
|
1896
|
+
}
|
|
1897
|
+
const keyLength = prop.name.getText().length;
|
|
1898
|
+
const isOnProperty = position - prop.getStart() < keyLength;
|
|
1899
|
+
if (isTokenamiObj) {
|
|
1900
|
+
const value = isOnProperty ? prop.name.getText() : prop.initializer.getText();
|
|
1901
|
+
return { isTokenamiProperty: isOnProperty, value };
|
|
1902
|
+
}
|
|
1903
|
+
if (isOnProperty) return null;
|
|
1904
|
+
if (!this.#isTokenValueContext(prop.initializer)) return null;
|
|
1905
|
+
return { isTokenamiProperty: false, value: prop.initializer.getText() };
|
|
1906
|
+
}
|
|
1907
|
+
#isTokenValueContext(node) {
|
|
1908
|
+
const checker = this.#ctx.info.languageService.getProgram()?.getTypeChecker();
|
|
1909
|
+
const contextualType = checker?.getContextualType(node);
|
|
1910
|
+
if (!contextualType) return false;
|
|
1911
|
+
return this.#hasTokenValueType(contextualType);
|
|
1912
|
+
}
|
|
1913
|
+
#hasTokenValueType(type) {
|
|
1914
|
+
if (type.isStringLiteral()) {
|
|
1915
|
+
return Tokenami2.TokenValue.safeParse(type.value).success;
|
|
1916
|
+
}
|
|
1917
|
+
if (type.isUnion()) {
|
|
1918
|
+
return type.types.some((t) => this.#hasTokenValueType(t));
|
|
1919
|
+
}
|
|
1920
|
+
return false;
|
|
1921
|
+
}
|
|
1922
|
+
#isTokenamiObjectCache = Tokenami2.createLRUCache();
|
|
1923
|
+
#isTokenamiObject(objLit, fileName) {
|
|
1924
|
+
const sourceFile = this.#ctx.info.languageService.getProgram()?.getSourceFile(fileName);
|
|
1925
|
+
if (!sourceFile) return false;
|
|
1926
|
+
const startPos = objLit.getStart(sourceFile);
|
|
1927
|
+
const textBeforeBrace = sourceFile.text.substring(Math.max(0, startPos - 10), startPos);
|
|
1928
|
+
const cacheKey = `${fileName}:${objLit.pos}:${textBeforeBrace}`;
|
|
1929
|
+
if (this.#isTokenamiObjectCache.get(cacheKey)) return true;
|
|
1930
|
+
const checker = this.#ctx.info.languageService.getProgram()?.getTypeChecker();
|
|
1931
|
+
const contextual = checker?.getContextualType(objLit);
|
|
1932
|
+
if (!contextual) return false;
|
|
1933
|
+
const isTokenami = this.#hasTokenamiType(contextual);
|
|
1934
|
+
if (isTokenami) this.#isTokenamiObjectCache.set(cacheKey, true);
|
|
1935
|
+
return isTokenami;
|
|
1936
|
+
}
|
|
1937
|
+
#hasTokenamiType(type) {
|
|
1938
|
+
const symbol = type.getSymbol();
|
|
1939
|
+
const aliasSymbol = type.aliasSymbol;
|
|
1940
|
+
const name = symbol?.getName() || aliasSymbol?.getName();
|
|
1941
|
+
if (name?.startsWith("Tokenami")) return true;
|
|
1942
|
+
if (type.isUnion() || type.isIntersection()) {
|
|
1943
|
+
return type.types.some((t) => this.#hasTokenamiType(t));
|
|
1944
|
+
}
|
|
1945
|
+
return false;
|
|
1946
|
+
}
|
|
1947
|
+
};
|
|
1948
|
+
function updateEnvFile(configPath) {
|
|
1949
|
+
const envFilePath = getTypeDefsPath(configPath);
|
|
1950
|
+
const envFileContent = ts.sys.readFile(envFilePath, "utf-8");
|
|
1951
|
+
if (!envFileContent) throw new Error("Cannot read tokenami.env.d.ts file");
|
|
1952
|
+
const updatedEnvFileContent = generateTypeDefs(configPath, "../stubs/tokenami.env.d.ts");
|
|
1953
|
+
ts.sys.writeFile(envFilePath, updatedEnvFileContent);
|
|
1954
|
+
}
|
|
1955
|
+
function quotedInsertFormatter(name, options) {
|
|
1956
|
+
if (options?.type === "value") return `"${name}"`;
|
|
1957
|
+
if (name.slice(-1) === "_") return `"${name}\${1}": \${2}`;
|
|
1958
|
+
return `"${name}": \${1}`;
|
|
1959
|
+
}
|
|
1960
|
+
function findNodeAtPosition(sourceFile, position) {
|
|
1961
|
+
function find(node) {
|
|
1962
|
+
if (position >= node.getStart(sourceFile) && position < node.getEnd()) {
|
|
1963
|
+
return ts.forEachChild(node, find) || node;
|
|
1964
|
+
}
|
|
1965
|
+
}
|
|
1966
|
+
return find(sourceFile);
|
|
1967
|
+
}
|
|
1968
|
+
function createTextSpanFromNode(node) {
|
|
1969
|
+
return { start: node.getStart(), length: node.getEnd() - node.getStart() };
|
|
1970
|
+
}
|
|
1971
|
+
var createEntryDetails = (original, entryConfig, documentation) => ({
|
|
1972
|
+
...original,
|
|
1973
|
+
...entryConfig,
|
|
1974
|
+
displayParts: original?.displayParts || [],
|
|
1975
|
+
documentation: [{ text: documentation, kind: "markdown" }, ...original?.documentation ?? []]
|
|
1976
|
+
});
|
|
1977
|
+
function removeQuotes(name) {
|
|
1978
|
+
return name.replace(/'|"/g, "");
|
|
1979
|
+
}
|
|
1980
|
+
function createColorTokenDescription(modeValues) {
|
|
1981
|
+
const entries = Object.entries(modeValues);
|
|
1982
|
+
const rows = entries.map(([mode, value]) => {
|
|
1983
|
+
const swatch = createSquare(value, mode);
|
|
1984
|
+
return `${swatch} ${mode} ${value}`;
|
|
1985
|
+
});
|
|
1986
|
+
return rows.join("\n\n");
|
|
1987
|
+
}
|
|
1988
|
+
function createTokenDescription(modeValues) {
|
|
1989
|
+
const entries = Object.entries(modeValues);
|
|
1990
|
+
return entries.map(([mode, value]) => `${mode} ${value}`).join("\n\n");
|
|
1991
|
+
}
|
|
1992
|
+
function createSquare(color2, mode) {
|
|
1993
|
+
const fill = convertToRgb(replaceCssVarsWithFallback(color2), mode);
|
|
1994
|
+
const svg = `<svg width="10" height="10" xmlns="http://www.w3.org/2000/svg"><rect width="10" height="10" x="0" y="0" fill="${fill}" /></svg>`;
|
|
1995
|
+
return `})`;
|
|
1996
|
+
}
|
|
1997
|
+
function convertToRgb(fill, mode) {
|
|
1998
|
+
try {
|
|
1999
|
+
const parsed = culori2.parse(fill);
|
|
2000
|
+
const color2 = culori2.rgb(parsed);
|
|
2001
|
+
const modeColor = culori2.rgb(mode == "dark" ? "#000" : "#fff");
|
|
2002
|
+
const bgColor = fill === "transparent" ? void 0 : modeColor;
|
|
2003
|
+
if (!color2) return fill;
|
|
2004
|
+
if (!bgColor || parsed?.alpha === void 0 || parsed.alpha === 1) {
|
|
2005
|
+
return culori2.formatRgb(color2);
|
|
2006
|
+
}
|
|
2007
|
+
const alpha = parsed.alpha;
|
|
2008
|
+
color2.r = color2.r * alpha + bgColor.r * (1 - alpha);
|
|
2009
|
+
color2.g = color2.g * alpha + bgColor.g * (1 - alpha);
|
|
2010
|
+
color2.b = color2.b * alpha + bgColor.b * (1 - alpha);
|
|
2011
|
+
color2.alpha = 1;
|
|
2012
|
+
return culori2.formatRgb(color2);
|
|
2013
|
+
} catch {
|
|
2014
|
+
return fill;
|
|
2015
|
+
}
|
|
2016
|
+
}
|
|
2017
|
+
var createServiceProxy = (service, plugin) => {
|
|
2018
|
+
const proxy = /* @__PURE__ */ Object.create(null);
|
|
2019
|
+
for (const key of Object.keys(service)) {
|
|
2020
|
+
const originalMethod = service[key];
|
|
2021
|
+
proxy[key] = (...args) => {
|
|
2022
|
+
if (key in plugin) {
|
|
2023
|
+
return plugin[key].apply(plugin, args);
|
|
2024
|
+
}
|
|
2025
|
+
return originalMethod.apply(service, args);
|
|
2026
|
+
};
|
|
2027
|
+
}
|
|
2028
|
+
return proxy;
|
|
2029
|
+
};
|
|
2030
|
+
|
|
2031
|
+
export { TokenamiDiagnostics, createTSPlugin, findUsedTokens, generate as generateSheet, log_exports as log, utils_exports as utils };
|