@usefragments/core 1.10.1 → 1.10.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/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/tokens/scss.test.ts +32 -1
- package/src/tokens/scss.ts +12 -7
package/package.json
CHANGED
package/src/tokens/scss.test.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { describe, expect, it } from "vitest";
|
|
2
2
|
|
|
3
3
|
import { normalizeTokenGroupComment } from "./categories.js";
|
|
4
|
-
import { parseScssTokens } from "./scss.js";
|
|
4
|
+
import { parseScssTokens, parseScssVariables } from "./scss.js";
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* FRICTION #7d — stop prose SCSS comments from being slugified into token
|
|
@@ -92,3 +92,34 @@ describe("parseScssTokens category derivation (#7d)", () => {
|
|
|
92
92
|
expect(out.categories.colors?.some((t) => t.name === "--fui-color-accent")).toBe(true);
|
|
93
93
|
});
|
|
94
94
|
});
|
|
95
|
+
|
|
96
|
+
describe("parseScssVariables", () => {
|
|
97
|
+
it("retains multiline generated adapter expressions as one variable value", () => {
|
|
98
|
+
const variables = parseScssVariables(`
|
|
99
|
+
$fui-font-weight-normal: map.get(
|
|
100
|
+
measurements.$legacy,
|
|
101
|
+
"typography",
|
|
102
|
+
"fontWeight",
|
|
103
|
+
"normal"
|
|
104
|
+
) !default;
|
|
105
|
+
`);
|
|
106
|
+
|
|
107
|
+
expect(variables.get("$fui-font-weight-normal")).toBe(
|
|
108
|
+
'map.get( measurements.$legacy, "typography", "fontWeight", "normal" )'
|
|
109
|
+
);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it("keeps Sass maps available for resolution without emitting the map container as a token", () => {
|
|
113
|
+
const scss = `
|
|
114
|
+
$spacing: (
|
|
115
|
+
xs: 4px,
|
|
116
|
+
sm: 8px,
|
|
117
|
+
);
|
|
118
|
+
`;
|
|
119
|
+
|
|
120
|
+
expect(parseScssVariables(scss).get("$spacing")).toBe("( xs: 4px, sm: 8px, )");
|
|
121
|
+
|
|
122
|
+
const tokens = Object.values(parseScssTokens(scss).categories).flat();
|
|
123
|
+
expect(tokens.map((token) => token.name)).not.toContain("$spacing");
|
|
124
|
+
});
|
|
125
|
+
});
|
package/src/tokens/scss.ts
CHANGED
|
@@ -27,12 +27,15 @@ export function detectTokenPrefix(names: string[]): string {
|
|
|
27
27
|
|
|
28
28
|
export function parseScssVariables(content: string): Map<string, string> {
|
|
29
29
|
const vars = new Map<string, string>();
|
|
30
|
-
const scssVarRegex = /^\s*(\$[\w-]+)\s*:\s*(
|
|
30
|
+
const scssVarRegex = /^\s*(\$[\w-]+)\s*:\s*([\s\S]*?)\s*(?:!default\s*)?;/gm;
|
|
31
31
|
|
|
32
32
|
let match: RegExpExecArray | null;
|
|
33
33
|
while ((match = scssVarRegex.exec(content)) !== null) {
|
|
34
34
|
const name = match[1];
|
|
35
|
-
const value = match[2]
|
|
35
|
+
const value = match[2]
|
|
36
|
+
.replace(/\s*\/\/[^\n]*$/gm, "")
|
|
37
|
+
.replace(/\s+/g, " ")
|
|
38
|
+
.trim();
|
|
36
39
|
if (!vars.has(name)) {
|
|
37
40
|
vars.set(name, value);
|
|
38
41
|
}
|
|
@@ -45,7 +48,7 @@ export function resolveTokenValue(
|
|
|
45
48
|
rawValue: string,
|
|
46
49
|
scssVars: Map<string, string>,
|
|
47
50
|
cssVarValues: Map<string, string>,
|
|
48
|
-
depth = 0
|
|
51
|
+
depth = 0
|
|
49
52
|
): string {
|
|
50
53
|
if (depth > 5) return rawValue;
|
|
51
54
|
|
|
@@ -60,9 +63,7 @@ export function resolveTokenValue(
|
|
|
60
63
|
|
|
61
64
|
resolved = resolved.replace(/(?<![#\{])(\$[\w-]+)/g, (_, varName) => {
|
|
62
65
|
const val = scssVars.get(varName);
|
|
63
|
-
return val !== undefined
|
|
64
|
-
? resolveTokenValue(val, scssVars, cssVarValues, depth + 1)
|
|
65
|
-
: varName;
|
|
66
|
+
return val !== undefined ? resolveTokenValue(val, scssVars, cssVarValues, depth + 1) : varName;
|
|
66
67
|
});
|
|
67
68
|
|
|
68
69
|
resolved = resolved.replace(
|
|
@@ -76,7 +77,7 @@ export function resolveTokenValue(
|
|
|
76
77
|
return resolveTokenValue(fallback.trim(), scssVars, cssVarValues, depth + 1);
|
|
77
78
|
}
|
|
78
79
|
return original;
|
|
79
|
-
}
|
|
80
|
+
}
|
|
80
81
|
);
|
|
81
82
|
|
|
82
83
|
return resolved;
|
|
@@ -134,6 +135,10 @@ export function parseScssTokens(content: string, filePath = "tokens.scss"): Toke
|
|
|
134
135
|
|
|
135
136
|
for (const [name, value] of scssVars) {
|
|
136
137
|
if (seenNames.has(name)) continue;
|
|
138
|
+
// Parenthesized Sass maps are containers, not addressable token values.
|
|
139
|
+
// Keep them in `scssVars` for reference resolution, but let the dedicated
|
|
140
|
+
// map-entry parser expose their individual members.
|
|
141
|
+
if (value.startsWith("(")) continue;
|
|
137
142
|
seenNames.add(name);
|
|
138
143
|
tokens.push({
|
|
139
144
|
name,
|