Skip to content

Commit 33b6234

Browse files
author
Dario Soller
committed
fix: restore original transformColorModifiers function API and adding more platform config integration tests
1 parent 9d40322 commit 33b6234

11 files changed

+540
-330
lines changed

src/checkAndEvaluateMath.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { DesignToken } from 'style-dictionary/types';
22
import { Parser } from 'expr-eval-fork';
33
import { parse, reduceExpression } from '@bundled-es-modules/postcss-calc-ast-parser';
4+
import { defaultFractionDigits } from './register.js';
45

56
const mathChars = ['+', '-', '*', '/'];
67
const parser = new Parser();
@@ -151,7 +152,7 @@ export function parseAndReduce(expr: string, mathFractionDigits: number): string
151152

152153
export function checkAndEvaluateMath(
153154
token: DesignToken,
154-
mathFractionDigits: number,
155+
mathFractionDigits = defaultFractionDigits,
155156
): DesignToken['value'] {
156157
const expr = token.$value ?? token.value;
157158
const type = token.$type ?? token.type;

src/color-modifiers/modifyColor.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,20 @@ export function modifyColor(
4141
baseColor = parseUIColor(baseColor);
4242
const color = new Color(baseColor);
4343
let returnedColor = color;
44-
const resolvedMathFractionDigits: number = modifier.mathFractionDigits ?? defaultFractionDigits;
44+
45+
let resolvedMathFractionDigits: number = defaultFractionDigits;
46+
if (modifier?.mathFractionDigits) {
47+
resolvedMathFractionDigits = modifier.mathFractionDigits;
48+
}
4549
const modifyValueResolvedCalc = Number(
4650
parseAndReduce(modifier.value, resolvedMathFractionDigits),
4751
);
4852

53+
let resolvedColorPrecision: number = defaultColorPrecision;
54+
if (modifier?.precision) {
55+
resolvedColorPrecision = modifier.precision;
56+
}
57+
4958
try {
5059
switch (modifier.type) {
5160
case 'lighten':
@@ -60,7 +69,7 @@ export function modifyColor(
6069
modifier.space,
6170
modifyValueResolvedCalc,
6271
new Color(modifier.color),
63-
modifier.precision ?? defaultColorPrecision,
72+
resolvedColorPrecision,
6473
);
6574
break;
6675
case 'alpha': {

src/color-modifiers/transformColorModifiers.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { usesReferences } from 'style-dictionary/utils';
33
import { modifyColor } from './modifyColor.js';
44
import { ColorModifier } from '@tokens-studio/types';
55
import { ColorModifierOptions } from '../TransformOptions.js';
6+
import { defaultFractionDigits } from '../register.js';
67

78
// 3 for backwards compatibility, but should better be 5, referring to the default precision (5) of the colorJS.io library
89
// see: https://colorjs.io/docs/output.html#getting-a-string-representation-of-a-color
@@ -13,7 +14,6 @@ export const defaultColorPrecision = 3;
1314
*/
1415
export function transformColorModifiers(
1516
token: DesignToken,
16-
mathFractionDigits: number,
1717
options?: ColorModifierOptions,
1818
): string | undefined {
1919
const modifier = token.$extensions['studio.tokens']?.modify as ColorModifier;
@@ -29,7 +29,7 @@ export function transformColorModifiers(
2929
modifier.format = options.format;
3030
}
3131
if (!modifier.mathFractionDigits) {
32-
modifier.mathFractionDigits = options?.mathFractionDigits ?? mathFractionDigits;
32+
modifier.mathFractionDigits = options?.mathFractionDigits ?? defaultFractionDigits;
3333
}
3434
if (!modifier.precision) {
3535
modifier.precision = options?.precision ?? defaultColorPrecision;

src/register.ts

Lines changed: 48 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { PreprocessedTokens } from 'style-dictionary/types';
2-
import StyleDictionary from 'style-dictionary';
2+
import StyleDictionary, { PlatformConfig } from 'style-dictionary';
33
import { transformDimension } from './transformDimension.js';
44
import { transformHEXRGBaForCSS } from './css/transformHEXRGBa.js';
55
import { transformFontWeight } from './transformFontWeight.js';
@@ -9,7 +9,7 @@ import { transformTypographyForCompose } from './compose/transformTypography.js'
99
import { checkAndEvaluateMath } from './checkAndEvaluateMath.js';
1010
import { mapDescriptionToComment } from './mapDescriptionToComment.js';
1111
import { transformColorModifiers } from './color-modifiers/transformColorModifiers.js';
12-
import { TransformOptions } from './TransformOptions.js';
12+
import { ColorModifierOptions, TransformOptions } from './TransformOptions.js';
1313
import { transformOpacity } from './transformOpacity.js';
1414
import { parseTokens } from './preprocessors/parse-tokens.js';
1515
import { transformShadow } from './css/transformShadow.js';
@@ -174,12 +174,52 @@ export async function register(sd: typeof StyleDictionary, transformOpts?: Trans
174174
(token.$type ?? token.type) === 'color' &&
175175
token.$extensions &&
176176
token.$extensions['studio.tokens']?.modify,
177-
transform: (token, platformCfg) =>
178-
transformColorModifiers(
179-
token,
180-
platformCfg.mathFractionDigits ?? defaultFractionDigits,
181-
transformOpts?.['ts/color/modifiers'],
182-
),
177+
transform: (token, platformCfg) => {
178+
const hasTransformOpts = transformOpts?.['ts/color/modifiers'];
179+
const hasPlatformPrecision = platformCfg.precision !== undefined;
180+
const hasPlatformMathFractionDigits = platformCfg.mathFractionDigits !== undefined;
181+
182+
if (hasTransformOpts || hasPlatformPrecision || hasPlatformMathFractionDigits) {
183+
const resolveColorModifyTransformOpts = (
184+
platformCfg: PlatformConfig,
185+
transformOpts?: TransformOptions,
186+
): ColorModifierOptions | undefined => {
187+
let resolvedOpts: ColorModifierOptions | undefined;
188+
189+
if (platformCfg.precision) {
190+
resolvedOpts = {} as ColorModifierOptions;
191+
resolvedOpts.precision = platformCfg.precision;
192+
}
193+
194+
if (platformCfg.mathFractionDigits) {
195+
resolvedOpts = resolvedOpts ? resolvedOpts : ({} as ColorModifierOptions);
196+
resolvedOpts.mathFractionDigits = platformCfg.mathFractionDigits;
197+
}
198+
199+
if (transformOpts?.['ts/color/modifiers']) {
200+
if (transformOpts['ts/color/modifiers']?.precision) {
201+
resolvedOpts = resolvedOpts ? resolvedOpts : ({} as ColorModifierOptions);
202+
resolvedOpts.precision = transformOpts['ts/color/modifiers']?.precision;
203+
}
204+
205+
if (transformOpts['ts/color/modifiers']?.mathFractionDigits) {
206+
resolvedOpts = resolvedOpts ? resolvedOpts : ({} as ColorModifierOptions);
207+
resolvedOpts.mathFractionDigits =
208+
transformOpts['ts/color/modifiers']?.mathFractionDigits;
209+
}
210+
}
211+
212+
return resolvedOpts;
213+
};
214+
215+
const resolvedColorModifyTransformOpts: ColorModifierOptions | undefined =
216+
resolveColorModifyTransformOpts(platformCfg, transformOpts);
217+
218+
return transformColorModifiers(token, resolvedColorModifyTransformOpts);
219+
}
220+
221+
return transformColorModifiers(token);
222+
},
183223
});
184224

185225
const includeBuiltinGroup = transformOpts?.withSDBuiltins ?? true;

test/integration/color-modifier-references.test.ts

Lines changed: 117 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,26 +8,26 @@ const outputDir = 'test/integration/tokens/';
88
const outputFileName = 'vars.css';
99
const outputFilePath = path.resolve(outputDir, outputFileName);
1010

11-
const cfg = {
12-
source: ['test/integration/tokens/color-modifier-references.tokens.json'],
13-
platforms: {
14-
css: {
15-
transformGroup: 'tokens-studio',
16-
prefix: 'sd',
17-
buildPath: outputDir,
18-
files: [
19-
{
20-
destination: outputFileName,
21-
format: 'css/variables',
22-
},
23-
],
11+
describe('color modifier references', () => {
12+
const cfg = {
13+
source: ['test/integration/tokens/color-modifier-references.tokens.json'],
14+
platforms: {
15+
css: {
16+
transformGroup: 'tokens-studio',
17+
prefix: 'sd',
18+
buildPath: outputDir,
19+
files: [
20+
{
21+
destination: outputFileName,
22+
format: 'css/variables',
23+
},
24+
],
25+
},
2426
},
25-
},
26-
};
27+
};
2728

28-
let dict: StyleDictionary | undefined;
29+
let dict: StyleDictionary | undefined;
2930

30-
describe('color modifier references', () => {
3131
beforeEach(async () => {
3232
if (dict) {
3333
cleanup(dict);
@@ -95,8 +95,107 @@ describe('color modifier references', () => {
9595

9696
it('supports color with referenced base color, referenced mix color, and expression-based mix value with references', async () => {
9797
const file = await promises.readFile(outputFilePath, 'utf-8');
98-
const content = excerpt(file, { start: new RegExp('--sdColor7: .*;'), end: '}' });
98+
const content = excerpt(file, { start: new RegExp('--sdColor7: .*;'), end: '--sdColor9' });
9999
const expectedOutput = `--sdColor8: #3b64b3;`;
100100
expect(content).toBe(expectedOutput);
101101
});
102102
});
103+
104+
describe('color modifier platform config mathFractionDigits', () => {
105+
const cfg = {
106+
source: ['test/integration/tokens/color-modifier-references.tokens.json'],
107+
platforms: {
108+
css: {
109+
transformGroup: 'tokens-studio',
110+
prefix: 'sd',
111+
buildPath: outputDir,
112+
mathFractionDigits: 10,
113+
files: [
114+
{
115+
destination: outputFileName,
116+
format: 'css/variables',
117+
},
118+
],
119+
},
120+
},
121+
};
122+
123+
let dict: StyleDictionary | undefined;
124+
125+
beforeEach(async () => {
126+
if (dict) {
127+
cleanup(dict);
128+
}
129+
dict = await init(cfg, { withSDBuiltins: false });
130+
});
131+
132+
afterEach(async () => {
133+
if (dict) {
134+
await cleanup(dict);
135+
}
136+
});
137+
138+
it('supports platform config math fraction digits', async () => {
139+
const file = await promises.readFile(outputFilePath, 'utf-8');
140+
const contentMorePrecise = excerpt(file, {
141+
start: new RegExp('--sdColor8: .*;'),
142+
end: '--sdColor10',
143+
});
144+
const expectedOutputMorePrecise = `--sdColor9: rgb(44.287% 59.482% 89.87%);`;
145+
expect(contentMorePrecise).toBe(expectedOutputMorePrecise);
146+
const contentLessPrecise = excerpt(file, {
147+
start: new RegExp('--sdColor9: .*;'),
148+
end: '--sdColor11',
149+
});
150+
const expectedOutputLessPrecise = `--sdColor10: rgb(44.289% 59.483% 89.871%);`;
151+
expect(contentLessPrecise).toBe(expectedOutputLessPrecise);
152+
});
153+
});
154+
155+
describe('color modifier platform config color precision', () => {
156+
const cfg = {
157+
source: ['test/integration/tokens/color-modifier-references.tokens.json'],
158+
platforms: {
159+
css: {
160+
transformGroup: 'tokens-studio',
161+
prefix: 'sd',
162+
buildPath: outputDir,
163+
precision: 8,
164+
files: [
165+
{
166+
destination: outputFileName,
167+
format: 'css/variables',
168+
},
169+
],
170+
},
171+
},
172+
};
173+
174+
let dict: StyleDictionary | undefined;
175+
176+
beforeEach(async () => {
177+
if (dict) {
178+
cleanup(dict);
179+
}
180+
dict = await init(cfg, { withSDBuiltins: false });
181+
});
182+
183+
afterEach(async () => {
184+
if (dict) {
185+
await cleanup(dict);
186+
}
187+
});
188+
189+
it('supports platform config color precision', async () => {
190+
const file = await promises.readFile(outputFilePath, 'utf-8');
191+
const contentMorePrecise = excerpt(file, {
192+
start: new RegExp('--sdColor10: .*;'),
193+
end: '--sdColor12',
194+
});
195+
const expectedOutputMorePrecise = `--sdColor11: rgb(44.288667% 59.482667% 89.870667%);`;
196+
expect(contentMorePrecise).toBe(expectedOutputMorePrecise);
197+
const contentLessPrecise = excerpt(file, { start: new RegExp('--sdColor11: .*;'), end: '}' });
198+
const expectedOutputLessPrecise = `--sdColor12: rgb(44.3% 59.5% 89.9%);`;
199+
expect(contentLessPrecise).toBe(expectedOutputLessPrecise);
200+
});
201+
});

test/integration/tokens/color-modifier-references.tokens.json

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,5 +139,65 @@
139139
}
140140
}
141141
}
142+
},
143+
"color9": {
144+
"value": "#FFFFFF",
145+
"type": "color",
146+
"$extensions": {
147+
"studio.tokens": {
148+
"modify": {
149+
"type": "mix",
150+
"value": "0.5123123452 + 6 * 0.0412341234",
151+
"space": "srgb",
152+
"color": "#4477DD",
153+
"precision": 5
154+
}
155+
}
156+
}
157+
},
158+
"color10": {
159+
"value": "#FFFFFF",
160+
"type": "color",
161+
"$extensions": {
162+
"studio.tokens": {
163+
"modify": {
164+
"type": "mix",
165+
"value": "0.5123123452 + 6 * 0.0412341234",
166+
"space": "srgb",
167+
"color": "#4477DD",
168+
"precision": 5,
169+
"mathFractionDigits": 4
170+
}
171+
}
172+
}
173+
},
174+
"color11": {
175+
"value": "#FFFFFF",
176+
"type": "color",
177+
"$extensions": {
178+
"studio.tokens": {
179+
"modify": {
180+
"type": "mix",
181+
"value": "0.5123123452 + 6 * 0.0412341234",
182+
"space": "srgb",
183+
"color": "#4477DD"
184+
}
185+
}
186+
}
187+
},
188+
"color12": {
189+
"value": "#FFFFFF",
190+
"type": "color",
191+
"$extensions": {
192+
"studio.tokens": {
193+
"modify": {
194+
"type": "mix",
195+
"value": "0.5123123452 + 6 * 0.0412341234",
196+
"space": "srgb",
197+
"color": "#4477DD",
198+
"precision": 3
199+
}
200+
}
201+
}
142202
}
143203
}

test/integration/tokens/sd-transforms.tokens.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,8 @@
7070
"modify": {
7171
"type": "lighten",
7272
"value": "0.1",
73-
"space": "srgb"
73+
"space": "srgb",
74+
"format": "hex"
7475
}
7576
}
7677
}
@@ -87,7 +88,8 @@
8788
"modify": {
8889
"type": "darken",
8990
"value": "0.1",
90-
"space": "srgb"
91+
"space": "srgb",
92+
"format": "hex"
9193
}
9294
}
9395
}

0 commit comments

Comments
 (0)