dispersa 0.4.1 → 0.4.3
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/README.md +8 -9
- package/dist/builders.cjs +479 -598
- package/dist/builders.cjs.map +1 -1
- package/dist/builders.d.cts +4 -3
- package/dist/builders.d.ts +4 -3
- package/dist/builders.js +479 -598
- package/dist/builders.js.map +1 -1
- package/dist/cli/cli.js +27 -19
- package/dist/cli/cli.js.map +1 -1
- package/dist/cli/index.js +27 -19
- package/dist/cli/index.js.map +1 -1
- package/dist/filters.cjs +1 -1
- package/dist/filters.cjs.map +1 -1
- package/dist/filters.js +1 -1
- package/dist/filters.js.map +1 -1
- package/dist/{index-dwm-xYbQ.d.cts → index-CNT2Meyf.d.cts} +79 -74
- package/dist/{index-Bkedvob6.d.ts → index-CqdaN3X0.d.ts} +79 -74
- package/dist/index.cjs +638 -771
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +638 -771
- package/dist/index.js.map +1 -1
- package/dist/preprocessors.cjs.map +1 -1
- package/dist/preprocessors.js.map +1 -1
- package/dist/renderers.cjs.map +1 -1
- package/dist/renderers.d.cts +2 -2
- package/dist/renderers.d.ts +2 -2
- package/dist/renderers.js.map +1 -1
- package/dist/transforms.cjs +5 -17
- package/dist/transforms.cjs.map +1 -1
- package/dist/transforms.d.cts +1 -5
- package/dist/transforms.d.ts +1 -5
- package/dist/transforms.js +6 -17
- package/dist/transforms.js.map +1 -1
- package/package.json +1 -1
package/dist/builders.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { kebabCase } from 'change-case';
|
|
1
2
|
import { converter, formatHex8, formatHex } from 'culori';
|
|
2
3
|
import prettier from 'prettier';
|
|
3
4
|
|
|
@@ -46,13 +47,12 @@ function formatDeprecationMessage(token, description = "", format = "bracket") {
|
|
|
46
47
|
}
|
|
47
48
|
const deprecationMsg = typeof token.$deprecated === "string" ? token.$deprecated : "";
|
|
48
49
|
if (format === "comment") {
|
|
49
|
-
const
|
|
50
|
-
return `DEPRECATED${
|
|
51
|
-
} else {
|
|
52
|
-
const msg = deprecationMsg ? `: ${deprecationMsg}` : "";
|
|
53
|
-
const prefix = `[DEPRECATED${msg}]`;
|
|
54
|
-
return description ? `${prefix} ${description}` : prefix;
|
|
50
|
+
const msg2 = deprecationMsg ? ` ${deprecationMsg}` : "";
|
|
51
|
+
return `DEPRECATED${msg2}`;
|
|
55
52
|
}
|
|
53
|
+
const msg = deprecationMsg ? `: ${deprecationMsg}` : "";
|
|
54
|
+
const prefix = `[DEPRECATED${msg}]`;
|
|
55
|
+
return description ? `${prefix} ${description}` : prefix;
|
|
56
56
|
}
|
|
57
57
|
function stripInternalTokenMetadata(tokens) {
|
|
58
58
|
const cleaned = {};
|
|
@@ -65,6 +65,30 @@ function stripInternalTokenMetadata(tokens) {
|
|
|
65
65
|
function getSortedTokenEntries(tokens) {
|
|
66
66
|
return Object.entries(tokens).sort(([nameA], [nameB]) => nameA.localeCompare(nameB));
|
|
67
67
|
}
|
|
68
|
+
function buildNestedTokenObject(tokens, extractValue) {
|
|
69
|
+
const result = {};
|
|
70
|
+
for (const [, token] of getSortedTokenEntries(tokens)) {
|
|
71
|
+
setNestedValue(result, token.path, extractValue(token));
|
|
72
|
+
}
|
|
73
|
+
return result;
|
|
74
|
+
}
|
|
75
|
+
function setNestedValue(root, path, value) {
|
|
76
|
+
let current = root;
|
|
77
|
+
for (let i = 0; i < path.length - 1; i++) {
|
|
78
|
+
const part = path[i];
|
|
79
|
+
if (part == null) {
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
if (!(part in current)) {
|
|
83
|
+
current[part] = {};
|
|
84
|
+
}
|
|
85
|
+
current = current[part];
|
|
86
|
+
}
|
|
87
|
+
const lastPart = path[path.length - 1];
|
|
88
|
+
if (lastPart != null) {
|
|
89
|
+
current[lastPart] = value;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
68
92
|
function getPureAliasReferenceName(value) {
|
|
69
93
|
if (typeof value !== "string") {
|
|
70
94
|
return void 0;
|
|
@@ -84,6 +108,35 @@ function sanitizeDataAttributeName(value) {
|
|
|
84
108
|
function escapeCssString(value) {
|
|
85
109
|
return value.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\r?\n/g, " ");
|
|
86
110
|
}
|
|
111
|
+
function groupTokensByType(tokens, typeGroupMap) {
|
|
112
|
+
const groupMap = /* @__PURE__ */ new Map();
|
|
113
|
+
for (const [, token] of getSortedTokenEntries(tokens)) {
|
|
114
|
+
const groupName = typeGroupMap[token.$type ?? ""] ?? "Other";
|
|
115
|
+
const existing = groupMap.get(groupName) ?? [];
|
|
116
|
+
existing.push(token);
|
|
117
|
+
groupMap.set(groupName, existing);
|
|
118
|
+
}
|
|
119
|
+
return Array.from(groupMap.entries()).map(([name, groupTokens]) => ({
|
|
120
|
+
name,
|
|
121
|
+
tokens: groupTokens
|
|
122
|
+
}));
|
|
123
|
+
}
|
|
124
|
+
function indentStr(width, level) {
|
|
125
|
+
return " ".repeat(width * level);
|
|
126
|
+
}
|
|
127
|
+
function buildGeneratedFileHeader() {
|
|
128
|
+
return [
|
|
129
|
+
"// Generated by Dispersa - do not edit manually",
|
|
130
|
+
"// https://github.com/dispersa-core/dispersa"
|
|
131
|
+
].join("\n");
|
|
132
|
+
}
|
|
133
|
+
function toSafeIdentifier(name, keywords, capitalize) {
|
|
134
|
+
const camel = name.replace(/[-._]+(.)/g, (_, c) => c.toUpperCase()).replace(/[-._]+$/g, "").replace(/^[-._]+/g, "");
|
|
135
|
+
const cased = capitalize ? camel.charAt(0).toUpperCase() + camel.slice(1) : camel.charAt(0).toLowerCase() + camel.slice(1);
|
|
136
|
+
const safe = /^\d/.test(cased) ? `_${cased}` : cased;
|
|
137
|
+
const keyCheck = capitalize ? safe.charAt(0).toLowerCase() + safe.slice(1) : safe;
|
|
138
|
+
return keywords.has(keyCheck) ? `\`${safe}\`` : safe;
|
|
139
|
+
}
|
|
87
140
|
function normalizeModifierInputs(inputs) {
|
|
88
141
|
const normalized = {};
|
|
89
142
|
for (const [key, value] of Object.entries(inputs)) {
|
|
@@ -91,6 +144,14 @@ function normalizeModifierInputs(inputs) {
|
|
|
91
144
|
}
|
|
92
145
|
return normalized;
|
|
93
146
|
}
|
|
147
|
+
function assertFileRequired(buildPath, outputFile, outputName, presetLabel) {
|
|
148
|
+
const requiresFile = buildPath !== void 0 && buildPath !== "";
|
|
149
|
+
if (!outputFile && requiresFile) {
|
|
150
|
+
throw new ConfigurationError(
|
|
151
|
+
`Output "${outputName}": file is required for ${presetLabel} output`
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
94
155
|
function buildStablePermutationKey(modifierInputs, dimensions) {
|
|
95
156
|
return dimensions.map((dimension) => `${dimension}=${modifierInputs[dimension] ?? ""}`).join("|");
|
|
96
157
|
}
|
|
@@ -140,14 +201,18 @@ function generatePermutationKey(modifierInputs, resolver, isBase) {
|
|
|
140
201
|
}
|
|
141
202
|
return buildStablePermutationKey(normalizedInputs, metadata.dimensions);
|
|
142
203
|
}
|
|
143
|
-
function
|
|
144
|
-
const { outputName, extension, modifierInputs, resolver, defaults } = params;
|
|
204
|
+
function isBasePermutation(modifierInputs, defaults) {
|
|
145
205
|
const normalizedInputs = normalizeModifierInputs(modifierInputs);
|
|
146
206
|
const normalizedDefaults = normalizeModifierInputs(defaults);
|
|
147
|
-
|
|
148
|
-
|
|
207
|
+
return Object.entries(normalizedDefaults).every(([key, value]) => normalizedInputs[key] === value);
|
|
208
|
+
}
|
|
209
|
+
function buildInMemoryOutputKey(params) {
|
|
210
|
+
const { outputName, extension, modifierInputs, resolver, defaults } = params;
|
|
211
|
+
const permutationKey = generatePermutationKey(
|
|
212
|
+
modifierInputs,
|
|
213
|
+
resolver,
|
|
214
|
+
isBasePermutation(modifierInputs, defaults)
|
|
149
215
|
);
|
|
150
|
-
const permutationKey = generatePermutationKey(modifierInputs, resolver, isBase);
|
|
151
216
|
return `${outputName}-${permutationKey}.${extension}`;
|
|
152
217
|
}
|
|
153
218
|
function buildMetadata(resolver) {
|
|
@@ -261,6 +326,7 @@ function resolveFileName(fileName, modifierInputs) {
|
|
|
261
326
|
}
|
|
262
327
|
var init_utils = __esm({
|
|
263
328
|
"src/renderers/bundlers/utils.ts"() {
|
|
329
|
+
init_errors();
|
|
264
330
|
init_token_utils();
|
|
265
331
|
}
|
|
266
332
|
});
|
|
@@ -270,36 +336,38 @@ var js_exports = {};
|
|
|
270
336
|
__export(js_exports, {
|
|
271
337
|
bundleAsJsModule: () => bundleAsJsModule
|
|
272
338
|
});
|
|
339
|
+
function updateStringTracking(state, char) {
|
|
340
|
+
if (!state.escaped && (char === '"' || char === "'" || char === "`")) {
|
|
341
|
+
if (!state.inString) {
|
|
342
|
+
state.inString = true;
|
|
343
|
+
state.stringChar = char;
|
|
344
|
+
} else if (char === state.stringChar) {
|
|
345
|
+
state.inString = false;
|
|
346
|
+
state.stringChar = "";
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
state.escaped = !state.escaped && char === "\\";
|
|
350
|
+
}
|
|
273
351
|
function extractObjectFromJsModule(formattedJs) {
|
|
274
352
|
const assignmentMatch = /const\s+\w+\s*=\s*\{/.exec(formattedJs);
|
|
275
353
|
if (!assignmentMatch) {
|
|
276
354
|
return "{}";
|
|
277
355
|
}
|
|
278
356
|
const startIndex = assignmentMatch.index + assignmentMatch[0].length - 1;
|
|
357
|
+
const state = { inString: false, stringChar: "", escaped: false };
|
|
279
358
|
let braceCount = 0;
|
|
280
|
-
let inString = false;
|
|
281
|
-
let stringChar = "";
|
|
282
|
-
let escaped = false;
|
|
283
359
|
for (let i = startIndex; i < formattedJs.length; i++) {
|
|
284
360
|
const char = formattedJs[i];
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
stringChar = char;
|
|
289
|
-
} else if (char === stringChar) {
|
|
290
|
-
inString = false;
|
|
291
|
-
stringChar = "";
|
|
292
|
-
}
|
|
361
|
+
updateStringTracking(state, char);
|
|
362
|
+
if (state.inString) {
|
|
363
|
+
continue;
|
|
293
364
|
}
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
if (braceCount === 0) {
|
|
301
|
-
return formattedJs.substring(startIndex, i + 1);
|
|
302
|
-
}
|
|
365
|
+
if (char === "{") {
|
|
366
|
+
braceCount++;
|
|
367
|
+
} else if (char === "}") {
|
|
368
|
+
braceCount--;
|
|
369
|
+
if (braceCount === 0) {
|
|
370
|
+
return formattedJs.substring(startIndex, i + 1);
|
|
303
371
|
}
|
|
304
372
|
}
|
|
305
373
|
}
|
|
@@ -396,22 +464,19 @@ __export(json_exports, {
|
|
|
396
464
|
bundleAsJson: () => bundleAsJson
|
|
397
465
|
});
|
|
398
466
|
async function bundleAsJson(bundleData, resolver, formatTokens) {
|
|
467
|
+
if (!formatTokens) {
|
|
468
|
+
throw new ConfigurationError("JSON formatter was not provided");
|
|
469
|
+
}
|
|
399
470
|
const metadata = buildMetadata(resolver);
|
|
400
471
|
const tokens = {};
|
|
401
472
|
for (const { tokens: tokenSet, modifierInputs } of bundleData) {
|
|
402
473
|
const cleanTokens = stripInternalMetadata(tokenSet);
|
|
403
|
-
if (!formatTokens) {
|
|
404
|
-
throw new ConfigurationError("JSON formatter was not provided");
|
|
405
|
-
}
|
|
406
474
|
const normalizedInputs = normalizeModifierInputs(modifierInputs);
|
|
407
475
|
const key = buildStablePermutationKey(normalizedInputs, metadata.dimensions);
|
|
408
476
|
const themeJson = await formatTokens(cleanTokens);
|
|
409
477
|
tokens[key] = JSON.parse(themeJson);
|
|
410
478
|
}
|
|
411
|
-
const bundle = {
|
|
412
|
-
_meta: metadata,
|
|
413
|
-
tokens
|
|
414
|
-
};
|
|
479
|
+
const bundle = { _meta: metadata, tokens };
|
|
415
480
|
return JSON.stringify(bundle, null, 2);
|
|
416
481
|
}
|
|
417
482
|
var init_json = __esm({
|
|
@@ -420,6 +485,17 @@ var init_json = __esm({
|
|
|
420
485
|
init_utils();
|
|
421
486
|
}
|
|
422
487
|
});
|
|
488
|
+
function nameKebabCase() {
|
|
489
|
+
return {
|
|
490
|
+
transform: (token) => {
|
|
491
|
+
const name = kebabCase(token.path.join(" "));
|
|
492
|
+
return {
|
|
493
|
+
...token,
|
|
494
|
+
name
|
|
495
|
+
};
|
|
496
|
+
}
|
|
497
|
+
};
|
|
498
|
+
}
|
|
423
499
|
function isColorObject(value) {
|
|
424
500
|
return typeof value === "object" && value !== null && "colorSpace" in value && "components" in value;
|
|
425
501
|
}
|
|
@@ -477,7 +553,7 @@ function colorObjectToHex(color) {
|
|
|
477
553
|
return formatHex(culoriColor);
|
|
478
554
|
}
|
|
479
555
|
|
|
480
|
-
// src/processing/
|
|
556
|
+
// src/processing/transforms/built-in/dimension-converter.ts
|
|
481
557
|
function isDimensionObject(value) {
|
|
482
558
|
return typeof value === "object" && value !== null && "value" in value && "unit" in value;
|
|
483
559
|
}
|
|
@@ -485,6 +561,14 @@ function dimensionObjectToString(dimension) {
|
|
|
485
561
|
return `${dimension.value}${dimension.unit}`;
|
|
486
562
|
}
|
|
487
563
|
|
|
564
|
+
// src/processing/transforms/built-in/duration-converter.ts
|
|
565
|
+
function isDurationObject(value) {
|
|
566
|
+
return typeof value === "object" && value !== null && "value" in value && "unit" in value && value.unit !== void 0;
|
|
567
|
+
}
|
|
568
|
+
function durationObjectToString(duration) {
|
|
569
|
+
return `${duration.value}${duration.unit}`;
|
|
570
|
+
}
|
|
571
|
+
|
|
488
572
|
// src/renderers/android.ts
|
|
489
573
|
init_errors();
|
|
490
574
|
init_token_utils();
|
|
@@ -546,9 +630,6 @@ function resolveColorFormat(format) {
|
|
|
546
630
|
}
|
|
547
631
|
return "argb_hex";
|
|
548
632
|
}
|
|
549
|
-
function indent(width, level) {
|
|
550
|
-
return " ".repeat(width * level);
|
|
551
|
-
}
|
|
552
633
|
function escapeKotlinString(str) {
|
|
553
634
|
return str.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\$/g, "\\$");
|
|
554
635
|
}
|
|
@@ -564,22 +645,6 @@ function roundComponent(value) {
|
|
|
564
645
|
function toResourceName(family) {
|
|
565
646
|
return family.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_|_$/g, "");
|
|
566
647
|
}
|
|
567
|
-
function toPascalCase(name) {
|
|
568
|
-
const pascal = name.replace(/[-._]+(.)/g, (_, c) => c.toUpperCase()).replace(/[-._]+$/g, "").replace(/^[-._]+/g, "");
|
|
569
|
-
const result = pascal.charAt(0).toUpperCase() + pascal.slice(1);
|
|
570
|
-
if (/^\d/.test(result)) {
|
|
571
|
-
return `_${result}`;
|
|
572
|
-
}
|
|
573
|
-
return KOTLIN_KEYWORDS.has(result.charAt(0).toLowerCase() + result.slice(1)) ? `\`${result}\`` : result;
|
|
574
|
-
}
|
|
575
|
-
function toKotlinIdentifier(name) {
|
|
576
|
-
const camel = name.replace(/[-._]+(.)/g, (_, c) => c.toUpperCase()).replace(/[-._]+$/g, "").replace(/^[-._]+/g, "");
|
|
577
|
-
const identifier = camel.charAt(0).toLowerCase() + camel.slice(1);
|
|
578
|
-
if (/^\d/.test(identifier)) {
|
|
579
|
-
return `_${identifier}`;
|
|
580
|
-
}
|
|
581
|
-
return KOTLIN_KEYWORDS.has(identifier) ? `\`${identifier}\`` : identifier;
|
|
582
|
-
}
|
|
583
648
|
var AndroidRenderer = class {
|
|
584
649
|
async format(context, options) {
|
|
585
650
|
if (!options?.packageName) {
|
|
@@ -587,6 +652,7 @@ var AndroidRenderer = class {
|
|
|
587
652
|
`Output "${context.output.name}": packageName is required for Android output`
|
|
588
653
|
);
|
|
589
654
|
}
|
|
655
|
+
const visibility = options?.visibility;
|
|
590
656
|
const opts = {
|
|
591
657
|
preset: options?.preset ?? "standalone",
|
|
592
658
|
packageName: options.packageName,
|
|
@@ -594,7 +660,8 @@ var AndroidRenderer = class {
|
|
|
594
660
|
colorFormat: resolveColorFormat(options?.colorFormat),
|
|
595
661
|
colorSpace: options?.colorSpace ?? "sRGB",
|
|
596
662
|
structure: options?.structure ?? "nested",
|
|
597
|
-
visibility
|
|
663
|
+
visibility,
|
|
664
|
+
visPrefix: visibility ? `${visibility} ` : "",
|
|
598
665
|
indent: options?.indent ?? 4
|
|
599
666
|
};
|
|
600
667
|
if (opts.preset === "bundle") {
|
|
@@ -627,19 +694,6 @@ var AndroidRenderer = class {
|
|
|
627
694
|
// -----------------------------------------------------------------------
|
|
628
695
|
// Flat structure grouping
|
|
629
696
|
// -----------------------------------------------------------------------
|
|
630
|
-
groupTokensByType(tokens) {
|
|
631
|
-
const groupMap = /* @__PURE__ */ new Map();
|
|
632
|
-
for (const [, token] of getSortedTokenEntries(tokens)) {
|
|
633
|
-
const groupName = KOTLIN_TYPE_GROUP_MAP[token.$type ?? ""] ?? "Other";
|
|
634
|
-
const existing = groupMap.get(groupName) ?? [];
|
|
635
|
-
existing.push(token);
|
|
636
|
-
groupMap.set(groupName, existing);
|
|
637
|
-
}
|
|
638
|
-
return Array.from(groupMap.entries()).map(([name, groupTokens]) => ({
|
|
639
|
-
name,
|
|
640
|
-
tokens: groupTokens
|
|
641
|
-
}));
|
|
642
|
-
}
|
|
643
697
|
/**
|
|
644
698
|
* Builds a flattened camelCase name from a token's path, stripping the
|
|
645
699
|
* type prefix segment (which is already represented by the group object).
|
|
@@ -648,7 +702,7 @@ var AndroidRenderer = class {
|
|
|
648
702
|
const path = token.path;
|
|
649
703
|
const withoutTypePrefix = path.length > 1 ? path.slice(1) : path;
|
|
650
704
|
const joined = withoutTypePrefix.join("_");
|
|
651
|
-
return
|
|
705
|
+
return toSafeIdentifier(joined, KOTLIN_KEYWORDS, false);
|
|
652
706
|
}
|
|
653
707
|
// -----------------------------------------------------------------------
|
|
654
708
|
// Rendering
|
|
@@ -660,22 +714,21 @@ var AndroidRenderer = class {
|
|
|
660
714
|
return this.formatAsNested(tokens, options);
|
|
661
715
|
}
|
|
662
716
|
formatAsNested(tokens, options) {
|
|
717
|
+
const tokenTypes = this.collectTokenTypesFromEntries(tokens);
|
|
663
718
|
const tree = this.buildTokenTree(tokens);
|
|
664
|
-
|
|
665
|
-
this.collectTokenTypes(tree, tokenTypes);
|
|
666
|
-
return this.buildFile(tokenTypes, options, (lines, vis) => {
|
|
719
|
+
return this.buildFile(tokenTypes, options, (lines) => {
|
|
667
720
|
lines.push(`@Suppress("unused")`);
|
|
668
|
-
lines.push(`${
|
|
721
|
+
lines.push(`${options.visPrefix}object ${options.objectName} {`);
|
|
669
722
|
this.renderTreeChildren(lines, tree, 1, options);
|
|
670
723
|
lines.push("}");
|
|
671
724
|
});
|
|
672
725
|
}
|
|
673
726
|
formatAsFlat(tokens, options) {
|
|
674
|
-
const groups =
|
|
727
|
+
const groups = groupTokensByType(tokens, KOTLIN_TYPE_GROUP_MAP);
|
|
675
728
|
const tokenTypes = this.collectTokenTypesFromEntries(tokens);
|
|
676
|
-
return this.buildFile(tokenTypes, options, (lines
|
|
729
|
+
return this.buildFile(tokenTypes, options, (lines) => {
|
|
677
730
|
lines.push(`@Suppress("unused")`);
|
|
678
|
-
lines.push(`${
|
|
731
|
+
lines.push(`${options.visPrefix}object ${options.objectName} {`);
|
|
679
732
|
this.renderFlatGroups(lines, groups, 1, options);
|
|
680
733
|
lines.push("}");
|
|
681
734
|
});
|
|
@@ -686,9 +739,8 @@ var AndroidRenderer = class {
|
|
|
686
739
|
*/
|
|
687
740
|
buildFile(tokenTypes, options, renderBody) {
|
|
688
741
|
const imports = this.collectImports(tokenTypes, options);
|
|
689
|
-
const vis = options.visibility ? `${options.visibility} ` : "";
|
|
690
742
|
const lines = [];
|
|
691
|
-
lines.push(
|
|
743
|
+
lines.push(buildGeneratedFileHeader());
|
|
692
744
|
lines.push("");
|
|
693
745
|
lines.push(`package ${options.packageName}`);
|
|
694
746
|
lines.push("");
|
|
@@ -699,19 +751,18 @@ var AndroidRenderer = class {
|
|
|
699
751
|
lines.push("");
|
|
700
752
|
}
|
|
701
753
|
if (tokenTypes.has("shadow")) {
|
|
702
|
-
lines.push(...this.buildShadowTokenClass(
|
|
754
|
+
lines.push(...this.buildShadowTokenClass(options));
|
|
703
755
|
lines.push("");
|
|
704
756
|
}
|
|
705
|
-
renderBody(lines
|
|
757
|
+
renderBody(lines);
|
|
706
758
|
lines.push("");
|
|
707
759
|
return lines.join("\n");
|
|
708
760
|
}
|
|
709
761
|
renderFlatGroups(lines, groups, baseDepth, options) {
|
|
710
|
-
const
|
|
711
|
-
const
|
|
712
|
-
const valIndent = indent(options.indent, baseDepth + 1);
|
|
762
|
+
const groupIndent = indentStr(options.indent, baseDepth);
|
|
763
|
+
const valIndent = indentStr(options.indent, baseDepth + 1);
|
|
713
764
|
for (const group of groups) {
|
|
714
|
-
lines.push(`${groupIndent}${
|
|
765
|
+
lines.push(`${groupIndent}${options.visPrefix}object ${group.name} {`);
|
|
715
766
|
for (const token of group.tokens) {
|
|
716
767
|
const kotlinName = this.buildFlatKotlinName(token);
|
|
717
768
|
const kotlinValue = this.formatKotlinValue(token, options, baseDepth + 1);
|
|
@@ -719,23 +770,24 @@ var AndroidRenderer = class {
|
|
|
719
770
|
if (token.$description) {
|
|
720
771
|
lines.push(`${valIndent}/** ${escapeKDoc(token.$description)} */`);
|
|
721
772
|
}
|
|
722
|
-
lines.push(
|
|
773
|
+
lines.push(
|
|
774
|
+
`${valIndent}${options.visPrefix}val ${kotlinName}${annotation} = ${kotlinValue}`
|
|
775
|
+
);
|
|
723
776
|
}
|
|
724
777
|
lines.push(`${groupIndent}}`);
|
|
725
778
|
lines.push("");
|
|
726
779
|
}
|
|
727
780
|
}
|
|
728
781
|
renderTreeChildren(lines, node, depth, options) {
|
|
729
|
-
const
|
|
730
|
-
const pad = indent(options.indent, depth);
|
|
782
|
+
const pad = indentStr(options.indent, depth);
|
|
731
783
|
const entries = Array.from(node.children.entries());
|
|
732
784
|
for (let idx = 0; idx < entries.length; idx++) {
|
|
733
785
|
const [key, child] = entries[idx];
|
|
734
786
|
if (child.token && child.children.size === 0) {
|
|
735
787
|
this.renderLeaf(lines, key, child.token, depth, options);
|
|
736
788
|
} else if (child.children.size > 0 && !child.token) {
|
|
737
|
-
const objectName =
|
|
738
|
-
lines.push(`${pad}${
|
|
789
|
+
const objectName = toSafeIdentifier(key, KOTLIN_KEYWORDS, true);
|
|
790
|
+
lines.push(`${pad}${options.visPrefix}object ${objectName} {`);
|
|
739
791
|
this.renderTreeChildren(lines, child, depth + 1, options);
|
|
740
792
|
lines.push(`${pad}}`);
|
|
741
793
|
if (idx < entries.length - 1) {
|
|
@@ -748,30 +800,23 @@ var AndroidRenderer = class {
|
|
|
748
800
|
}
|
|
749
801
|
}
|
|
750
802
|
renderLeaf(lines, key, token, depth, options) {
|
|
751
|
-
const
|
|
752
|
-
const
|
|
753
|
-
const kotlinName = toKotlinIdentifier(key);
|
|
803
|
+
const pad = indentStr(options.indent, depth);
|
|
804
|
+
const kotlinName = toSafeIdentifier(key, KOTLIN_KEYWORDS, false);
|
|
754
805
|
const kotlinValue = this.formatKotlinValue(token, options, depth);
|
|
755
806
|
const annotation = this.typeAnnotationSuffix(token);
|
|
756
807
|
if (token.$description) {
|
|
757
808
|
lines.push(`${pad}/** ${escapeKDoc(token.$description)} */`);
|
|
758
809
|
}
|
|
759
|
-
lines.push(`${pad}${
|
|
760
|
-
}
|
|
761
|
-
buildFileHeader() {
|
|
762
|
-
return [
|
|
763
|
-
"// Generated by Dispersa - do not edit manually",
|
|
764
|
-
"// https://github.com/timges/dispersa"
|
|
765
|
-
].join("\n");
|
|
810
|
+
lines.push(`${pad}${options.visPrefix}val ${kotlinName}${annotation} = ${kotlinValue}`);
|
|
766
811
|
}
|
|
767
812
|
// -----------------------------------------------------------------------
|
|
768
813
|
// Shadow data class
|
|
769
814
|
// -----------------------------------------------------------------------
|
|
770
|
-
buildShadowTokenClass(
|
|
771
|
-
const i1 =
|
|
815
|
+
buildShadowTokenClass(options) {
|
|
816
|
+
const i1 = indentStr(options.indent, 1);
|
|
772
817
|
return [
|
|
773
818
|
"@Immutable",
|
|
774
|
-
`${
|
|
819
|
+
`${options.visPrefix}data class ShadowToken(`,
|
|
775
820
|
`${i1}val color: Color,`,
|
|
776
821
|
`${i1}val elevation: Dp,`,
|
|
777
822
|
`${i1}val offsetX: Dp,`,
|
|
@@ -822,14 +867,6 @@ var AndroidRenderer = class {
|
|
|
822
867
|
}
|
|
823
868
|
return Array.from(imports).sort();
|
|
824
869
|
}
|
|
825
|
-
collectTokenTypes(node, types) {
|
|
826
|
-
if (node.token?.$type) {
|
|
827
|
-
types.add(node.token.$type);
|
|
828
|
-
}
|
|
829
|
-
for (const child of node.children.values()) {
|
|
830
|
-
this.collectTokenTypes(child, types);
|
|
831
|
-
}
|
|
832
|
-
}
|
|
833
870
|
collectTokenTypesFromEntries(tokens) {
|
|
834
871
|
const types = /* @__PURE__ */ new Set();
|
|
835
872
|
for (const [, token] of Object.entries(tokens)) {
|
|
@@ -1056,9 +1093,8 @@ var AndroidRenderer = class {
|
|
|
1056
1093
|
return map[name.toLowerCase()];
|
|
1057
1094
|
}
|
|
1058
1095
|
formatDurationValue(value) {
|
|
1059
|
-
if (
|
|
1060
|
-
|
|
1061
|
-
return dur.unit === "ms" ? `${dur.value}.milliseconds` : `${dur.value}.seconds`;
|
|
1096
|
+
if (isDurationObject(value)) {
|
|
1097
|
+
return value.unit === "ms" ? `${value.value}.milliseconds` : `${value.value}.seconds`;
|
|
1062
1098
|
}
|
|
1063
1099
|
return typeof value === "number" ? `${value}.milliseconds` : "0.milliseconds";
|
|
1064
1100
|
}
|
|
@@ -1076,8 +1112,8 @@ var AndroidRenderer = class {
|
|
|
1076
1112
|
const elevation = isDimensionObject(shadow.blur) ? this.formatDimensionValue(shadow.blur) : "0.dp";
|
|
1077
1113
|
const offsetX = isDimensionObject(shadow.offsetX) ? this.formatDimensionValue(shadow.offsetX) : "0.dp";
|
|
1078
1114
|
const offsetY = isDimensionObject(shadow.offsetY) ? this.formatDimensionValue(shadow.offsetY) : "0.dp";
|
|
1079
|
-
const propIndent =
|
|
1080
|
-
const closeIndent =
|
|
1115
|
+
const propIndent = indentStr(options.indent, depth + 1);
|
|
1116
|
+
const closeIndent = indentStr(options.indent, depth);
|
|
1081
1117
|
return [
|
|
1082
1118
|
"ShadowToken(",
|
|
1083
1119
|
`${propIndent}color = ${color},`,
|
|
@@ -1126,8 +1162,8 @@ var AndroidRenderer = class {
|
|
|
1126
1162
|
if (parts.length === 0) {
|
|
1127
1163
|
return "TextStyle()";
|
|
1128
1164
|
}
|
|
1129
|
-
const propIndent =
|
|
1130
|
-
const closeIndent =
|
|
1165
|
+
const propIndent = indentStr(options.indent, depth + 1);
|
|
1166
|
+
const closeIndent = indentStr(options.indent, depth);
|
|
1131
1167
|
return `TextStyle(
|
|
1132
1168
|
${parts.map((p) => `${propIndent}${p}`).join(",\n")},
|
|
1133
1169
|
${closeIndent})`;
|
|
@@ -1136,12 +1172,12 @@ ${closeIndent})`;
|
|
|
1136
1172
|
// Output: standalone
|
|
1137
1173
|
// -----------------------------------------------------------------------
|
|
1138
1174
|
async formatStandalone(context, options) {
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1175
|
+
assertFileRequired(
|
|
1176
|
+
context.buildPath,
|
|
1177
|
+
context.output.file,
|
|
1178
|
+
context.output.name,
|
|
1179
|
+
"standalone Android"
|
|
1180
|
+
);
|
|
1145
1181
|
const files = {};
|
|
1146
1182
|
for (const { tokens, modifierInputs } of context.permutations) {
|
|
1147
1183
|
const processedTokens = stripInternalMetadata(tokens);
|
|
@@ -1161,12 +1197,12 @@ ${closeIndent})`;
|
|
|
1161
1197
|
// Output: bundle
|
|
1162
1198
|
// -----------------------------------------------------------------------
|
|
1163
1199
|
async formatBundle(context, options) {
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1200
|
+
assertFileRequired(
|
|
1201
|
+
context.buildPath,
|
|
1202
|
+
context.output.file,
|
|
1203
|
+
context.output.name,
|
|
1204
|
+
"bundle Android"
|
|
1205
|
+
);
|
|
1170
1206
|
const content = this.formatBundleContent(context, options);
|
|
1171
1207
|
const fileName = context.output.file ? resolveFileName(context.output.file, context.meta.basePermutation) : buildInMemoryOutputKey({
|
|
1172
1208
|
outputName: context.output.name,
|
|
@@ -1179,15 +1215,15 @@ ${closeIndent})`;
|
|
|
1179
1215
|
}
|
|
1180
1216
|
formatBundleContent(context, options) {
|
|
1181
1217
|
const allTokenTypes = this.collectAllPermutationTypes(context);
|
|
1182
|
-
return this.buildFile(allTokenTypes, options, (lines
|
|
1183
|
-
const i1 =
|
|
1218
|
+
return this.buildFile(allTokenTypes, options, (lines) => {
|
|
1219
|
+
const i1 = indentStr(options.indent, 1);
|
|
1184
1220
|
lines.push(`@Suppress("unused")`);
|
|
1185
|
-
lines.push(`${
|
|
1221
|
+
lines.push(`${options.visPrefix}object ${options.objectName} {`);
|
|
1186
1222
|
for (let idx = 0; idx < context.permutations.length; idx++) {
|
|
1187
1223
|
const { tokens, modifierInputs } = context.permutations[idx];
|
|
1188
1224
|
const processedTokens = stripInternalMetadata(tokens);
|
|
1189
1225
|
const permName = this.buildPermutationName(modifierInputs);
|
|
1190
|
-
lines.push(`${i1}${
|
|
1226
|
+
lines.push(`${i1}${options.visPrefix}object ${permName} {`);
|
|
1191
1227
|
this.renderBundleTokens(lines, processedTokens, options, 2);
|
|
1192
1228
|
lines.push(`${i1}}`);
|
|
1193
1229
|
if (idx < context.permutations.length - 1) {
|
|
@@ -1198,20 +1234,17 @@ ${closeIndent})`;
|
|
|
1198
1234
|
});
|
|
1199
1235
|
}
|
|
1200
1236
|
collectAllPermutationTypes(context) {
|
|
1201
|
-
const
|
|
1237
|
+
const types = /* @__PURE__ */ new Set();
|
|
1202
1238
|
for (const { tokens } of context.permutations) {
|
|
1203
|
-
const
|
|
1204
|
-
|
|
1205
|
-
if (token.$type) {
|
|
1206
|
-
allTokenTypes.add(token.$type);
|
|
1207
|
-
}
|
|
1239
|
+
for (const t of this.collectTokenTypesFromEntries(stripInternalMetadata(tokens))) {
|
|
1240
|
+
types.add(t);
|
|
1208
1241
|
}
|
|
1209
1242
|
}
|
|
1210
|
-
return
|
|
1243
|
+
return types;
|
|
1211
1244
|
}
|
|
1212
1245
|
renderBundleTokens(lines, tokens, options, baseDepth) {
|
|
1213
1246
|
if (options.structure === "flat") {
|
|
1214
|
-
const groups =
|
|
1247
|
+
const groups = groupTokensByType(tokens, KOTLIN_TYPE_GROUP_MAP);
|
|
1215
1248
|
this.renderFlatGroups(lines, groups, baseDepth, options);
|
|
1216
1249
|
return;
|
|
1217
1250
|
}
|
|
@@ -1223,7 +1256,7 @@ ${closeIndent})`;
|
|
|
1223
1256
|
if (values.length === 0) {
|
|
1224
1257
|
return "Default";
|
|
1225
1258
|
}
|
|
1226
|
-
return values.map((v) =>
|
|
1259
|
+
return values.map((v) => toSafeIdentifier(v, KOTLIN_KEYWORDS, true)).join("");
|
|
1227
1260
|
}
|
|
1228
1261
|
};
|
|
1229
1262
|
function androidRenderer() {
|
|
@@ -1243,19 +1276,19 @@ init_token_utils();
|
|
|
1243
1276
|
// src/renderers/bundlers/css.ts
|
|
1244
1277
|
init_errors();
|
|
1245
1278
|
init_utils();
|
|
1279
|
+
var REF_PREFIX_SETS = "#/sets/";
|
|
1280
|
+
var REF_PREFIX_MODIFIERS = "#/modifiers/";
|
|
1246
1281
|
var getSourceSet = (token) => {
|
|
1247
1282
|
if (typeof token !== "object" || token === null) {
|
|
1248
1283
|
return void 0;
|
|
1249
1284
|
}
|
|
1250
|
-
|
|
1251
|
-
return typeof maybe._sourceSet === "string" ? maybe._sourceSet : void 0;
|
|
1285
|
+
return "_sourceSet" in token && typeof token._sourceSet === "string" ? token._sourceSet : void 0;
|
|
1252
1286
|
};
|
|
1253
1287
|
var getSourceModifier = (token) => {
|
|
1254
1288
|
if (typeof token !== "object" || token === null) {
|
|
1255
1289
|
return void 0;
|
|
1256
1290
|
}
|
|
1257
|
-
|
|
1258
|
-
return typeof maybe._sourceModifier === "string" ? maybe._sourceModifier : void 0;
|
|
1291
|
+
return "_sourceModifier" in token && typeof token._sourceModifier === "string" ? token._sourceModifier : void 0;
|
|
1259
1292
|
};
|
|
1260
1293
|
async function bundleAsCss(bundleData, resolver, options, formatTokens) {
|
|
1261
1294
|
const baseItem = bundleData.find((item) => item.isBase);
|
|
@@ -1340,6 +1373,15 @@ async function formatModifierPermutation({ tokens, modifierInputs }, baseItem, o
|
|
|
1340
1373
|
return `/* Modifier: ${modifier}=${context} */
|
|
1341
1374
|
${css2}`;
|
|
1342
1375
|
}
|
|
1376
|
+
function addLayerBlock(blocks, included, key, blockTokens, description) {
|
|
1377
|
+
if (Object.keys(blockTokens).length === 0) {
|
|
1378
|
+
return;
|
|
1379
|
+
}
|
|
1380
|
+
for (const k of Object.keys(blockTokens)) {
|
|
1381
|
+
included.add(k);
|
|
1382
|
+
}
|
|
1383
|
+
blocks.push({ key, description, tokens: blockTokens });
|
|
1384
|
+
}
|
|
1343
1385
|
function collectSetTokens(tokens, setName, included) {
|
|
1344
1386
|
const result = {};
|
|
1345
1387
|
for (const [name, token] of Object.entries(tokens)) {
|
|
@@ -1370,75 +1412,67 @@ function collectRemainder(tokens, included) {
|
|
|
1370
1412
|
function buildSetLayerBlocks(tokens, resolver) {
|
|
1371
1413
|
const blocks = [];
|
|
1372
1414
|
const included = /* @__PURE__ */ new Set();
|
|
1373
|
-
const addBlock = (key, blockTokens, description) => {
|
|
1374
|
-
if (Object.keys(blockTokens).length === 0) {
|
|
1375
|
-
return;
|
|
1376
|
-
}
|
|
1377
|
-
for (const k of Object.keys(blockTokens)) {
|
|
1378
|
-
included.add(k);
|
|
1379
|
-
}
|
|
1380
|
-
blocks.push({ key, description, tokens: blockTokens });
|
|
1381
|
-
};
|
|
1382
1415
|
for (const item of resolver.resolutionOrder) {
|
|
1383
1416
|
const ref = item.$ref;
|
|
1384
|
-
if (typeof ref !== "string" || !ref.startsWith(
|
|
1417
|
+
if (typeof ref !== "string" || !ref.startsWith(REF_PREFIX_SETS)) {
|
|
1385
1418
|
continue;
|
|
1386
1419
|
}
|
|
1387
|
-
const setName = ref.slice(
|
|
1388
|
-
|
|
1420
|
+
const setName = ref.slice(REF_PREFIX_SETS.length);
|
|
1421
|
+
addLayerBlock(
|
|
1422
|
+
blocks,
|
|
1423
|
+
included,
|
|
1389
1424
|
`Set: ${setName}`,
|
|
1390
1425
|
collectSetTokens(tokens, setName, included),
|
|
1391
1426
|
resolver.sets?.[setName]?.description
|
|
1392
1427
|
);
|
|
1393
1428
|
}
|
|
1394
|
-
|
|
1429
|
+
addLayerBlock(blocks, included, "Unattributed", collectRemainder(tokens, included));
|
|
1395
1430
|
return blocks;
|
|
1396
1431
|
}
|
|
1397
1432
|
function buildDefaultLayerBlocks(tokens, baseModifierInputs, resolver) {
|
|
1398
1433
|
const blocks = [];
|
|
1399
1434
|
const included = /* @__PURE__ */ new Set();
|
|
1400
1435
|
const baseInputs = normalizeModifierInputs(baseModifierInputs);
|
|
1401
|
-
const addBlock = (key, blockTokens, description) => {
|
|
1402
|
-
if (Object.keys(blockTokens).length === 0) {
|
|
1403
|
-
return;
|
|
1404
|
-
}
|
|
1405
|
-
for (const k of Object.keys(blockTokens)) {
|
|
1406
|
-
included.add(k);
|
|
1407
|
-
}
|
|
1408
|
-
blocks.push({ key, description, tokens: blockTokens });
|
|
1409
|
-
};
|
|
1410
1436
|
for (const item of resolver.resolutionOrder) {
|
|
1411
1437
|
const ref = item.$ref;
|
|
1412
1438
|
if (typeof ref !== "string") {
|
|
1413
1439
|
continue;
|
|
1414
1440
|
}
|
|
1415
|
-
|
|
1416
|
-
const setName = ref.slice("#/sets/".length);
|
|
1417
|
-
addBlock(
|
|
1418
|
-
`Set: ${setName}`,
|
|
1419
|
-
collectSetTokens(tokens, setName, included),
|
|
1420
|
-
resolver.sets?.[setName]?.description
|
|
1421
|
-
);
|
|
1422
|
-
continue;
|
|
1423
|
-
}
|
|
1424
|
-
if (ref.startsWith("#/modifiers/")) {
|
|
1425
|
-
const modifierName = ref.slice("#/modifiers/".length);
|
|
1426
|
-
const modifier = resolver.modifiers?.[modifierName];
|
|
1427
|
-
const selectedContext = baseInputs[modifierName.toLowerCase()];
|
|
1428
|
-
if (!modifier || !selectedContext) {
|
|
1429
|
-
continue;
|
|
1430
|
-
}
|
|
1431
|
-
const expectedSource = `${modifierName}-${selectedContext}`.toLowerCase();
|
|
1432
|
-
addBlock(
|
|
1433
|
-
`Modifier: ${modifierName}=${selectedContext} (default)`,
|
|
1434
|
-
collectModifierTokens(tokens, expectedSource, included),
|
|
1435
|
-
modifier.description
|
|
1436
|
-
);
|
|
1437
|
-
}
|
|
1441
|
+
processResolutionOrderRef(ref, tokens, blocks, included, baseInputs, resolver);
|
|
1438
1442
|
}
|
|
1439
|
-
|
|
1443
|
+
addLayerBlock(blocks, included, "Unattributed", collectRemainder(tokens, included));
|
|
1440
1444
|
return blocks;
|
|
1441
1445
|
}
|
|
1446
|
+
function processResolutionOrderRef(ref, tokens, blocks, included, baseInputs, resolver) {
|
|
1447
|
+
if (ref.startsWith(REF_PREFIX_SETS)) {
|
|
1448
|
+
const setName = ref.slice(REF_PREFIX_SETS.length);
|
|
1449
|
+
addLayerBlock(
|
|
1450
|
+
blocks,
|
|
1451
|
+
included,
|
|
1452
|
+
`Set: ${setName}`,
|
|
1453
|
+
collectSetTokens(tokens, setName, included),
|
|
1454
|
+
resolver.sets?.[setName]?.description
|
|
1455
|
+
);
|
|
1456
|
+
return;
|
|
1457
|
+
}
|
|
1458
|
+
if (!ref.startsWith(REF_PREFIX_MODIFIERS)) {
|
|
1459
|
+
return;
|
|
1460
|
+
}
|
|
1461
|
+
const modifierName = ref.slice(REF_PREFIX_MODIFIERS.length);
|
|
1462
|
+
const modifier = resolver.modifiers?.[modifierName];
|
|
1463
|
+
const selectedContext = baseInputs[modifierName.toLowerCase()];
|
|
1464
|
+
if (!modifier || !selectedContext) {
|
|
1465
|
+
return;
|
|
1466
|
+
}
|
|
1467
|
+
const expectedSource = `${modifierName}-${selectedContext}`.toLowerCase();
|
|
1468
|
+
addLayerBlock(
|
|
1469
|
+
blocks,
|
|
1470
|
+
included,
|
|
1471
|
+
`Modifier: ${modifierName}=${selectedContext} (default)`,
|
|
1472
|
+
collectModifierTokens(tokens, expectedSource, included),
|
|
1473
|
+
modifier.description
|
|
1474
|
+
);
|
|
1475
|
+
}
|
|
1442
1476
|
function findSingleDiffPermutation(bundleData, modifierName, context, baseInputs) {
|
|
1443
1477
|
const normalizedModifier = modifierName.toLowerCase();
|
|
1444
1478
|
const normalizedContext = context.toLowerCase();
|
|
@@ -1453,6 +1487,36 @@ function findSingleDiffPermutation(bundleData, modifierName, context, baseInputs
|
|
|
1453
1487
|
return Object.entries(baseInputs).every(([k, v]) => k === normalizedModifier || inputs[k] === v);
|
|
1454
1488
|
});
|
|
1455
1489
|
}
|
|
1490
|
+
function pushUniqueBundleItem(ordered, includedKeys, item) {
|
|
1491
|
+
if (!item) {
|
|
1492
|
+
return;
|
|
1493
|
+
}
|
|
1494
|
+
const key = stableInputsKey(item.modifierInputs);
|
|
1495
|
+
if (includedKeys.has(key)) {
|
|
1496
|
+
return;
|
|
1497
|
+
}
|
|
1498
|
+
includedKeys.add(key);
|
|
1499
|
+
ordered.push(item);
|
|
1500
|
+
}
|
|
1501
|
+
function appendModifierPermutations(bundleData, modifiers, orderedNames, baseInputs, ordered, includedKeys) {
|
|
1502
|
+
for (const modifierName of orderedNames) {
|
|
1503
|
+
const modifierDef = modifiers[modifierName];
|
|
1504
|
+
if (!modifierDef) {
|
|
1505
|
+
continue;
|
|
1506
|
+
}
|
|
1507
|
+
const defaultValue = baseInputs[modifierName.toLowerCase()] ?? "";
|
|
1508
|
+
for (const ctx of Object.keys(modifierDef.contexts)) {
|
|
1509
|
+
if (defaultValue === ctx.toLowerCase()) {
|
|
1510
|
+
continue;
|
|
1511
|
+
}
|
|
1512
|
+
pushUniqueBundleItem(
|
|
1513
|
+
ordered,
|
|
1514
|
+
includedKeys,
|
|
1515
|
+
findSingleDiffPermutation(bundleData, modifierName, ctx, baseInputs)
|
|
1516
|
+
);
|
|
1517
|
+
}
|
|
1518
|
+
}
|
|
1519
|
+
}
|
|
1456
1520
|
function orderBundleData(bundleData, resolver, baseItem) {
|
|
1457
1521
|
const modifiers = resolver.modifiers;
|
|
1458
1522
|
if (!modifiers) {
|
|
@@ -1469,31 +1533,15 @@ function orderBundleData(bundleData, resolver, baseItem) {
|
|
|
1469
1533
|
}
|
|
1470
1534
|
const includedKeys = /* @__PURE__ */ new Set();
|
|
1471
1535
|
const ordered = [];
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
ordered.push(item);
|
|
1482
|
-
};
|
|
1483
|
-
pushUnique(baseItem);
|
|
1484
|
-
for (const modifierName of orderedModifierNames) {
|
|
1485
|
-
const modifierDef = modifiers[modifierName];
|
|
1486
|
-
if (!modifierDef) {
|
|
1487
|
-
continue;
|
|
1488
|
-
}
|
|
1489
|
-
const defaultValue = baseInputs[modifierName.toLowerCase()] ?? "";
|
|
1490
|
-
for (const ctx of Object.keys(modifierDef.contexts)) {
|
|
1491
|
-
if (defaultValue === ctx.toLowerCase()) {
|
|
1492
|
-
continue;
|
|
1493
|
-
}
|
|
1494
|
-
pushUnique(findSingleDiffPermutation(bundleData, modifierName, ctx, baseInputs));
|
|
1495
|
-
}
|
|
1496
|
-
}
|
|
1536
|
+
pushUniqueBundleItem(ordered, includedKeys, baseItem);
|
|
1537
|
+
appendModifierPermutations(
|
|
1538
|
+
bundleData,
|
|
1539
|
+
modifiers,
|
|
1540
|
+
orderedModifierNames,
|
|
1541
|
+
baseInputs,
|
|
1542
|
+
ordered,
|
|
1543
|
+
includedKeys
|
|
1544
|
+
);
|
|
1497
1545
|
return ordered.length > 0 ? ordered : bundleData;
|
|
1498
1546
|
}
|
|
1499
1547
|
function getOrderedModifierNames(resolver) {
|
|
@@ -1505,10 +1553,10 @@ function getOrderedModifierNames(resolver) {
|
|
|
1505
1553
|
if (typeof ref !== "string") {
|
|
1506
1554
|
continue;
|
|
1507
1555
|
}
|
|
1508
|
-
if (!ref.startsWith(
|
|
1556
|
+
if (!ref.startsWith(REF_PREFIX_MODIFIERS)) {
|
|
1509
1557
|
continue;
|
|
1510
1558
|
}
|
|
1511
|
-
const name = ref.slice(
|
|
1559
|
+
const name = ref.slice(REF_PREFIX_MODIFIERS.length);
|
|
1512
1560
|
if (seen.has(name)) {
|
|
1513
1561
|
continue;
|
|
1514
1562
|
}
|
|
@@ -1579,24 +1627,22 @@ var CssRenderer = class _CssRenderer {
|
|
|
1579
1627
|
...options,
|
|
1580
1628
|
referenceTokens: options?.referenceTokens ?? tokens
|
|
1581
1629
|
};
|
|
1582
|
-
const
|
|
1630
|
+
const sortedTokens = getSortedTokenEntries(tokens).map(([, token]) => token);
|
|
1583
1631
|
const referenceTokens = opts.referenceTokens;
|
|
1584
1632
|
const lines = [];
|
|
1585
|
-
|
|
1586
|
-
this.buildCssBlock(lines, groupTokens, selector, tokens, referenceTokens, opts);
|
|
1587
|
-
}
|
|
1633
|
+
this.buildCssBlock(lines, sortedTokens, opts.selector, tokens, referenceTokens, opts);
|
|
1588
1634
|
const cssString = lines.join("");
|
|
1589
1635
|
return opts.minify ? cssString : await this.formatWithPrettier(cssString);
|
|
1590
1636
|
}
|
|
1591
1637
|
buildCssBlock(lines, groupTokens, selector, tokens, referenceTokens, opts) {
|
|
1592
|
-
const
|
|
1638
|
+
const indent = opts.minify ? "" : " ";
|
|
1593
1639
|
const newline = opts.minify ? "" : "\n";
|
|
1594
1640
|
const space = opts.minify ? "" : " ";
|
|
1595
1641
|
const hasMediaQuery = opts.mediaQuery != null && opts.mediaQuery !== "";
|
|
1596
|
-
const tokenIndent = hasMediaQuery ?
|
|
1642
|
+
const tokenIndent = hasMediaQuery ? indent + indent : indent;
|
|
1597
1643
|
if (hasMediaQuery) {
|
|
1598
1644
|
lines.push(`@media ${opts.mediaQuery}${space}{${newline}`);
|
|
1599
|
-
lines.push(`${
|
|
1645
|
+
lines.push(`${indent}${selector}${space}{${newline}`);
|
|
1600
1646
|
} else {
|
|
1601
1647
|
lines.push(`${selector}${space}{${newline}`);
|
|
1602
1648
|
}
|
|
@@ -1613,21 +1659,21 @@ var CssRenderer = class _CssRenderer {
|
|
|
1613
1659
|
);
|
|
1614
1660
|
}
|
|
1615
1661
|
if (hasMediaQuery) {
|
|
1616
|
-
lines.push(`${
|
|
1662
|
+
lines.push(`${indent}}${newline}`);
|
|
1617
1663
|
}
|
|
1618
1664
|
lines.push(`}${newline}${newline}`);
|
|
1619
1665
|
}
|
|
1620
|
-
pushTokenLines(lines, token, tokens, referenceTokens, preserveReferences,
|
|
1666
|
+
pushTokenLines(lines, token, tokens, referenceTokens, preserveReferences, indent, newline, space) {
|
|
1621
1667
|
const entries = this.buildCssEntries(token, tokens, referenceTokens, preserveReferences);
|
|
1622
1668
|
if (token.$deprecated != null && token.$deprecated !== false) {
|
|
1623
1669
|
const deprecationMsg = formatDeprecationMessage(token, "", "comment");
|
|
1624
|
-
lines.push(`${
|
|
1670
|
+
lines.push(`${indent}/* ${this.sanitizeCssCommentText(deprecationMsg)} */${newline}`);
|
|
1625
1671
|
}
|
|
1626
1672
|
if (token.$description && token.$description !== "") {
|
|
1627
|
-
lines.push(`${
|
|
1673
|
+
lines.push(`${indent}/* ${this.sanitizeCssCommentText(token.$description)} */${newline}`);
|
|
1628
1674
|
}
|
|
1629
1675
|
for (const entry of entries) {
|
|
1630
|
-
lines.push(`${
|
|
1676
|
+
lines.push(`${indent}--${entry.name}:${space}${entry.value};${newline}`);
|
|
1631
1677
|
}
|
|
1632
1678
|
}
|
|
1633
1679
|
async formatWithPrettier(css2) {
|
|
@@ -1642,15 +1688,6 @@ var CssRenderer = class _CssRenderer {
|
|
|
1642
1688
|
return css2;
|
|
1643
1689
|
}
|
|
1644
1690
|
}
|
|
1645
|
-
/**
|
|
1646
|
-
* Group tokens by selector (for theme support)
|
|
1647
|
-
*/
|
|
1648
|
-
groupTokens(tokens, options) {
|
|
1649
|
-
const sortedTokens = getSortedTokenEntries(tokens).map(([, token]) => token);
|
|
1650
|
-
return {
|
|
1651
|
-
[options.selector]: sortedTokens
|
|
1652
|
-
};
|
|
1653
|
-
}
|
|
1654
1691
|
buildCssEntries(token, tokens, referenceTokens, preserveReferences) {
|
|
1655
1692
|
if (preserveReferences) {
|
|
1656
1693
|
const refName = getPureAliasReferenceName(token.originalValue);
|
|
@@ -1792,7 +1829,7 @@ var CssRenderer = class _CssRenderer {
|
|
|
1792
1829
|
leaves.push({ path, value });
|
|
1793
1830
|
return;
|
|
1794
1831
|
}
|
|
1795
|
-
if (isColorObject(value) || isDimensionObject(value) ||
|
|
1832
|
+
if (isColorObject(value) || isDimensionObject(value) || isDurationObject(value)) {
|
|
1796
1833
|
leaves.push({ path, value });
|
|
1797
1834
|
return;
|
|
1798
1835
|
}
|
|
@@ -1835,8 +1872,8 @@ var CssRenderer = class _CssRenderer {
|
|
|
1835
1872
|
if (isDimensionObject(value)) {
|
|
1836
1873
|
return dimensionObjectToString(value);
|
|
1837
1874
|
}
|
|
1838
|
-
if (
|
|
1839
|
-
return
|
|
1875
|
+
if (isDurationObject(value)) {
|
|
1876
|
+
return durationObjectToString(value);
|
|
1840
1877
|
}
|
|
1841
1878
|
if (typeof value === "string") {
|
|
1842
1879
|
return value;
|
|
@@ -1899,15 +1936,6 @@ var CssRenderer = class _CssRenderer {
|
|
|
1899
1936
|
isPrimitiveValue(value) {
|
|
1900
1937
|
return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
|
|
1901
1938
|
}
|
|
1902
|
-
isDurationObject(value) {
|
|
1903
|
-
return typeof value === "object" && value !== null && "value" in value && "unit" in value && value.unit !== void 0;
|
|
1904
|
-
}
|
|
1905
|
-
formatDurationValue(value) {
|
|
1906
|
-
if (typeof value === "string") {
|
|
1907
|
-
return value;
|
|
1908
|
-
}
|
|
1909
|
-
return `${value.value}${value.unit}`;
|
|
1910
|
-
}
|
|
1911
1939
|
/**
|
|
1912
1940
|
* Format token value for CSS
|
|
1913
1941
|
* Handles DTCG 2025.10 object formats for colors and dimensions
|
|
@@ -1928,8 +1956,8 @@ var CssRenderer = class _CssRenderer {
|
|
|
1928
1956
|
return typeof value === "string" ? value : dimensionObjectToString(value);
|
|
1929
1957
|
}
|
|
1930
1958
|
if (type === "duration") {
|
|
1931
|
-
if (
|
|
1932
|
-
return
|
|
1959
|
+
if (isDurationObject(value)) {
|
|
1960
|
+
return durationObjectToString(value);
|
|
1933
1961
|
}
|
|
1934
1962
|
if (typeof value === "string") {
|
|
1935
1963
|
return value;
|
|
@@ -2019,16 +2047,16 @@ var CssRenderer = class _CssRenderer {
|
|
|
2019
2047
|
*/
|
|
2020
2048
|
formatTransition(value) {
|
|
2021
2049
|
const parts = [];
|
|
2022
|
-
if (
|
|
2023
|
-
parts.push(
|
|
2050
|
+
if (isDurationObject(value.duration)) {
|
|
2051
|
+
parts.push(durationObjectToString(value.duration));
|
|
2024
2052
|
} else if (value.duration != null) {
|
|
2025
2053
|
parts.push(String(value.duration));
|
|
2026
2054
|
}
|
|
2027
2055
|
if (Array.isArray(value.timingFunction) && value.timingFunction.length === 4) {
|
|
2028
2056
|
parts.push(`cubic-bezier(${value.timingFunction.join(", ")})`);
|
|
2029
2057
|
}
|
|
2030
|
-
if (
|
|
2031
|
-
parts.push(
|
|
2058
|
+
if (isDurationObject(value.delay)) {
|
|
2059
|
+
parts.push(durationObjectToString(value.delay));
|
|
2032
2060
|
} else if (value.delay != null) {
|
|
2033
2061
|
parts.push(String(value.delay));
|
|
2034
2062
|
}
|
|
@@ -2038,7 +2066,7 @@ var CssRenderer = class _CssRenderer {
|
|
|
2038
2066
|
const bundleData = context.permutations.map(({ tokens, modifierInputs }) => ({
|
|
2039
2067
|
tokens,
|
|
2040
2068
|
modifierInputs,
|
|
2041
|
-
isBase:
|
|
2069
|
+
isBase: isBasePermutation(modifierInputs, context.meta.defaults)
|
|
2042
2070
|
}));
|
|
2043
2071
|
return await bundleAsCss(bundleData, context.resolver, options, async (tokens, resolved) => {
|
|
2044
2072
|
return await this.formatTokens(tokens, {
|
|
@@ -2048,12 +2076,12 @@ var CssRenderer = class _CssRenderer {
|
|
|
2048
2076
|
});
|
|
2049
2077
|
}
|
|
2050
2078
|
async formatStandalone(context, options) {
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2079
|
+
assertFileRequired(
|
|
2080
|
+
context.buildPath,
|
|
2081
|
+
context.output.file,
|
|
2082
|
+
context.output.name,
|
|
2083
|
+
"standalone CSS"
|
|
2084
|
+
);
|
|
2057
2085
|
const files = {};
|
|
2058
2086
|
for (const { tokens, modifierInputs } of context.permutations) {
|
|
2059
2087
|
const { fileName, content } = await this.buildStandaloneFile(
|
|
@@ -2067,7 +2095,7 @@ var CssRenderer = class _CssRenderer {
|
|
|
2067
2095
|
return { kind: "outputTree", files };
|
|
2068
2096
|
}
|
|
2069
2097
|
async buildStandaloneFile(tokens, modifierInputs, context, options) {
|
|
2070
|
-
const isBase =
|
|
2098
|
+
const isBase = isBasePermutation(modifierInputs, context.meta.defaults);
|
|
2071
2099
|
const { modifierName, modifierContext } = this.resolveModifierContext(
|
|
2072
2100
|
modifierInputs,
|
|
2073
2101
|
context,
|
|
@@ -2104,12 +2132,7 @@ var CssRenderer = class _CssRenderer {
|
|
|
2104
2132
|
return { fileName, content };
|
|
2105
2133
|
}
|
|
2106
2134
|
async formatModifier(context, options) {
|
|
2107
|
-
|
|
2108
|
-
if (!context.output.file && requiresFile) {
|
|
2109
|
-
throw new ConfigurationError(
|
|
2110
|
-
`Output "${context.output.name}": file is required for modifier CSS output`
|
|
2111
|
-
);
|
|
2112
|
-
}
|
|
2135
|
+
assertFileRequired(context.buildPath, context.output.file, context.output.name, "modifier CSS");
|
|
2113
2136
|
if (!context.resolver.modifiers) {
|
|
2114
2137
|
throw new ConfigurationError("Modifier preset requires modifiers to be defined in resolver");
|
|
2115
2138
|
}
|
|
@@ -2135,7 +2158,7 @@ var CssRenderer = class _CssRenderer {
|
|
|
2135
2158
|
}
|
|
2136
2159
|
async buildModifierBaseFile(context, options) {
|
|
2137
2160
|
const basePermutation = context.permutations.find(
|
|
2138
|
-
({ modifierInputs }) =>
|
|
2161
|
+
({ modifierInputs }) => isBasePermutation(modifierInputs, context.meta.defaults)
|
|
2139
2162
|
);
|
|
2140
2163
|
if (!basePermutation) {
|
|
2141
2164
|
return void 0;
|
|
@@ -2148,25 +2171,40 @@ var CssRenderer = class _CssRenderer {
|
|
|
2148
2171
|
if (setBlocks.length === 0) {
|
|
2149
2172
|
return void 0;
|
|
2150
2173
|
}
|
|
2174
|
+
const { selector, mediaQuery } = this.resolveBaseModifierContext(context, options);
|
|
2175
|
+
const content = await this.formatSetBlocksCss(
|
|
2176
|
+
setBlocks,
|
|
2177
|
+
basePermutation.tokens,
|
|
2178
|
+
selector,
|
|
2179
|
+
mediaQuery,
|
|
2180
|
+
options
|
|
2181
|
+
);
|
|
2182
|
+
const fileName = context.output.file ? resolveBaseFileName(context.output.file, context.meta.defaults) : `${context.output.name}-base.css`;
|
|
2183
|
+
return { fileName, content };
|
|
2184
|
+
}
|
|
2185
|
+
resolveBaseModifierContext(context, options) {
|
|
2151
2186
|
const modifiers = context.resolver.modifiers;
|
|
2152
2187
|
const firstModifierName = Object.keys(modifiers)[0] ?? "";
|
|
2153
2188
|
const firstModifierContext = context.meta.defaults[firstModifierName] ?? "";
|
|
2154
2189
|
const baseModifierInputs = { ...context.meta.defaults };
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2190
|
+
return {
|
|
2191
|
+
selector: resolveSelector(
|
|
2192
|
+
options.selector,
|
|
2193
|
+
firstModifierName,
|
|
2194
|
+
firstModifierContext,
|
|
2195
|
+
true,
|
|
2196
|
+
baseModifierInputs
|
|
2197
|
+
),
|
|
2198
|
+
mediaQuery: resolveMediaQuery(
|
|
2199
|
+
options.mediaQuery,
|
|
2200
|
+
firstModifierName,
|
|
2201
|
+
firstModifierContext,
|
|
2202
|
+
true,
|
|
2203
|
+
baseModifierInputs
|
|
2204
|
+
)
|
|
2205
|
+
};
|
|
2206
|
+
}
|
|
2207
|
+
async formatSetBlocksCss(setBlocks, referenceTokens, selector, mediaQuery, options) {
|
|
2170
2208
|
const cssBlocks = [];
|
|
2171
2209
|
for (const block of setBlocks) {
|
|
2172
2210
|
const cleanTokens = stripInternalMetadata(block.tokens);
|
|
@@ -2182,9 +2220,7 @@ var CssRenderer = class _CssRenderer {
|
|
|
2182
2220
|
cssBlocks.push(`${header}
|
|
2183
2221
|
${css2}`);
|
|
2184
2222
|
}
|
|
2185
|
-
|
|
2186
|
-
const fileName = context.output.file ? resolveBaseFileName(context.output.file, context.meta.defaults) : `${context.output.name}-base.css`;
|
|
2187
|
-
return { fileName, content };
|
|
2223
|
+
return cssBlocks.join("\n");
|
|
2188
2224
|
}
|
|
2189
2225
|
collectTokensForModifierContext(modifierName, contextValue, permutations) {
|
|
2190
2226
|
const expectedSource = `${modifierName}-${contextValue}`;
|
|
@@ -2261,13 +2297,6 @@ ${css2}`);
|
|
|
2261
2297
|
}
|
|
2262
2298
|
return { modifierName: "", modifierContext: "" };
|
|
2263
2299
|
}
|
|
2264
|
-
isBasePermutation(modifierInputs, defaults) {
|
|
2265
|
-
const normalizedInputs = normalizeModifierInputs(modifierInputs);
|
|
2266
|
-
const normalizedDefaults = normalizeModifierInputs(defaults);
|
|
2267
|
-
return Object.entries(normalizedDefaults).every(
|
|
2268
|
-
([key, value]) => normalizedInputs[key] === value
|
|
2269
|
-
);
|
|
2270
|
-
}
|
|
2271
2300
|
};
|
|
2272
2301
|
function cssRenderer() {
|
|
2273
2302
|
const rendererInstance = new CssRenderer();
|
|
@@ -2279,9 +2308,18 @@ function cssRenderer() {
|
|
|
2279
2308
|
};
|
|
2280
2309
|
}
|
|
2281
2310
|
|
|
2311
|
+
// src/tokens/types.ts
|
|
2312
|
+
function isShadowToken(token) {
|
|
2313
|
+
return token.$type === "shadow";
|
|
2314
|
+
}
|
|
2315
|
+
function isTypographyToken(token) {
|
|
2316
|
+
return token.$type === "typography";
|
|
2317
|
+
}
|
|
2318
|
+
function isBorderToken(token) {
|
|
2319
|
+
return token.$type === "border";
|
|
2320
|
+
}
|
|
2321
|
+
|
|
2282
2322
|
// src/renderers/ios.ts
|
|
2283
|
-
init_errors();
|
|
2284
|
-
init_token_utils();
|
|
2285
2323
|
init_utils();
|
|
2286
2324
|
var toSRGB2 = converter("rgb");
|
|
2287
2325
|
var toP32 = converter("p3");
|
|
@@ -2370,94 +2408,68 @@ var IosRenderer = class {
|
|
|
2370
2408
|
return await this.formatStandalone(context, opts);
|
|
2371
2409
|
}
|
|
2372
2410
|
formatTokens(tokens, options) {
|
|
2373
|
-
if (options.structure === "grouped") {
|
|
2374
|
-
return this.formatAsGrouped(tokens, options);
|
|
2375
|
-
}
|
|
2376
|
-
return this.formatAsEnum(tokens, options);
|
|
2377
|
-
}
|
|
2378
|
-
formatAsEnum(tokens, options) {
|
|
2379
2411
|
const access = options.accessLevel;
|
|
2380
|
-
const groups =
|
|
2412
|
+
const groups = groupTokensByType(tokens, SWIFT_TYPE_GROUP_MAP);
|
|
2381
2413
|
const imports = this.collectImports(tokens);
|
|
2382
|
-
const i1 = this.indentStr(options.indent, 1);
|
|
2383
|
-
const i2 = this.indentStr(options.indent, 2);
|
|
2384
2414
|
const staticPrefix = this.staticLetPrefix(options);
|
|
2385
2415
|
const frozen = this.frozenPrefix(options);
|
|
2386
2416
|
const lines = [];
|
|
2387
|
-
lines.push(
|
|
2417
|
+
lines.push(buildGeneratedFileHeader());
|
|
2388
2418
|
lines.push("");
|
|
2389
2419
|
for (const imp of imports) {
|
|
2390
2420
|
lines.push(`import ${imp}`);
|
|
2391
2421
|
}
|
|
2392
2422
|
lines.push(...this.buildStructDefinitions(tokens, access, options));
|
|
2423
|
+
this.pushTokenLayout(lines, groups, options, access, staticPrefix, frozen);
|
|
2424
|
+
lines.push(...this.buildViewExtensions(tokens, access, options));
|
|
2425
|
+
if (options.structure !== "grouped") {
|
|
2426
|
+
lines.push("");
|
|
2427
|
+
}
|
|
2428
|
+
return lines.join("\n");
|
|
2429
|
+
}
|
|
2430
|
+
pushTokenLayout(lines, groups, options, access, staticPrefix, frozen) {
|
|
2431
|
+
const i1 = indentStr(options.indent, 1);
|
|
2432
|
+
const i2 = indentStr(options.indent, 2);
|
|
2433
|
+
if (options.structure === "grouped") {
|
|
2434
|
+
this.pushGroupedLayout(lines, groups, options, access, i1, i2, staticPrefix, frozen);
|
|
2435
|
+
return;
|
|
2436
|
+
}
|
|
2393
2437
|
lines.push("");
|
|
2394
2438
|
lines.push(`${frozen}${access} enum ${options.enumName} {`);
|
|
2395
2439
|
for (const group of groups) {
|
|
2396
2440
|
lines.push(`${i1}${frozen}${access} enum ${group.name} {`);
|
|
2397
|
-
|
|
2398
|
-
const swiftName = this.buildQualifiedSwiftName(token);
|
|
2399
|
-
const swiftValue = this.formatSwiftValue(token, options);
|
|
2400
|
-
const typeAnnotation = this.getTypeAnnotation(token);
|
|
2401
|
-
const annotation = typeAnnotation ? `: ${typeAnnotation}` : "";
|
|
2402
|
-
const docComment = this.buildDocComment(token, i2);
|
|
2403
|
-
if (docComment) {
|
|
2404
|
-
lines.push(docComment);
|
|
2405
|
-
}
|
|
2406
|
-
lines.push(`${i2}${access} ${staticPrefix}${swiftName}${annotation} = ${swiftValue}`);
|
|
2407
|
-
}
|
|
2441
|
+
this.pushTokenDeclarations(lines, group.tokens, options, access, i2, staticPrefix);
|
|
2408
2442
|
lines.push(`${i1}}`);
|
|
2409
2443
|
lines.push("");
|
|
2410
2444
|
}
|
|
2411
2445
|
lines.push("}");
|
|
2412
|
-
lines.push(...this.buildViewExtensions(tokens, access, options));
|
|
2413
|
-
lines.push("");
|
|
2414
|
-
return lines.join("\n");
|
|
2415
2446
|
}
|
|
2416
|
-
|
|
2417
|
-
const access = options.accessLevel;
|
|
2447
|
+
pushGroupedLayout(lines, groups, options, access, i1, i2, staticPrefix, frozen) {
|
|
2418
2448
|
const namespace = options.extensionNamespace;
|
|
2419
|
-
const groups = this.groupTokensByType(tokens);
|
|
2420
|
-
const imports = this.collectImports(tokens);
|
|
2421
|
-
const i1 = this.indentStr(options.indent, 1);
|
|
2422
|
-
const i2 = this.indentStr(options.indent, 2);
|
|
2423
|
-
const staticPrefix = this.staticLetPrefix(options);
|
|
2424
|
-
const frozen = this.frozenPrefix(options);
|
|
2425
|
-
const lines = [];
|
|
2426
|
-
lines.push(this.buildFileHeader());
|
|
2427
|
-
lines.push("");
|
|
2428
|
-
for (const imp of imports) {
|
|
2429
|
-
lines.push(`import ${imp}`);
|
|
2430
|
-
}
|
|
2431
|
-
lines.push(...this.buildStructDefinitions(tokens, access, options));
|
|
2432
2449
|
lines.push("");
|
|
2433
2450
|
lines.push(`${frozen}${access} enum ${namespace} {}`);
|
|
2434
2451
|
lines.push("");
|
|
2435
2452
|
for (const group of groups) {
|
|
2436
2453
|
lines.push(`${access} extension ${namespace} {`);
|
|
2437
2454
|
lines.push(`${i1}${frozen}enum ${group.name} {`);
|
|
2438
|
-
|
|
2439
|
-
const swiftName = this.buildQualifiedSwiftName(token);
|
|
2440
|
-
const swiftValue = this.formatSwiftValue(token, options);
|
|
2441
|
-
const typeAnnotation = this.getTypeAnnotation(token);
|
|
2442
|
-
const annotation = typeAnnotation ? `: ${typeAnnotation}` : "";
|
|
2443
|
-
const docComment = this.buildDocComment(token, i2);
|
|
2444
|
-
if (docComment) {
|
|
2445
|
-
lines.push(docComment);
|
|
2446
|
-
}
|
|
2447
|
-
lines.push(`${i2}${access} ${staticPrefix}${swiftName}${annotation} = ${swiftValue}`);
|
|
2448
|
-
}
|
|
2455
|
+
this.pushTokenDeclarations(lines, group.tokens, options, access, i2, staticPrefix);
|
|
2449
2456
|
lines.push(`${i1}}`);
|
|
2450
2457
|
lines.push("}");
|
|
2451
2458
|
lines.push("");
|
|
2452
2459
|
}
|
|
2453
|
-
lines.push(...this.buildViewExtensions(tokens, access, options));
|
|
2454
|
-
return lines.join("\n");
|
|
2455
2460
|
}
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
+
pushTokenDeclarations(lines, tokens, options, access, indent, staticPrefix) {
|
|
2462
|
+
for (const token of tokens) {
|
|
2463
|
+
const swiftName = this.buildQualifiedSwiftName(token);
|
|
2464
|
+
const swiftValue = this.formatSwiftValue(token, options);
|
|
2465
|
+
const typeAnnotation = this.getTypeAnnotation(token);
|
|
2466
|
+
const annotation = typeAnnotation ? `: ${typeAnnotation}` : "";
|
|
2467
|
+
const docComment = this.buildDocComment(token, indent);
|
|
2468
|
+
if (docComment) {
|
|
2469
|
+
lines.push(docComment);
|
|
2470
|
+
}
|
|
2471
|
+
lines.push(`${indent}${access} ${staticPrefix}${swiftName}${annotation} = ${swiftValue}`);
|
|
2472
|
+
}
|
|
2461
2473
|
}
|
|
2462
2474
|
collectImports(tokens) {
|
|
2463
2475
|
const imports = /* @__PURE__ */ new Set();
|
|
@@ -2472,24 +2484,11 @@ var IosRenderer = class {
|
|
|
2472
2484
|
/**
|
|
2473
2485
|
* Builds a `///` doc comment from a token's `$description`, if present.
|
|
2474
2486
|
*/
|
|
2475
|
-
buildDocComment(token,
|
|
2487
|
+
buildDocComment(token, indent) {
|
|
2476
2488
|
if (!token.$description) {
|
|
2477
2489
|
return void 0;
|
|
2478
2490
|
}
|
|
2479
|
-
return `${
|
|
2480
|
-
}
|
|
2481
|
-
groupTokensByType(tokens) {
|
|
2482
|
-
const groupMap = /* @__PURE__ */ new Map();
|
|
2483
|
-
for (const [, token] of getSortedTokenEntries(tokens)) {
|
|
2484
|
-
const groupName = SWIFT_TYPE_GROUP_MAP[token.$type ?? ""] ?? "Other";
|
|
2485
|
-
const existing = groupMap.get(groupName) ?? [];
|
|
2486
|
-
existing.push(token);
|
|
2487
|
-
groupMap.set(groupName, existing);
|
|
2488
|
-
}
|
|
2489
|
-
return Array.from(groupMap.entries()).map(([name, groupTokens]) => ({
|
|
2490
|
-
name,
|
|
2491
|
-
tokens: groupTokens
|
|
2492
|
-
}));
|
|
2491
|
+
return `${indent}/// ${token.$description}`;
|
|
2493
2492
|
}
|
|
2494
2493
|
/**
|
|
2495
2494
|
* Builds a qualified Swift name from a token's path, preserving parent
|
|
@@ -2502,43 +2501,40 @@ var IosRenderer = class {
|
|
|
2502
2501
|
const path = token.path;
|
|
2503
2502
|
const withoutTypePrefix = path.length > 1 ? path.slice(1) : path;
|
|
2504
2503
|
const joined = withoutTypePrefix.join("_");
|
|
2505
|
-
return
|
|
2504
|
+
return toSafeIdentifier(joined, SWIFT_KEYWORDS, false);
|
|
2506
2505
|
}
|
|
2507
2506
|
formatSwiftValue(token, options) {
|
|
2508
|
-
const value = token
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
}
|
|
2536
|
-
if (token.$type === "number") {
|
|
2537
|
-
return String(value);
|
|
2538
|
-
}
|
|
2539
|
-
if (token.$type === "cubicBezier" && Array.isArray(value) && value.length === 4) {
|
|
2540
|
-
return `UnitCurve.bezier(startControlPoint: UnitPoint(x: ${value[0]}, y: ${value[1]}), endControlPoint: UnitPoint(x: ${value[2]}, y: ${value[3]}))`;
|
|
2507
|
+
const { $type, $value: value } = token;
|
|
2508
|
+
switch ($type) {
|
|
2509
|
+
case "color":
|
|
2510
|
+
return this.formatColorValue(value, options);
|
|
2511
|
+
case "dimension":
|
|
2512
|
+
return this.formatDimensionValue(value);
|
|
2513
|
+
case "fontFamily":
|
|
2514
|
+
return this.formatFontFamilyValue(value);
|
|
2515
|
+
case "fontWeight":
|
|
2516
|
+
return this.formatFontWeightValue(value);
|
|
2517
|
+
case "duration":
|
|
2518
|
+
return this.formatDurationValue(value);
|
|
2519
|
+
case "shadow":
|
|
2520
|
+
return this.formatShadowValue(value, options);
|
|
2521
|
+
case "typography":
|
|
2522
|
+
return this.formatTypographyValue(value);
|
|
2523
|
+
case "border":
|
|
2524
|
+
return this.formatBorderValue(value, options);
|
|
2525
|
+
case "gradient":
|
|
2526
|
+
return this.formatGradientValue(value, options);
|
|
2527
|
+
case "number":
|
|
2528
|
+
return String(value);
|
|
2529
|
+
case "cubicBezier":
|
|
2530
|
+
if (Array.isArray(value) && value.length === 4) {
|
|
2531
|
+
return `UnitCurve.bezier(startControlPoint: UnitPoint(x: ${value[0]}, y: ${value[1]}), endControlPoint: UnitPoint(x: ${value[2]}, y: ${value[3]}))`;
|
|
2532
|
+
}
|
|
2533
|
+
break;
|
|
2541
2534
|
}
|
|
2535
|
+
return this.formatSwiftPrimitive(value);
|
|
2536
|
+
}
|
|
2537
|
+
formatSwiftPrimitive(value) {
|
|
2542
2538
|
if (typeof value === "string") {
|
|
2543
2539
|
return `"${this.escapeSwiftString(value)}"`;
|
|
2544
2540
|
}
|
|
@@ -2571,9 +2567,7 @@ var IosRenderer = class {
|
|
|
2571
2567
|
}
|
|
2572
2568
|
formatDimensionValue(value) {
|
|
2573
2569
|
if (isDimensionObject(value)) {
|
|
2574
|
-
|
|
2575
|
-
const ptValue = dim.unit === "rem" ? dim.value * 16 : dim.value;
|
|
2576
|
-
return String(ptValue);
|
|
2570
|
+
return this.dimensionToPoints(value);
|
|
2577
2571
|
}
|
|
2578
2572
|
return String(value);
|
|
2579
2573
|
}
|
|
@@ -2640,7 +2634,7 @@ var IosRenderer = class {
|
|
|
2640
2634
|
return map[name.toLowerCase()];
|
|
2641
2635
|
}
|
|
2642
2636
|
formatDurationValue(value) {
|
|
2643
|
-
if (
|
|
2637
|
+
if (isDurationObject(value)) {
|
|
2644
2638
|
const dur = value;
|
|
2645
2639
|
const seconds = dur.unit === "ms" ? dur.value / 1e3 : dur.value;
|
|
2646
2640
|
return String(seconds);
|
|
@@ -2689,9 +2683,7 @@ var IosRenderer = class {
|
|
|
2689
2683
|
if (!isDimensionObject(typo.letterSpacing)) {
|
|
2690
2684
|
return "0";
|
|
2691
2685
|
}
|
|
2692
|
-
|
|
2693
|
-
const ptValue = dim.unit === "rem" ? dim.value * 16 : dim.value;
|
|
2694
|
-
return String(ptValue);
|
|
2686
|
+
return this.dimensionToPoints(typo.letterSpacing);
|
|
2695
2687
|
}
|
|
2696
2688
|
extractLineSpacing(typo) {
|
|
2697
2689
|
if (typo.lineHeight == null || typeof typo.lineHeight !== "number") {
|
|
@@ -2700,18 +2692,19 @@ var IosRenderer = class {
|
|
|
2700
2692
|
if (!isDimensionObject(typo.fontSize)) {
|
|
2701
2693
|
return "0";
|
|
2702
2694
|
}
|
|
2703
|
-
const
|
|
2704
|
-
const basePt = dim.unit === "rem" ? dim.value * 16 : dim.value;
|
|
2695
|
+
const basePt = this.dimensionToNumericPoints(typo.fontSize);
|
|
2705
2696
|
const lineHeightPt = Math.round(basePt * typo.lineHeight * 100) / 100;
|
|
2706
2697
|
return String(lineHeightPt - basePt);
|
|
2707
2698
|
}
|
|
2699
|
+
dimensionToNumericPoints(dim) {
|
|
2700
|
+
return dim.unit === "rem" ? dim.value * 16 : dim.value;
|
|
2701
|
+
}
|
|
2708
2702
|
dimensionToPoints(dim) {
|
|
2709
|
-
|
|
2710
|
-
return String(ptValue);
|
|
2703
|
+
return String(this.dimensionToNumericPoints(dim));
|
|
2711
2704
|
}
|
|
2712
2705
|
/** Formats a dimension as a CGFloat literal (appends `.0` for integers). */
|
|
2713
2706
|
dimensionToCGFloat(dim) {
|
|
2714
|
-
const ptValue =
|
|
2707
|
+
const ptValue = this.dimensionToNumericPoints(dim);
|
|
2715
2708
|
return Number.isInteger(ptValue) ? `${ptValue}.0` : String(ptValue);
|
|
2716
2709
|
}
|
|
2717
2710
|
getTypeAnnotation(token) {
|
|
@@ -2730,21 +2723,12 @@ var IosRenderer = class {
|
|
|
2730
2723
|
return void 0;
|
|
2731
2724
|
}
|
|
2732
2725
|
}
|
|
2733
|
-
toSwiftIdentifier(name) {
|
|
2734
|
-
const camel = name.replace(/[-._]+(.)/g, (_, c) => c.toUpperCase()).replace(/[-._]+$/g, "").replace(/^[-._]+/g, "");
|
|
2735
|
-
const identifier = camel.charAt(0).toLowerCase() + camel.slice(1);
|
|
2736
|
-
const safe = /^\d/.test(identifier) ? `_${identifier}` : identifier;
|
|
2737
|
-
return SWIFT_KEYWORDS.has(safe) ? `\`${safe}\`` : safe;
|
|
2738
|
-
}
|
|
2739
2726
|
escapeSwiftString(str) {
|
|
2740
2727
|
return str.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n");
|
|
2741
2728
|
}
|
|
2742
2729
|
roundComponent(value) {
|
|
2743
2730
|
return Math.round(value * 1e4) / 1e4;
|
|
2744
2731
|
}
|
|
2745
|
-
indentStr(width, level) {
|
|
2746
|
-
return " ".repeat(width * level);
|
|
2747
|
-
}
|
|
2748
2732
|
/**
|
|
2749
2733
|
* Returns the prefix for `static let` declarations.
|
|
2750
2734
|
* Swift 6 requires `nonisolated(unsafe)` on global stored properties.
|
|
@@ -2760,34 +2744,25 @@ var IosRenderer = class {
|
|
|
2760
2744
|
structConformances(options) {
|
|
2761
2745
|
return options.swiftVersion === "6.0" ? ": Sendable" : "";
|
|
2762
2746
|
}
|
|
2763
|
-
hasShadowTokens(tokens) {
|
|
2764
|
-
return Object.values(tokens).some((t) => t.$type === "shadow");
|
|
2765
|
-
}
|
|
2766
|
-
hasTypographyTokens(tokens) {
|
|
2767
|
-
return Object.values(tokens).some((t) => t.$type === "typography");
|
|
2768
|
-
}
|
|
2769
|
-
hasBorderTokens(tokens) {
|
|
2770
|
-
return Object.values(tokens).some((t) => t.$type === "border");
|
|
2771
|
-
}
|
|
2772
2747
|
/** Emits all struct definitions needed by the token set. */
|
|
2773
2748
|
buildStructDefinitions(tokens, access, options) {
|
|
2774
2749
|
const lines = [];
|
|
2775
|
-
if (
|
|
2750
|
+
if (Object.values(tokens).some(isShadowToken)) {
|
|
2776
2751
|
lines.push("");
|
|
2777
2752
|
lines.push(...this.buildShadowStyleStruct(access, options));
|
|
2778
2753
|
}
|
|
2779
|
-
if (
|
|
2754
|
+
if (Object.values(tokens).some(isTypographyToken)) {
|
|
2780
2755
|
lines.push("");
|
|
2781
2756
|
lines.push(...this.buildTypographyStyleStruct(access, options));
|
|
2782
2757
|
}
|
|
2783
|
-
if (
|
|
2758
|
+
if (Object.values(tokens).some(isBorderToken)) {
|
|
2784
2759
|
lines.push("");
|
|
2785
2760
|
lines.push(...this.buildBorderStyleStruct(access, options));
|
|
2786
2761
|
}
|
|
2787
2762
|
return lines;
|
|
2788
2763
|
}
|
|
2789
2764
|
buildShadowStyleStruct(access, options) {
|
|
2790
|
-
const i1 =
|
|
2765
|
+
const i1 = indentStr(options.indent, 1);
|
|
2791
2766
|
const conformances = this.structConformances(options);
|
|
2792
2767
|
const frozen = this.frozenPrefix(options);
|
|
2793
2768
|
return [
|
|
@@ -2801,7 +2776,7 @@ var IosRenderer = class {
|
|
|
2801
2776
|
];
|
|
2802
2777
|
}
|
|
2803
2778
|
buildTypographyStyleStruct(access, options) {
|
|
2804
|
-
const i1 =
|
|
2779
|
+
const i1 = indentStr(options.indent, 1);
|
|
2805
2780
|
const conformances = this.structConformances(options);
|
|
2806
2781
|
const frozen = this.frozenPrefix(options);
|
|
2807
2782
|
return [
|
|
@@ -2813,7 +2788,7 @@ var IosRenderer = class {
|
|
|
2813
2788
|
];
|
|
2814
2789
|
}
|
|
2815
2790
|
buildBorderStyleStruct(access, options) {
|
|
2816
|
-
const i1 =
|
|
2791
|
+
const i1 = indentStr(options.indent, 1);
|
|
2817
2792
|
const conformances = this.structConformances(options);
|
|
2818
2793
|
const frozen = this.frozenPrefix(options);
|
|
2819
2794
|
return [
|
|
@@ -2826,9 +2801,9 @@ var IosRenderer = class {
|
|
|
2826
2801
|
/** Emits convenience View extensions for shadow and typography application. */
|
|
2827
2802
|
buildViewExtensions(tokens, access, options) {
|
|
2828
2803
|
const lines = [];
|
|
2829
|
-
const i1 =
|
|
2830
|
-
const i2 =
|
|
2831
|
-
if (
|
|
2804
|
+
const i1 = indentStr(options.indent, 1);
|
|
2805
|
+
const i2 = indentStr(options.indent, 2);
|
|
2806
|
+
if (Object.values(tokens).some(isShadowToken)) {
|
|
2832
2807
|
lines.push("");
|
|
2833
2808
|
lines.push(`${access} extension View {`);
|
|
2834
2809
|
lines.push(`${i1}func shadowStyle(_ style: ShadowStyle) -> some View {`);
|
|
@@ -2838,7 +2813,7 @@ var IosRenderer = class {
|
|
|
2838
2813
|
lines.push(`${i1}}`);
|
|
2839
2814
|
lines.push("}");
|
|
2840
2815
|
}
|
|
2841
|
-
if (
|
|
2816
|
+
if (Object.values(tokens).some(isTypographyToken)) {
|
|
2842
2817
|
lines.push("");
|
|
2843
2818
|
lines.push(`${access} extension View {`);
|
|
2844
2819
|
lines.push(`${i1}func typographyStyle(_ style: TypographyStyle) -> some View {`);
|
|
@@ -2870,12 +2845,12 @@ var IosRenderer = class {
|
|
|
2870
2845
|
return `Gradient(stops: [${stops.join(", ")}])`;
|
|
2871
2846
|
}
|
|
2872
2847
|
async formatStandalone(context, options) {
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
|
|
2848
|
+
assertFileRequired(
|
|
2849
|
+
context.buildPath,
|
|
2850
|
+
context.output.file,
|
|
2851
|
+
context.output.name,
|
|
2852
|
+
"standalone iOS"
|
|
2853
|
+
);
|
|
2879
2854
|
const files = {};
|
|
2880
2855
|
for (const { tokens, modifierInputs } of context.permutations) {
|
|
2881
2856
|
const processedTokens = stripInternalMetadata(tokens);
|
|
@@ -2904,7 +2879,6 @@ function iosRenderer() {
|
|
|
2904
2879
|
|
|
2905
2880
|
// src/renderers/js-module.ts
|
|
2906
2881
|
init_utils();
|
|
2907
|
-
init_errors();
|
|
2908
2882
|
init_token_utils();
|
|
2909
2883
|
var JsModuleRenderer = class {
|
|
2910
2884
|
async format(context, options) {
|
|
@@ -2920,18 +2894,13 @@ var JsModuleRenderer = class {
|
|
|
2920
2894
|
const bundleData = context.permutations.map(({ tokens, modifierInputs }) => ({
|
|
2921
2895
|
tokens: stripInternalMetadata(tokens),
|
|
2922
2896
|
modifierInputs,
|
|
2923
|
-
isBase:
|
|
2897
|
+
isBase: isBasePermutation(modifierInputs, context.meta.defaults)
|
|
2924
2898
|
}));
|
|
2925
2899
|
return await bundleAsJsModule2(bundleData, context.resolver, opts, async (tokens) => {
|
|
2926
2900
|
return await this.formatTokens(tokens, opts);
|
|
2927
2901
|
});
|
|
2928
2902
|
}
|
|
2929
|
-
|
|
2930
|
-
if (!context.output.file && requiresFile) {
|
|
2931
|
-
throw new ConfigurationError(
|
|
2932
|
-
`Output "${context.output.name}": file is required for JS module output`
|
|
2933
|
-
);
|
|
2934
|
-
}
|
|
2903
|
+
assertFileRequired(context.buildPath, context.output.file, context.output.name, "JS module");
|
|
2935
2904
|
const files = {};
|
|
2936
2905
|
for (const { tokens, modifierInputs } of context.permutations) {
|
|
2937
2906
|
const cleanTokens = stripInternalMetadata(tokens);
|
|
@@ -2985,42 +2954,18 @@ var JsModuleRenderer = class {
|
|
|
2985
2954
|
lines.push(`export default ${varName}`);
|
|
2986
2955
|
return lines;
|
|
2987
2956
|
}
|
|
2988
|
-
/**
|
|
2989
|
-
* Convert tokens to plain object with flat or nested structure
|
|
2990
|
-
*/
|
|
2991
2957
|
tokensToPlainObject(tokens, structure) {
|
|
2958
|
+
if (structure === "nested") {
|
|
2959
|
+
return buildNestedTokenObject(tokens, (token) => token.$value);
|
|
2960
|
+
}
|
|
2992
2961
|
const result = {};
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
result[name] = token.$value;
|
|
2996
|
-
}
|
|
2997
|
-
} else {
|
|
2998
|
-
for (const [, token] of getSortedTokenEntries(tokens)) {
|
|
2999
|
-
const parts = token.path;
|
|
3000
|
-
let current = result;
|
|
3001
|
-
for (let i = 0; i < parts.length - 1; i++) {
|
|
3002
|
-
const part = parts[i];
|
|
3003
|
-
if (part == null) {
|
|
3004
|
-
continue;
|
|
3005
|
-
}
|
|
3006
|
-
if (!(part in current)) {
|
|
3007
|
-
current[part] = {};
|
|
3008
|
-
}
|
|
3009
|
-
current = current[part];
|
|
3010
|
-
}
|
|
3011
|
-
const lastPart = parts[parts.length - 1];
|
|
3012
|
-
if (lastPart != null) {
|
|
3013
|
-
current[lastPart] = token.$value;
|
|
3014
|
-
}
|
|
3015
|
-
}
|
|
2962
|
+
for (const [name, token] of getSortedTokenEntries(tokens)) {
|
|
2963
|
+
result[name] = token.$value;
|
|
3016
2964
|
}
|
|
3017
2965
|
return result;
|
|
3018
2966
|
}
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
*/
|
|
3022
|
-
addObjectProperties(lines, obj, indent2) {
|
|
3023
|
-
const indentStr = " ".repeat(indent2);
|
|
2967
|
+
addObjectProperties(lines, obj, indent) {
|
|
2968
|
+
const indentStr2 = " ".repeat(indent);
|
|
3024
2969
|
const entries = Object.entries(obj).sort(([keyA], [keyB]) => keyA.localeCompare(keyB));
|
|
3025
2970
|
for (let i = 0; i < entries.length; i++) {
|
|
3026
2971
|
const entry = entries[i];
|
|
@@ -3029,14 +2974,16 @@ var JsModuleRenderer = class {
|
|
|
3029
2974
|
}
|
|
3030
2975
|
const [key, value] = entry;
|
|
3031
2976
|
const isLast = i === entries.length - 1;
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
lines.push(`${indentStr}${this.quoteKey(key)}: ${valueStr}${isLast ? "" : ","}`);
|
|
2977
|
+
const isNestedObject = typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2978
|
+
if (!isNestedObject) {
|
|
2979
|
+
lines.push(
|
|
2980
|
+
`${indentStr2}${this.quoteKey(key)}: ${JSON.stringify(value)}${isLast ? "" : ","}`
|
|
2981
|
+
);
|
|
2982
|
+
continue;
|
|
3039
2983
|
}
|
|
2984
|
+
lines.push(`${indentStr2}${this.quoteKey(key)}: {`);
|
|
2985
|
+
this.addObjectProperties(lines, value, indent + 1);
|
|
2986
|
+
lines.push(`${indentStr2}}${isLast ? "" : ","}`);
|
|
3040
2987
|
}
|
|
3041
2988
|
}
|
|
3042
2989
|
/**
|
|
@@ -3048,9 +2995,6 @@ var JsModuleRenderer = class {
|
|
|
3048
2995
|
}
|
|
3049
2996
|
return `"${key}"`;
|
|
3050
2997
|
}
|
|
3051
|
-
isBasePermutation(modifierInputs, defaults) {
|
|
3052
|
-
return Object.entries(modifierInputs).every(([key, value]) => value === defaults[key]);
|
|
3053
|
-
}
|
|
3054
2998
|
};
|
|
3055
2999
|
function jsRenderer() {
|
|
3056
3000
|
const rendererInstance = new JsModuleRenderer();
|
|
@@ -3064,7 +3008,6 @@ function jsRenderer() {
|
|
|
3064
3008
|
|
|
3065
3009
|
// src/renderers/json.ts
|
|
3066
3010
|
init_utils();
|
|
3067
|
-
init_errors();
|
|
3068
3011
|
init_token_utils();
|
|
3069
3012
|
var JsonRenderer = class {
|
|
3070
3013
|
async format(context, options) {
|
|
@@ -3079,18 +3022,13 @@ var JsonRenderer = class {
|
|
|
3079
3022
|
const bundleData = context.permutations.map(({ tokens, modifierInputs }) => ({
|
|
3080
3023
|
tokens: stripInternalMetadata(tokens),
|
|
3081
3024
|
modifierInputs,
|
|
3082
|
-
isBase:
|
|
3025
|
+
isBase: isBasePermutation(modifierInputs, context.meta.defaults)
|
|
3083
3026
|
}));
|
|
3084
3027
|
return await bundleAsJson2(bundleData, context.resolver, async (tokens) => {
|
|
3085
3028
|
return await this.formatTokens(tokens, opts);
|
|
3086
3029
|
});
|
|
3087
3030
|
}
|
|
3088
|
-
|
|
3089
|
-
if (!context.output.file && requiresFile) {
|
|
3090
|
-
throw new ConfigurationError(
|
|
3091
|
-
`Output "${context.output.name}": file is required for JSON output`
|
|
3092
|
-
);
|
|
3093
|
-
}
|
|
3031
|
+
assertFileRequired(context.buildPath, context.output.file, context.output.name, "JSON");
|
|
3094
3032
|
const files = {};
|
|
3095
3033
|
for (const { tokens, modifierInputs } of context.permutations) {
|
|
3096
3034
|
const processedTokens = stripInternalMetadata(tokens);
|
|
@@ -3150,55 +3088,11 @@ var JsonRenderer = class {
|
|
|
3150
3088
|
}
|
|
3151
3089
|
return result;
|
|
3152
3090
|
}
|
|
3153
|
-
/**
|
|
3154
|
-
* Nest tokens by path (values only)
|
|
3155
|
-
*/
|
|
3156
3091
|
nestValues(tokens) {
|
|
3157
|
-
|
|
3158
|
-
for (const [, token] of getSortedTokenEntries(tokens)) {
|
|
3159
|
-
const parts = token.path;
|
|
3160
|
-
let current = result;
|
|
3161
|
-
for (let i = 0; i < parts.length - 1; i++) {
|
|
3162
|
-
const part = parts[i];
|
|
3163
|
-
if (part === null || part === void 0) {
|
|
3164
|
-
continue;
|
|
3165
|
-
}
|
|
3166
|
-
if (!(part in current)) {
|
|
3167
|
-
current[part] = {};
|
|
3168
|
-
}
|
|
3169
|
-
current = current[part];
|
|
3170
|
-
}
|
|
3171
|
-
const lastPart = parts[parts.length - 1];
|
|
3172
|
-
if (lastPart !== null && lastPart !== void 0) {
|
|
3173
|
-
current[lastPart] = token.$value;
|
|
3174
|
-
}
|
|
3175
|
-
}
|
|
3176
|
-
return result;
|
|
3092
|
+
return buildNestedTokenObject(tokens, (token) => token.$value);
|
|
3177
3093
|
}
|
|
3178
|
-
/**
|
|
3179
|
-
* Nest tokens by path (with metadata)
|
|
3180
|
-
*/
|
|
3181
3094
|
nestTokens(tokens) {
|
|
3182
|
-
|
|
3183
|
-
for (const [, token] of getSortedTokenEntries(tokens)) {
|
|
3184
|
-
const parts = token.path;
|
|
3185
|
-
let current = result;
|
|
3186
|
-
for (let i = 0; i < parts.length - 1; i++) {
|
|
3187
|
-
const part = parts[i];
|
|
3188
|
-
if (part === null || part === void 0) {
|
|
3189
|
-
continue;
|
|
3190
|
-
}
|
|
3191
|
-
if (!(part in current)) {
|
|
3192
|
-
current[part] = {};
|
|
3193
|
-
}
|
|
3194
|
-
current = current[part];
|
|
3195
|
-
}
|
|
3196
|
-
const lastPart = parts[parts.length - 1];
|
|
3197
|
-
if (lastPart !== null && lastPart !== void 0) {
|
|
3198
|
-
current[lastPart] = this.serializeToken(token);
|
|
3199
|
-
}
|
|
3200
|
-
}
|
|
3201
|
-
return result;
|
|
3095
|
+
return buildNestedTokenObject(tokens, (token) => this.serializeToken(token));
|
|
3202
3096
|
}
|
|
3203
3097
|
serializeToken(token) {
|
|
3204
3098
|
return {
|
|
@@ -3209,9 +3103,6 @@ var JsonRenderer = class {
|
|
|
3209
3103
|
...token.$extensions != null && { $extensions: token.$extensions }
|
|
3210
3104
|
};
|
|
3211
3105
|
}
|
|
3212
|
-
isBasePermutation(modifierInputs, defaults) {
|
|
3213
|
-
return Object.entries(modifierInputs).every(([key, value]) => value === defaults[key]);
|
|
3214
|
-
}
|
|
3215
3106
|
};
|
|
3216
3107
|
function jsonRenderer() {
|
|
3217
3108
|
const rendererInstance = new JsonRenderer();
|
|
@@ -3224,7 +3115,6 @@ function jsonRenderer() {
|
|
|
3224
3115
|
}
|
|
3225
3116
|
|
|
3226
3117
|
// src/renderers/tailwind.ts
|
|
3227
|
-
init_errors();
|
|
3228
3118
|
init_token_utils();
|
|
3229
3119
|
|
|
3230
3120
|
// src/renderers/bundlers/tailwind.ts
|
|
@@ -3253,6 +3143,13 @@ async function bundleAsTailwind(bundleData, options, formatThemeTokens, formatOv
|
|
|
3253
3143
|
}
|
|
3254
3144
|
return cssBlocks.join("\n");
|
|
3255
3145
|
}
|
|
3146
|
+
function resolveModifierSelectorAndMedia(options, modifier, context, modifierInputs) {
|
|
3147
|
+
const normalized = normalizeModifierInputs(modifierInputs);
|
|
3148
|
+
return {
|
|
3149
|
+
selector: resolveSelector(options.selector, modifier, context, false, normalized),
|
|
3150
|
+
mediaQuery: resolveMediaQuery(options.mediaQuery, modifier, context, false, normalized)
|
|
3151
|
+
};
|
|
3152
|
+
}
|
|
3256
3153
|
async function formatModifierOverride({ tokens, modifierInputs }, baseItem, options, formatOverrideBlock) {
|
|
3257
3154
|
const differenceCount = countModifierDifferences(modifierInputs, baseItem.modifierInputs);
|
|
3258
3155
|
if (differenceCount > 1) {
|
|
@@ -3265,19 +3162,11 @@ async function formatModifierOverride({ tokens, modifierInputs }, baseItem, opti
|
|
|
3265
3162
|
const expectedSource = getExpectedSource(modifierInputs, baseItem.modifierInputs);
|
|
3266
3163
|
const [modifier, context] = parseModifierSource(expectedSource);
|
|
3267
3164
|
const cleanTokens = stripInternalMetadata(tokensToInclude);
|
|
3268
|
-
const selector =
|
|
3269
|
-
options
|
|
3270
|
-
modifier,
|
|
3271
|
-
context,
|
|
3272
|
-
false,
|
|
3273
|
-
normalizeModifierInputs(modifierInputs)
|
|
3274
|
-
);
|
|
3275
|
-
const mediaQuery = resolveMediaQuery(
|
|
3276
|
-
options.mediaQuery,
|
|
3165
|
+
const { selector, mediaQuery } = resolveModifierSelectorAndMedia(
|
|
3166
|
+
options,
|
|
3277
3167
|
modifier,
|
|
3278
3168
|
context,
|
|
3279
|
-
|
|
3280
|
-
normalizeModifierInputs(modifierInputs)
|
|
3169
|
+
modifierInputs
|
|
3281
3170
|
);
|
|
3282
3171
|
const css2 = await formatOverrideBlock(cleanTokens, selector, mediaQuery, options.minify);
|
|
3283
3172
|
return `/* Modifier: ${modifier}=${context} */
|
|
@@ -3366,7 +3255,7 @@ var TailwindRenderer = class {
|
|
|
3366
3255
|
*/
|
|
3367
3256
|
async formatTokens(tokens, options) {
|
|
3368
3257
|
const lines = [];
|
|
3369
|
-
const
|
|
3258
|
+
const indent = options.minify ? "" : " ";
|
|
3370
3259
|
const newline = options.minify ? "" : "\n";
|
|
3371
3260
|
const space = options.minify ? "" : " ";
|
|
3372
3261
|
if (options.includeImport) {
|
|
@@ -3388,7 +3277,7 @@ var TailwindRenderer = class {
|
|
|
3388
3277
|
for (const [, token] of getSortedTokenEntries(tokens)) {
|
|
3389
3278
|
const varName = this.buildVariableName(token);
|
|
3390
3279
|
const varValue = this.formatValue(token);
|
|
3391
|
-
lines.push(`${
|
|
3280
|
+
lines.push(`${indent}--${varName}:${space}${varValue};${newline}`);
|
|
3392
3281
|
}
|
|
3393
3282
|
lines.push(`}${newline}`);
|
|
3394
3283
|
const cssString = lines.join("");
|
|
@@ -3399,15 +3288,15 @@ var TailwindRenderer = class {
|
|
|
3399
3288
|
* Used for modifier overrides (e.g., dark mode) appended after the @theme block.
|
|
3400
3289
|
*/
|
|
3401
3290
|
async formatOverrideBlock(tokens, selector, mediaQuery, minify) {
|
|
3402
|
-
const
|
|
3291
|
+
const indent = minify ? "" : " ";
|
|
3403
3292
|
const newline = minify ? "" : "\n";
|
|
3404
3293
|
const space = minify ? "" : " ";
|
|
3405
3294
|
const hasMediaQuery = mediaQuery !== "";
|
|
3406
|
-
const tokenIndent = hasMediaQuery ?
|
|
3295
|
+
const tokenIndent = hasMediaQuery ? indent + indent : indent;
|
|
3407
3296
|
const lines = [];
|
|
3408
3297
|
if (hasMediaQuery) {
|
|
3409
3298
|
lines.push(`@media ${mediaQuery}${space}{${newline}`);
|
|
3410
|
-
lines.push(`${
|
|
3299
|
+
lines.push(`${indent}${selector}${space}{${newline}`);
|
|
3411
3300
|
} else {
|
|
3412
3301
|
lines.push(`${selector}${space}{${newline}`);
|
|
3413
3302
|
}
|
|
@@ -3417,7 +3306,7 @@ var TailwindRenderer = class {
|
|
|
3417
3306
|
lines.push(`${tokenIndent}--${varName}:${space}${varValue};${newline}`);
|
|
3418
3307
|
}
|
|
3419
3308
|
if (hasMediaQuery) {
|
|
3420
|
-
lines.push(`${
|
|
3309
|
+
lines.push(`${indent}}${newline}`);
|
|
3421
3310
|
lines.push(`}${newline}`);
|
|
3422
3311
|
} else {
|
|
3423
3312
|
lines.push(`}${newline}`);
|
|
@@ -3444,8 +3333,8 @@ var TailwindRenderer = class {
|
|
|
3444
3333
|
if (token.$type === "dimension" && isDimensionObject(value)) {
|
|
3445
3334
|
return dimensionObjectToString(value);
|
|
3446
3335
|
}
|
|
3447
|
-
if (token.$type === "duration" &&
|
|
3448
|
-
return
|
|
3336
|
+
if (token.$type === "duration" && isDurationObject(value)) {
|
|
3337
|
+
return durationObjectToString(value);
|
|
3449
3338
|
}
|
|
3450
3339
|
if (token.$type === "fontFamily") {
|
|
3451
3340
|
if (Array.isArray(value)) {
|
|
@@ -3500,9 +3389,6 @@ var TailwindRenderer = class {
|
|
|
3500
3389
|
}
|
|
3501
3390
|
return parts.join(" ");
|
|
3502
3391
|
}
|
|
3503
|
-
isDurationObject(value) {
|
|
3504
|
-
return typeof value === "object" && value !== null && "value" in value && "unit" in value && value.unit !== void 0;
|
|
3505
|
-
}
|
|
3506
3392
|
async formatWithPrettier(css2) {
|
|
3507
3393
|
try {
|
|
3508
3394
|
return await prettier.format(css2, {
|
|
@@ -3519,7 +3405,7 @@ var TailwindRenderer = class {
|
|
|
3519
3405
|
const bundleData = context.permutations.map(({ tokens, modifierInputs }) => ({
|
|
3520
3406
|
tokens,
|
|
3521
3407
|
modifierInputs,
|
|
3522
|
-
isBase:
|
|
3408
|
+
isBase: isBasePermutation(modifierInputs, context.meta.defaults)
|
|
3523
3409
|
}));
|
|
3524
3410
|
return await bundleAsTailwind(
|
|
3525
3411
|
bundleData,
|
|
@@ -3529,12 +3415,12 @@ var TailwindRenderer = class {
|
|
|
3529
3415
|
);
|
|
3530
3416
|
}
|
|
3531
3417
|
async formatStandalone(context, options) {
|
|
3532
|
-
|
|
3533
|
-
|
|
3534
|
-
|
|
3535
|
-
|
|
3536
|
-
|
|
3537
|
-
|
|
3418
|
+
assertFileRequired(
|
|
3419
|
+
context.buildPath,
|
|
3420
|
+
context.output.file,
|
|
3421
|
+
context.output.name,
|
|
3422
|
+
"standalone Tailwind"
|
|
3423
|
+
);
|
|
3538
3424
|
const files = {};
|
|
3539
3425
|
for (const { tokens, modifierInputs } of context.permutations) {
|
|
3540
3426
|
const processedTokens = stripInternalMetadata(tokens);
|
|
@@ -3550,11 +3436,6 @@ var TailwindRenderer = class {
|
|
|
3550
3436
|
}
|
|
3551
3437
|
return outputTree(files);
|
|
3552
3438
|
}
|
|
3553
|
-
isBasePermutation(modifierInputs, defaults) {
|
|
3554
|
-
return Object.entries(defaults).every(
|
|
3555
|
-
([key, value]) => modifierInputs[key]?.toLowerCase() === value.toLowerCase()
|
|
3556
|
-
);
|
|
3557
|
-
}
|
|
3558
3439
|
};
|
|
3559
3440
|
function tailwindRenderer() {
|
|
3560
3441
|
const rendererInstance = new TailwindRenderer();
|
|
@@ -3582,7 +3463,7 @@ function css(config) {
|
|
|
3582
3463
|
file,
|
|
3583
3464
|
renderer: cssRenderer(),
|
|
3584
3465
|
options: { preset, ...rendererOptions },
|
|
3585
|
-
transforms,
|
|
3466
|
+
transforms: [nameKebabCase(), ...transforms ?? []],
|
|
3586
3467
|
filters,
|
|
3587
3468
|
hooks
|
|
3588
3469
|
};
|