dispersa 0.4.0 → 0.4.2
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 +0 -2
- package/dist/builders.cjs +466 -597
- package/dist/builders.cjs.map +1 -1
- package/dist/builders.d.cts +2 -2
- package/dist/builders.d.ts +2 -2
- package/dist/builders.js +466 -597
- 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/errors.cjs +0 -16
- package/dist/errors.cjs.map +1 -1
- package/dist/errors.d.cts +1 -15
- package/dist/errors.d.ts +1 -15
- package/dist/errors.js +1 -15
- package/dist/errors.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-BkvV7Z54.d.cts → index-CNT2Meyf.d.cts} +88 -76
- package/dist/{index-DJ_UHSQG.d.ts → index-CqdaN3X0.d.ts} +88 -76
- package/dist/index.cjs +626 -791
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +627 -792
- 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 -5
- package/dist/transforms.cjs.map +1 -1
- package/dist/transforms.js +5 -5
- package/dist/transforms.js.map +1 -1
- package/package.json +1 -1
package/dist/builders.js
CHANGED
|
@@ -46,13 +46,12 @@ function formatDeprecationMessage(token, description = "", format = "bracket") {
|
|
|
46
46
|
}
|
|
47
47
|
const deprecationMsg = typeof token.$deprecated === "string" ? token.$deprecated : "";
|
|
48
48
|
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;
|
|
49
|
+
const msg2 = deprecationMsg ? ` ${deprecationMsg}` : "";
|
|
50
|
+
return `DEPRECATED${msg2}`;
|
|
55
51
|
}
|
|
52
|
+
const msg = deprecationMsg ? `: ${deprecationMsg}` : "";
|
|
53
|
+
const prefix = `[DEPRECATED${msg}]`;
|
|
54
|
+
return description ? `${prefix} ${description}` : prefix;
|
|
56
55
|
}
|
|
57
56
|
function stripInternalTokenMetadata(tokens) {
|
|
58
57
|
const cleaned = {};
|
|
@@ -65,6 +64,30 @@ function stripInternalTokenMetadata(tokens) {
|
|
|
65
64
|
function getSortedTokenEntries(tokens) {
|
|
66
65
|
return Object.entries(tokens).sort(([nameA], [nameB]) => nameA.localeCompare(nameB));
|
|
67
66
|
}
|
|
67
|
+
function buildNestedTokenObject(tokens, extractValue) {
|
|
68
|
+
const result = {};
|
|
69
|
+
for (const [, token] of getSortedTokenEntries(tokens)) {
|
|
70
|
+
setNestedValue(result, token.path, extractValue(token));
|
|
71
|
+
}
|
|
72
|
+
return result;
|
|
73
|
+
}
|
|
74
|
+
function setNestedValue(root, path, value) {
|
|
75
|
+
let current = root;
|
|
76
|
+
for (let i = 0; i < path.length - 1; i++) {
|
|
77
|
+
const part = path[i];
|
|
78
|
+
if (part == null) {
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
if (!(part in current)) {
|
|
82
|
+
current[part] = {};
|
|
83
|
+
}
|
|
84
|
+
current = current[part];
|
|
85
|
+
}
|
|
86
|
+
const lastPart = path[path.length - 1];
|
|
87
|
+
if (lastPart != null) {
|
|
88
|
+
current[lastPart] = value;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
68
91
|
function getPureAliasReferenceName(value) {
|
|
69
92
|
if (typeof value !== "string") {
|
|
70
93
|
return void 0;
|
|
@@ -84,6 +107,35 @@ function sanitizeDataAttributeName(value) {
|
|
|
84
107
|
function escapeCssString(value) {
|
|
85
108
|
return value.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\r?\n/g, " ");
|
|
86
109
|
}
|
|
110
|
+
function groupTokensByType(tokens, typeGroupMap) {
|
|
111
|
+
const groupMap = /* @__PURE__ */ new Map();
|
|
112
|
+
for (const [, token] of getSortedTokenEntries(tokens)) {
|
|
113
|
+
const groupName = typeGroupMap[token.$type ?? ""] ?? "Other";
|
|
114
|
+
const existing = groupMap.get(groupName) ?? [];
|
|
115
|
+
existing.push(token);
|
|
116
|
+
groupMap.set(groupName, existing);
|
|
117
|
+
}
|
|
118
|
+
return Array.from(groupMap.entries()).map(([name, groupTokens]) => ({
|
|
119
|
+
name,
|
|
120
|
+
tokens: groupTokens
|
|
121
|
+
}));
|
|
122
|
+
}
|
|
123
|
+
function indentStr(width, level) {
|
|
124
|
+
return " ".repeat(width * level);
|
|
125
|
+
}
|
|
126
|
+
function buildGeneratedFileHeader() {
|
|
127
|
+
return [
|
|
128
|
+
"// Generated by Dispersa - do not edit manually",
|
|
129
|
+
"// https://github.com/timges/dispersa"
|
|
130
|
+
].join("\n");
|
|
131
|
+
}
|
|
132
|
+
function toSafeIdentifier(name, keywords, capitalize) {
|
|
133
|
+
const camel = name.replace(/[-._]+(.)/g, (_, c) => c.toUpperCase()).replace(/[-._]+$/g, "").replace(/^[-._]+/g, "");
|
|
134
|
+
const cased = capitalize ? camel.charAt(0).toUpperCase() + camel.slice(1) : camel.charAt(0).toLowerCase() + camel.slice(1);
|
|
135
|
+
const safe = /^\d/.test(cased) ? `_${cased}` : cased;
|
|
136
|
+
const keyCheck = capitalize ? safe.charAt(0).toLowerCase() + safe.slice(1) : safe;
|
|
137
|
+
return keywords.has(keyCheck) ? `\`${safe}\`` : safe;
|
|
138
|
+
}
|
|
87
139
|
function normalizeModifierInputs(inputs) {
|
|
88
140
|
const normalized = {};
|
|
89
141
|
for (const [key, value] of Object.entries(inputs)) {
|
|
@@ -91,6 +143,14 @@ function normalizeModifierInputs(inputs) {
|
|
|
91
143
|
}
|
|
92
144
|
return normalized;
|
|
93
145
|
}
|
|
146
|
+
function assertFileRequired(buildPath, outputFile, outputName, presetLabel) {
|
|
147
|
+
const requiresFile = buildPath !== void 0 && buildPath !== "";
|
|
148
|
+
if (!outputFile && requiresFile) {
|
|
149
|
+
throw new ConfigurationError(
|
|
150
|
+
`Output "${outputName}": file is required for ${presetLabel} output`
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
94
154
|
function buildStablePermutationKey(modifierInputs, dimensions) {
|
|
95
155
|
return dimensions.map((dimension) => `${dimension}=${modifierInputs[dimension] ?? ""}`).join("|");
|
|
96
156
|
}
|
|
@@ -140,14 +200,18 @@ function generatePermutationKey(modifierInputs, resolver, isBase) {
|
|
|
140
200
|
}
|
|
141
201
|
return buildStablePermutationKey(normalizedInputs, metadata.dimensions);
|
|
142
202
|
}
|
|
143
|
-
function
|
|
144
|
-
const { outputName, extension, modifierInputs, resolver, defaults } = params;
|
|
203
|
+
function isBasePermutation(modifierInputs, defaults) {
|
|
145
204
|
const normalizedInputs = normalizeModifierInputs(modifierInputs);
|
|
146
205
|
const normalizedDefaults = normalizeModifierInputs(defaults);
|
|
147
|
-
|
|
148
|
-
|
|
206
|
+
return Object.entries(normalizedDefaults).every(([key, value]) => normalizedInputs[key] === value);
|
|
207
|
+
}
|
|
208
|
+
function buildInMemoryOutputKey(params) {
|
|
209
|
+
const { outputName, extension, modifierInputs, resolver, defaults } = params;
|
|
210
|
+
const permutationKey = generatePermutationKey(
|
|
211
|
+
modifierInputs,
|
|
212
|
+
resolver,
|
|
213
|
+
isBasePermutation(modifierInputs, defaults)
|
|
149
214
|
);
|
|
150
|
-
const permutationKey = generatePermutationKey(modifierInputs, resolver, isBase);
|
|
151
215
|
return `${outputName}-${permutationKey}.${extension}`;
|
|
152
216
|
}
|
|
153
217
|
function buildMetadata(resolver) {
|
|
@@ -261,6 +325,7 @@ function resolveFileName(fileName, modifierInputs) {
|
|
|
261
325
|
}
|
|
262
326
|
var init_utils = __esm({
|
|
263
327
|
"src/renderers/bundlers/utils.ts"() {
|
|
328
|
+
init_errors();
|
|
264
329
|
init_token_utils();
|
|
265
330
|
}
|
|
266
331
|
});
|
|
@@ -270,36 +335,38 @@ var js_exports = {};
|
|
|
270
335
|
__export(js_exports, {
|
|
271
336
|
bundleAsJsModule: () => bundleAsJsModule
|
|
272
337
|
});
|
|
338
|
+
function updateStringTracking(state, char) {
|
|
339
|
+
if (!state.escaped && (char === '"' || char === "'" || char === "`")) {
|
|
340
|
+
if (!state.inString) {
|
|
341
|
+
state.inString = true;
|
|
342
|
+
state.stringChar = char;
|
|
343
|
+
} else if (char === state.stringChar) {
|
|
344
|
+
state.inString = false;
|
|
345
|
+
state.stringChar = "";
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
state.escaped = !state.escaped && char === "\\";
|
|
349
|
+
}
|
|
273
350
|
function extractObjectFromJsModule(formattedJs) {
|
|
274
351
|
const assignmentMatch = /const\s+\w+\s*=\s*\{/.exec(formattedJs);
|
|
275
352
|
if (!assignmentMatch) {
|
|
276
353
|
return "{}";
|
|
277
354
|
}
|
|
278
355
|
const startIndex = assignmentMatch.index + assignmentMatch[0].length - 1;
|
|
356
|
+
const state = { inString: false, stringChar: "", escaped: false };
|
|
279
357
|
let braceCount = 0;
|
|
280
|
-
let inString = false;
|
|
281
|
-
let stringChar = "";
|
|
282
|
-
let escaped = false;
|
|
283
358
|
for (let i = startIndex; i < formattedJs.length; i++) {
|
|
284
359
|
const char = formattedJs[i];
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
stringChar = char;
|
|
289
|
-
} else if (char === stringChar) {
|
|
290
|
-
inString = false;
|
|
291
|
-
stringChar = "";
|
|
292
|
-
}
|
|
360
|
+
updateStringTracking(state, char);
|
|
361
|
+
if (state.inString) {
|
|
362
|
+
continue;
|
|
293
363
|
}
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
if (braceCount === 0) {
|
|
301
|
-
return formattedJs.substring(startIndex, i + 1);
|
|
302
|
-
}
|
|
364
|
+
if (char === "{") {
|
|
365
|
+
braceCount++;
|
|
366
|
+
} else if (char === "}") {
|
|
367
|
+
braceCount--;
|
|
368
|
+
if (braceCount === 0) {
|
|
369
|
+
return formattedJs.substring(startIndex, i + 1);
|
|
303
370
|
}
|
|
304
371
|
}
|
|
305
372
|
}
|
|
@@ -396,22 +463,19 @@ __export(json_exports, {
|
|
|
396
463
|
bundleAsJson: () => bundleAsJson
|
|
397
464
|
});
|
|
398
465
|
async function bundleAsJson(bundleData, resolver, formatTokens) {
|
|
466
|
+
if (!formatTokens) {
|
|
467
|
+
throw new ConfigurationError("JSON formatter was not provided");
|
|
468
|
+
}
|
|
399
469
|
const metadata = buildMetadata(resolver);
|
|
400
470
|
const tokens = {};
|
|
401
471
|
for (const { tokens: tokenSet, modifierInputs } of bundleData) {
|
|
402
472
|
const cleanTokens = stripInternalMetadata(tokenSet);
|
|
403
|
-
if (!formatTokens) {
|
|
404
|
-
throw new ConfigurationError("JSON formatter was not provided");
|
|
405
|
-
}
|
|
406
473
|
const normalizedInputs = normalizeModifierInputs(modifierInputs);
|
|
407
474
|
const key = buildStablePermutationKey(normalizedInputs, metadata.dimensions);
|
|
408
475
|
const themeJson = await formatTokens(cleanTokens);
|
|
409
476
|
tokens[key] = JSON.parse(themeJson);
|
|
410
477
|
}
|
|
411
|
-
const bundle = {
|
|
412
|
-
_meta: metadata,
|
|
413
|
-
tokens
|
|
414
|
-
};
|
|
478
|
+
const bundle = { _meta: metadata, tokens };
|
|
415
479
|
return JSON.stringify(bundle, null, 2);
|
|
416
480
|
}
|
|
417
481
|
var init_json = __esm({
|
|
@@ -477,7 +541,7 @@ function colorObjectToHex(color) {
|
|
|
477
541
|
return formatHex(culoriColor);
|
|
478
542
|
}
|
|
479
543
|
|
|
480
|
-
// src/processing/
|
|
544
|
+
// src/processing/transforms/built-in/dimension-converter.ts
|
|
481
545
|
function isDimensionObject(value) {
|
|
482
546
|
return typeof value === "object" && value !== null && "value" in value && "unit" in value;
|
|
483
547
|
}
|
|
@@ -485,6 +549,14 @@ function dimensionObjectToString(dimension) {
|
|
|
485
549
|
return `${dimension.value}${dimension.unit}`;
|
|
486
550
|
}
|
|
487
551
|
|
|
552
|
+
// src/processing/transforms/built-in/duration-converter.ts
|
|
553
|
+
function isDurationObject(value) {
|
|
554
|
+
return typeof value === "object" && value !== null && "value" in value && "unit" in value && value.unit !== void 0;
|
|
555
|
+
}
|
|
556
|
+
function durationObjectToString(duration) {
|
|
557
|
+
return `${duration.value}${duration.unit}`;
|
|
558
|
+
}
|
|
559
|
+
|
|
488
560
|
// src/renderers/android.ts
|
|
489
561
|
init_errors();
|
|
490
562
|
init_token_utils();
|
|
@@ -546,9 +618,6 @@ function resolveColorFormat(format) {
|
|
|
546
618
|
}
|
|
547
619
|
return "argb_hex";
|
|
548
620
|
}
|
|
549
|
-
function indent(width, level) {
|
|
550
|
-
return " ".repeat(width * level);
|
|
551
|
-
}
|
|
552
621
|
function escapeKotlinString(str) {
|
|
553
622
|
return str.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\$/g, "\\$");
|
|
554
623
|
}
|
|
@@ -564,22 +633,6 @@ function roundComponent(value) {
|
|
|
564
633
|
function toResourceName(family) {
|
|
565
634
|
return family.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_|_$/g, "");
|
|
566
635
|
}
|
|
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
636
|
var AndroidRenderer = class {
|
|
584
637
|
async format(context, options) {
|
|
585
638
|
if (!options?.packageName) {
|
|
@@ -587,6 +640,7 @@ var AndroidRenderer = class {
|
|
|
587
640
|
`Output "${context.output.name}": packageName is required for Android output`
|
|
588
641
|
);
|
|
589
642
|
}
|
|
643
|
+
const visibility = options?.visibility;
|
|
590
644
|
const opts = {
|
|
591
645
|
preset: options?.preset ?? "standalone",
|
|
592
646
|
packageName: options.packageName,
|
|
@@ -594,7 +648,8 @@ var AndroidRenderer = class {
|
|
|
594
648
|
colorFormat: resolveColorFormat(options?.colorFormat),
|
|
595
649
|
colorSpace: options?.colorSpace ?? "sRGB",
|
|
596
650
|
structure: options?.structure ?? "nested",
|
|
597
|
-
visibility
|
|
651
|
+
visibility,
|
|
652
|
+
visPrefix: visibility ? `${visibility} ` : "",
|
|
598
653
|
indent: options?.indent ?? 4
|
|
599
654
|
};
|
|
600
655
|
if (opts.preset === "bundle") {
|
|
@@ -627,19 +682,6 @@ var AndroidRenderer = class {
|
|
|
627
682
|
// -----------------------------------------------------------------------
|
|
628
683
|
// Flat structure grouping
|
|
629
684
|
// -----------------------------------------------------------------------
|
|
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
685
|
/**
|
|
644
686
|
* Builds a flattened camelCase name from a token's path, stripping the
|
|
645
687
|
* type prefix segment (which is already represented by the group object).
|
|
@@ -648,7 +690,7 @@ var AndroidRenderer = class {
|
|
|
648
690
|
const path = token.path;
|
|
649
691
|
const withoutTypePrefix = path.length > 1 ? path.slice(1) : path;
|
|
650
692
|
const joined = withoutTypePrefix.join("_");
|
|
651
|
-
return
|
|
693
|
+
return toSafeIdentifier(joined, KOTLIN_KEYWORDS, false);
|
|
652
694
|
}
|
|
653
695
|
// -----------------------------------------------------------------------
|
|
654
696
|
// Rendering
|
|
@@ -660,22 +702,21 @@ var AndroidRenderer = class {
|
|
|
660
702
|
return this.formatAsNested(tokens, options);
|
|
661
703
|
}
|
|
662
704
|
formatAsNested(tokens, options) {
|
|
705
|
+
const tokenTypes = this.collectTokenTypesFromEntries(tokens);
|
|
663
706
|
const tree = this.buildTokenTree(tokens);
|
|
664
|
-
|
|
665
|
-
this.collectTokenTypes(tree, tokenTypes);
|
|
666
|
-
return this.buildFile(tokenTypes, options, (lines, vis) => {
|
|
707
|
+
return this.buildFile(tokenTypes, options, (lines) => {
|
|
667
708
|
lines.push(`@Suppress("unused")`);
|
|
668
|
-
lines.push(`${
|
|
709
|
+
lines.push(`${options.visPrefix}object ${options.objectName} {`);
|
|
669
710
|
this.renderTreeChildren(lines, tree, 1, options);
|
|
670
711
|
lines.push("}");
|
|
671
712
|
});
|
|
672
713
|
}
|
|
673
714
|
formatAsFlat(tokens, options) {
|
|
674
|
-
const groups =
|
|
715
|
+
const groups = groupTokensByType(tokens, KOTLIN_TYPE_GROUP_MAP);
|
|
675
716
|
const tokenTypes = this.collectTokenTypesFromEntries(tokens);
|
|
676
|
-
return this.buildFile(tokenTypes, options, (lines
|
|
717
|
+
return this.buildFile(tokenTypes, options, (lines) => {
|
|
677
718
|
lines.push(`@Suppress("unused")`);
|
|
678
|
-
lines.push(`${
|
|
719
|
+
lines.push(`${options.visPrefix}object ${options.objectName} {`);
|
|
679
720
|
this.renderFlatGroups(lines, groups, 1, options);
|
|
680
721
|
lines.push("}");
|
|
681
722
|
});
|
|
@@ -686,9 +727,8 @@ var AndroidRenderer = class {
|
|
|
686
727
|
*/
|
|
687
728
|
buildFile(tokenTypes, options, renderBody) {
|
|
688
729
|
const imports = this.collectImports(tokenTypes, options);
|
|
689
|
-
const vis = options.visibility ? `${options.visibility} ` : "";
|
|
690
730
|
const lines = [];
|
|
691
|
-
lines.push(
|
|
731
|
+
lines.push(buildGeneratedFileHeader());
|
|
692
732
|
lines.push("");
|
|
693
733
|
lines.push(`package ${options.packageName}`);
|
|
694
734
|
lines.push("");
|
|
@@ -699,19 +739,18 @@ var AndroidRenderer = class {
|
|
|
699
739
|
lines.push("");
|
|
700
740
|
}
|
|
701
741
|
if (tokenTypes.has("shadow")) {
|
|
702
|
-
lines.push(...this.buildShadowTokenClass(
|
|
742
|
+
lines.push(...this.buildShadowTokenClass(options));
|
|
703
743
|
lines.push("");
|
|
704
744
|
}
|
|
705
|
-
renderBody(lines
|
|
745
|
+
renderBody(lines);
|
|
706
746
|
lines.push("");
|
|
707
747
|
return lines.join("\n");
|
|
708
748
|
}
|
|
709
749
|
renderFlatGroups(lines, groups, baseDepth, options) {
|
|
710
|
-
const
|
|
711
|
-
const
|
|
712
|
-
const valIndent = indent(options.indent, baseDepth + 1);
|
|
750
|
+
const groupIndent = indentStr(options.indent, baseDepth);
|
|
751
|
+
const valIndent = indentStr(options.indent, baseDepth + 1);
|
|
713
752
|
for (const group of groups) {
|
|
714
|
-
lines.push(`${groupIndent}${
|
|
753
|
+
lines.push(`${groupIndent}${options.visPrefix}object ${group.name} {`);
|
|
715
754
|
for (const token of group.tokens) {
|
|
716
755
|
const kotlinName = this.buildFlatKotlinName(token);
|
|
717
756
|
const kotlinValue = this.formatKotlinValue(token, options, baseDepth + 1);
|
|
@@ -719,23 +758,24 @@ var AndroidRenderer = class {
|
|
|
719
758
|
if (token.$description) {
|
|
720
759
|
lines.push(`${valIndent}/** ${escapeKDoc(token.$description)} */`);
|
|
721
760
|
}
|
|
722
|
-
lines.push(
|
|
761
|
+
lines.push(
|
|
762
|
+
`${valIndent}${options.visPrefix}val ${kotlinName}${annotation} = ${kotlinValue}`
|
|
763
|
+
);
|
|
723
764
|
}
|
|
724
765
|
lines.push(`${groupIndent}}`);
|
|
725
766
|
lines.push("");
|
|
726
767
|
}
|
|
727
768
|
}
|
|
728
769
|
renderTreeChildren(lines, node, depth, options) {
|
|
729
|
-
const
|
|
730
|
-
const pad = indent(options.indent, depth);
|
|
770
|
+
const pad = indentStr(options.indent, depth);
|
|
731
771
|
const entries = Array.from(node.children.entries());
|
|
732
772
|
for (let idx = 0; idx < entries.length; idx++) {
|
|
733
773
|
const [key, child] = entries[idx];
|
|
734
774
|
if (child.token && child.children.size === 0) {
|
|
735
775
|
this.renderLeaf(lines, key, child.token, depth, options);
|
|
736
776
|
} else if (child.children.size > 0 && !child.token) {
|
|
737
|
-
const objectName =
|
|
738
|
-
lines.push(`${pad}${
|
|
777
|
+
const objectName = toSafeIdentifier(key, KOTLIN_KEYWORDS, true);
|
|
778
|
+
lines.push(`${pad}${options.visPrefix}object ${objectName} {`);
|
|
739
779
|
this.renderTreeChildren(lines, child, depth + 1, options);
|
|
740
780
|
lines.push(`${pad}}`);
|
|
741
781
|
if (idx < entries.length - 1) {
|
|
@@ -748,30 +788,23 @@ var AndroidRenderer = class {
|
|
|
748
788
|
}
|
|
749
789
|
}
|
|
750
790
|
renderLeaf(lines, key, token, depth, options) {
|
|
751
|
-
const
|
|
752
|
-
const
|
|
753
|
-
const kotlinName = toKotlinIdentifier(key);
|
|
791
|
+
const pad = indentStr(options.indent, depth);
|
|
792
|
+
const kotlinName = toSafeIdentifier(key, KOTLIN_KEYWORDS, false);
|
|
754
793
|
const kotlinValue = this.formatKotlinValue(token, options, depth);
|
|
755
794
|
const annotation = this.typeAnnotationSuffix(token);
|
|
756
795
|
if (token.$description) {
|
|
757
796
|
lines.push(`${pad}/** ${escapeKDoc(token.$description)} */`);
|
|
758
797
|
}
|
|
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");
|
|
798
|
+
lines.push(`${pad}${options.visPrefix}val ${kotlinName}${annotation} = ${kotlinValue}`);
|
|
766
799
|
}
|
|
767
800
|
// -----------------------------------------------------------------------
|
|
768
801
|
// Shadow data class
|
|
769
802
|
// -----------------------------------------------------------------------
|
|
770
|
-
buildShadowTokenClass(
|
|
771
|
-
const i1 =
|
|
803
|
+
buildShadowTokenClass(options) {
|
|
804
|
+
const i1 = indentStr(options.indent, 1);
|
|
772
805
|
return [
|
|
773
806
|
"@Immutable",
|
|
774
|
-
`${
|
|
807
|
+
`${options.visPrefix}data class ShadowToken(`,
|
|
775
808
|
`${i1}val color: Color,`,
|
|
776
809
|
`${i1}val elevation: Dp,`,
|
|
777
810
|
`${i1}val offsetX: Dp,`,
|
|
@@ -822,14 +855,6 @@ var AndroidRenderer = class {
|
|
|
822
855
|
}
|
|
823
856
|
return Array.from(imports).sort();
|
|
824
857
|
}
|
|
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
858
|
collectTokenTypesFromEntries(tokens) {
|
|
834
859
|
const types = /* @__PURE__ */ new Set();
|
|
835
860
|
for (const [, token] of Object.entries(tokens)) {
|
|
@@ -1056,9 +1081,8 @@ var AndroidRenderer = class {
|
|
|
1056
1081
|
return map[name.toLowerCase()];
|
|
1057
1082
|
}
|
|
1058
1083
|
formatDurationValue(value) {
|
|
1059
|
-
if (
|
|
1060
|
-
|
|
1061
|
-
return dur.unit === "ms" ? `${dur.value}.milliseconds` : `${dur.value}.seconds`;
|
|
1084
|
+
if (isDurationObject(value)) {
|
|
1085
|
+
return value.unit === "ms" ? `${value.value}.milliseconds` : `${value.value}.seconds`;
|
|
1062
1086
|
}
|
|
1063
1087
|
return typeof value === "number" ? `${value}.milliseconds` : "0.milliseconds";
|
|
1064
1088
|
}
|
|
@@ -1076,8 +1100,8 @@ var AndroidRenderer = class {
|
|
|
1076
1100
|
const elevation = isDimensionObject(shadow.blur) ? this.formatDimensionValue(shadow.blur) : "0.dp";
|
|
1077
1101
|
const offsetX = isDimensionObject(shadow.offsetX) ? this.formatDimensionValue(shadow.offsetX) : "0.dp";
|
|
1078
1102
|
const offsetY = isDimensionObject(shadow.offsetY) ? this.formatDimensionValue(shadow.offsetY) : "0.dp";
|
|
1079
|
-
const propIndent =
|
|
1080
|
-
const closeIndent =
|
|
1103
|
+
const propIndent = indentStr(options.indent, depth + 1);
|
|
1104
|
+
const closeIndent = indentStr(options.indent, depth);
|
|
1081
1105
|
return [
|
|
1082
1106
|
"ShadowToken(",
|
|
1083
1107
|
`${propIndent}color = ${color},`,
|
|
@@ -1126,8 +1150,8 @@ var AndroidRenderer = class {
|
|
|
1126
1150
|
if (parts.length === 0) {
|
|
1127
1151
|
return "TextStyle()";
|
|
1128
1152
|
}
|
|
1129
|
-
const propIndent =
|
|
1130
|
-
const closeIndent =
|
|
1153
|
+
const propIndent = indentStr(options.indent, depth + 1);
|
|
1154
|
+
const closeIndent = indentStr(options.indent, depth);
|
|
1131
1155
|
return `TextStyle(
|
|
1132
1156
|
${parts.map((p) => `${propIndent}${p}`).join(",\n")},
|
|
1133
1157
|
${closeIndent})`;
|
|
@@ -1136,12 +1160,12 @@ ${closeIndent})`;
|
|
|
1136
1160
|
// Output: standalone
|
|
1137
1161
|
// -----------------------------------------------------------------------
|
|
1138
1162
|
async formatStandalone(context, options) {
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1163
|
+
assertFileRequired(
|
|
1164
|
+
context.buildPath,
|
|
1165
|
+
context.output.file,
|
|
1166
|
+
context.output.name,
|
|
1167
|
+
"standalone Android"
|
|
1168
|
+
);
|
|
1145
1169
|
const files = {};
|
|
1146
1170
|
for (const { tokens, modifierInputs } of context.permutations) {
|
|
1147
1171
|
const processedTokens = stripInternalMetadata(tokens);
|
|
@@ -1161,12 +1185,12 @@ ${closeIndent})`;
|
|
|
1161
1185
|
// Output: bundle
|
|
1162
1186
|
// -----------------------------------------------------------------------
|
|
1163
1187
|
async formatBundle(context, options) {
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1188
|
+
assertFileRequired(
|
|
1189
|
+
context.buildPath,
|
|
1190
|
+
context.output.file,
|
|
1191
|
+
context.output.name,
|
|
1192
|
+
"bundle Android"
|
|
1193
|
+
);
|
|
1170
1194
|
const content = this.formatBundleContent(context, options);
|
|
1171
1195
|
const fileName = context.output.file ? resolveFileName(context.output.file, context.meta.basePermutation) : buildInMemoryOutputKey({
|
|
1172
1196
|
outputName: context.output.name,
|
|
@@ -1179,15 +1203,15 @@ ${closeIndent})`;
|
|
|
1179
1203
|
}
|
|
1180
1204
|
formatBundleContent(context, options) {
|
|
1181
1205
|
const allTokenTypes = this.collectAllPermutationTypes(context);
|
|
1182
|
-
return this.buildFile(allTokenTypes, options, (lines
|
|
1183
|
-
const i1 =
|
|
1206
|
+
return this.buildFile(allTokenTypes, options, (lines) => {
|
|
1207
|
+
const i1 = indentStr(options.indent, 1);
|
|
1184
1208
|
lines.push(`@Suppress("unused")`);
|
|
1185
|
-
lines.push(`${
|
|
1209
|
+
lines.push(`${options.visPrefix}object ${options.objectName} {`);
|
|
1186
1210
|
for (let idx = 0; idx < context.permutations.length; idx++) {
|
|
1187
1211
|
const { tokens, modifierInputs } = context.permutations[idx];
|
|
1188
1212
|
const processedTokens = stripInternalMetadata(tokens);
|
|
1189
1213
|
const permName = this.buildPermutationName(modifierInputs);
|
|
1190
|
-
lines.push(`${i1}${
|
|
1214
|
+
lines.push(`${i1}${options.visPrefix}object ${permName} {`);
|
|
1191
1215
|
this.renderBundleTokens(lines, processedTokens, options, 2);
|
|
1192
1216
|
lines.push(`${i1}}`);
|
|
1193
1217
|
if (idx < context.permutations.length - 1) {
|
|
@@ -1198,20 +1222,17 @@ ${closeIndent})`;
|
|
|
1198
1222
|
});
|
|
1199
1223
|
}
|
|
1200
1224
|
collectAllPermutationTypes(context) {
|
|
1201
|
-
const
|
|
1225
|
+
const types = /* @__PURE__ */ new Set();
|
|
1202
1226
|
for (const { tokens } of context.permutations) {
|
|
1203
|
-
const
|
|
1204
|
-
|
|
1205
|
-
if (token.$type) {
|
|
1206
|
-
allTokenTypes.add(token.$type);
|
|
1207
|
-
}
|
|
1227
|
+
for (const t of this.collectTokenTypesFromEntries(stripInternalMetadata(tokens))) {
|
|
1228
|
+
types.add(t);
|
|
1208
1229
|
}
|
|
1209
1230
|
}
|
|
1210
|
-
return
|
|
1231
|
+
return types;
|
|
1211
1232
|
}
|
|
1212
1233
|
renderBundleTokens(lines, tokens, options, baseDepth) {
|
|
1213
1234
|
if (options.structure === "flat") {
|
|
1214
|
-
const groups =
|
|
1235
|
+
const groups = groupTokensByType(tokens, KOTLIN_TYPE_GROUP_MAP);
|
|
1215
1236
|
this.renderFlatGroups(lines, groups, baseDepth, options);
|
|
1216
1237
|
return;
|
|
1217
1238
|
}
|
|
@@ -1223,7 +1244,7 @@ ${closeIndent})`;
|
|
|
1223
1244
|
if (values.length === 0) {
|
|
1224
1245
|
return "Default";
|
|
1225
1246
|
}
|
|
1226
|
-
return values.map((v) =>
|
|
1247
|
+
return values.map((v) => toSafeIdentifier(v, KOTLIN_KEYWORDS, true)).join("");
|
|
1227
1248
|
}
|
|
1228
1249
|
};
|
|
1229
1250
|
function androidRenderer() {
|
|
@@ -1243,19 +1264,19 @@ init_token_utils();
|
|
|
1243
1264
|
// src/renderers/bundlers/css.ts
|
|
1244
1265
|
init_errors();
|
|
1245
1266
|
init_utils();
|
|
1267
|
+
var REF_PREFIX_SETS = "#/sets/";
|
|
1268
|
+
var REF_PREFIX_MODIFIERS = "#/modifiers/";
|
|
1246
1269
|
var getSourceSet = (token) => {
|
|
1247
1270
|
if (typeof token !== "object" || token === null) {
|
|
1248
1271
|
return void 0;
|
|
1249
1272
|
}
|
|
1250
|
-
|
|
1251
|
-
return typeof maybe._sourceSet === "string" ? maybe._sourceSet : void 0;
|
|
1273
|
+
return "_sourceSet" in token && typeof token._sourceSet === "string" ? token._sourceSet : void 0;
|
|
1252
1274
|
};
|
|
1253
1275
|
var getSourceModifier = (token) => {
|
|
1254
1276
|
if (typeof token !== "object" || token === null) {
|
|
1255
1277
|
return void 0;
|
|
1256
1278
|
}
|
|
1257
|
-
|
|
1258
|
-
return typeof maybe._sourceModifier === "string" ? maybe._sourceModifier : void 0;
|
|
1279
|
+
return "_sourceModifier" in token && typeof token._sourceModifier === "string" ? token._sourceModifier : void 0;
|
|
1259
1280
|
};
|
|
1260
1281
|
async function bundleAsCss(bundleData, resolver, options, formatTokens) {
|
|
1261
1282
|
const baseItem = bundleData.find((item) => item.isBase);
|
|
@@ -1340,6 +1361,15 @@ async function formatModifierPermutation({ tokens, modifierInputs }, baseItem, o
|
|
|
1340
1361
|
return `/* Modifier: ${modifier}=${context} */
|
|
1341
1362
|
${css2}`;
|
|
1342
1363
|
}
|
|
1364
|
+
function addLayerBlock(blocks, included, key, blockTokens, description) {
|
|
1365
|
+
if (Object.keys(blockTokens).length === 0) {
|
|
1366
|
+
return;
|
|
1367
|
+
}
|
|
1368
|
+
for (const k of Object.keys(blockTokens)) {
|
|
1369
|
+
included.add(k);
|
|
1370
|
+
}
|
|
1371
|
+
blocks.push({ key, description, tokens: blockTokens });
|
|
1372
|
+
}
|
|
1343
1373
|
function collectSetTokens(tokens, setName, included) {
|
|
1344
1374
|
const result = {};
|
|
1345
1375
|
for (const [name, token] of Object.entries(tokens)) {
|
|
@@ -1370,75 +1400,67 @@ function collectRemainder(tokens, included) {
|
|
|
1370
1400
|
function buildSetLayerBlocks(tokens, resolver) {
|
|
1371
1401
|
const blocks = [];
|
|
1372
1402
|
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
1403
|
for (const item of resolver.resolutionOrder) {
|
|
1383
1404
|
const ref = item.$ref;
|
|
1384
|
-
if (typeof ref !== "string" || !ref.startsWith(
|
|
1405
|
+
if (typeof ref !== "string" || !ref.startsWith(REF_PREFIX_SETS)) {
|
|
1385
1406
|
continue;
|
|
1386
1407
|
}
|
|
1387
|
-
const setName = ref.slice(
|
|
1388
|
-
|
|
1408
|
+
const setName = ref.slice(REF_PREFIX_SETS.length);
|
|
1409
|
+
addLayerBlock(
|
|
1410
|
+
blocks,
|
|
1411
|
+
included,
|
|
1389
1412
|
`Set: ${setName}`,
|
|
1390
1413
|
collectSetTokens(tokens, setName, included),
|
|
1391
1414
|
resolver.sets?.[setName]?.description
|
|
1392
1415
|
);
|
|
1393
1416
|
}
|
|
1394
|
-
|
|
1417
|
+
addLayerBlock(blocks, included, "Unattributed", collectRemainder(tokens, included));
|
|
1395
1418
|
return blocks;
|
|
1396
1419
|
}
|
|
1397
1420
|
function buildDefaultLayerBlocks(tokens, baseModifierInputs, resolver) {
|
|
1398
1421
|
const blocks = [];
|
|
1399
1422
|
const included = /* @__PURE__ */ new Set();
|
|
1400
1423
|
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
1424
|
for (const item of resolver.resolutionOrder) {
|
|
1411
1425
|
const ref = item.$ref;
|
|
1412
1426
|
if (typeof ref !== "string") {
|
|
1413
1427
|
continue;
|
|
1414
1428
|
}
|
|
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
|
-
}
|
|
1429
|
+
processResolutionOrderRef(ref, tokens, blocks, included, baseInputs, resolver);
|
|
1438
1430
|
}
|
|
1439
|
-
|
|
1431
|
+
addLayerBlock(blocks, included, "Unattributed", collectRemainder(tokens, included));
|
|
1440
1432
|
return blocks;
|
|
1441
1433
|
}
|
|
1434
|
+
function processResolutionOrderRef(ref, tokens, blocks, included, baseInputs, resolver) {
|
|
1435
|
+
if (ref.startsWith(REF_PREFIX_SETS)) {
|
|
1436
|
+
const setName = ref.slice(REF_PREFIX_SETS.length);
|
|
1437
|
+
addLayerBlock(
|
|
1438
|
+
blocks,
|
|
1439
|
+
included,
|
|
1440
|
+
`Set: ${setName}`,
|
|
1441
|
+
collectSetTokens(tokens, setName, included),
|
|
1442
|
+
resolver.sets?.[setName]?.description
|
|
1443
|
+
);
|
|
1444
|
+
return;
|
|
1445
|
+
}
|
|
1446
|
+
if (!ref.startsWith(REF_PREFIX_MODIFIERS)) {
|
|
1447
|
+
return;
|
|
1448
|
+
}
|
|
1449
|
+
const modifierName = ref.slice(REF_PREFIX_MODIFIERS.length);
|
|
1450
|
+
const modifier = resolver.modifiers?.[modifierName];
|
|
1451
|
+
const selectedContext = baseInputs[modifierName.toLowerCase()];
|
|
1452
|
+
if (!modifier || !selectedContext) {
|
|
1453
|
+
return;
|
|
1454
|
+
}
|
|
1455
|
+
const expectedSource = `${modifierName}-${selectedContext}`.toLowerCase();
|
|
1456
|
+
addLayerBlock(
|
|
1457
|
+
blocks,
|
|
1458
|
+
included,
|
|
1459
|
+
`Modifier: ${modifierName}=${selectedContext} (default)`,
|
|
1460
|
+
collectModifierTokens(tokens, expectedSource, included),
|
|
1461
|
+
modifier.description
|
|
1462
|
+
);
|
|
1463
|
+
}
|
|
1442
1464
|
function findSingleDiffPermutation(bundleData, modifierName, context, baseInputs) {
|
|
1443
1465
|
const normalizedModifier = modifierName.toLowerCase();
|
|
1444
1466
|
const normalizedContext = context.toLowerCase();
|
|
@@ -1453,6 +1475,36 @@ function findSingleDiffPermutation(bundleData, modifierName, context, baseInputs
|
|
|
1453
1475
|
return Object.entries(baseInputs).every(([k, v]) => k === normalizedModifier || inputs[k] === v);
|
|
1454
1476
|
});
|
|
1455
1477
|
}
|
|
1478
|
+
function pushUniqueBundleItem(ordered, includedKeys, item) {
|
|
1479
|
+
if (!item) {
|
|
1480
|
+
return;
|
|
1481
|
+
}
|
|
1482
|
+
const key = stableInputsKey(item.modifierInputs);
|
|
1483
|
+
if (includedKeys.has(key)) {
|
|
1484
|
+
return;
|
|
1485
|
+
}
|
|
1486
|
+
includedKeys.add(key);
|
|
1487
|
+
ordered.push(item);
|
|
1488
|
+
}
|
|
1489
|
+
function appendModifierPermutations(bundleData, modifiers, orderedNames, baseInputs, ordered, includedKeys) {
|
|
1490
|
+
for (const modifierName of orderedNames) {
|
|
1491
|
+
const modifierDef = modifiers[modifierName];
|
|
1492
|
+
if (!modifierDef) {
|
|
1493
|
+
continue;
|
|
1494
|
+
}
|
|
1495
|
+
const defaultValue = baseInputs[modifierName.toLowerCase()] ?? "";
|
|
1496
|
+
for (const ctx of Object.keys(modifierDef.contexts)) {
|
|
1497
|
+
if (defaultValue === ctx.toLowerCase()) {
|
|
1498
|
+
continue;
|
|
1499
|
+
}
|
|
1500
|
+
pushUniqueBundleItem(
|
|
1501
|
+
ordered,
|
|
1502
|
+
includedKeys,
|
|
1503
|
+
findSingleDiffPermutation(bundleData, modifierName, ctx, baseInputs)
|
|
1504
|
+
);
|
|
1505
|
+
}
|
|
1506
|
+
}
|
|
1507
|
+
}
|
|
1456
1508
|
function orderBundleData(bundleData, resolver, baseItem) {
|
|
1457
1509
|
const modifiers = resolver.modifiers;
|
|
1458
1510
|
if (!modifiers) {
|
|
@@ -1469,31 +1521,15 @@ function orderBundleData(bundleData, resolver, baseItem) {
|
|
|
1469
1521
|
}
|
|
1470
1522
|
const includedKeys = /* @__PURE__ */ new Set();
|
|
1471
1523
|
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
|
-
}
|
|
1524
|
+
pushUniqueBundleItem(ordered, includedKeys, baseItem);
|
|
1525
|
+
appendModifierPermutations(
|
|
1526
|
+
bundleData,
|
|
1527
|
+
modifiers,
|
|
1528
|
+
orderedModifierNames,
|
|
1529
|
+
baseInputs,
|
|
1530
|
+
ordered,
|
|
1531
|
+
includedKeys
|
|
1532
|
+
);
|
|
1497
1533
|
return ordered.length > 0 ? ordered : bundleData;
|
|
1498
1534
|
}
|
|
1499
1535
|
function getOrderedModifierNames(resolver) {
|
|
@@ -1505,10 +1541,10 @@ function getOrderedModifierNames(resolver) {
|
|
|
1505
1541
|
if (typeof ref !== "string") {
|
|
1506
1542
|
continue;
|
|
1507
1543
|
}
|
|
1508
|
-
if (!ref.startsWith(
|
|
1544
|
+
if (!ref.startsWith(REF_PREFIX_MODIFIERS)) {
|
|
1509
1545
|
continue;
|
|
1510
1546
|
}
|
|
1511
|
-
const name = ref.slice(
|
|
1547
|
+
const name = ref.slice(REF_PREFIX_MODIFIERS.length);
|
|
1512
1548
|
if (seen.has(name)) {
|
|
1513
1549
|
continue;
|
|
1514
1550
|
}
|
|
@@ -1579,24 +1615,22 @@ var CssRenderer = class _CssRenderer {
|
|
|
1579
1615
|
...options,
|
|
1580
1616
|
referenceTokens: options?.referenceTokens ?? tokens
|
|
1581
1617
|
};
|
|
1582
|
-
const
|
|
1618
|
+
const sortedTokens = getSortedTokenEntries(tokens).map(([, token]) => token);
|
|
1583
1619
|
const referenceTokens = opts.referenceTokens;
|
|
1584
1620
|
const lines = [];
|
|
1585
|
-
|
|
1586
|
-
this.buildCssBlock(lines, groupTokens, selector, tokens, referenceTokens, opts);
|
|
1587
|
-
}
|
|
1621
|
+
this.buildCssBlock(lines, sortedTokens, opts.selector, tokens, referenceTokens, opts);
|
|
1588
1622
|
const cssString = lines.join("");
|
|
1589
1623
|
return opts.minify ? cssString : await this.formatWithPrettier(cssString);
|
|
1590
1624
|
}
|
|
1591
1625
|
buildCssBlock(lines, groupTokens, selector, tokens, referenceTokens, opts) {
|
|
1592
|
-
const
|
|
1626
|
+
const indent = opts.minify ? "" : " ";
|
|
1593
1627
|
const newline = opts.minify ? "" : "\n";
|
|
1594
1628
|
const space = opts.minify ? "" : " ";
|
|
1595
1629
|
const hasMediaQuery = opts.mediaQuery != null && opts.mediaQuery !== "";
|
|
1596
|
-
const tokenIndent = hasMediaQuery ?
|
|
1630
|
+
const tokenIndent = hasMediaQuery ? indent + indent : indent;
|
|
1597
1631
|
if (hasMediaQuery) {
|
|
1598
1632
|
lines.push(`@media ${opts.mediaQuery}${space}{${newline}`);
|
|
1599
|
-
lines.push(`${
|
|
1633
|
+
lines.push(`${indent}${selector}${space}{${newline}`);
|
|
1600
1634
|
} else {
|
|
1601
1635
|
lines.push(`${selector}${space}{${newline}`);
|
|
1602
1636
|
}
|
|
@@ -1613,21 +1647,21 @@ var CssRenderer = class _CssRenderer {
|
|
|
1613
1647
|
);
|
|
1614
1648
|
}
|
|
1615
1649
|
if (hasMediaQuery) {
|
|
1616
|
-
lines.push(`${
|
|
1650
|
+
lines.push(`${indent}}${newline}`);
|
|
1617
1651
|
}
|
|
1618
1652
|
lines.push(`}${newline}${newline}`);
|
|
1619
1653
|
}
|
|
1620
|
-
pushTokenLines(lines, token, tokens, referenceTokens, preserveReferences,
|
|
1654
|
+
pushTokenLines(lines, token, tokens, referenceTokens, preserveReferences, indent, newline, space) {
|
|
1621
1655
|
const entries = this.buildCssEntries(token, tokens, referenceTokens, preserveReferences);
|
|
1622
1656
|
if (token.$deprecated != null && token.$deprecated !== false) {
|
|
1623
1657
|
const deprecationMsg = formatDeprecationMessage(token, "", "comment");
|
|
1624
|
-
lines.push(`${
|
|
1658
|
+
lines.push(`${indent}/* ${this.sanitizeCssCommentText(deprecationMsg)} */${newline}`);
|
|
1625
1659
|
}
|
|
1626
1660
|
if (token.$description && token.$description !== "") {
|
|
1627
|
-
lines.push(`${
|
|
1661
|
+
lines.push(`${indent}/* ${this.sanitizeCssCommentText(token.$description)} */${newline}`);
|
|
1628
1662
|
}
|
|
1629
1663
|
for (const entry of entries) {
|
|
1630
|
-
lines.push(`${
|
|
1664
|
+
lines.push(`${indent}--${entry.name}:${space}${entry.value};${newline}`);
|
|
1631
1665
|
}
|
|
1632
1666
|
}
|
|
1633
1667
|
async formatWithPrettier(css2) {
|
|
@@ -1642,15 +1676,6 @@ var CssRenderer = class _CssRenderer {
|
|
|
1642
1676
|
return css2;
|
|
1643
1677
|
}
|
|
1644
1678
|
}
|
|
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
1679
|
buildCssEntries(token, tokens, referenceTokens, preserveReferences) {
|
|
1655
1680
|
if (preserveReferences) {
|
|
1656
1681
|
const refName = getPureAliasReferenceName(token.originalValue);
|
|
@@ -1792,7 +1817,7 @@ var CssRenderer = class _CssRenderer {
|
|
|
1792
1817
|
leaves.push({ path, value });
|
|
1793
1818
|
return;
|
|
1794
1819
|
}
|
|
1795
|
-
if (isColorObject(value) || isDimensionObject(value) ||
|
|
1820
|
+
if (isColorObject(value) || isDimensionObject(value) || isDurationObject(value)) {
|
|
1796
1821
|
leaves.push({ path, value });
|
|
1797
1822
|
return;
|
|
1798
1823
|
}
|
|
@@ -1835,8 +1860,8 @@ var CssRenderer = class _CssRenderer {
|
|
|
1835
1860
|
if (isDimensionObject(value)) {
|
|
1836
1861
|
return dimensionObjectToString(value);
|
|
1837
1862
|
}
|
|
1838
|
-
if (
|
|
1839
|
-
return
|
|
1863
|
+
if (isDurationObject(value)) {
|
|
1864
|
+
return durationObjectToString(value);
|
|
1840
1865
|
}
|
|
1841
1866
|
if (typeof value === "string") {
|
|
1842
1867
|
return value;
|
|
@@ -1899,15 +1924,6 @@ var CssRenderer = class _CssRenderer {
|
|
|
1899
1924
|
isPrimitiveValue(value) {
|
|
1900
1925
|
return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
|
|
1901
1926
|
}
|
|
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
1927
|
/**
|
|
1912
1928
|
* Format token value for CSS
|
|
1913
1929
|
* Handles DTCG 2025.10 object formats for colors and dimensions
|
|
@@ -1928,8 +1944,8 @@ var CssRenderer = class _CssRenderer {
|
|
|
1928
1944
|
return typeof value === "string" ? value : dimensionObjectToString(value);
|
|
1929
1945
|
}
|
|
1930
1946
|
if (type === "duration") {
|
|
1931
|
-
if (
|
|
1932
|
-
return
|
|
1947
|
+
if (isDurationObject(value)) {
|
|
1948
|
+
return durationObjectToString(value);
|
|
1933
1949
|
}
|
|
1934
1950
|
if (typeof value === "string") {
|
|
1935
1951
|
return value;
|
|
@@ -2019,16 +2035,16 @@ var CssRenderer = class _CssRenderer {
|
|
|
2019
2035
|
*/
|
|
2020
2036
|
formatTransition(value) {
|
|
2021
2037
|
const parts = [];
|
|
2022
|
-
if (
|
|
2023
|
-
parts.push(
|
|
2038
|
+
if (isDurationObject(value.duration)) {
|
|
2039
|
+
parts.push(durationObjectToString(value.duration));
|
|
2024
2040
|
} else if (value.duration != null) {
|
|
2025
2041
|
parts.push(String(value.duration));
|
|
2026
2042
|
}
|
|
2027
2043
|
if (Array.isArray(value.timingFunction) && value.timingFunction.length === 4) {
|
|
2028
2044
|
parts.push(`cubic-bezier(${value.timingFunction.join(", ")})`);
|
|
2029
2045
|
}
|
|
2030
|
-
if (
|
|
2031
|
-
parts.push(
|
|
2046
|
+
if (isDurationObject(value.delay)) {
|
|
2047
|
+
parts.push(durationObjectToString(value.delay));
|
|
2032
2048
|
} else if (value.delay != null) {
|
|
2033
2049
|
parts.push(String(value.delay));
|
|
2034
2050
|
}
|
|
@@ -2038,7 +2054,7 @@ var CssRenderer = class _CssRenderer {
|
|
|
2038
2054
|
const bundleData = context.permutations.map(({ tokens, modifierInputs }) => ({
|
|
2039
2055
|
tokens,
|
|
2040
2056
|
modifierInputs,
|
|
2041
|
-
isBase:
|
|
2057
|
+
isBase: isBasePermutation(modifierInputs, context.meta.defaults)
|
|
2042
2058
|
}));
|
|
2043
2059
|
return await bundleAsCss(bundleData, context.resolver, options, async (tokens, resolved) => {
|
|
2044
2060
|
return await this.formatTokens(tokens, {
|
|
@@ -2048,12 +2064,12 @@ var CssRenderer = class _CssRenderer {
|
|
|
2048
2064
|
});
|
|
2049
2065
|
}
|
|
2050
2066
|
async formatStandalone(context, options) {
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2067
|
+
assertFileRequired(
|
|
2068
|
+
context.buildPath,
|
|
2069
|
+
context.output.file,
|
|
2070
|
+
context.output.name,
|
|
2071
|
+
"standalone CSS"
|
|
2072
|
+
);
|
|
2057
2073
|
const files = {};
|
|
2058
2074
|
for (const { tokens, modifierInputs } of context.permutations) {
|
|
2059
2075
|
const { fileName, content } = await this.buildStandaloneFile(
|
|
@@ -2067,7 +2083,7 @@ var CssRenderer = class _CssRenderer {
|
|
|
2067
2083
|
return { kind: "outputTree", files };
|
|
2068
2084
|
}
|
|
2069
2085
|
async buildStandaloneFile(tokens, modifierInputs, context, options) {
|
|
2070
|
-
const isBase =
|
|
2086
|
+
const isBase = isBasePermutation(modifierInputs, context.meta.defaults);
|
|
2071
2087
|
const { modifierName, modifierContext } = this.resolveModifierContext(
|
|
2072
2088
|
modifierInputs,
|
|
2073
2089
|
context,
|
|
@@ -2104,12 +2120,7 @@ var CssRenderer = class _CssRenderer {
|
|
|
2104
2120
|
return { fileName, content };
|
|
2105
2121
|
}
|
|
2106
2122
|
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
|
-
}
|
|
2123
|
+
assertFileRequired(context.buildPath, context.output.file, context.output.name, "modifier CSS");
|
|
2113
2124
|
if (!context.resolver.modifiers) {
|
|
2114
2125
|
throw new ConfigurationError("Modifier preset requires modifiers to be defined in resolver");
|
|
2115
2126
|
}
|
|
@@ -2135,7 +2146,7 @@ var CssRenderer = class _CssRenderer {
|
|
|
2135
2146
|
}
|
|
2136
2147
|
async buildModifierBaseFile(context, options) {
|
|
2137
2148
|
const basePermutation = context.permutations.find(
|
|
2138
|
-
({ modifierInputs }) =>
|
|
2149
|
+
({ modifierInputs }) => isBasePermutation(modifierInputs, context.meta.defaults)
|
|
2139
2150
|
);
|
|
2140
2151
|
if (!basePermutation) {
|
|
2141
2152
|
return void 0;
|
|
@@ -2148,25 +2159,40 @@ var CssRenderer = class _CssRenderer {
|
|
|
2148
2159
|
if (setBlocks.length === 0) {
|
|
2149
2160
|
return void 0;
|
|
2150
2161
|
}
|
|
2162
|
+
const { selector, mediaQuery } = this.resolveBaseModifierContext(context, options);
|
|
2163
|
+
const content = await this.formatSetBlocksCss(
|
|
2164
|
+
setBlocks,
|
|
2165
|
+
basePermutation.tokens,
|
|
2166
|
+
selector,
|
|
2167
|
+
mediaQuery,
|
|
2168
|
+
options
|
|
2169
|
+
);
|
|
2170
|
+
const fileName = context.output.file ? resolveBaseFileName(context.output.file, context.meta.defaults) : `${context.output.name}-base.css`;
|
|
2171
|
+
return { fileName, content };
|
|
2172
|
+
}
|
|
2173
|
+
resolveBaseModifierContext(context, options) {
|
|
2151
2174
|
const modifiers = context.resolver.modifiers;
|
|
2152
2175
|
const firstModifierName = Object.keys(modifiers)[0] ?? "";
|
|
2153
2176
|
const firstModifierContext = context.meta.defaults[firstModifierName] ?? "";
|
|
2154
2177
|
const baseModifierInputs = { ...context.meta.defaults };
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2178
|
+
return {
|
|
2179
|
+
selector: resolveSelector(
|
|
2180
|
+
options.selector,
|
|
2181
|
+
firstModifierName,
|
|
2182
|
+
firstModifierContext,
|
|
2183
|
+
true,
|
|
2184
|
+
baseModifierInputs
|
|
2185
|
+
),
|
|
2186
|
+
mediaQuery: resolveMediaQuery(
|
|
2187
|
+
options.mediaQuery,
|
|
2188
|
+
firstModifierName,
|
|
2189
|
+
firstModifierContext,
|
|
2190
|
+
true,
|
|
2191
|
+
baseModifierInputs
|
|
2192
|
+
)
|
|
2193
|
+
};
|
|
2194
|
+
}
|
|
2195
|
+
async formatSetBlocksCss(setBlocks, referenceTokens, selector, mediaQuery, options) {
|
|
2170
2196
|
const cssBlocks = [];
|
|
2171
2197
|
for (const block of setBlocks) {
|
|
2172
2198
|
const cleanTokens = stripInternalMetadata(block.tokens);
|
|
@@ -2182,9 +2208,7 @@ var CssRenderer = class _CssRenderer {
|
|
|
2182
2208
|
cssBlocks.push(`${header}
|
|
2183
2209
|
${css2}`);
|
|
2184
2210
|
}
|
|
2185
|
-
|
|
2186
|
-
const fileName = context.output.file ? resolveBaseFileName(context.output.file, context.meta.defaults) : `${context.output.name}-base.css`;
|
|
2187
|
-
return { fileName, content };
|
|
2211
|
+
return cssBlocks.join("\n");
|
|
2188
2212
|
}
|
|
2189
2213
|
collectTokensForModifierContext(modifierName, contextValue, permutations) {
|
|
2190
2214
|
const expectedSource = `${modifierName}-${contextValue}`;
|
|
@@ -2261,13 +2285,6 @@ ${css2}`);
|
|
|
2261
2285
|
}
|
|
2262
2286
|
return { modifierName: "", modifierContext: "" };
|
|
2263
2287
|
}
|
|
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
2288
|
};
|
|
2272
2289
|
function cssRenderer() {
|
|
2273
2290
|
const rendererInstance = new CssRenderer();
|
|
@@ -2279,9 +2296,18 @@ function cssRenderer() {
|
|
|
2279
2296
|
};
|
|
2280
2297
|
}
|
|
2281
2298
|
|
|
2299
|
+
// src/tokens/types.ts
|
|
2300
|
+
function isShadowToken(token) {
|
|
2301
|
+
return token.$type === "shadow";
|
|
2302
|
+
}
|
|
2303
|
+
function isTypographyToken(token) {
|
|
2304
|
+
return token.$type === "typography";
|
|
2305
|
+
}
|
|
2306
|
+
function isBorderToken(token) {
|
|
2307
|
+
return token.$type === "border";
|
|
2308
|
+
}
|
|
2309
|
+
|
|
2282
2310
|
// src/renderers/ios.ts
|
|
2283
|
-
init_errors();
|
|
2284
|
-
init_token_utils();
|
|
2285
2311
|
init_utils();
|
|
2286
2312
|
var toSRGB2 = converter("rgb");
|
|
2287
2313
|
var toP32 = converter("p3");
|
|
@@ -2370,94 +2396,68 @@ var IosRenderer = class {
|
|
|
2370
2396
|
return await this.formatStandalone(context, opts);
|
|
2371
2397
|
}
|
|
2372
2398
|
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
2399
|
const access = options.accessLevel;
|
|
2380
|
-
const groups =
|
|
2400
|
+
const groups = groupTokensByType(tokens, SWIFT_TYPE_GROUP_MAP);
|
|
2381
2401
|
const imports = this.collectImports(tokens);
|
|
2382
|
-
const i1 = this.indentStr(options.indent, 1);
|
|
2383
|
-
const i2 = this.indentStr(options.indent, 2);
|
|
2384
2402
|
const staticPrefix = this.staticLetPrefix(options);
|
|
2385
2403
|
const frozen = this.frozenPrefix(options);
|
|
2386
2404
|
const lines = [];
|
|
2387
|
-
lines.push(
|
|
2405
|
+
lines.push(buildGeneratedFileHeader());
|
|
2388
2406
|
lines.push("");
|
|
2389
2407
|
for (const imp of imports) {
|
|
2390
2408
|
lines.push(`import ${imp}`);
|
|
2391
2409
|
}
|
|
2392
2410
|
lines.push(...this.buildStructDefinitions(tokens, access, options));
|
|
2411
|
+
this.pushTokenLayout(lines, groups, options, access, staticPrefix, frozen);
|
|
2412
|
+
lines.push(...this.buildViewExtensions(tokens, access, options));
|
|
2413
|
+
if (options.structure !== "grouped") {
|
|
2414
|
+
lines.push("");
|
|
2415
|
+
}
|
|
2416
|
+
return lines.join("\n");
|
|
2417
|
+
}
|
|
2418
|
+
pushTokenLayout(lines, groups, options, access, staticPrefix, frozen) {
|
|
2419
|
+
const i1 = indentStr(options.indent, 1);
|
|
2420
|
+
const i2 = indentStr(options.indent, 2);
|
|
2421
|
+
if (options.structure === "grouped") {
|
|
2422
|
+
this.pushGroupedLayout(lines, groups, options, access, i1, i2, staticPrefix, frozen);
|
|
2423
|
+
return;
|
|
2424
|
+
}
|
|
2393
2425
|
lines.push("");
|
|
2394
2426
|
lines.push(`${frozen}${access} enum ${options.enumName} {`);
|
|
2395
2427
|
for (const group of groups) {
|
|
2396
2428
|
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
|
-
}
|
|
2429
|
+
this.pushTokenDeclarations(lines, group.tokens, options, access, i2, staticPrefix);
|
|
2408
2430
|
lines.push(`${i1}}`);
|
|
2409
2431
|
lines.push("");
|
|
2410
2432
|
}
|
|
2411
2433
|
lines.push("}");
|
|
2412
|
-
lines.push(...this.buildViewExtensions(tokens, access, options));
|
|
2413
|
-
lines.push("");
|
|
2414
|
-
return lines.join("\n");
|
|
2415
2434
|
}
|
|
2416
|
-
|
|
2417
|
-
const access = options.accessLevel;
|
|
2435
|
+
pushGroupedLayout(lines, groups, options, access, i1, i2, staticPrefix, frozen) {
|
|
2418
2436
|
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
2437
|
lines.push("");
|
|
2433
2438
|
lines.push(`${frozen}${access} enum ${namespace} {}`);
|
|
2434
2439
|
lines.push("");
|
|
2435
2440
|
for (const group of groups) {
|
|
2436
2441
|
lines.push(`${access} extension ${namespace} {`);
|
|
2437
2442
|
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
|
-
}
|
|
2443
|
+
this.pushTokenDeclarations(lines, group.tokens, options, access, i2, staticPrefix);
|
|
2449
2444
|
lines.push(`${i1}}`);
|
|
2450
2445
|
lines.push("}");
|
|
2451
2446
|
lines.push("");
|
|
2452
2447
|
}
|
|
2453
|
-
lines.push(...this.buildViewExtensions(tokens, access, options));
|
|
2454
|
-
return lines.join("\n");
|
|
2455
2448
|
}
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2449
|
+
pushTokenDeclarations(lines, tokens, options, access, indent, staticPrefix) {
|
|
2450
|
+
for (const token of tokens) {
|
|
2451
|
+
const swiftName = this.buildQualifiedSwiftName(token);
|
|
2452
|
+
const swiftValue = this.formatSwiftValue(token, options);
|
|
2453
|
+
const typeAnnotation = this.getTypeAnnotation(token);
|
|
2454
|
+
const annotation = typeAnnotation ? `: ${typeAnnotation}` : "";
|
|
2455
|
+
const docComment = this.buildDocComment(token, indent);
|
|
2456
|
+
if (docComment) {
|
|
2457
|
+
lines.push(docComment);
|
|
2458
|
+
}
|
|
2459
|
+
lines.push(`${indent}${access} ${staticPrefix}${swiftName}${annotation} = ${swiftValue}`);
|
|
2460
|
+
}
|
|
2461
2461
|
}
|
|
2462
2462
|
collectImports(tokens) {
|
|
2463
2463
|
const imports = /* @__PURE__ */ new Set();
|
|
@@ -2472,24 +2472,11 @@ var IosRenderer = class {
|
|
|
2472
2472
|
/**
|
|
2473
2473
|
* Builds a `///` doc comment from a token's `$description`, if present.
|
|
2474
2474
|
*/
|
|
2475
|
-
buildDocComment(token,
|
|
2475
|
+
buildDocComment(token, indent) {
|
|
2476
2476
|
if (!token.$description) {
|
|
2477
2477
|
return void 0;
|
|
2478
2478
|
}
|
|
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
|
-
}));
|
|
2479
|
+
return `${indent}/// ${token.$description}`;
|
|
2493
2480
|
}
|
|
2494
2481
|
/**
|
|
2495
2482
|
* Builds a qualified Swift name from a token's path, preserving parent
|
|
@@ -2502,43 +2489,40 @@ var IosRenderer = class {
|
|
|
2502
2489
|
const path = token.path;
|
|
2503
2490
|
const withoutTypePrefix = path.length > 1 ? path.slice(1) : path;
|
|
2504
2491
|
const joined = withoutTypePrefix.join("_");
|
|
2505
|
-
return
|
|
2492
|
+
return toSafeIdentifier(joined, SWIFT_KEYWORDS, false);
|
|
2506
2493
|
}
|
|
2507
2494
|
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]}))`;
|
|
2495
|
+
const { $type, $value: value } = token;
|
|
2496
|
+
switch ($type) {
|
|
2497
|
+
case "color":
|
|
2498
|
+
return this.formatColorValue(value, options);
|
|
2499
|
+
case "dimension":
|
|
2500
|
+
return this.formatDimensionValue(value);
|
|
2501
|
+
case "fontFamily":
|
|
2502
|
+
return this.formatFontFamilyValue(value);
|
|
2503
|
+
case "fontWeight":
|
|
2504
|
+
return this.formatFontWeightValue(value);
|
|
2505
|
+
case "duration":
|
|
2506
|
+
return this.formatDurationValue(value);
|
|
2507
|
+
case "shadow":
|
|
2508
|
+
return this.formatShadowValue(value, options);
|
|
2509
|
+
case "typography":
|
|
2510
|
+
return this.formatTypographyValue(value);
|
|
2511
|
+
case "border":
|
|
2512
|
+
return this.formatBorderValue(value, options);
|
|
2513
|
+
case "gradient":
|
|
2514
|
+
return this.formatGradientValue(value, options);
|
|
2515
|
+
case "number":
|
|
2516
|
+
return String(value);
|
|
2517
|
+
case "cubicBezier":
|
|
2518
|
+
if (Array.isArray(value) && value.length === 4) {
|
|
2519
|
+
return `UnitCurve.bezier(startControlPoint: UnitPoint(x: ${value[0]}, y: ${value[1]}), endControlPoint: UnitPoint(x: ${value[2]}, y: ${value[3]}))`;
|
|
2520
|
+
}
|
|
2521
|
+
break;
|
|
2541
2522
|
}
|
|
2523
|
+
return this.formatSwiftPrimitive(value);
|
|
2524
|
+
}
|
|
2525
|
+
formatSwiftPrimitive(value) {
|
|
2542
2526
|
if (typeof value === "string") {
|
|
2543
2527
|
return `"${this.escapeSwiftString(value)}"`;
|
|
2544
2528
|
}
|
|
@@ -2571,9 +2555,7 @@ var IosRenderer = class {
|
|
|
2571
2555
|
}
|
|
2572
2556
|
formatDimensionValue(value) {
|
|
2573
2557
|
if (isDimensionObject(value)) {
|
|
2574
|
-
|
|
2575
|
-
const ptValue = dim.unit === "rem" ? dim.value * 16 : dim.value;
|
|
2576
|
-
return String(ptValue);
|
|
2558
|
+
return this.dimensionToPoints(value);
|
|
2577
2559
|
}
|
|
2578
2560
|
return String(value);
|
|
2579
2561
|
}
|
|
@@ -2640,7 +2622,7 @@ var IosRenderer = class {
|
|
|
2640
2622
|
return map[name.toLowerCase()];
|
|
2641
2623
|
}
|
|
2642
2624
|
formatDurationValue(value) {
|
|
2643
|
-
if (
|
|
2625
|
+
if (isDurationObject(value)) {
|
|
2644
2626
|
const dur = value;
|
|
2645
2627
|
const seconds = dur.unit === "ms" ? dur.value / 1e3 : dur.value;
|
|
2646
2628
|
return String(seconds);
|
|
@@ -2689,9 +2671,7 @@ var IosRenderer = class {
|
|
|
2689
2671
|
if (!isDimensionObject(typo.letterSpacing)) {
|
|
2690
2672
|
return "0";
|
|
2691
2673
|
}
|
|
2692
|
-
|
|
2693
|
-
const ptValue = dim.unit === "rem" ? dim.value * 16 : dim.value;
|
|
2694
|
-
return String(ptValue);
|
|
2674
|
+
return this.dimensionToPoints(typo.letterSpacing);
|
|
2695
2675
|
}
|
|
2696
2676
|
extractLineSpacing(typo) {
|
|
2697
2677
|
if (typo.lineHeight == null || typeof typo.lineHeight !== "number") {
|
|
@@ -2700,18 +2680,19 @@ var IosRenderer = class {
|
|
|
2700
2680
|
if (!isDimensionObject(typo.fontSize)) {
|
|
2701
2681
|
return "0";
|
|
2702
2682
|
}
|
|
2703
|
-
const
|
|
2704
|
-
const basePt = dim.unit === "rem" ? dim.value * 16 : dim.value;
|
|
2683
|
+
const basePt = this.dimensionToNumericPoints(typo.fontSize);
|
|
2705
2684
|
const lineHeightPt = Math.round(basePt * typo.lineHeight * 100) / 100;
|
|
2706
2685
|
return String(lineHeightPt - basePt);
|
|
2707
2686
|
}
|
|
2687
|
+
dimensionToNumericPoints(dim) {
|
|
2688
|
+
return dim.unit === "rem" ? dim.value * 16 : dim.value;
|
|
2689
|
+
}
|
|
2708
2690
|
dimensionToPoints(dim) {
|
|
2709
|
-
|
|
2710
|
-
return String(ptValue);
|
|
2691
|
+
return String(this.dimensionToNumericPoints(dim));
|
|
2711
2692
|
}
|
|
2712
2693
|
/** Formats a dimension as a CGFloat literal (appends `.0` for integers). */
|
|
2713
2694
|
dimensionToCGFloat(dim) {
|
|
2714
|
-
const ptValue =
|
|
2695
|
+
const ptValue = this.dimensionToNumericPoints(dim);
|
|
2715
2696
|
return Number.isInteger(ptValue) ? `${ptValue}.0` : String(ptValue);
|
|
2716
2697
|
}
|
|
2717
2698
|
getTypeAnnotation(token) {
|
|
@@ -2730,21 +2711,12 @@ var IosRenderer = class {
|
|
|
2730
2711
|
return void 0;
|
|
2731
2712
|
}
|
|
2732
2713
|
}
|
|
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
2714
|
escapeSwiftString(str) {
|
|
2740
2715
|
return str.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n");
|
|
2741
2716
|
}
|
|
2742
2717
|
roundComponent(value) {
|
|
2743
2718
|
return Math.round(value * 1e4) / 1e4;
|
|
2744
2719
|
}
|
|
2745
|
-
indentStr(width, level) {
|
|
2746
|
-
return " ".repeat(width * level);
|
|
2747
|
-
}
|
|
2748
2720
|
/**
|
|
2749
2721
|
* Returns the prefix for `static let` declarations.
|
|
2750
2722
|
* Swift 6 requires `nonisolated(unsafe)` on global stored properties.
|
|
@@ -2760,34 +2732,25 @@ var IosRenderer = class {
|
|
|
2760
2732
|
structConformances(options) {
|
|
2761
2733
|
return options.swiftVersion === "6.0" ? ": Sendable" : "";
|
|
2762
2734
|
}
|
|
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
2735
|
/** Emits all struct definitions needed by the token set. */
|
|
2773
2736
|
buildStructDefinitions(tokens, access, options) {
|
|
2774
2737
|
const lines = [];
|
|
2775
|
-
if (
|
|
2738
|
+
if (Object.values(tokens).some(isShadowToken)) {
|
|
2776
2739
|
lines.push("");
|
|
2777
2740
|
lines.push(...this.buildShadowStyleStruct(access, options));
|
|
2778
2741
|
}
|
|
2779
|
-
if (
|
|
2742
|
+
if (Object.values(tokens).some(isTypographyToken)) {
|
|
2780
2743
|
lines.push("");
|
|
2781
2744
|
lines.push(...this.buildTypographyStyleStruct(access, options));
|
|
2782
2745
|
}
|
|
2783
|
-
if (
|
|
2746
|
+
if (Object.values(tokens).some(isBorderToken)) {
|
|
2784
2747
|
lines.push("");
|
|
2785
2748
|
lines.push(...this.buildBorderStyleStruct(access, options));
|
|
2786
2749
|
}
|
|
2787
2750
|
return lines;
|
|
2788
2751
|
}
|
|
2789
2752
|
buildShadowStyleStruct(access, options) {
|
|
2790
|
-
const i1 =
|
|
2753
|
+
const i1 = indentStr(options.indent, 1);
|
|
2791
2754
|
const conformances = this.structConformances(options);
|
|
2792
2755
|
const frozen = this.frozenPrefix(options);
|
|
2793
2756
|
return [
|
|
@@ -2801,7 +2764,7 @@ var IosRenderer = class {
|
|
|
2801
2764
|
];
|
|
2802
2765
|
}
|
|
2803
2766
|
buildTypographyStyleStruct(access, options) {
|
|
2804
|
-
const i1 =
|
|
2767
|
+
const i1 = indentStr(options.indent, 1);
|
|
2805
2768
|
const conformances = this.structConformances(options);
|
|
2806
2769
|
const frozen = this.frozenPrefix(options);
|
|
2807
2770
|
return [
|
|
@@ -2813,7 +2776,7 @@ var IosRenderer = class {
|
|
|
2813
2776
|
];
|
|
2814
2777
|
}
|
|
2815
2778
|
buildBorderStyleStruct(access, options) {
|
|
2816
|
-
const i1 =
|
|
2779
|
+
const i1 = indentStr(options.indent, 1);
|
|
2817
2780
|
const conformances = this.structConformances(options);
|
|
2818
2781
|
const frozen = this.frozenPrefix(options);
|
|
2819
2782
|
return [
|
|
@@ -2826,9 +2789,9 @@ var IosRenderer = class {
|
|
|
2826
2789
|
/** Emits convenience View extensions for shadow and typography application. */
|
|
2827
2790
|
buildViewExtensions(tokens, access, options) {
|
|
2828
2791
|
const lines = [];
|
|
2829
|
-
const i1 =
|
|
2830
|
-
const i2 =
|
|
2831
|
-
if (
|
|
2792
|
+
const i1 = indentStr(options.indent, 1);
|
|
2793
|
+
const i2 = indentStr(options.indent, 2);
|
|
2794
|
+
if (Object.values(tokens).some(isShadowToken)) {
|
|
2832
2795
|
lines.push("");
|
|
2833
2796
|
lines.push(`${access} extension View {`);
|
|
2834
2797
|
lines.push(`${i1}func shadowStyle(_ style: ShadowStyle) -> some View {`);
|
|
@@ -2838,7 +2801,7 @@ var IosRenderer = class {
|
|
|
2838
2801
|
lines.push(`${i1}}`);
|
|
2839
2802
|
lines.push("}");
|
|
2840
2803
|
}
|
|
2841
|
-
if (
|
|
2804
|
+
if (Object.values(tokens).some(isTypographyToken)) {
|
|
2842
2805
|
lines.push("");
|
|
2843
2806
|
lines.push(`${access} extension View {`);
|
|
2844
2807
|
lines.push(`${i1}func typographyStyle(_ style: TypographyStyle) -> some View {`);
|
|
@@ -2870,12 +2833,12 @@ var IosRenderer = class {
|
|
|
2870
2833
|
return `Gradient(stops: [${stops.join(", ")}])`;
|
|
2871
2834
|
}
|
|
2872
2835
|
async formatStandalone(context, options) {
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
|
|
2836
|
+
assertFileRequired(
|
|
2837
|
+
context.buildPath,
|
|
2838
|
+
context.output.file,
|
|
2839
|
+
context.output.name,
|
|
2840
|
+
"standalone iOS"
|
|
2841
|
+
);
|
|
2879
2842
|
const files = {};
|
|
2880
2843
|
for (const { tokens, modifierInputs } of context.permutations) {
|
|
2881
2844
|
const processedTokens = stripInternalMetadata(tokens);
|
|
@@ -2904,7 +2867,6 @@ function iosRenderer() {
|
|
|
2904
2867
|
|
|
2905
2868
|
// src/renderers/js-module.ts
|
|
2906
2869
|
init_utils();
|
|
2907
|
-
init_errors();
|
|
2908
2870
|
init_token_utils();
|
|
2909
2871
|
var JsModuleRenderer = class {
|
|
2910
2872
|
async format(context, options) {
|
|
@@ -2920,18 +2882,13 @@ var JsModuleRenderer = class {
|
|
|
2920
2882
|
const bundleData = context.permutations.map(({ tokens, modifierInputs }) => ({
|
|
2921
2883
|
tokens: stripInternalMetadata(tokens),
|
|
2922
2884
|
modifierInputs,
|
|
2923
|
-
isBase:
|
|
2885
|
+
isBase: isBasePermutation(modifierInputs, context.meta.defaults)
|
|
2924
2886
|
}));
|
|
2925
2887
|
return await bundleAsJsModule2(bundleData, context.resolver, opts, async (tokens) => {
|
|
2926
2888
|
return await this.formatTokens(tokens, opts);
|
|
2927
2889
|
});
|
|
2928
2890
|
}
|
|
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
|
-
}
|
|
2891
|
+
assertFileRequired(context.buildPath, context.output.file, context.output.name, "JS module");
|
|
2935
2892
|
const files = {};
|
|
2936
2893
|
for (const { tokens, modifierInputs } of context.permutations) {
|
|
2937
2894
|
const cleanTokens = stripInternalMetadata(tokens);
|
|
@@ -2985,42 +2942,18 @@ var JsModuleRenderer = class {
|
|
|
2985
2942
|
lines.push(`export default ${varName}`);
|
|
2986
2943
|
return lines;
|
|
2987
2944
|
}
|
|
2988
|
-
/**
|
|
2989
|
-
* Convert tokens to plain object with flat or nested structure
|
|
2990
|
-
*/
|
|
2991
2945
|
tokensToPlainObject(tokens, structure) {
|
|
2946
|
+
if (structure === "nested") {
|
|
2947
|
+
return buildNestedTokenObject(tokens, (token) => token.$value);
|
|
2948
|
+
}
|
|
2992
2949
|
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
|
-
}
|
|
2950
|
+
for (const [name, token] of getSortedTokenEntries(tokens)) {
|
|
2951
|
+
result[name] = token.$value;
|
|
3016
2952
|
}
|
|
3017
2953
|
return result;
|
|
3018
2954
|
}
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
*/
|
|
3022
|
-
addObjectProperties(lines, obj, indent2) {
|
|
3023
|
-
const indentStr = " ".repeat(indent2);
|
|
2955
|
+
addObjectProperties(lines, obj, indent) {
|
|
2956
|
+
const indentStr2 = " ".repeat(indent);
|
|
3024
2957
|
const entries = Object.entries(obj).sort(([keyA], [keyB]) => keyA.localeCompare(keyB));
|
|
3025
2958
|
for (let i = 0; i < entries.length; i++) {
|
|
3026
2959
|
const entry = entries[i];
|
|
@@ -3029,14 +2962,16 @@ var JsModuleRenderer = class {
|
|
|
3029
2962
|
}
|
|
3030
2963
|
const [key, value] = entry;
|
|
3031
2964
|
const isLast = i === entries.length - 1;
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
lines.push(`${indentStr}${this.quoteKey(key)}: ${valueStr}${isLast ? "" : ","}`);
|
|
2965
|
+
const isNestedObject = typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2966
|
+
if (!isNestedObject) {
|
|
2967
|
+
lines.push(
|
|
2968
|
+
`${indentStr2}${this.quoteKey(key)}: ${JSON.stringify(value)}${isLast ? "" : ","}`
|
|
2969
|
+
);
|
|
2970
|
+
continue;
|
|
3039
2971
|
}
|
|
2972
|
+
lines.push(`${indentStr2}${this.quoteKey(key)}: {`);
|
|
2973
|
+
this.addObjectProperties(lines, value, indent + 1);
|
|
2974
|
+
lines.push(`${indentStr2}}${isLast ? "" : ","}`);
|
|
3040
2975
|
}
|
|
3041
2976
|
}
|
|
3042
2977
|
/**
|
|
@@ -3048,9 +2983,6 @@ var JsModuleRenderer = class {
|
|
|
3048
2983
|
}
|
|
3049
2984
|
return `"${key}"`;
|
|
3050
2985
|
}
|
|
3051
|
-
isBasePermutation(modifierInputs, defaults) {
|
|
3052
|
-
return Object.entries(modifierInputs).every(([key, value]) => value === defaults[key]);
|
|
3053
|
-
}
|
|
3054
2986
|
};
|
|
3055
2987
|
function jsRenderer() {
|
|
3056
2988
|
const rendererInstance = new JsModuleRenderer();
|
|
@@ -3064,7 +2996,6 @@ function jsRenderer() {
|
|
|
3064
2996
|
|
|
3065
2997
|
// src/renderers/json.ts
|
|
3066
2998
|
init_utils();
|
|
3067
|
-
init_errors();
|
|
3068
2999
|
init_token_utils();
|
|
3069
3000
|
var JsonRenderer = class {
|
|
3070
3001
|
async format(context, options) {
|
|
@@ -3079,18 +3010,13 @@ var JsonRenderer = class {
|
|
|
3079
3010
|
const bundleData = context.permutations.map(({ tokens, modifierInputs }) => ({
|
|
3080
3011
|
tokens: stripInternalMetadata(tokens),
|
|
3081
3012
|
modifierInputs,
|
|
3082
|
-
isBase:
|
|
3013
|
+
isBase: isBasePermutation(modifierInputs, context.meta.defaults)
|
|
3083
3014
|
}));
|
|
3084
3015
|
return await bundleAsJson2(bundleData, context.resolver, async (tokens) => {
|
|
3085
3016
|
return await this.formatTokens(tokens, opts);
|
|
3086
3017
|
});
|
|
3087
3018
|
}
|
|
3088
|
-
|
|
3089
|
-
if (!context.output.file && requiresFile) {
|
|
3090
|
-
throw new ConfigurationError(
|
|
3091
|
-
`Output "${context.output.name}": file is required for JSON output`
|
|
3092
|
-
);
|
|
3093
|
-
}
|
|
3019
|
+
assertFileRequired(context.buildPath, context.output.file, context.output.name, "JSON");
|
|
3094
3020
|
const files = {};
|
|
3095
3021
|
for (const { tokens, modifierInputs } of context.permutations) {
|
|
3096
3022
|
const processedTokens = stripInternalMetadata(tokens);
|
|
@@ -3150,55 +3076,11 @@ var JsonRenderer = class {
|
|
|
3150
3076
|
}
|
|
3151
3077
|
return result;
|
|
3152
3078
|
}
|
|
3153
|
-
/**
|
|
3154
|
-
* Nest tokens by path (values only)
|
|
3155
|
-
*/
|
|
3156
3079
|
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;
|
|
3080
|
+
return buildNestedTokenObject(tokens, (token) => token.$value);
|
|
3177
3081
|
}
|
|
3178
|
-
/**
|
|
3179
|
-
* Nest tokens by path (with metadata)
|
|
3180
|
-
*/
|
|
3181
3082
|
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;
|
|
3083
|
+
return buildNestedTokenObject(tokens, (token) => this.serializeToken(token));
|
|
3202
3084
|
}
|
|
3203
3085
|
serializeToken(token) {
|
|
3204
3086
|
return {
|
|
@@ -3209,9 +3091,6 @@ var JsonRenderer = class {
|
|
|
3209
3091
|
...token.$extensions != null && { $extensions: token.$extensions }
|
|
3210
3092
|
};
|
|
3211
3093
|
}
|
|
3212
|
-
isBasePermutation(modifierInputs, defaults) {
|
|
3213
|
-
return Object.entries(modifierInputs).every(([key, value]) => value === defaults[key]);
|
|
3214
|
-
}
|
|
3215
3094
|
};
|
|
3216
3095
|
function jsonRenderer() {
|
|
3217
3096
|
const rendererInstance = new JsonRenderer();
|
|
@@ -3224,7 +3103,6 @@ function jsonRenderer() {
|
|
|
3224
3103
|
}
|
|
3225
3104
|
|
|
3226
3105
|
// src/renderers/tailwind.ts
|
|
3227
|
-
init_errors();
|
|
3228
3106
|
init_token_utils();
|
|
3229
3107
|
|
|
3230
3108
|
// src/renderers/bundlers/tailwind.ts
|
|
@@ -3253,6 +3131,13 @@ async function bundleAsTailwind(bundleData, options, formatThemeTokens, formatOv
|
|
|
3253
3131
|
}
|
|
3254
3132
|
return cssBlocks.join("\n");
|
|
3255
3133
|
}
|
|
3134
|
+
function resolveModifierSelectorAndMedia(options, modifier, context, modifierInputs) {
|
|
3135
|
+
const normalized = normalizeModifierInputs(modifierInputs);
|
|
3136
|
+
return {
|
|
3137
|
+
selector: resolveSelector(options.selector, modifier, context, false, normalized),
|
|
3138
|
+
mediaQuery: resolveMediaQuery(options.mediaQuery, modifier, context, false, normalized)
|
|
3139
|
+
};
|
|
3140
|
+
}
|
|
3256
3141
|
async function formatModifierOverride({ tokens, modifierInputs }, baseItem, options, formatOverrideBlock) {
|
|
3257
3142
|
const differenceCount = countModifierDifferences(modifierInputs, baseItem.modifierInputs);
|
|
3258
3143
|
if (differenceCount > 1) {
|
|
@@ -3265,19 +3150,11 @@ async function formatModifierOverride({ tokens, modifierInputs }, baseItem, opti
|
|
|
3265
3150
|
const expectedSource = getExpectedSource(modifierInputs, baseItem.modifierInputs);
|
|
3266
3151
|
const [modifier, context] = parseModifierSource(expectedSource);
|
|
3267
3152
|
const cleanTokens = stripInternalMetadata(tokensToInclude);
|
|
3268
|
-
const selector =
|
|
3269
|
-
options
|
|
3153
|
+
const { selector, mediaQuery } = resolveModifierSelectorAndMedia(
|
|
3154
|
+
options,
|
|
3270
3155
|
modifier,
|
|
3271
3156
|
context,
|
|
3272
|
-
|
|
3273
|
-
normalizeModifierInputs(modifierInputs)
|
|
3274
|
-
);
|
|
3275
|
-
const mediaQuery = resolveMediaQuery(
|
|
3276
|
-
options.mediaQuery,
|
|
3277
|
-
modifier,
|
|
3278
|
-
context,
|
|
3279
|
-
false,
|
|
3280
|
-
normalizeModifierInputs(modifierInputs)
|
|
3157
|
+
modifierInputs
|
|
3281
3158
|
);
|
|
3282
3159
|
const css2 = await formatOverrideBlock(cleanTokens, selector, mediaQuery, options.minify);
|
|
3283
3160
|
return `/* Modifier: ${modifier}=${context} */
|
|
@@ -3366,7 +3243,7 @@ var TailwindRenderer = class {
|
|
|
3366
3243
|
*/
|
|
3367
3244
|
async formatTokens(tokens, options) {
|
|
3368
3245
|
const lines = [];
|
|
3369
|
-
const
|
|
3246
|
+
const indent = options.minify ? "" : " ";
|
|
3370
3247
|
const newline = options.minify ? "" : "\n";
|
|
3371
3248
|
const space = options.minify ? "" : " ";
|
|
3372
3249
|
if (options.includeImport) {
|
|
@@ -3388,7 +3265,7 @@ var TailwindRenderer = class {
|
|
|
3388
3265
|
for (const [, token] of getSortedTokenEntries(tokens)) {
|
|
3389
3266
|
const varName = this.buildVariableName(token);
|
|
3390
3267
|
const varValue = this.formatValue(token);
|
|
3391
|
-
lines.push(`${
|
|
3268
|
+
lines.push(`${indent}--${varName}:${space}${varValue};${newline}`);
|
|
3392
3269
|
}
|
|
3393
3270
|
lines.push(`}${newline}`);
|
|
3394
3271
|
const cssString = lines.join("");
|
|
@@ -3399,15 +3276,15 @@ var TailwindRenderer = class {
|
|
|
3399
3276
|
* Used for modifier overrides (e.g., dark mode) appended after the @theme block.
|
|
3400
3277
|
*/
|
|
3401
3278
|
async formatOverrideBlock(tokens, selector, mediaQuery, minify) {
|
|
3402
|
-
const
|
|
3279
|
+
const indent = minify ? "" : " ";
|
|
3403
3280
|
const newline = minify ? "" : "\n";
|
|
3404
3281
|
const space = minify ? "" : " ";
|
|
3405
3282
|
const hasMediaQuery = mediaQuery !== "";
|
|
3406
|
-
const tokenIndent = hasMediaQuery ?
|
|
3283
|
+
const tokenIndent = hasMediaQuery ? indent + indent : indent;
|
|
3407
3284
|
const lines = [];
|
|
3408
3285
|
if (hasMediaQuery) {
|
|
3409
3286
|
lines.push(`@media ${mediaQuery}${space}{${newline}`);
|
|
3410
|
-
lines.push(`${
|
|
3287
|
+
lines.push(`${indent}${selector}${space}{${newline}`);
|
|
3411
3288
|
} else {
|
|
3412
3289
|
lines.push(`${selector}${space}{${newline}`);
|
|
3413
3290
|
}
|
|
@@ -3417,7 +3294,7 @@ var TailwindRenderer = class {
|
|
|
3417
3294
|
lines.push(`${tokenIndent}--${varName}:${space}${varValue};${newline}`);
|
|
3418
3295
|
}
|
|
3419
3296
|
if (hasMediaQuery) {
|
|
3420
|
-
lines.push(`${
|
|
3297
|
+
lines.push(`${indent}}${newline}`);
|
|
3421
3298
|
lines.push(`}${newline}`);
|
|
3422
3299
|
} else {
|
|
3423
3300
|
lines.push(`}${newline}`);
|
|
@@ -3444,8 +3321,8 @@ var TailwindRenderer = class {
|
|
|
3444
3321
|
if (token.$type === "dimension" && isDimensionObject(value)) {
|
|
3445
3322
|
return dimensionObjectToString(value);
|
|
3446
3323
|
}
|
|
3447
|
-
if (token.$type === "duration" &&
|
|
3448
|
-
return
|
|
3324
|
+
if (token.$type === "duration" && isDurationObject(value)) {
|
|
3325
|
+
return durationObjectToString(value);
|
|
3449
3326
|
}
|
|
3450
3327
|
if (token.$type === "fontFamily") {
|
|
3451
3328
|
if (Array.isArray(value)) {
|
|
@@ -3500,9 +3377,6 @@ var TailwindRenderer = class {
|
|
|
3500
3377
|
}
|
|
3501
3378
|
return parts.join(" ");
|
|
3502
3379
|
}
|
|
3503
|
-
isDurationObject(value) {
|
|
3504
|
-
return typeof value === "object" && value !== null && "value" in value && "unit" in value && value.unit !== void 0;
|
|
3505
|
-
}
|
|
3506
3380
|
async formatWithPrettier(css2) {
|
|
3507
3381
|
try {
|
|
3508
3382
|
return await prettier.format(css2, {
|
|
@@ -3519,7 +3393,7 @@ var TailwindRenderer = class {
|
|
|
3519
3393
|
const bundleData = context.permutations.map(({ tokens, modifierInputs }) => ({
|
|
3520
3394
|
tokens,
|
|
3521
3395
|
modifierInputs,
|
|
3522
|
-
isBase:
|
|
3396
|
+
isBase: isBasePermutation(modifierInputs, context.meta.defaults)
|
|
3523
3397
|
}));
|
|
3524
3398
|
return await bundleAsTailwind(
|
|
3525
3399
|
bundleData,
|
|
@@ -3529,12 +3403,12 @@ var TailwindRenderer = class {
|
|
|
3529
3403
|
);
|
|
3530
3404
|
}
|
|
3531
3405
|
async formatStandalone(context, options) {
|
|
3532
|
-
|
|
3533
|
-
|
|
3534
|
-
|
|
3535
|
-
|
|
3536
|
-
|
|
3537
|
-
|
|
3406
|
+
assertFileRequired(
|
|
3407
|
+
context.buildPath,
|
|
3408
|
+
context.output.file,
|
|
3409
|
+
context.output.name,
|
|
3410
|
+
"standalone Tailwind"
|
|
3411
|
+
);
|
|
3538
3412
|
const files = {};
|
|
3539
3413
|
for (const { tokens, modifierInputs } of context.permutations) {
|
|
3540
3414
|
const processedTokens = stripInternalMetadata(tokens);
|
|
@@ -3550,11 +3424,6 @@ var TailwindRenderer = class {
|
|
|
3550
3424
|
}
|
|
3551
3425
|
return outputTree(files);
|
|
3552
3426
|
}
|
|
3553
|
-
isBasePermutation(modifierInputs, defaults) {
|
|
3554
|
-
return Object.entries(defaults).every(
|
|
3555
|
-
([key, value]) => modifierInputs[key]?.toLowerCase() === value.toLowerCase()
|
|
3556
|
-
);
|
|
3557
|
-
}
|
|
3558
3427
|
};
|
|
3559
3428
|
function tailwindRenderer() {
|
|
3560
3429
|
const rendererInstance = new TailwindRenderer();
|