dispersa 0.4.1 → 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/dist/builders.cjs +466 -597
- package/dist/builders.cjs.map +1 -1
- package/dist/builders.d.cts +1 -1
- package/dist/builders.d.ts +1 -1
- 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/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 +622 -767
- 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 +622 -767
- 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.cjs
CHANGED
|
@@ -52,13 +52,12 @@ function formatDeprecationMessage(token, description = "", format = "bracket") {
|
|
|
52
52
|
}
|
|
53
53
|
const deprecationMsg = typeof token.$deprecated === "string" ? token.$deprecated : "";
|
|
54
54
|
if (format === "comment") {
|
|
55
|
-
const
|
|
56
|
-
return `DEPRECATED${
|
|
57
|
-
} else {
|
|
58
|
-
const msg = deprecationMsg ? `: ${deprecationMsg}` : "";
|
|
59
|
-
const prefix = `[DEPRECATED${msg}]`;
|
|
60
|
-
return description ? `${prefix} ${description}` : prefix;
|
|
55
|
+
const msg2 = deprecationMsg ? ` ${deprecationMsg}` : "";
|
|
56
|
+
return `DEPRECATED${msg2}`;
|
|
61
57
|
}
|
|
58
|
+
const msg = deprecationMsg ? `: ${deprecationMsg}` : "";
|
|
59
|
+
const prefix = `[DEPRECATED${msg}]`;
|
|
60
|
+
return description ? `${prefix} ${description}` : prefix;
|
|
62
61
|
}
|
|
63
62
|
function stripInternalTokenMetadata(tokens) {
|
|
64
63
|
const cleaned = {};
|
|
@@ -71,6 +70,30 @@ function stripInternalTokenMetadata(tokens) {
|
|
|
71
70
|
function getSortedTokenEntries(tokens) {
|
|
72
71
|
return Object.entries(tokens).sort(([nameA], [nameB]) => nameA.localeCompare(nameB));
|
|
73
72
|
}
|
|
73
|
+
function buildNestedTokenObject(tokens, extractValue) {
|
|
74
|
+
const result = {};
|
|
75
|
+
for (const [, token] of getSortedTokenEntries(tokens)) {
|
|
76
|
+
setNestedValue(result, token.path, extractValue(token));
|
|
77
|
+
}
|
|
78
|
+
return result;
|
|
79
|
+
}
|
|
80
|
+
function setNestedValue(root, path, value) {
|
|
81
|
+
let current = root;
|
|
82
|
+
for (let i = 0; i < path.length - 1; i++) {
|
|
83
|
+
const part = path[i];
|
|
84
|
+
if (part == null) {
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
if (!(part in current)) {
|
|
88
|
+
current[part] = {};
|
|
89
|
+
}
|
|
90
|
+
current = current[part];
|
|
91
|
+
}
|
|
92
|
+
const lastPart = path[path.length - 1];
|
|
93
|
+
if (lastPart != null) {
|
|
94
|
+
current[lastPart] = value;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
74
97
|
function getPureAliasReferenceName(value) {
|
|
75
98
|
if (typeof value !== "string") {
|
|
76
99
|
return void 0;
|
|
@@ -90,6 +113,35 @@ function sanitizeDataAttributeName(value) {
|
|
|
90
113
|
function escapeCssString(value) {
|
|
91
114
|
return value.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\r?\n/g, " ");
|
|
92
115
|
}
|
|
116
|
+
function groupTokensByType(tokens, typeGroupMap) {
|
|
117
|
+
const groupMap = /* @__PURE__ */ new Map();
|
|
118
|
+
for (const [, token] of getSortedTokenEntries(tokens)) {
|
|
119
|
+
const groupName = typeGroupMap[token.$type ?? ""] ?? "Other";
|
|
120
|
+
const existing = groupMap.get(groupName) ?? [];
|
|
121
|
+
existing.push(token);
|
|
122
|
+
groupMap.set(groupName, existing);
|
|
123
|
+
}
|
|
124
|
+
return Array.from(groupMap.entries()).map(([name, groupTokens]) => ({
|
|
125
|
+
name,
|
|
126
|
+
tokens: groupTokens
|
|
127
|
+
}));
|
|
128
|
+
}
|
|
129
|
+
function indentStr(width, level) {
|
|
130
|
+
return " ".repeat(width * level);
|
|
131
|
+
}
|
|
132
|
+
function buildGeneratedFileHeader() {
|
|
133
|
+
return [
|
|
134
|
+
"// Generated by Dispersa - do not edit manually",
|
|
135
|
+
"// https://github.com/timges/dispersa"
|
|
136
|
+
].join("\n");
|
|
137
|
+
}
|
|
138
|
+
function toSafeIdentifier(name, keywords, capitalize) {
|
|
139
|
+
const camel = name.replace(/[-._]+(.)/g, (_, c) => c.toUpperCase()).replace(/[-._]+$/g, "").replace(/^[-._]+/g, "");
|
|
140
|
+
const cased = capitalize ? camel.charAt(0).toUpperCase() + camel.slice(1) : camel.charAt(0).toLowerCase() + camel.slice(1);
|
|
141
|
+
const safe = /^\d/.test(cased) ? `_${cased}` : cased;
|
|
142
|
+
const keyCheck = capitalize ? safe.charAt(0).toLowerCase() + safe.slice(1) : safe;
|
|
143
|
+
return keywords.has(keyCheck) ? `\`${safe}\`` : safe;
|
|
144
|
+
}
|
|
93
145
|
function normalizeModifierInputs(inputs) {
|
|
94
146
|
const normalized = {};
|
|
95
147
|
for (const [key, value] of Object.entries(inputs)) {
|
|
@@ -97,6 +149,14 @@ function normalizeModifierInputs(inputs) {
|
|
|
97
149
|
}
|
|
98
150
|
return normalized;
|
|
99
151
|
}
|
|
152
|
+
function assertFileRequired(buildPath, outputFile, outputName, presetLabel) {
|
|
153
|
+
const requiresFile = buildPath !== void 0 && buildPath !== "";
|
|
154
|
+
if (!outputFile && requiresFile) {
|
|
155
|
+
throw new ConfigurationError(
|
|
156
|
+
`Output "${outputName}": file is required for ${presetLabel} output`
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
100
160
|
function buildStablePermutationKey(modifierInputs, dimensions) {
|
|
101
161
|
return dimensions.map((dimension) => `${dimension}=${modifierInputs[dimension] ?? ""}`).join("|");
|
|
102
162
|
}
|
|
@@ -146,14 +206,18 @@ function generatePermutationKey(modifierInputs, resolver, isBase) {
|
|
|
146
206
|
}
|
|
147
207
|
return buildStablePermutationKey(normalizedInputs, metadata.dimensions);
|
|
148
208
|
}
|
|
149
|
-
function
|
|
150
|
-
const { outputName, extension, modifierInputs, resolver, defaults } = params;
|
|
209
|
+
function isBasePermutation(modifierInputs, defaults) {
|
|
151
210
|
const normalizedInputs = normalizeModifierInputs(modifierInputs);
|
|
152
211
|
const normalizedDefaults = normalizeModifierInputs(defaults);
|
|
153
|
-
|
|
154
|
-
|
|
212
|
+
return Object.entries(normalizedDefaults).every(([key, value]) => normalizedInputs[key] === value);
|
|
213
|
+
}
|
|
214
|
+
function buildInMemoryOutputKey(params) {
|
|
215
|
+
const { outputName, extension, modifierInputs, resolver, defaults } = params;
|
|
216
|
+
const permutationKey = generatePermutationKey(
|
|
217
|
+
modifierInputs,
|
|
218
|
+
resolver,
|
|
219
|
+
isBasePermutation(modifierInputs, defaults)
|
|
155
220
|
);
|
|
156
|
-
const permutationKey = generatePermutationKey(modifierInputs, resolver, isBase);
|
|
157
221
|
return `${outputName}-${permutationKey}.${extension}`;
|
|
158
222
|
}
|
|
159
223
|
function buildMetadata(resolver) {
|
|
@@ -267,6 +331,7 @@ function resolveFileName(fileName, modifierInputs) {
|
|
|
267
331
|
}
|
|
268
332
|
var init_utils = __esm({
|
|
269
333
|
"src/renderers/bundlers/utils.ts"() {
|
|
334
|
+
init_errors();
|
|
270
335
|
init_token_utils();
|
|
271
336
|
}
|
|
272
337
|
});
|
|
@@ -276,36 +341,38 @@ var js_exports = {};
|
|
|
276
341
|
__export(js_exports, {
|
|
277
342
|
bundleAsJsModule: () => bundleAsJsModule
|
|
278
343
|
});
|
|
344
|
+
function updateStringTracking(state, char) {
|
|
345
|
+
if (!state.escaped && (char === '"' || char === "'" || char === "`")) {
|
|
346
|
+
if (!state.inString) {
|
|
347
|
+
state.inString = true;
|
|
348
|
+
state.stringChar = char;
|
|
349
|
+
} else if (char === state.stringChar) {
|
|
350
|
+
state.inString = false;
|
|
351
|
+
state.stringChar = "";
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
state.escaped = !state.escaped && char === "\\";
|
|
355
|
+
}
|
|
279
356
|
function extractObjectFromJsModule(formattedJs) {
|
|
280
357
|
const assignmentMatch = /const\s+\w+\s*=\s*\{/.exec(formattedJs);
|
|
281
358
|
if (!assignmentMatch) {
|
|
282
359
|
return "{}";
|
|
283
360
|
}
|
|
284
361
|
const startIndex = assignmentMatch.index + assignmentMatch[0].length - 1;
|
|
362
|
+
const state = { inString: false, stringChar: "", escaped: false };
|
|
285
363
|
let braceCount = 0;
|
|
286
|
-
let inString = false;
|
|
287
|
-
let stringChar = "";
|
|
288
|
-
let escaped = false;
|
|
289
364
|
for (let i = startIndex; i < formattedJs.length; i++) {
|
|
290
365
|
const char = formattedJs[i];
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
stringChar = char;
|
|
295
|
-
} else if (char === stringChar) {
|
|
296
|
-
inString = false;
|
|
297
|
-
stringChar = "";
|
|
298
|
-
}
|
|
366
|
+
updateStringTracking(state, char);
|
|
367
|
+
if (state.inString) {
|
|
368
|
+
continue;
|
|
299
369
|
}
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
if (braceCount === 0) {
|
|
307
|
-
return formattedJs.substring(startIndex, i + 1);
|
|
308
|
-
}
|
|
370
|
+
if (char === "{") {
|
|
371
|
+
braceCount++;
|
|
372
|
+
} else if (char === "}") {
|
|
373
|
+
braceCount--;
|
|
374
|
+
if (braceCount === 0) {
|
|
375
|
+
return formattedJs.substring(startIndex, i + 1);
|
|
309
376
|
}
|
|
310
377
|
}
|
|
311
378
|
}
|
|
@@ -402,22 +469,19 @@ __export(json_exports, {
|
|
|
402
469
|
bundleAsJson: () => bundleAsJson
|
|
403
470
|
});
|
|
404
471
|
async function bundleAsJson(bundleData, resolver, formatTokens) {
|
|
472
|
+
if (!formatTokens) {
|
|
473
|
+
throw new ConfigurationError("JSON formatter was not provided");
|
|
474
|
+
}
|
|
405
475
|
const metadata = buildMetadata(resolver);
|
|
406
476
|
const tokens = {};
|
|
407
477
|
for (const { tokens: tokenSet, modifierInputs } of bundleData) {
|
|
408
478
|
const cleanTokens = stripInternalMetadata(tokenSet);
|
|
409
|
-
if (!formatTokens) {
|
|
410
|
-
throw new ConfigurationError("JSON formatter was not provided");
|
|
411
|
-
}
|
|
412
479
|
const normalizedInputs = normalizeModifierInputs(modifierInputs);
|
|
413
480
|
const key = buildStablePermutationKey(normalizedInputs, metadata.dimensions);
|
|
414
481
|
const themeJson = await formatTokens(cleanTokens);
|
|
415
482
|
tokens[key] = JSON.parse(themeJson);
|
|
416
483
|
}
|
|
417
|
-
const bundle = {
|
|
418
|
-
_meta: metadata,
|
|
419
|
-
tokens
|
|
420
|
-
};
|
|
484
|
+
const bundle = { _meta: metadata, tokens };
|
|
421
485
|
return JSON.stringify(bundle, null, 2);
|
|
422
486
|
}
|
|
423
487
|
var init_json = __esm({
|
|
@@ -483,7 +547,7 @@ function colorObjectToHex(color) {
|
|
|
483
547
|
return culori.formatHex(culoriColor);
|
|
484
548
|
}
|
|
485
549
|
|
|
486
|
-
// src/processing/
|
|
550
|
+
// src/processing/transforms/built-in/dimension-converter.ts
|
|
487
551
|
function isDimensionObject(value) {
|
|
488
552
|
return typeof value === "object" && value !== null && "value" in value && "unit" in value;
|
|
489
553
|
}
|
|
@@ -491,6 +555,14 @@ function dimensionObjectToString(dimension) {
|
|
|
491
555
|
return `${dimension.value}${dimension.unit}`;
|
|
492
556
|
}
|
|
493
557
|
|
|
558
|
+
// src/processing/transforms/built-in/duration-converter.ts
|
|
559
|
+
function isDurationObject(value) {
|
|
560
|
+
return typeof value === "object" && value !== null && "value" in value && "unit" in value && value.unit !== void 0;
|
|
561
|
+
}
|
|
562
|
+
function durationObjectToString(duration) {
|
|
563
|
+
return `${duration.value}${duration.unit}`;
|
|
564
|
+
}
|
|
565
|
+
|
|
494
566
|
// src/renderers/android.ts
|
|
495
567
|
init_errors();
|
|
496
568
|
init_token_utils();
|
|
@@ -552,9 +624,6 @@ function resolveColorFormat(format) {
|
|
|
552
624
|
}
|
|
553
625
|
return "argb_hex";
|
|
554
626
|
}
|
|
555
|
-
function indent(width, level) {
|
|
556
|
-
return " ".repeat(width * level);
|
|
557
|
-
}
|
|
558
627
|
function escapeKotlinString(str) {
|
|
559
628
|
return str.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\$/g, "\\$");
|
|
560
629
|
}
|
|
@@ -570,22 +639,6 @@ function roundComponent(value) {
|
|
|
570
639
|
function toResourceName(family) {
|
|
571
640
|
return family.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_|_$/g, "");
|
|
572
641
|
}
|
|
573
|
-
function toPascalCase(name) {
|
|
574
|
-
const pascal = name.replace(/[-._]+(.)/g, (_, c) => c.toUpperCase()).replace(/[-._]+$/g, "").replace(/^[-._]+/g, "");
|
|
575
|
-
const result = pascal.charAt(0).toUpperCase() + pascal.slice(1);
|
|
576
|
-
if (/^\d/.test(result)) {
|
|
577
|
-
return `_${result}`;
|
|
578
|
-
}
|
|
579
|
-
return KOTLIN_KEYWORDS.has(result.charAt(0).toLowerCase() + result.slice(1)) ? `\`${result}\`` : result;
|
|
580
|
-
}
|
|
581
|
-
function toKotlinIdentifier(name) {
|
|
582
|
-
const camel = name.replace(/[-._]+(.)/g, (_, c) => c.toUpperCase()).replace(/[-._]+$/g, "").replace(/^[-._]+/g, "");
|
|
583
|
-
const identifier = camel.charAt(0).toLowerCase() + camel.slice(1);
|
|
584
|
-
if (/^\d/.test(identifier)) {
|
|
585
|
-
return `_${identifier}`;
|
|
586
|
-
}
|
|
587
|
-
return KOTLIN_KEYWORDS.has(identifier) ? `\`${identifier}\`` : identifier;
|
|
588
|
-
}
|
|
589
642
|
var AndroidRenderer = class {
|
|
590
643
|
async format(context, options) {
|
|
591
644
|
if (!options?.packageName) {
|
|
@@ -593,6 +646,7 @@ var AndroidRenderer = class {
|
|
|
593
646
|
`Output "${context.output.name}": packageName is required for Android output`
|
|
594
647
|
);
|
|
595
648
|
}
|
|
649
|
+
const visibility = options?.visibility;
|
|
596
650
|
const opts = {
|
|
597
651
|
preset: options?.preset ?? "standalone",
|
|
598
652
|
packageName: options.packageName,
|
|
@@ -600,7 +654,8 @@ var AndroidRenderer = class {
|
|
|
600
654
|
colorFormat: resolveColorFormat(options?.colorFormat),
|
|
601
655
|
colorSpace: options?.colorSpace ?? "sRGB",
|
|
602
656
|
structure: options?.structure ?? "nested",
|
|
603
|
-
visibility
|
|
657
|
+
visibility,
|
|
658
|
+
visPrefix: visibility ? `${visibility} ` : "",
|
|
604
659
|
indent: options?.indent ?? 4
|
|
605
660
|
};
|
|
606
661
|
if (opts.preset === "bundle") {
|
|
@@ -633,19 +688,6 @@ var AndroidRenderer = class {
|
|
|
633
688
|
// -----------------------------------------------------------------------
|
|
634
689
|
// Flat structure grouping
|
|
635
690
|
// -----------------------------------------------------------------------
|
|
636
|
-
groupTokensByType(tokens) {
|
|
637
|
-
const groupMap = /* @__PURE__ */ new Map();
|
|
638
|
-
for (const [, token] of getSortedTokenEntries(tokens)) {
|
|
639
|
-
const groupName = KOTLIN_TYPE_GROUP_MAP[token.$type ?? ""] ?? "Other";
|
|
640
|
-
const existing = groupMap.get(groupName) ?? [];
|
|
641
|
-
existing.push(token);
|
|
642
|
-
groupMap.set(groupName, existing);
|
|
643
|
-
}
|
|
644
|
-
return Array.from(groupMap.entries()).map(([name, groupTokens]) => ({
|
|
645
|
-
name,
|
|
646
|
-
tokens: groupTokens
|
|
647
|
-
}));
|
|
648
|
-
}
|
|
649
691
|
/**
|
|
650
692
|
* Builds a flattened camelCase name from a token's path, stripping the
|
|
651
693
|
* type prefix segment (which is already represented by the group object).
|
|
@@ -654,7 +696,7 @@ var AndroidRenderer = class {
|
|
|
654
696
|
const path = token.path;
|
|
655
697
|
const withoutTypePrefix = path.length > 1 ? path.slice(1) : path;
|
|
656
698
|
const joined = withoutTypePrefix.join("_");
|
|
657
|
-
return
|
|
699
|
+
return toSafeIdentifier(joined, KOTLIN_KEYWORDS, false);
|
|
658
700
|
}
|
|
659
701
|
// -----------------------------------------------------------------------
|
|
660
702
|
// Rendering
|
|
@@ -666,22 +708,21 @@ var AndroidRenderer = class {
|
|
|
666
708
|
return this.formatAsNested(tokens, options);
|
|
667
709
|
}
|
|
668
710
|
formatAsNested(tokens, options) {
|
|
711
|
+
const tokenTypes = this.collectTokenTypesFromEntries(tokens);
|
|
669
712
|
const tree = this.buildTokenTree(tokens);
|
|
670
|
-
|
|
671
|
-
this.collectTokenTypes(tree, tokenTypes);
|
|
672
|
-
return this.buildFile(tokenTypes, options, (lines, vis) => {
|
|
713
|
+
return this.buildFile(tokenTypes, options, (lines) => {
|
|
673
714
|
lines.push(`@Suppress("unused")`);
|
|
674
|
-
lines.push(`${
|
|
715
|
+
lines.push(`${options.visPrefix}object ${options.objectName} {`);
|
|
675
716
|
this.renderTreeChildren(lines, tree, 1, options);
|
|
676
717
|
lines.push("}");
|
|
677
718
|
});
|
|
678
719
|
}
|
|
679
720
|
formatAsFlat(tokens, options) {
|
|
680
|
-
const groups =
|
|
721
|
+
const groups = groupTokensByType(tokens, KOTLIN_TYPE_GROUP_MAP);
|
|
681
722
|
const tokenTypes = this.collectTokenTypesFromEntries(tokens);
|
|
682
|
-
return this.buildFile(tokenTypes, options, (lines
|
|
723
|
+
return this.buildFile(tokenTypes, options, (lines) => {
|
|
683
724
|
lines.push(`@Suppress("unused")`);
|
|
684
|
-
lines.push(`${
|
|
725
|
+
lines.push(`${options.visPrefix}object ${options.objectName} {`);
|
|
685
726
|
this.renderFlatGroups(lines, groups, 1, options);
|
|
686
727
|
lines.push("}");
|
|
687
728
|
});
|
|
@@ -692,9 +733,8 @@ var AndroidRenderer = class {
|
|
|
692
733
|
*/
|
|
693
734
|
buildFile(tokenTypes, options, renderBody) {
|
|
694
735
|
const imports = this.collectImports(tokenTypes, options);
|
|
695
|
-
const vis = options.visibility ? `${options.visibility} ` : "";
|
|
696
736
|
const lines = [];
|
|
697
|
-
lines.push(
|
|
737
|
+
lines.push(buildGeneratedFileHeader());
|
|
698
738
|
lines.push("");
|
|
699
739
|
lines.push(`package ${options.packageName}`);
|
|
700
740
|
lines.push("");
|
|
@@ -705,19 +745,18 @@ var AndroidRenderer = class {
|
|
|
705
745
|
lines.push("");
|
|
706
746
|
}
|
|
707
747
|
if (tokenTypes.has("shadow")) {
|
|
708
|
-
lines.push(...this.buildShadowTokenClass(
|
|
748
|
+
lines.push(...this.buildShadowTokenClass(options));
|
|
709
749
|
lines.push("");
|
|
710
750
|
}
|
|
711
|
-
renderBody(lines
|
|
751
|
+
renderBody(lines);
|
|
712
752
|
lines.push("");
|
|
713
753
|
return lines.join("\n");
|
|
714
754
|
}
|
|
715
755
|
renderFlatGroups(lines, groups, baseDepth, options) {
|
|
716
|
-
const
|
|
717
|
-
const
|
|
718
|
-
const valIndent = indent(options.indent, baseDepth + 1);
|
|
756
|
+
const groupIndent = indentStr(options.indent, baseDepth);
|
|
757
|
+
const valIndent = indentStr(options.indent, baseDepth + 1);
|
|
719
758
|
for (const group of groups) {
|
|
720
|
-
lines.push(`${groupIndent}${
|
|
759
|
+
lines.push(`${groupIndent}${options.visPrefix}object ${group.name} {`);
|
|
721
760
|
for (const token of group.tokens) {
|
|
722
761
|
const kotlinName = this.buildFlatKotlinName(token);
|
|
723
762
|
const kotlinValue = this.formatKotlinValue(token, options, baseDepth + 1);
|
|
@@ -725,23 +764,24 @@ var AndroidRenderer = class {
|
|
|
725
764
|
if (token.$description) {
|
|
726
765
|
lines.push(`${valIndent}/** ${escapeKDoc(token.$description)} */`);
|
|
727
766
|
}
|
|
728
|
-
lines.push(
|
|
767
|
+
lines.push(
|
|
768
|
+
`${valIndent}${options.visPrefix}val ${kotlinName}${annotation} = ${kotlinValue}`
|
|
769
|
+
);
|
|
729
770
|
}
|
|
730
771
|
lines.push(`${groupIndent}}`);
|
|
731
772
|
lines.push("");
|
|
732
773
|
}
|
|
733
774
|
}
|
|
734
775
|
renderTreeChildren(lines, node, depth, options) {
|
|
735
|
-
const
|
|
736
|
-
const pad = indent(options.indent, depth);
|
|
776
|
+
const pad = indentStr(options.indent, depth);
|
|
737
777
|
const entries = Array.from(node.children.entries());
|
|
738
778
|
for (let idx = 0; idx < entries.length; idx++) {
|
|
739
779
|
const [key, child] = entries[idx];
|
|
740
780
|
if (child.token && child.children.size === 0) {
|
|
741
781
|
this.renderLeaf(lines, key, child.token, depth, options);
|
|
742
782
|
} else if (child.children.size > 0 && !child.token) {
|
|
743
|
-
const objectName =
|
|
744
|
-
lines.push(`${pad}${
|
|
783
|
+
const objectName = toSafeIdentifier(key, KOTLIN_KEYWORDS, true);
|
|
784
|
+
lines.push(`${pad}${options.visPrefix}object ${objectName} {`);
|
|
745
785
|
this.renderTreeChildren(lines, child, depth + 1, options);
|
|
746
786
|
lines.push(`${pad}}`);
|
|
747
787
|
if (idx < entries.length - 1) {
|
|
@@ -754,30 +794,23 @@ var AndroidRenderer = class {
|
|
|
754
794
|
}
|
|
755
795
|
}
|
|
756
796
|
renderLeaf(lines, key, token, depth, options) {
|
|
757
|
-
const
|
|
758
|
-
const
|
|
759
|
-
const kotlinName = toKotlinIdentifier(key);
|
|
797
|
+
const pad = indentStr(options.indent, depth);
|
|
798
|
+
const kotlinName = toSafeIdentifier(key, KOTLIN_KEYWORDS, false);
|
|
760
799
|
const kotlinValue = this.formatKotlinValue(token, options, depth);
|
|
761
800
|
const annotation = this.typeAnnotationSuffix(token);
|
|
762
801
|
if (token.$description) {
|
|
763
802
|
lines.push(`${pad}/** ${escapeKDoc(token.$description)} */`);
|
|
764
803
|
}
|
|
765
|
-
lines.push(`${pad}${
|
|
766
|
-
}
|
|
767
|
-
buildFileHeader() {
|
|
768
|
-
return [
|
|
769
|
-
"// Generated by Dispersa - do not edit manually",
|
|
770
|
-
"// https://github.com/timges/dispersa"
|
|
771
|
-
].join("\n");
|
|
804
|
+
lines.push(`${pad}${options.visPrefix}val ${kotlinName}${annotation} = ${kotlinValue}`);
|
|
772
805
|
}
|
|
773
806
|
// -----------------------------------------------------------------------
|
|
774
807
|
// Shadow data class
|
|
775
808
|
// -----------------------------------------------------------------------
|
|
776
|
-
buildShadowTokenClass(
|
|
777
|
-
const i1 =
|
|
809
|
+
buildShadowTokenClass(options) {
|
|
810
|
+
const i1 = indentStr(options.indent, 1);
|
|
778
811
|
return [
|
|
779
812
|
"@Immutable",
|
|
780
|
-
`${
|
|
813
|
+
`${options.visPrefix}data class ShadowToken(`,
|
|
781
814
|
`${i1}val color: Color,`,
|
|
782
815
|
`${i1}val elevation: Dp,`,
|
|
783
816
|
`${i1}val offsetX: Dp,`,
|
|
@@ -828,14 +861,6 @@ var AndroidRenderer = class {
|
|
|
828
861
|
}
|
|
829
862
|
return Array.from(imports).sort();
|
|
830
863
|
}
|
|
831
|
-
collectTokenTypes(node, types) {
|
|
832
|
-
if (node.token?.$type) {
|
|
833
|
-
types.add(node.token.$type);
|
|
834
|
-
}
|
|
835
|
-
for (const child of node.children.values()) {
|
|
836
|
-
this.collectTokenTypes(child, types);
|
|
837
|
-
}
|
|
838
|
-
}
|
|
839
864
|
collectTokenTypesFromEntries(tokens) {
|
|
840
865
|
const types = /* @__PURE__ */ new Set();
|
|
841
866
|
for (const [, token] of Object.entries(tokens)) {
|
|
@@ -1062,9 +1087,8 @@ var AndroidRenderer = class {
|
|
|
1062
1087
|
return map[name.toLowerCase()];
|
|
1063
1088
|
}
|
|
1064
1089
|
formatDurationValue(value) {
|
|
1065
|
-
if (
|
|
1066
|
-
|
|
1067
|
-
return dur.unit === "ms" ? `${dur.value}.milliseconds` : `${dur.value}.seconds`;
|
|
1090
|
+
if (isDurationObject(value)) {
|
|
1091
|
+
return value.unit === "ms" ? `${value.value}.milliseconds` : `${value.value}.seconds`;
|
|
1068
1092
|
}
|
|
1069
1093
|
return typeof value === "number" ? `${value}.milliseconds` : "0.milliseconds";
|
|
1070
1094
|
}
|
|
@@ -1082,8 +1106,8 @@ var AndroidRenderer = class {
|
|
|
1082
1106
|
const elevation = isDimensionObject(shadow.blur) ? this.formatDimensionValue(shadow.blur) : "0.dp";
|
|
1083
1107
|
const offsetX = isDimensionObject(shadow.offsetX) ? this.formatDimensionValue(shadow.offsetX) : "0.dp";
|
|
1084
1108
|
const offsetY = isDimensionObject(shadow.offsetY) ? this.formatDimensionValue(shadow.offsetY) : "0.dp";
|
|
1085
|
-
const propIndent =
|
|
1086
|
-
const closeIndent =
|
|
1109
|
+
const propIndent = indentStr(options.indent, depth + 1);
|
|
1110
|
+
const closeIndent = indentStr(options.indent, depth);
|
|
1087
1111
|
return [
|
|
1088
1112
|
"ShadowToken(",
|
|
1089
1113
|
`${propIndent}color = ${color},`,
|
|
@@ -1132,8 +1156,8 @@ var AndroidRenderer = class {
|
|
|
1132
1156
|
if (parts.length === 0) {
|
|
1133
1157
|
return "TextStyle()";
|
|
1134
1158
|
}
|
|
1135
|
-
const propIndent =
|
|
1136
|
-
const closeIndent =
|
|
1159
|
+
const propIndent = indentStr(options.indent, depth + 1);
|
|
1160
|
+
const closeIndent = indentStr(options.indent, depth);
|
|
1137
1161
|
return `TextStyle(
|
|
1138
1162
|
${parts.map((p) => `${propIndent}${p}`).join(",\n")},
|
|
1139
1163
|
${closeIndent})`;
|
|
@@ -1142,12 +1166,12 @@ ${closeIndent})`;
|
|
|
1142
1166
|
// Output: standalone
|
|
1143
1167
|
// -----------------------------------------------------------------------
|
|
1144
1168
|
async formatStandalone(context, options) {
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1169
|
+
assertFileRequired(
|
|
1170
|
+
context.buildPath,
|
|
1171
|
+
context.output.file,
|
|
1172
|
+
context.output.name,
|
|
1173
|
+
"standalone Android"
|
|
1174
|
+
);
|
|
1151
1175
|
const files = {};
|
|
1152
1176
|
for (const { tokens, modifierInputs } of context.permutations) {
|
|
1153
1177
|
const processedTokens = stripInternalMetadata(tokens);
|
|
@@ -1167,12 +1191,12 @@ ${closeIndent})`;
|
|
|
1167
1191
|
// Output: bundle
|
|
1168
1192
|
// -----------------------------------------------------------------------
|
|
1169
1193
|
async formatBundle(context, options) {
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1194
|
+
assertFileRequired(
|
|
1195
|
+
context.buildPath,
|
|
1196
|
+
context.output.file,
|
|
1197
|
+
context.output.name,
|
|
1198
|
+
"bundle Android"
|
|
1199
|
+
);
|
|
1176
1200
|
const content = this.formatBundleContent(context, options);
|
|
1177
1201
|
const fileName = context.output.file ? resolveFileName(context.output.file, context.meta.basePermutation) : buildInMemoryOutputKey({
|
|
1178
1202
|
outputName: context.output.name,
|
|
@@ -1185,15 +1209,15 @@ ${closeIndent})`;
|
|
|
1185
1209
|
}
|
|
1186
1210
|
formatBundleContent(context, options) {
|
|
1187
1211
|
const allTokenTypes = this.collectAllPermutationTypes(context);
|
|
1188
|
-
return this.buildFile(allTokenTypes, options, (lines
|
|
1189
|
-
const i1 =
|
|
1212
|
+
return this.buildFile(allTokenTypes, options, (lines) => {
|
|
1213
|
+
const i1 = indentStr(options.indent, 1);
|
|
1190
1214
|
lines.push(`@Suppress("unused")`);
|
|
1191
|
-
lines.push(`${
|
|
1215
|
+
lines.push(`${options.visPrefix}object ${options.objectName} {`);
|
|
1192
1216
|
for (let idx = 0; idx < context.permutations.length; idx++) {
|
|
1193
1217
|
const { tokens, modifierInputs } = context.permutations[idx];
|
|
1194
1218
|
const processedTokens = stripInternalMetadata(tokens);
|
|
1195
1219
|
const permName = this.buildPermutationName(modifierInputs);
|
|
1196
|
-
lines.push(`${i1}${
|
|
1220
|
+
lines.push(`${i1}${options.visPrefix}object ${permName} {`);
|
|
1197
1221
|
this.renderBundleTokens(lines, processedTokens, options, 2);
|
|
1198
1222
|
lines.push(`${i1}}`);
|
|
1199
1223
|
if (idx < context.permutations.length - 1) {
|
|
@@ -1204,20 +1228,17 @@ ${closeIndent})`;
|
|
|
1204
1228
|
});
|
|
1205
1229
|
}
|
|
1206
1230
|
collectAllPermutationTypes(context) {
|
|
1207
|
-
const
|
|
1231
|
+
const types = /* @__PURE__ */ new Set();
|
|
1208
1232
|
for (const { tokens } of context.permutations) {
|
|
1209
|
-
const
|
|
1210
|
-
|
|
1211
|
-
if (token.$type) {
|
|
1212
|
-
allTokenTypes.add(token.$type);
|
|
1213
|
-
}
|
|
1233
|
+
for (const t of this.collectTokenTypesFromEntries(stripInternalMetadata(tokens))) {
|
|
1234
|
+
types.add(t);
|
|
1214
1235
|
}
|
|
1215
1236
|
}
|
|
1216
|
-
return
|
|
1237
|
+
return types;
|
|
1217
1238
|
}
|
|
1218
1239
|
renderBundleTokens(lines, tokens, options, baseDepth) {
|
|
1219
1240
|
if (options.structure === "flat") {
|
|
1220
|
-
const groups =
|
|
1241
|
+
const groups = groupTokensByType(tokens, KOTLIN_TYPE_GROUP_MAP);
|
|
1221
1242
|
this.renderFlatGroups(lines, groups, baseDepth, options);
|
|
1222
1243
|
return;
|
|
1223
1244
|
}
|
|
@@ -1229,7 +1250,7 @@ ${closeIndent})`;
|
|
|
1229
1250
|
if (values.length === 0) {
|
|
1230
1251
|
return "Default";
|
|
1231
1252
|
}
|
|
1232
|
-
return values.map((v) =>
|
|
1253
|
+
return values.map((v) => toSafeIdentifier(v, KOTLIN_KEYWORDS, true)).join("");
|
|
1233
1254
|
}
|
|
1234
1255
|
};
|
|
1235
1256
|
function androidRenderer() {
|
|
@@ -1249,19 +1270,19 @@ init_token_utils();
|
|
|
1249
1270
|
// src/renderers/bundlers/css.ts
|
|
1250
1271
|
init_errors();
|
|
1251
1272
|
init_utils();
|
|
1273
|
+
var REF_PREFIX_SETS = "#/sets/";
|
|
1274
|
+
var REF_PREFIX_MODIFIERS = "#/modifiers/";
|
|
1252
1275
|
var getSourceSet = (token) => {
|
|
1253
1276
|
if (typeof token !== "object" || token === null) {
|
|
1254
1277
|
return void 0;
|
|
1255
1278
|
}
|
|
1256
|
-
|
|
1257
|
-
return typeof maybe._sourceSet === "string" ? maybe._sourceSet : void 0;
|
|
1279
|
+
return "_sourceSet" in token && typeof token._sourceSet === "string" ? token._sourceSet : void 0;
|
|
1258
1280
|
};
|
|
1259
1281
|
var getSourceModifier = (token) => {
|
|
1260
1282
|
if (typeof token !== "object" || token === null) {
|
|
1261
1283
|
return void 0;
|
|
1262
1284
|
}
|
|
1263
|
-
|
|
1264
|
-
return typeof maybe._sourceModifier === "string" ? maybe._sourceModifier : void 0;
|
|
1285
|
+
return "_sourceModifier" in token && typeof token._sourceModifier === "string" ? token._sourceModifier : void 0;
|
|
1265
1286
|
};
|
|
1266
1287
|
async function bundleAsCss(bundleData, resolver, options, formatTokens) {
|
|
1267
1288
|
const baseItem = bundleData.find((item) => item.isBase);
|
|
@@ -1346,6 +1367,15 @@ async function formatModifierPermutation({ tokens, modifierInputs }, baseItem, o
|
|
|
1346
1367
|
return `/* Modifier: ${modifier}=${context} */
|
|
1347
1368
|
${css2}`;
|
|
1348
1369
|
}
|
|
1370
|
+
function addLayerBlock(blocks, included, key, blockTokens, description) {
|
|
1371
|
+
if (Object.keys(blockTokens).length === 0) {
|
|
1372
|
+
return;
|
|
1373
|
+
}
|
|
1374
|
+
for (const k of Object.keys(blockTokens)) {
|
|
1375
|
+
included.add(k);
|
|
1376
|
+
}
|
|
1377
|
+
blocks.push({ key, description, tokens: blockTokens });
|
|
1378
|
+
}
|
|
1349
1379
|
function collectSetTokens(tokens, setName, included) {
|
|
1350
1380
|
const result = {};
|
|
1351
1381
|
for (const [name, token] of Object.entries(tokens)) {
|
|
@@ -1376,75 +1406,67 @@ function collectRemainder(tokens, included) {
|
|
|
1376
1406
|
function buildSetLayerBlocks(tokens, resolver) {
|
|
1377
1407
|
const blocks = [];
|
|
1378
1408
|
const included = /* @__PURE__ */ new Set();
|
|
1379
|
-
const addBlock = (key, blockTokens, description) => {
|
|
1380
|
-
if (Object.keys(blockTokens).length === 0) {
|
|
1381
|
-
return;
|
|
1382
|
-
}
|
|
1383
|
-
for (const k of Object.keys(blockTokens)) {
|
|
1384
|
-
included.add(k);
|
|
1385
|
-
}
|
|
1386
|
-
blocks.push({ key, description, tokens: blockTokens });
|
|
1387
|
-
};
|
|
1388
1409
|
for (const item of resolver.resolutionOrder) {
|
|
1389
1410
|
const ref = item.$ref;
|
|
1390
|
-
if (typeof ref !== "string" || !ref.startsWith(
|
|
1411
|
+
if (typeof ref !== "string" || !ref.startsWith(REF_PREFIX_SETS)) {
|
|
1391
1412
|
continue;
|
|
1392
1413
|
}
|
|
1393
|
-
const setName = ref.slice(
|
|
1394
|
-
|
|
1414
|
+
const setName = ref.slice(REF_PREFIX_SETS.length);
|
|
1415
|
+
addLayerBlock(
|
|
1416
|
+
blocks,
|
|
1417
|
+
included,
|
|
1395
1418
|
`Set: ${setName}`,
|
|
1396
1419
|
collectSetTokens(tokens, setName, included),
|
|
1397
1420
|
resolver.sets?.[setName]?.description
|
|
1398
1421
|
);
|
|
1399
1422
|
}
|
|
1400
|
-
|
|
1423
|
+
addLayerBlock(blocks, included, "Unattributed", collectRemainder(tokens, included));
|
|
1401
1424
|
return blocks;
|
|
1402
1425
|
}
|
|
1403
1426
|
function buildDefaultLayerBlocks(tokens, baseModifierInputs, resolver) {
|
|
1404
1427
|
const blocks = [];
|
|
1405
1428
|
const included = /* @__PURE__ */ new Set();
|
|
1406
1429
|
const baseInputs = normalizeModifierInputs(baseModifierInputs);
|
|
1407
|
-
const addBlock = (key, blockTokens, description) => {
|
|
1408
|
-
if (Object.keys(blockTokens).length === 0) {
|
|
1409
|
-
return;
|
|
1410
|
-
}
|
|
1411
|
-
for (const k of Object.keys(blockTokens)) {
|
|
1412
|
-
included.add(k);
|
|
1413
|
-
}
|
|
1414
|
-
blocks.push({ key, description, tokens: blockTokens });
|
|
1415
|
-
};
|
|
1416
1430
|
for (const item of resolver.resolutionOrder) {
|
|
1417
1431
|
const ref = item.$ref;
|
|
1418
1432
|
if (typeof ref !== "string") {
|
|
1419
1433
|
continue;
|
|
1420
1434
|
}
|
|
1421
|
-
|
|
1422
|
-
const setName = ref.slice("#/sets/".length);
|
|
1423
|
-
addBlock(
|
|
1424
|
-
`Set: ${setName}`,
|
|
1425
|
-
collectSetTokens(tokens, setName, included),
|
|
1426
|
-
resolver.sets?.[setName]?.description
|
|
1427
|
-
);
|
|
1428
|
-
continue;
|
|
1429
|
-
}
|
|
1430
|
-
if (ref.startsWith("#/modifiers/")) {
|
|
1431
|
-
const modifierName = ref.slice("#/modifiers/".length);
|
|
1432
|
-
const modifier = resolver.modifiers?.[modifierName];
|
|
1433
|
-
const selectedContext = baseInputs[modifierName.toLowerCase()];
|
|
1434
|
-
if (!modifier || !selectedContext) {
|
|
1435
|
-
continue;
|
|
1436
|
-
}
|
|
1437
|
-
const expectedSource = `${modifierName}-${selectedContext}`.toLowerCase();
|
|
1438
|
-
addBlock(
|
|
1439
|
-
`Modifier: ${modifierName}=${selectedContext} (default)`,
|
|
1440
|
-
collectModifierTokens(tokens, expectedSource, included),
|
|
1441
|
-
modifier.description
|
|
1442
|
-
);
|
|
1443
|
-
}
|
|
1435
|
+
processResolutionOrderRef(ref, tokens, blocks, included, baseInputs, resolver);
|
|
1444
1436
|
}
|
|
1445
|
-
|
|
1437
|
+
addLayerBlock(blocks, included, "Unattributed", collectRemainder(tokens, included));
|
|
1446
1438
|
return blocks;
|
|
1447
1439
|
}
|
|
1440
|
+
function processResolutionOrderRef(ref, tokens, blocks, included, baseInputs, resolver) {
|
|
1441
|
+
if (ref.startsWith(REF_PREFIX_SETS)) {
|
|
1442
|
+
const setName = ref.slice(REF_PREFIX_SETS.length);
|
|
1443
|
+
addLayerBlock(
|
|
1444
|
+
blocks,
|
|
1445
|
+
included,
|
|
1446
|
+
`Set: ${setName}`,
|
|
1447
|
+
collectSetTokens(tokens, setName, included),
|
|
1448
|
+
resolver.sets?.[setName]?.description
|
|
1449
|
+
);
|
|
1450
|
+
return;
|
|
1451
|
+
}
|
|
1452
|
+
if (!ref.startsWith(REF_PREFIX_MODIFIERS)) {
|
|
1453
|
+
return;
|
|
1454
|
+
}
|
|
1455
|
+
const modifierName = ref.slice(REF_PREFIX_MODIFIERS.length);
|
|
1456
|
+
const modifier = resolver.modifiers?.[modifierName];
|
|
1457
|
+
const selectedContext = baseInputs[modifierName.toLowerCase()];
|
|
1458
|
+
if (!modifier || !selectedContext) {
|
|
1459
|
+
return;
|
|
1460
|
+
}
|
|
1461
|
+
const expectedSource = `${modifierName}-${selectedContext}`.toLowerCase();
|
|
1462
|
+
addLayerBlock(
|
|
1463
|
+
blocks,
|
|
1464
|
+
included,
|
|
1465
|
+
`Modifier: ${modifierName}=${selectedContext} (default)`,
|
|
1466
|
+
collectModifierTokens(tokens, expectedSource, included),
|
|
1467
|
+
modifier.description
|
|
1468
|
+
);
|
|
1469
|
+
}
|
|
1448
1470
|
function findSingleDiffPermutation(bundleData, modifierName, context, baseInputs) {
|
|
1449
1471
|
const normalizedModifier = modifierName.toLowerCase();
|
|
1450
1472
|
const normalizedContext = context.toLowerCase();
|
|
@@ -1459,6 +1481,36 @@ function findSingleDiffPermutation(bundleData, modifierName, context, baseInputs
|
|
|
1459
1481
|
return Object.entries(baseInputs).every(([k, v]) => k === normalizedModifier || inputs[k] === v);
|
|
1460
1482
|
});
|
|
1461
1483
|
}
|
|
1484
|
+
function pushUniqueBundleItem(ordered, includedKeys, item) {
|
|
1485
|
+
if (!item) {
|
|
1486
|
+
return;
|
|
1487
|
+
}
|
|
1488
|
+
const key = stableInputsKey(item.modifierInputs);
|
|
1489
|
+
if (includedKeys.has(key)) {
|
|
1490
|
+
return;
|
|
1491
|
+
}
|
|
1492
|
+
includedKeys.add(key);
|
|
1493
|
+
ordered.push(item);
|
|
1494
|
+
}
|
|
1495
|
+
function appendModifierPermutations(bundleData, modifiers, orderedNames, baseInputs, ordered, includedKeys) {
|
|
1496
|
+
for (const modifierName of orderedNames) {
|
|
1497
|
+
const modifierDef = modifiers[modifierName];
|
|
1498
|
+
if (!modifierDef) {
|
|
1499
|
+
continue;
|
|
1500
|
+
}
|
|
1501
|
+
const defaultValue = baseInputs[modifierName.toLowerCase()] ?? "";
|
|
1502
|
+
for (const ctx of Object.keys(modifierDef.contexts)) {
|
|
1503
|
+
if (defaultValue === ctx.toLowerCase()) {
|
|
1504
|
+
continue;
|
|
1505
|
+
}
|
|
1506
|
+
pushUniqueBundleItem(
|
|
1507
|
+
ordered,
|
|
1508
|
+
includedKeys,
|
|
1509
|
+
findSingleDiffPermutation(bundleData, modifierName, ctx, baseInputs)
|
|
1510
|
+
);
|
|
1511
|
+
}
|
|
1512
|
+
}
|
|
1513
|
+
}
|
|
1462
1514
|
function orderBundleData(bundleData, resolver, baseItem) {
|
|
1463
1515
|
const modifiers = resolver.modifiers;
|
|
1464
1516
|
if (!modifiers) {
|
|
@@ -1475,31 +1527,15 @@ function orderBundleData(bundleData, resolver, baseItem) {
|
|
|
1475
1527
|
}
|
|
1476
1528
|
const includedKeys = /* @__PURE__ */ new Set();
|
|
1477
1529
|
const ordered = [];
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
ordered.push(item);
|
|
1488
|
-
};
|
|
1489
|
-
pushUnique(baseItem);
|
|
1490
|
-
for (const modifierName of orderedModifierNames) {
|
|
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
|
-
pushUnique(findSingleDiffPermutation(bundleData, modifierName, ctx, baseInputs));
|
|
1501
|
-
}
|
|
1502
|
-
}
|
|
1530
|
+
pushUniqueBundleItem(ordered, includedKeys, baseItem);
|
|
1531
|
+
appendModifierPermutations(
|
|
1532
|
+
bundleData,
|
|
1533
|
+
modifiers,
|
|
1534
|
+
orderedModifierNames,
|
|
1535
|
+
baseInputs,
|
|
1536
|
+
ordered,
|
|
1537
|
+
includedKeys
|
|
1538
|
+
);
|
|
1503
1539
|
return ordered.length > 0 ? ordered : bundleData;
|
|
1504
1540
|
}
|
|
1505
1541
|
function getOrderedModifierNames(resolver) {
|
|
@@ -1511,10 +1547,10 @@ function getOrderedModifierNames(resolver) {
|
|
|
1511
1547
|
if (typeof ref !== "string") {
|
|
1512
1548
|
continue;
|
|
1513
1549
|
}
|
|
1514
|
-
if (!ref.startsWith(
|
|
1550
|
+
if (!ref.startsWith(REF_PREFIX_MODIFIERS)) {
|
|
1515
1551
|
continue;
|
|
1516
1552
|
}
|
|
1517
|
-
const name = ref.slice(
|
|
1553
|
+
const name = ref.slice(REF_PREFIX_MODIFIERS.length);
|
|
1518
1554
|
if (seen.has(name)) {
|
|
1519
1555
|
continue;
|
|
1520
1556
|
}
|
|
@@ -1585,24 +1621,22 @@ var CssRenderer = class _CssRenderer {
|
|
|
1585
1621
|
...options,
|
|
1586
1622
|
referenceTokens: options?.referenceTokens ?? tokens
|
|
1587
1623
|
};
|
|
1588
|
-
const
|
|
1624
|
+
const sortedTokens = getSortedTokenEntries(tokens).map(([, token]) => token);
|
|
1589
1625
|
const referenceTokens = opts.referenceTokens;
|
|
1590
1626
|
const lines = [];
|
|
1591
|
-
|
|
1592
|
-
this.buildCssBlock(lines, groupTokens, selector, tokens, referenceTokens, opts);
|
|
1593
|
-
}
|
|
1627
|
+
this.buildCssBlock(lines, sortedTokens, opts.selector, tokens, referenceTokens, opts);
|
|
1594
1628
|
const cssString = lines.join("");
|
|
1595
1629
|
return opts.minify ? cssString : await this.formatWithPrettier(cssString);
|
|
1596
1630
|
}
|
|
1597
1631
|
buildCssBlock(lines, groupTokens, selector, tokens, referenceTokens, opts) {
|
|
1598
|
-
const
|
|
1632
|
+
const indent = opts.minify ? "" : " ";
|
|
1599
1633
|
const newline = opts.minify ? "" : "\n";
|
|
1600
1634
|
const space = opts.minify ? "" : " ";
|
|
1601
1635
|
const hasMediaQuery = opts.mediaQuery != null && opts.mediaQuery !== "";
|
|
1602
|
-
const tokenIndent = hasMediaQuery ?
|
|
1636
|
+
const tokenIndent = hasMediaQuery ? indent + indent : indent;
|
|
1603
1637
|
if (hasMediaQuery) {
|
|
1604
1638
|
lines.push(`@media ${opts.mediaQuery}${space}{${newline}`);
|
|
1605
|
-
lines.push(`${
|
|
1639
|
+
lines.push(`${indent}${selector}${space}{${newline}`);
|
|
1606
1640
|
} else {
|
|
1607
1641
|
lines.push(`${selector}${space}{${newline}`);
|
|
1608
1642
|
}
|
|
@@ -1619,21 +1653,21 @@ var CssRenderer = class _CssRenderer {
|
|
|
1619
1653
|
);
|
|
1620
1654
|
}
|
|
1621
1655
|
if (hasMediaQuery) {
|
|
1622
|
-
lines.push(`${
|
|
1656
|
+
lines.push(`${indent}}${newline}`);
|
|
1623
1657
|
}
|
|
1624
1658
|
lines.push(`}${newline}${newline}`);
|
|
1625
1659
|
}
|
|
1626
|
-
pushTokenLines(lines, token, tokens, referenceTokens, preserveReferences,
|
|
1660
|
+
pushTokenLines(lines, token, tokens, referenceTokens, preserveReferences, indent, newline, space) {
|
|
1627
1661
|
const entries = this.buildCssEntries(token, tokens, referenceTokens, preserveReferences);
|
|
1628
1662
|
if (token.$deprecated != null && token.$deprecated !== false) {
|
|
1629
1663
|
const deprecationMsg = formatDeprecationMessage(token, "", "comment");
|
|
1630
|
-
lines.push(`${
|
|
1664
|
+
lines.push(`${indent}/* ${this.sanitizeCssCommentText(deprecationMsg)} */${newline}`);
|
|
1631
1665
|
}
|
|
1632
1666
|
if (token.$description && token.$description !== "") {
|
|
1633
|
-
lines.push(`${
|
|
1667
|
+
lines.push(`${indent}/* ${this.sanitizeCssCommentText(token.$description)} */${newline}`);
|
|
1634
1668
|
}
|
|
1635
1669
|
for (const entry of entries) {
|
|
1636
|
-
lines.push(`${
|
|
1670
|
+
lines.push(`${indent}--${entry.name}:${space}${entry.value};${newline}`);
|
|
1637
1671
|
}
|
|
1638
1672
|
}
|
|
1639
1673
|
async formatWithPrettier(css2) {
|
|
@@ -1648,15 +1682,6 @@ var CssRenderer = class _CssRenderer {
|
|
|
1648
1682
|
return css2;
|
|
1649
1683
|
}
|
|
1650
1684
|
}
|
|
1651
|
-
/**
|
|
1652
|
-
* Group tokens by selector (for theme support)
|
|
1653
|
-
*/
|
|
1654
|
-
groupTokens(tokens, options) {
|
|
1655
|
-
const sortedTokens = getSortedTokenEntries(tokens).map(([, token]) => token);
|
|
1656
|
-
return {
|
|
1657
|
-
[options.selector]: sortedTokens
|
|
1658
|
-
};
|
|
1659
|
-
}
|
|
1660
1685
|
buildCssEntries(token, tokens, referenceTokens, preserveReferences) {
|
|
1661
1686
|
if (preserveReferences) {
|
|
1662
1687
|
const refName = getPureAliasReferenceName(token.originalValue);
|
|
@@ -1798,7 +1823,7 @@ var CssRenderer = class _CssRenderer {
|
|
|
1798
1823
|
leaves.push({ path, value });
|
|
1799
1824
|
return;
|
|
1800
1825
|
}
|
|
1801
|
-
if (isColorObject(value) || isDimensionObject(value) ||
|
|
1826
|
+
if (isColorObject(value) || isDimensionObject(value) || isDurationObject(value)) {
|
|
1802
1827
|
leaves.push({ path, value });
|
|
1803
1828
|
return;
|
|
1804
1829
|
}
|
|
@@ -1841,8 +1866,8 @@ var CssRenderer = class _CssRenderer {
|
|
|
1841
1866
|
if (isDimensionObject(value)) {
|
|
1842
1867
|
return dimensionObjectToString(value);
|
|
1843
1868
|
}
|
|
1844
|
-
if (
|
|
1845
|
-
return
|
|
1869
|
+
if (isDurationObject(value)) {
|
|
1870
|
+
return durationObjectToString(value);
|
|
1846
1871
|
}
|
|
1847
1872
|
if (typeof value === "string") {
|
|
1848
1873
|
return value;
|
|
@@ -1905,15 +1930,6 @@ var CssRenderer = class _CssRenderer {
|
|
|
1905
1930
|
isPrimitiveValue(value) {
|
|
1906
1931
|
return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
|
|
1907
1932
|
}
|
|
1908
|
-
isDurationObject(value) {
|
|
1909
|
-
return typeof value === "object" && value !== null && "value" in value && "unit" in value && value.unit !== void 0;
|
|
1910
|
-
}
|
|
1911
|
-
formatDurationValue(value) {
|
|
1912
|
-
if (typeof value === "string") {
|
|
1913
|
-
return value;
|
|
1914
|
-
}
|
|
1915
|
-
return `${value.value}${value.unit}`;
|
|
1916
|
-
}
|
|
1917
1933
|
/**
|
|
1918
1934
|
* Format token value for CSS
|
|
1919
1935
|
* Handles DTCG 2025.10 object formats for colors and dimensions
|
|
@@ -1934,8 +1950,8 @@ var CssRenderer = class _CssRenderer {
|
|
|
1934
1950
|
return typeof value === "string" ? value : dimensionObjectToString(value);
|
|
1935
1951
|
}
|
|
1936
1952
|
if (type === "duration") {
|
|
1937
|
-
if (
|
|
1938
|
-
return
|
|
1953
|
+
if (isDurationObject(value)) {
|
|
1954
|
+
return durationObjectToString(value);
|
|
1939
1955
|
}
|
|
1940
1956
|
if (typeof value === "string") {
|
|
1941
1957
|
return value;
|
|
@@ -2025,16 +2041,16 @@ var CssRenderer = class _CssRenderer {
|
|
|
2025
2041
|
*/
|
|
2026
2042
|
formatTransition(value) {
|
|
2027
2043
|
const parts = [];
|
|
2028
|
-
if (
|
|
2029
|
-
parts.push(
|
|
2044
|
+
if (isDurationObject(value.duration)) {
|
|
2045
|
+
parts.push(durationObjectToString(value.duration));
|
|
2030
2046
|
} else if (value.duration != null) {
|
|
2031
2047
|
parts.push(String(value.duration));
|
|
2032
2048
|
}
|
|
2033
2049
|
if (Array.isArray(value.timingFunction) && value.timingFunction.length === 4) {
|
|
2034
2050
|
parts.push(`cubic-bezier(${value.timingFunction.join(", ")})`);
|
|
2035
2051
|
}
|
|
2036
|
-
if (
|
|
2037
|
-
parts.push(
|
|
2052
|
+
if (isDurationObject(value.delay)) {
|
|
2053
|
+
parts.push(durationObjectToString(value.delay));
|
|
2038
2054
|
} else if (value.delay != null) {
|
|
2039
2055
|
parts.push(String(value.delay));
|
|
2040
2056
|
}
|
|
@@ -2044,7 +2060,7 @@ var CssRenderer = class _CssRenderer {
|
|
|
2044
2060
|
const bundleData = context.permutations.map(({ tokens, modifierInputs }) => ({
|
|
2045
2061
|
tokens,
|
|
2046
2062
|
modifierInputs,
|
|
2047
|
-
isBase:
|
|
2063
|
+
isBase: isBasePermutation(modifierInputs, context.meta.defaults)
|
|
2048
2064
|
}));
|
|
2049
2065
|
return await bundleAsCss(bundleData, context.resolver, options, async (tokens, resolved) => {
|
|
2050
2066
|
return await this.formatTokens(tokens, {
|
|
@@ -2054,12 +2070,12 @@ var CssRenderer = class _CssRenderer {
|
|
|
2054
2070
|
});
|
|
2055
2071
|
}
|
|
2056
2072
|
async formatStandalone(context, options) {
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2073
|
+
assertFileRequired(
|
|
2074
|
+
context.buildPath,
|
|
2075
|
+
context.output.file,
|
|
2076
|
+
context.output.name,
|
|
2077
|
+
"standalone CSS"
|
|
2078
|
+
);
|
|
2063
2079
|
const files = {};
|
|
2064
2080
|
for (const { tokens, modifierInputs } of context.permutations) {
|
|
2065
2081
|
const { fileName, content } = await this.buildStandaloneFile(
|
|
@@ -2073,7 +2089,7 @@ var CssRenderer = class _CssRenderer {
|
|
|
2073
2089
|
return { kind: "outputTree", files };
|
|
2074
2090
|
}
|
|
2075
2091
|
async buildStandaloneFile(tokens, modifierInputs, context, options) {
|
|
2076
|
-
const isBase =
|
|
2092
|
+
const isBase = isBasePermutation(modifierInputs, context.meta.defaults);
|
|
2077
2093
|
const { modifierName, modifierContext } = this.resolveModifierContext(
|
|
2078
2094
|
modifierInputs,
|
|
2079
2095
|
context,
|
|
@@ -2110,12 +2126,7 @@ var CssRenderer = class _CssRenderer {
|
|
|
2110
2126
|
return { fileName, content };
|
|
2111
2127
|
}
|
|
2112
2128
|
async formatModifier(context, options) {
|
|
2113
|
-
|
|
2114
|
-
if (!context.output.file && requiresFile) {
|
|
2115
|
-
throw new ConfigurationError(
|
|
2116
|
-
`Output "${context.output.name}": file is required for modifier CSS output`
|
|
2117
|
-
);
|
|
2118
|
-
}
|
|
2129
|
+
assertFileRequired(context.buildPath, context.output.file, context.output.name, "modifier CSS");
|
|
2119
2130
|
if (!context.resolver.modifiers) {
|
|
2120
2131
|
throw new ConfigurationError("Modifier preset requires modifiers to be defined in resolver");
|
|
2121
2132
|
}
|
|
@@ -2141,7 +2152,7 @@ var CssRenderer = class _CssRenderer {
|
|
|
2141
2152
|
}
|
|
2142
2153
|
async buildModifierBaseFile(context, options) {
|
|
2143
2154
|
const basePermutation = context.permutations.find(
|
|
2144
|
-
({ modifierInputs }) =>
|
|
2155
|
+
({ modifierInputs }) => isBasePermutation(modifierInputs, context.meta.defaults)
|
|
2145
2156
|
);
|
|
2146
2157
|
if (!basePermutation) {
|
|
2147
2158
|
return void 0;
|
|
@@ -2154,25 +2165,40 @@ var CssRenderer = class _CssRenderer {
|
|
|
2154
2165
|
if (setBlocks.length === 0) {
|
|
2155
2166
|
return void 0;
|
|
2156
2167
|
}
|
|
2168
|
+
const { selector, mediaQuery } = this.resolveBaseModifierContext(context, options);
|
|
2169
|
+
const content = await this.formatSetBlocksCss(
|
|
2170
|
+
setBlocks,
|
|
2171
|
+
basePermutation.tokens,
|
|
2172
|
+
selector,
|
|
2173
|
+
mediaQuery,
|
|
2174
|
+
options
|
|
2175
|
+
);
|
|
2176
|
+
const fileName = context.output.file ? resolveBaseFileName(context.output.file, context.meta.defaults) : `${context.output.name}-base.css`;
|
|
2177
|
+
return { fileName, content };
|
|
2178
|
+
}
|
|
2179
|
+
resolveBaseModifierContext(context, options) {
|
|
2157
2180
|
const modifiers = context.resolver.modifiers;
|
|
2158
2181
|
const firstModifierName = Object.keys(modifiers)[0] ?? "";
|
|
2159
2182
|
const firstModifierContext = context.meta.defaults[firstModifierName] ?? "";
|
|
2160
2183
|
const baseModifierInputs = { ...context.meta.defaults };
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2184
|
+
return {
|
|
2185
|
+
selector: resolveSelector(
|
|
2186
|
+
options.selector,
|
|
2187
|
+
firstModifierName,
|
|
2188
|
+
firstModifierContext,
|
|
2189
|
+
true,
|
|
2190
|
+
baseModifierInputs
|
|
2191
|
+
),
|
|
2192
|
+
mediaQuery: resolveMediaQuery(
|
|
2193
|
+
options.mediaQuery,
|
|
2194
|
+
firstModifierName,
|
|
2195
|
+
firstModifierContext,
|
|
2196
|
+
true,
|
|
2197
|
+
baseModifierInputs
|
|
2198
|
+
)
|
|
2199
|
+
};
|
|
2200
|
+
}
|
|
2201
|
+
async formatSetBlocksCss(setBlocks, referenceTokens, selector, mediaQuery, options) {
|
|
2176
2202
|
const cssBlocks = [];
|
|
2177
2203
|
for (const block of setBlocks) {
|
|
2178
2204
|
const cleanTokens = stripInternalMetadata(block.tokens);
|
|
@@ -2188,9 +2214,7 @@ var CssRenderer = class _CssRenderer {
|
|
|
2188
2214
|
cssBlocks.push(`${header}
|
|
2189
2215
|
${css2}`);
|
|
2190
2216
|
}
|
|
2191
|
-
|
|
2192
|
-
const fileName = context.output.file ? resolveBaseFileName(context.output.file, context.meta.defaults) : `${context.output.name}-base.css`;
|
|
2193
|
-
return { fileName, content };
|
|
2217
|
+
return cssBlocks.join("\n");
|
|
2194
2218
|
}
|
|
2195
2219
|
collectTokensForModifierContext(modifierName, contextValue, permutations) {
|
|
2196
2220
|
const expectedSource = `${modifierName}-${contextValue}`;
|
|
@@ -2267,13 +2291,6 @@ ${css2}`);
|
|
|
2267
2291
|
}
|
|
2268
2292
|
return { modifierName: "", modifierContext: "" };
|
|
2269
2293
|
}
|
|
2270
|
-
isBasePermutation(modifierInputs, defaults) {
|
|
2271
|
-
const normalizedInputs = normalizeModifierInputs(modifierInputs);
|
|
2272
|
-
const normalizedDefaults = normalizeModifierInputs(defaults);
|
|
2273
|
-
return Object.entries(normalizedDefaults).every(
|
|
2274
|
-
([key, value]) => normalizedInputs[key] === value
|
|
2275
|
-
);
|
|
2276
|
-
}
|
|
2277
2294
|
};
|
|
2278
2295
|
function cssRenderer() {
|
|
2279
2296
|
const rendererInstance = new CssRenderer();
|
|
@@ -2285,9 +2302,18 @@ function cssRenderer() {
|
|
|
2285
2302
|
};
|
|
2286
2303
|
}
|
|
2287
2304
|
|
|
2305
|
+
// src/tokens/types.ts
|
|
2306
|
+
function isShadowToken(token) {
|
|
2307
|
+
return token.$type === "shadow";
|
|
2308
|
+
}
|
|
2309
|
+
function isTypographyToken(token) {
|
|
2310
|
+
return token.$type === "typography";
|
|
2311
|
+
}
|
|
2312
|
+
function isBorderToken(token) {
|
|
2313
|
+
return token.$type === "border";
|
|
2314
|
+
}
|
|
2315
|
+
|
|
2288
2316
|
// src/renderers/ios.ts
|
|
2289
|
-
init_errors();
|
|
2290
|
-
init_token_utils();
|
|
2291
2317
|
init_utils();
|
|
2292
2318
|
var toSRGB2 = culori.converter("rgb");
|
|
2293
2319
|
var toP32 = culori.converter("p3");
|
|
@@ -2376,94 +2402,68 @@ var IosRenderer = class {
|
|
|
2376
2402
|
return await this.formatStandalone(context, opts);
|
|
2377
2403
|
}
|
|
2378
2404
|
formatTokens(tokens, options) {
|
|
2379
|
-
if (options.structure === "grouped") {
|
|
2380
|
-
return this.formatAsGrouped(tokens, options);
|
|
2381
|
-
}
|
|
2382
|
-
return this.formatAsEnum(tokens, options);
|
|
2383
|
-
}
|
|
2384
|
-
formatAsEnum(tokens, options) {
|
|
2385
2405
|
const access = options.accessLevel;
|
|
2386
|
-
const groups =
|
|
2406
|
+
const groups = groupTokensByType(tokens, SWIFT_TYPE_GROUP_MAP);
|
|
2387
2407
|
const imports = this.collectImports(tokens);
|
|
2388
|
-
const i1 = this.indentStr(options.indent, 1);
|
|
2389
|
-
const i2 = this.indentStr(options.indent, 2);
|
|
2390
2408
|
const staticPrefix = this.staticLetPrefix(options);
|
|
2391
2409
|
const frozen = this.frozenPrefix(options);
|
|
2392
2410
|
const lines = [];
|
|
2393
|
-
lines.push(
|
|
2411
|
+
lines.push(buildGeneratedFileHeader());
|
|
2394
2412
|
lines.push("");
|
|
2395
2413
|
for (const imp of imports) {
|
|
2396
2414
|
lines.push(`import ${imp}`);
|
|
2397
2415
|
}
|
|
2398
2416
|
lines.push(...this.buildStructDefinitions(tokens, access, options));
|
|
2417
|
+
this.pushTokenLayout(lines, groups, options, access, staticPrefix, frozen);
|
|
2418
|
+
lines.push(...this.buildViewExtensions(tokens, access, options));
|
|
2419
|
+
if (options.structure !== "grouped") {
|
|
2420
|
+
lines.push("");
|
|
2421
|
+
}
|
|
2422
|
+
return lines.join("\n");
|
|
2423
|
+
}
|
|
2424
|
+
pushTokenLayout(lines, groups, options, access, staticPrefix, frozen) {
|
|
2425
|
+
const i1 = indentStr(options.indent, 1);
|
|
2426
|
+
const i2 = indentStr(options.indent, 2);
|
|
2427
|
+
if (options.structure === "grouped") {
|
|
2428
|
+
this.pushGroupedLayout(lines, groups, options, access, i1, i2, staticPrefix, frozen);
|
|
2429
|
+
return;
|
|
2430
|
+
}
|
|
2399
2431
|
lines.push("");
|
|
2400
2432
|
lines.push(`${frozen}${access} enum ${options.enumName} {`);
|
|
2401
2433
|
for (const group of groups) {
|
|
2402
2434
|
lines.push(`${i1}${frozen}${access} enum ${group.name} {`);
|
|
2403
|
-
|
|
2404
|
-
const swiftName = this.buildQualifiedSwiftName(token);
|
|
2405
|
-
const swiftValue = this.formatSwiftValue(token, options);
|
|
2406
|
-
const typeAnnotation = this.getTypeAnnotation(token);
|
|
2407
|
-
const annotation = typeAnnotation ? `: ${typeAnnotation}` : "";
|
|
2408
|
-
const docComment = this.buildDocComment(token, i2);
|
|
2409
|
-
if (docComment) {
|
|
2410
|
-
lines.push(docComment);
|
|
2411
|
-
}
|
|
2412
|
-
lines.push(`${i2}${access} ${staticPrefix}${swiftName}${annotation} = ${swiftValue}`);
|
|
2413
|
-
}
|
|
2435
|
+
this.pushTokenDeclarations(lines, group.tokens, options, access, i2, staticPrefix);
|
|
2414
2436
|
lines.push(`${i1}}`);
|
|
2415
2437
|
lines.push("");
|
|
2416
2438
|
}
|
|
2417
2439
|
lines.push("}");
|
|
2418
|
-
lines.push(...this.buildViewExtensions(tokens, access, options));
|
|
2419
|
-
lines.push("");
|
|
2420
|
-
return lines.join("\n");
|
|
2421
2440
|
}
|
|
2422
|
-
|
|
2423
|
-
const access = options.accessLevel;
|
|
2441
|
+
pushGroupedLayout(lines, groups, options, access, i1, i2, staticPrefix, frozen) {
|
|
2424
2442
|
const namespace = options.extensionNamespace;
|
|
2425
|
-
const groups = this.groupTokensByType(tokens);
|
|
2426
|
-
const imports = this.collectImports(tokens);
|
|
2427
|
-
const i1 = this.indentStr(options.indent, 1);
|
|
2428
|
-
const i2 = this.indentStr(options.indent, 2);
|
|
2429
|
-
const staticPrefix = this.staticLetPrefix(options);
|
|
2430
|
-
const frozen = this.frozenPrefix(options);
|
|
2431
|
-
const lines = [];
|
|
2432
|
-
lines.push(this.buildFileHeader());
|
|
2433
|
-
lines.push("");
|
|
2434
|
-
for (const imp of imports) {
|
|
2435
|
-
lines.push(`import ${imp}`);
|
|
2436
|
-
}
|
|
2437
|
-
lines.push(...this.buildStructDefinitions(tokens, access, options));
|
|
2438
2443
|
lines.push("");
|
|
2439
2444
|
lines.push(`${frozen}${access} enum ${namespace} {}`);
|
|
2440
2445
|
lines.push("");
|
|
2441
2446
|
for (const group of groups) {
|
|
2442
2447
|
lines.push(`${access} extension ${namespace} {`);
|
|
2443
2448
|
lines.push(`${i1}${frozen}enum ${group.name} {`);
|
|
2444
|
-
|
|
2445
|
-
const swiftName = this.buildQualifiedSwiftName(token);
|
|
2446
|
-
const swiftValue = this.formatSwiftValue(token, options);
|
|
2447
|
-
const typeAnnotation = this.getTypeAnnotation(token);
|
|
2448
|
-
const annotation = typeAnnotation ? `: ${typeAnnotation}` : "";
|
|
2449
|
-
const docComment = this.buildDocComment(token, i2);
|
|
2450
|
-
if (docComment) {
|
|
2451
|
-
lines.push(docComment);
|
|
2452
|
-
}
|
|
2453
|
-
lines.push(`${i2}${access} ${staticPrefix}${swiftName}${annotation} = ${swiftValue}`);
|
|
2454
|
-
}
|
|
2449
|
+
this.pushTokenDeclarations(lines, group.tokens, options, access, i2, staticPrefix);
|
|
2455
2450
|
lines.push(`${i1}}`);
|
|
2456
2451
|
lines.push("}");
|
|
2457
2452
|
lines.push("");
|
|
2458
2453
|
}
|
|
2459
|
-
lines.push(...this.buildViewExtensions(tokens, access, options));
|
|
2460
|
-
return lines.join("\n");
|
|
2461
2454
|
}
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2455
|
+
pushTokenDeclarations(lines, tokens, options, access, indent, staticPrefix) {
|
|
2456
|
+
for (const token of tokens) {
|
|
2457
|
+
const swiftName = this.buildQualifiedSwiftName(token);
|
|
2458
|
+
const swiftValue = this.formatSwiftValue(token, options);
|
|
2459
|
+
const typeAnnotation = this.getTypeAnnotation(token);
|
|
2460
|
+
const annotation = typeAnnotation ? `: ${typeAnnotation}` : "";
|
|
2461
|
+
const docComment = this.buildDocComment(token, indent);
|
|
2462
|
+
if (docComment) {
|
|
2463
|
+
lines.push(docComment);
|
|
2464
|
+
}
|
|
2465
|
+
lines.push(`${indent}${access} ${staticPrefix}${swiftName}${annotation} = ${swiftValue}`);
|
|
2466
|
+
}
|
|
2467
2467
|
}
|
|
2468
2468
|
collectImports(tokens) {
|
|
2469
2469
|
const imports = /* @__PURE__ */ new Set();
|
|
@@ -2478,24 +2478,11 @@ var IosRenderer = class {
|
|
|
2478
2478
|
/**
|
|
2479
2479
|
* Builds a `///` doc comment from a token's `$description`, if present.
|
|
2480
2480
|
*/
|
|
2481
|
-
buildDocComment(token,
|
|
2481
|
+
buildDocComment(token, indent) {
|
|
2482
2482
|
if (!token.$description) {
|
|
2483
2483
|
return void 0;
|
|
2484
2484
|
}
|
|
2485
|
-
return `${
|
|
2486
|
-
}
|
|
2487
|
-
groupTokensByType(tokens) {
|
|
2488
|
-
const groupMap = /* @__PURE__ */ new Map();
|
|
2489
|
-
for (const [, token] of getSortedTokenEntries(tokens)) {
|
|
2490
|
-
const groupName = SWIFT_TYPE_GROUP_MAP[token.$type ?? ""] ?? "Other";
|
|
2491
|
-
const existing = groupMap.get(groupName) ?? [];
|
|
2492
|
-
existing.push(token);
|
|
2493
|
-
groupMap.set(groupName, existing);
|
|
2494
|
-
}
|
|
2495
|
-
return Array.from(groupMap.entries()).map(([name, groupTokens]) => ({
|
|
2496
|
-
name,
|
|
2497
|
-
tokens: groupTokens
|
|
2498
|
-
}));
|
|
2485
|
+
return `${indent}/// ${token.$description}`;
|
|
2499
2486
|
}
|
|
2500
2487
|
/**
|
|
2501
2488
|
* Builds a qualified Swift name from a token's path, preserving parent
|
|
@@ -2508,43 +2495,40 @@ var IosRenderer = class {
|
|
|
2508
2495
|
const path = token.path;
|
|
2509
2496
|
const withoutTypePrefix = path.length > 1 ? path.slice(1) : path;
|
|
2510
2497
|
const joined = withoutTypePrefix.join("_");
|
|
2511
|
-
return
|
|
2498
|
+
return toSafeIdentifier(joined, SWIFT_KEYWORDS, false);
|
|
2512
2499
|
}
|
|
2513
2500
|
formatSwiftValue(token, options) {
|
|
2514
|
-
const value = token
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
}
|
|
2542
|
-
if (token.$type === "number") {
|
|
2543
|
-
return String(value);
|
|
2544
|
-
}
|
|
2545
|
-
if (token.$type === "cubicBezier" && Array.isArray(value) && value.length === 4) {
|
|
2546
|
-
return `UnitCurve.bezier(startControlPoint: UnitPoint(x: ${value[0]}, y: ${value[1]}), endControlPoint: UnitPoint(x: ${value[2]}, y: ${value[3]}))`;
|
|
2501
|
+
const { $type, $value: value } = token;
|
|
2502
|
+
switch ($type) {
|
|
2503
|
+
case "color":
|
|
2504
|
+
return this.formatColorValue(value, options);
|
|
2505
|
+
case "dimension":
|
|
2506
|
+
return this.formatDimensionValue(value);
|
|
2507
|
+
case "fontFamily":
|
|
2508
|
+
return this.formatFontFamilyValue(value);
|
|
2509
|
+
case "fontWeight":
|
|
2510
|
+
return this.formatFontWeightValue(value);
|
|
2511
|
+
case "duration":
|
|
2512
|
+
return this.formatDurationValue(value);
|
|
2513
|
+
case "shadow":
|
|
2514
|
+
return this.formatShadowValue(value, options);
|
|
2515
|
+
case "typography":
|
|
2516
|
+
return this.formatTypographyValue(value);
|
|
2517
|
+
case "border":
|
|
2518
|
+
return this.formatBorderValue(value, options);
|
|
2519
|
+
case "gradient":
|
|
2520
|
+
return this.formatGradientValue(value, options);
|
|
2521
|
+
case "number":
|
|
2522
|
+
return String(value);
|
|
2523
|
+
case "cubicBezier":
|
|
2524
|
+
if (Array.isArray(value) && value.length === 4) {
|
|
2525
|
+
return `UnitCurve.bezier(startControlPoint: UnitPoint(x: ${value[0]}, y: ${value[1]}), endControlPoint: UnitPoint(x: ${value[2]}, y: ${value[3]}))`;
|
|
2526
|
+
}
|
|
2527
|
+
break;
|
|
2547
2528
|
}
|
|
2529
|
+
return this.formatSwiftPrimitive(value);
|
|
2530
|
+
}
|
|
2531
|
+
formatSwiftPrimitive(value) {
|
|
2548
2532
|
if (typeof value === "string") {
|
|
2549
2533
|
return `"${this.escapeSwiftString(value)}"`;
|
|
2550
2534
|
}
|
|
@@ -2577,9 +2561,7 @@ var IosRenderer = class {
|
|
|
2577
2561
|
}
|
|
2578
2562
|
formatDimensionValue(value) {
|
|
2579
2563
|
if (isDimensionObject(value)) {
|
|
2580
|
-
|
|
2581
|
-
const ptValue = dim.unit === "rem" ? dim.value * 16 : dim.value;
|
|
2582
|
-
return String(ptValue);
|
|
2564
|
+
return this.dimensionToPoints(value);
|
|
2583
2565
|
}
|
|
2584
2566
|
return String(value);
|
|
2585
2567
|
}
|
|
@@ -2646,7 +2628,7 @@ var IosRenderer = class {
|
|
|
2646
2628
|
return map[name.toLowerCase()];
|
|
2647
2629
|
}
|
|
2648
2630
|
formatDurationValue(value) {
|
|
2649
|
-
if (
|
|
2631
|
+
if (isDurationObject(value)) {
|
|
2650
2632
|
const dur = value;
|
|
2651
2633
|
const seconds = dur.unit === "ms" ? dur.value / 1e3 : dur.value;
|
|
2652
2634
|
return String(seconds);
|
|
@@ -2695,9 +2677,7 @@ var IosRenderer = class {
|
|
|
2695
2677
|
if (!isDimensionObject(typo.letterSpacing)) {
|
|
2696
2678
|
return "0";
|
|
2697
2679
|
}
|
|
2698
|
-
|
|
2699
|
-
const ptValue = dim.unit === "rem" ? dim.value * 16 : dim.value;
|
|
2700
|
-
return String(ptValue);
|
|
2680
|
+
return this.dimensionToPoints(typo.letterSpacing);
|
|
2701
2681
|
}
|
|
2702
2682
|
extractLineSpacing(typo) {
|
|
2703
2683
|
if (typo.lineHeight == null || typeof typo.lineHeight !== "number") {
|
|
@@ -2706,18 +2686,19 @@ var IosRenderer = class {
|
|
|
2706
2686
|
if (!isDimensionObject(typo.fontSize)) {
|
|
2707
2687
|
return "0";
|
|
2708
2688
|
}
|
|
2709
|
-
const
|
|
2710
|
-
const basePt = dim.unit === "rem" ? dim.value * 16 : dim.value;
|
|
2689
|
+
const basePt = this.dimensionToNumericPoints(typo.fontSize);
|
|
2711
2690
|
const lineHeightPt = Math.round(basePt * typo.lineHeight * 100) / 100;
|
|
2712
2691
|
return String(lineHeightPt - basePt);
|
|
2713
2692
|
}
|
|
2693
|
+
dimensionToNumericPoints(dim) {
|
|
2694
|
+
return dim.unit === "rem" ? dim.value * 16 : dim.value;
|
|
2695
|
+
}
|
|
2714
2696
|
dimensionToPoints(dim) {
|
|
2715
|
-
|
|
2716
|
-
return String(ptValue);
|
|
2697
|
+
return String(this.dimensionToNumericPoints(dim));
|
|
2717
2698
|
}
|
|
2718
2699
|
/** Formats a dimension as a CGFloat literal (appends `.0` for integers). */
|
|
2719
2700
|
dimensionToCGFloat(dim) {
|
|
2720
|
-
const ptValue =
|
|
2701
|
+
const ptValue = this.dimensionToNumericPoints(dim);
|
|
2721
2702
|
return Number.isInteger(ptValue) ? `${ptValue}.0` : String(ptValue);
|
|
2722
2703
|
}
|
|
2723
2704
|
getTypeAnnotation(token) {
|
|
@@ -2736,21 +2717,12 @@ var IosRenderer = class {
|
|
|
2736
2717
|
return void 0;
|
|
2737
2718
|
}
|
|
2738
2719
|
}
|
|
2739
|
-
toSwiftIdentifier(name) {
|
|
2740
|
-
const camel = name.replace(/[-._]+(.)/g, (_, c) => c.toUpperCase()).replace(/[-._]+$/g, "").replace(/^[-._]+/g, "");
|
|
2741
|
-
const identifier = camel.charAt(0).toLowerCase() + camel.slice(1);
|
|
2742
|
-
const safe = /^\d/.test(identifier) ? `_${identifier}` : identifier;
|
|
2743
|
-
return SWIFT_KEYWORDS.has(safe) ? `\`${safe}\`` : safe;
|
|
2744
|
-
}
|
|
2745
2720
|
escapeSwiftString(str) {
|
|
2746
2721
|
return str.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\n/g, "\\n");
|
|
2747
2722
|
}
|
|
2748
2723
|
roundComponent(value) {
|
|
2749
2724
|
return Math.round(value * 1e4) / 1e4;
|
|
2750
2725
|
}
|
|
2751
|
-
indentStr(width, level) {
|
|
2752
|
-
return " ".repeat(width * level);
|
|
2753
|
-
}
|
|
2754
2726
|
/**
|
|
2755
2727
|
* Returns the prefix for `static let` declarations.
|
|
2756
2728
|
* Swift 6 requires `nonisolated(unsafe)` on global stored properties.
|
|
@@ -2766,34 +2738,25 @@ var IosRenderer = class {
|
|
|
2766
2738
|
structConformances(options) {
|
|
2767
2739
|
return options.swiftVersion === "6.0" ? ": Sendable" : "";
|
|
2768
2740
|
}
|
|
2769
|
-
hasShadowTokens(tokens) {
|
|
2770
|
-
return Object.values(tokens).some((t) => t.$type === "shadow");
|
|
2771
|
-
}
|
|
2772
|
-
hasTypographyTokens(tokens) {
|
|
2773
|
-
return Object.values(tokens).some((t) => t.$type === "typography");
|
|
2774
|
-
}
|
|
2775
|
-
hasBorderTokens(tokens) {
|
|
2776
|
-
return Object.values(tokens).some((t) => t.$type === "border");
|
|
2777
|
-
}
|
|
2778
2741
|
/** Emits all struct definitions needed by the token set. */
|
|
2779
2742
|
buildStructDefinitions(tokens, access, options) {
|
|
2780
2743
|
const lines = [];
|
|
2781
|
-
if (
|
|
2744
|
+
if (Object.values(tokens).some(isShadowToken)) {
|
|
2782
2745
|
lines.push("");
|
|
2783
2746
|
lines.push(...this.buildShadowStyleStruct(access, options));
|
|
2784
2747
|
}
|
|
2785
|
-
if (
|
|
2748
|
+
if (Object.values(tokens).some(isTypographyToken)) {
|
|
2786
2749
|
lines.push("");
|
|
2787
2750
|
lines.push(...this.buildTypographyStyleStruct(access, options));
|
|
2788
2751
|
}
|
|
2789
|
-
if (
|
|
2752
|
+
if (Object.values(tokens).some(isBorderToken)) {
|
|
2790
2753
|
lines.push("");
|
|
2791
2754
|
lines.push(...this.buildBorderStyleStruct(access, options));
|
|
2792
2755
|
}
|
|
2793
2756
|
return lines;
|
|
2794
2757
|
}
|
|
2795
2758
|
buildShadowStyleStruct(access, options) {
|
|
2796
|
-
const i1 =
|
|
2759
|
+
const i1 = indentStr(options.indent, 1);
|
|
2797
2760
|
const conformances = this.structConformances(options);
|
|
2798
2761
|
const frozen = this.frozenPrefix(options);
|
|
2799
2762
|
return [
|
|
@@ -2807,7 +2770,7 @@ var IosRenderer = class {
|
|
|
2807
2770
|
];
|
|
2808
2771
|
}
|
|
2809
2772
|
buildTypographyStyleStruct(access, options) {
|
|
2810
|
-
const i1 =
|
|
2773
|
+
const i1 = indentStr(options.indent, 1);
|
|
2811
2774
|
const conformances = this.structConformances(options);
|
|
2812
2775
|
const frozen = this.frozenPrefix(options);
|
|
2813
2776
|
return [
|
|
@@ -2819,7 +2782,7 @@ var IosRenderer = class {
|
|
|
2819
2782
|
];
|
|
2820
2783
|
}
|
|
2821
2784
|
buildBorderStyleStruct(access, options) {
|
|
2822
|
-
const i1 =
|
|
2785
|
+
const i1 = indentStr(options.indent, 1);
|
|
2823
2786
|
const conformances = this.structConformances(options);
|
|
2824
2787
|
const frozen = this.frozenPrefix(options);
|
|
2825
2788
|
return [
|
|
@@ -2832,9 +2795,9 @@ var IosRenderer = class {
|
|
|
2832
2795
|
/** Emits convenience View extensions for shadow and typography application. */
|
|
2833
2796
|
buildViewExtensions(tokens, access, options) {
|
|
2834
2797
|
const lines = [];
|
|
2835
|
-
const i1 =
|
|
2836
|
-
const i2 =
|
|
2837
|
-
if (
|
|
2798
|
+
const i1 = indentStr(options.indent, 1);
|
|
2799
|
+
const i2 = indentStr(options.indent, 2);
|
|
2800
|
+
if (Object.values(tokens).some(isShadowToken)) {
|
|
2838
2801
|
lines.push("");
|
|
2839
2802
|
lines.push(`${access} extension View {`);
|
|
2840
2803
|
lines.push(`${i1}func shadowStyle(_ style: ShadowStyle) -> some View {`);
|
|
@@ -2844,7 +2807,7 @@ var IosRenderer = class {
|
|
|
2844
2807
|
lines.push(`${i1}}`);
|
|
2845
2808
|
lines.push("}");
|
|
2846
2809
|
}
|
|
2847
|
-
if (
|
|
2810
|
+
if (Object.values(tokens).some(isTypographyToken)) {
|
|
2848
2811
|
lines.push("");
|
|
2849
2812
|
lines.push(`${access} extension View {`);
|
|
2850
2813
|
lines.push(`${i1}func typographyStyle(_ style: TypographyStyle) -> some View {`);
|
|
@@ -2876,12 +2839,12 @@ var IosRenderer = class {
|
|
|
2876
2839
|
return `Gradient(stops: [${stops.join(", ")}])`;
|
|
2877
2840
|
}
|
|
2878
2841
|
async formatStandalone(context, options) {
|
|
2879
|
-
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
2842
|
+
assertFileRequired(
|
|
2843
|
+
context.buildPath,
|
|
2844
|
+
context.output.file,
|
|
2845
|
+
context.output.name,
|
|
2846
|
+
"standalone iOS"
|
|
2847
|
+
);
|
|
2885
2848
|
const files = {};
|
|
2886
2849
|
for (const { tokens, modifierInputs } of context.permutations) {
|
|
2887
2850
|
const processedTokens = stripInternalMetadata(tokens);
|
|
@@ -2910,7 +2873,6 @@ function iosRenderer() {
|
|
|
2910
2873
|
|
|
2911
2874
|
// src/renderers/js-module.ts
|
|
2912
2875
|
init_utils();
|
|
2913
|
-
init_errors();
|
|
2914
2876
|
init_token_utils();
|
|
2915
2877
|
var JsModuleRenderer = class {
|
|
2916
2878
|
async format(context, options) {
|
|
@@ -2926,18 +2888,13 @@ var JsModuleRenderer = class {
|
|
|
2926
2888
|
const bundleData = context.permutations.map(({ tokens, modifierInputs }) => ({
|
|
2927
2889
|
tokens: stripInternalMetadata(tokens),
|
|
2928
2890
|
modifierInputs,
|
|
2929
|
-
isBase:
|
|
2891
|
+
isBase: isBasePermutation(modifierInputs, context.meta.defaults)
|
|
2930
2892
|
}));
|
|
2931
2893
|
return await bundleAsJsModule2(bundleData, context.resolver, opts, async (tokens) => {
|
|
2932
2894
|
return await this.formatTokens(tokens, opts);
|
|
2933
2895
|
});
|
|
2934
2896
|
}
|
|
2935
|
-
|
|
2936
|
-
if (!context.output.file && requiresFile) {
|
|
2937
|
-
throw new ConfigurationError(
|
|
2938
|
-
`Output "${context.output.name}": file is required for JS module output`
|
|
2939
|
-
);
|
|
2940
|
-
}
|
|
2897
|
+
assertFileRequired(context.buildPath, context.output.file, context.output.name, "JS module");
|
|
2941
2898
|
const files = {};
|
|
2942
2899
|
for (const { tokens, modifierInputs } of context.permutations) {
|
|
2943
2900
|
const cleanTokens = stripInternalMetadata(tokens);
|
|
@@ -2991,42 +2948,18 @@ var JsModuleRenderer = class {
|
|
|
2991
2948
|
lines.push(`export default ${varName}`);
|
|
2992
2949
|
return lines;
|
|
2993
2950
|
}
|
|
2994
|
-
/**
|
|
2995
|
-
* Convert tokens to plain object with flat or nested structure
|
|
2996
|
-
*/
|
|
2997
2951
|
tokensToPlainObject(tokens, structure) {
|
|
2952
|
+
if (structure === "nested") {
|
|
2953
|
+
return buildNestedTokenObject(tokens, (token) => token.$value);
|
|
2954
|
+
}
|
|
2998
2955
|
const result = {};
|
|
2999
|
-
|
|
3000
|
-
|
|
3001
|
-
result[name] = token.$value;
|
|
3002
|
-
}
|
|
3003
|
-
} else {
|
|
3004
|
-
for (const [, token] of getSortedTokenEntries(tokens)) {
|
|
3005
|
-
const parts = token.path;
|
|
3006
|
-
let current = result;
|
|
3007
|
-
for (let i = 0; i < parts.length - 1; i++) {
|
|
3008
|
-
const part = parts[i];
|
|
3009
|
-
if (part == null) {
|
|
3010
|
-
continue;
|
|
3011
|
-
}
|
|
3012
|
-
if (!(part in current)) {
|
|
3013
|
-
current[part] = {};
|
|
3014
|
-
}
|
|
3015
|
-
current = current[part];
|
|
3016
|
-
}
|
|
3017
|
-
const lastPart = parts[parts.length - 1];
|
|
3018
|
-
if (lastPart != null) {
|
|
3019
|
-
current[lastPart] = token.$value;
|
|
3020
|
-
}
|
|
3021
|
-
}
|
|
2956
|
+
for (const [name, token] of getSortedTokenEntries(tokens)) {
|
|
2957
|
+
result[name] = token.$value;
|
|
3022
2958
|
}
|
|
3023
2959
|
return result;
|
|
3024
2960
|
}
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
*/
|
|
3028
|
-
addObjectProperties(lines, obj, indent2) {
|
|
3029
|
-
const indentStr = " ".repeat(indent2);
|
|
2961
|
+
addObjectProperties(lines, obj, indent) {
|
|
2962
|
+
const indentStr2 = " ".repeat(indent);
|
|
3030
2963
|
const entries = Object.entries(obj).sort(([keyA], [keyB]) => keyA.localeCompare(keyB));
|
|
3031
2964
|
for (let i = 0; i < entries.length; i++) {
|
|
3032
2965
|
const entry = entries[i];
|
|
@@ -3035,14 +2968,16 @@ var JsModuleRenderer = class {
|
|
|
3035
2968
|
}
|
|
3036
2969
|
const [key, value] = entry;
|
|
3037
2970
|
const isLast = i === entries.length - 1;
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
lines.push(`${indentStr}${this.quoteKey(key)}: ${valueStr}${isLast ? "" : ","}`);
|
|
2971
|
+
const isNestedObject = typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2972
|
+
if (!isNestedObject) {
|
|
2973
|
+
lines.push(
|
|
2974
|
+
`${indentStr2}${this.quoteKey(key)}: ${JSON.stringify(value)}${isLast ? "" : ","}`
|
|
2975
|
+
);
|
|
2976
|
+
continue;
|
|
3045
2977
|
}
|
|
2978
|
+
lines.push(`${indentStr2}${this.quoteKey(key)}: {`);
|
|
2979
|
+
this.addObjectProperties(lines, value, indent + 1);
|
|
2980
|
+
lines.push(`${indentStr2}}${isLast ? "" : ","}`);
|
|
3046
2981
|
}
|
|
3047
2982
|
}
|
|
3048
2983
|
/**
|
|
@@ -3054,9 +2989,6 @@ var JsModuleRenderer = class {
|
|
|
3054
2989
|
}
|
|
3055
2990
|
return `"${key}"`;
|
|
3056
2991
|
}
|
|
3057
|
-
isBasePermutation(modifierInputs, defaults) {
|
|
3058
|
-
return Object.entries(modifierInputs).every(([key, value]) => value === defaults[key]);
|
|
3059
|
-
}
|
|
3060
2992
|
};
|
|
3061
2993
|
function jsRenderer() {
|
|
3062
2994
|
const rendererInstance = new JsModuleRenderer();
|
|
@@ -3070,7 +3002,6 @@ function jsRenderer() {
|
|
|
3070
3002
|
|
|
3071
3003
|
// src/renderers/json.ts
|
|
3072
3004
|
init_utils();
|
|
3073
|
-
init_errors();
|
|
3074
3005
|
init_token_utils();
|
|
3075
3006
|
var JsonRenderer = class {
|
|
3076
3007
|
async format(context, options) {
|
|
@@ -3085,18 +3016,13 @@ var JsonRenderer = class {
|
|
|
3085
3016
|
const bundleData = context.permutations.map(({ tokens, modifierInputs }) => ({
|
|
3086
3017
|
tokens: stripInternalMetadata(tokens),
|
|
3087
3018
|
modifierInputs,
|
|
3088
|
-
isBase:
|
|
3019
|
+
isBase: isBasePermutation(modifierInputs, context.meta.defaults)
|
|
3089
3020
|
}));
|
|
3090
3021
|
return await bundleAsJson2(bundleData, context.resolver, async (tokens) => {
|
|
3091
3022
|
return await this.formatTokens(tokens, opts);
|
|
3092
3023
|
});
|
|
3093
3024
|
}
|
|
3094
|
-
|
|
3095
|
-
if (!context.output.file && requiresFile) {
|
|
3096
|
-
throw new ConfigurationError(
|
|
3097
|
-
`Output "${context.output.name}": file is required for JSON output`
|
|
3098
|
-
);
|
|
3099
|
-
}
|
|
3025
|
+
assertFileRequired(context.buildPath, context.output.file, context.output.name, "JSON");
|
|
3100
3026
|
const files = {};
|
|
3101
3027
|
for (const { tokens, modifierInputs } of context.permutations) {
|
|
3102
3028
|
const processedTokens = stripInternalMetadata(tokens);
|
|
@@ -3156,55 +3082,11 @@ var JsonRenderer = class {
|
|
|
3156
3082
|
}
|
|
3157
3083
|
return result;
|
|
3158
3084
|
}
|
|
3159
|
-
/**
|
|
3160
|
-
* Nest tokens by path (values only)
|
|
3161
|
-
*/
|
|
3162
3085
|
nestValues(tokens) {
|
|
3163
|
-
|
|
3164
|
-
for (const [, token] of getSortedTokenEntries(tokens)) {
|
|
3165
|
-
const parts = token.path;
|
|
3166
|
-
let current = result;
|
|
3167
|
-
for (let i = 0; i < parts.length - 1; i++) {
|
|
3168
|
-
const part = parts[i];
|
|
3169
|
-
if (part === null || part === void 0) {
|
|
3170
|
-
continue;
|
|
3171
|
-
}
|
|
3172
|
-
if (!(part in current)) {
|
|
3173
|
-
current[part] = {};
|
|
3174
|
-
}
|
|
3175
|
-
current = current[part];
|
|
3176
|
-
}
|
|
3177
|
-
const lastPart = parts[parts.length - 1];
|
|
3178
|
-
if (lastPart !== null && lastPart !== void 0) {
|
|
3179
|
-
current[lastPart] = token.$value;
|
|
3180
|
-
}
|
|
3181
|
-
}
|
|
3182
|
-
return result;
|
|
3086
|
+
return buildNestedTokenObject(tokens, (token) => token.$value);
|
|
3183
3087
|
}
|
|
3184
|
-
/**
|
|
3185
|
-
* Nest tokens by path (with metadata)
|
|
3186
|
-
*/
|
|
3187
3088
|
nestTokens(tokens) {
|
|
3188
|
-
|
|
3189
|
-
for (const [, token] of getSortedTokenEntries(tokens)) {
|
|
3190
|
-
const parts = token.path;
|
|
3191
|
-
let current = result;
|
|
3192
|
-
for (let i = 0; i < parts.length - 1; i++) {
|
|
3193
|
-
const part = parts[i];
|
|
3194
|
-
if (part === null || part === void 0) {
|
|
3195
|
-
continue;
|
|
3196
|
-
}
|
|
3197
|
-
if (!(part in current)) {
|
|
3198
|
-
current[part] = {};
|
|
3199
|
-
}
|
|
3200
|
-
current = current[part];
|
|
3201
|
-
}
|
|
3202
|
-
const lastPart = parts[parts.length - 1];
|
|
3203
|
-
if (lastPart !== null && lastPart !== void 0) {
|
|
3204
|
-
current[lastPart] = this.serializeToken(token);
|
|
3205
|
-
}
|
|
3206
|
-
}
|
|
3207
|
-
return result;
|
|
3089
|
+
return buildNestedTokenObject(tokens, (token) => this.serializeToken(token));
|
|
3208
3090
|
}
|
|
3209
3091
|
serializeToken(token) {
|
|
3210
3092
|
return {
|
|
@@ -3215,9 +3097,6 @@ var JsonRenderer = class {
|
|
|
3215
3097
|
...token.$extensions != null && { $extensions: token.$extensions }
|
|
3216
3098
|
};
|
|
3217
3099
|
}
|
|
3218
|
-
isBasePermutation(modifierInputs, defaults) {
|
|
3219
|
-
return Object.entries(modifierInputs).every(([key, value]) => value === defaults[key]);
|
|
3220
|
-
}
|
|
3221
3100
|
};
|
|
3222
3101
|
function jsonRenderer() {
|
|
3223
3102
|
const rendererInstance = new JsonRenderer();
|
|
@@ -3230,7 +3109,6 @@ function jsonRenderer() {
|
|
|
3230
3109
|
}
|
|
3231
3110
|
|
|
3232
3111
|
// src/renderers/tailwind.ts
|
|
3233
|
-
init_errors();
|
|
3234
3112
|
init_token_utils();
|
|
3235
3113
|
|
|
3236
3114
|
// src/renderers/bundlers/tailwind.ts
|
|
@@ -3259,6 +3137,13 @@ async function bundleAsTailwind(bundleData, options, formatThemeTokens, formatOv
|
|
|
3259
3137
|
}
|
|
3260
3138
|
return cssBlocks.join("\n");
|
|
3261
3139
|
}
|
|
3140
|
+
function resolveModifierSelectorAndMedia(options, modifier, context, modifierInputs) {
|
|
3141
|
+
const normalized = normalizeModifierInputs(modifierInputs);
|
|
3142
|
+
return {
|
|
3143
|
+
selector: resolveSelector(options.selector, modifier, context, false, normalized),
|
|
3144
|
+
mediaQuery: resolveMediaQuery(options.mediaQuery, modifier, context, false, normalized)
|
|
3145
|
+
};
|
|
3146
|
+
}
|
|
3262
3147
|
async function formatModifierOverride({ tokens, modifierInputs }, baseItem, options, formatOverrideBlock) {
|
|
3263
3148
|
const differenceCount = countModifierDifferences(modifierInputs, baseItem.modifierInputs);
|
|
3264
3149
|
if (differenceCount > 1) {
|
|
@@ -3271,19 +3156,11 @@ async function formatModifierOverride({ tokens, modifierInputs }, baseItem, opti
|
|
|
3271
3156
|
const expectedSource = getExpectedSource(modifierInputs, baseItem.modifierInputs);
|
|
3272
3157
|
const [modifier, context] = parseModifierSource(expectedSource);
|
|
3273
3158
|
const cleanTokens = stripInternalMetadata(tokensToInclude);
|
|
3274
|
-
const selector =
|
|
3275
|
-
options
|
|
3159
|
+
const { selector, mediaQuery } = resolveModifierSelectorAndMedia(
|
|
3160
|
+
options,
|
|
3276
3161
|
modifier,
|
|
3277
3162
|
context,
|
|
3278
|
-
|
|
3279
|
-
normalizeModifierInputs(modifierInputs)
|
|
3280
|
-
);
|
|
3281
|
-
const mediaQuery = resolveMediaQuery(
|
|
3282
|
-
options.mediaQuery,
|
|
3283
|
-
modifier,
|
|
3284
|
-
context,
|
|
3285
|
-
false,
|
|
3286
|
-
normalizeModifierInputs(modifierInputs)
|
|
3163
|
+
modifierInputs
|
|
3287
3164
|
);
|
|
3288
3165
|
const css2 = await formatOverrideBlock(cleanTokens, selector, mediaQuery, options.minify);
|
|
3289
3166
|
return `/* Modifier: ${modifier}=${context} */
|
|
@@ -3372,7 +3249,7 @@ var TailwindRenderer = class {
|
|
|
3372
3249
|
*/
|
|
3373
3250
|
async formatTokens(tokens, options) {
|
|
3374
3251
|
const lines = [];
|
|
3375
|
-
const
|
|
3252
|
+
const indent = options.minify ? "" : " ";
|
|
3376
3253
|
const newline = options.minify ? "" : "\n";
|
|
3377
3254
|
const space = options.minify ? "" : " ";
|
|
3378
3255
|
if (options.includeImport) {
|
|
@@ -3394,7 +3271,7 @@ var TailwindRenderer = class {
|
|
|
3394
3271
|
for (const [, token] of getSortedTokenEntries(tokens)) {
|
|
3395
3272
|
const varName = this.buildVariableName(token);
|
|
3396
3273
|
const varValue = this.formatValue(token);
|
|
3397
|
-
lines.push(`${
|
|
3274
|
+
lines.push(`${indent}--${varName}:${space}${varValue};${newline}`);
|
|
3398
3275
|
}
|
|
3399
3276
|
lines.push(`}${newline}`);
|
|
3400
3277
|
const cssString = lines.join("");
|
|
@@ -3405,15 +3282,15 @@ var TailwindRenderer = class {
|
|
|
3405
3282
|
* Used for modifier overrides (e.g., dark mode) appended after the @theme block.
|
|
3406
3283
|
*/
|
|
3407
3284
|
async formatOverrideBlock(tokens, selector, mediaQuery, minify) {
|
|
3408
|
-
const
|
|
3285
|
+
const indent = minify ? "" : " ";
|
|
3409
3286
|
const newline = minify ? "" : "\n";
|
|
3410
3287
|
const space = minify ? "" : " ";
|
|
3411
3288
|
const hasMediaQuery = mediaQuery !== "";
|
|
3412
|
-
const tokenIndent = hasMediaQuery ?
|
|
3289
|
+
const tokenIndent = hasMediaQuery ? indent + indent : indent;
|
|
3413
3290
|
const lines = [];
|
|
3414
3291
|
if (hasMediaQuery) {
|
|
3415
3292
|
lines.push(`@media ${mediaQuery}${space}{${newline}`);
|
|
3416
|
-
lines.push(`${
|
|
3293
|
+
lines.push(`${indent}${selector}${space}{${newline}`);
|
|
3417
3294
|
} else {
|
|
3418
3295
|
lines.push(`${selector}${space}{${newline}`);
|
|
3419
3296
|
}
|
|
@@ -3423,7 +3300,7 @@ var TailwindRenderer = class {
|
|
|
3423
3300
|
lines.push(`${tokenIndent}--${varName}:${space}${varValue};${newline}`);
|
|
3424
3301
|
}
|
|
3425
3302
|
if (hasMediaQuery) {
|
|
3426
|
-
lines.push(`${
|
|
3303
|
+
lines.push(`${indent}}${newline}`);
|
|
3427
3304
|
lines.push(`}${newline}`);
|
|
3428
3305
|
} else {
|
|
3429
3306
|
lines.push(`}${newline}`);
|
|
@@ -3450,8 +3327,8 @@ var TailwindRenderer = class {
|
|
|
3450
3327
|
if (token.$type === "dimension" && isDimensionObject(value)) {
|
|
3451
3328
|
return dimensionObjectToString(value);
|
|
3452
3329
|
}
|
|
3453
|
-
if (token.$type === "duration" &&
|
|
3454
|
-
return
|
|
3330
|
+
if (token.$type === "duration" && isDurationObject(value)) {
|
|
3331
|
+
return durationObjectToString(value);
|
|
3455
3332
|
}
|
|
3456
3333
|
if (token.$type === "fontFamily") {
|
|
3457
3334
|
if (Array.isArray(value)) {
|
|
@@ -3506,9 +3383,6 @@ var TailwindRenderer = class {
|
|
|
3506
3383
|
}
|
|
3507
3384
|
return parts.join(" ");
|
|
3508
3385
|
}
|
|
3509
|
-
isDurationObject(value) {
|
|
3510
|
-
return typeof value === "object" && value !== null && "value" in value && "unit" in value && value.unit !== void 0;
|
|
3511
|
-
}
|
|
3512
3386
|
async formatWithPrettier(css2) {
|
|
3513
3387
|
try {
|
|
3514
3388
|
return await prettier__default.default.format(css2, {
|
|
@@ -3525,7 +3399,7 @@ var TailwindRenderer = class {
|
|
|
3525
3399
|
const bundleData = context.permutations.map(({ tokens, modifierInputs }) => ({
|
|
3526
3400
|
tokens,
|
|
3527
3401
|
modifierInputs,
|
|
3528
|
-
isBase:
|
|
3402
|
+
isBase: isBasePermutation(modifierInputs, context.meta.defaults)
|
|
3529
3403
|
}));
|
|
3530
3404
|
return await bundleAsTailwind(
|
|
3531
3405
|
bundleData,
|
|
@@ -3535,12 +3409,12 @@ var TailwindRenderer = class {
|
|
|
3535
3409
|
);
|
|
3536
3410
|
}
|
|
3537
3411
|
async formatStandalone(context, options) {
|
|
3538
|
-
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
|
|
3542
|
-
|
|
3543
|
-
|
|
3412
|
+
assertFileRequired(
|
|
3413
|
+
context.buildPath,
|
|
3414
|
+
context.output.file,
|
|
3415
|
+
context.output.name,
|
|
3416
|
+
"standalone Tailwind"
|
|
3417
|
+
);
|
|
3544
3418
|
const files = {};
|
|
3545
3419
|
for (const { tokens, modifierInputs } of context.permutations) {
|
|
3546
3420
|
const processedTokens = stripInternalMetadata(tokens);
|
|
@@ -3556,11 +3430,6 @@ var TailwindRenderer = class {
|
|
|
3556
3430
|
}
|
|
3557
3431
|
return outputTree(files);
|
|
3558
3432
|
}
|
|
3559
|
-
isBasePermutation(modifierInputs, defaults) {
|
|
3560
|
-
return Object.entries(defaults).every(
|
|
3561
|
-
([key, value]) => modifierInputs[key]?.toLowerCase() === value.toLowerCase()
|
|
3562
|
-
);
|
|
3563
|
-
}
|
|
3564
3433
|
};
|
|
3565
3434
|
function tailwindRenderer() {
|
|
3566
3435
|
const rendererInstance = new TailwindRenderer();
|