Skip to content

Commit

Permalink
Merge pull request #183 from thomasmattheussen/fix/check-and-evaluate…
Browse files Browse the repository at this point in the history
…math-booleans

fix for checkAndEvaluateMath as it currently crashed on boolean expressions
  • Loading branch information
jorenbroekema authored Aug 2, 2023
2 parents bad0d46 + 63a96a2 commit 72f4233
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 18 deletions.
8 changes: 8 additions & 0 deletions .changeset/hot-planets-whisper.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
'@tokens-studio/sd-transforms': minor
---

checkAndEvaluateMath to not stringify if not needed:

- for single math expressions resolving to a floating number without unit, we can keep it as a `Number`
- for expressions such as `false` or `true` (`Boolean`), keep as `Boolean` type
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 14 additions & 5 deletions src/checkAndEvaluateMath.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ function splitMultiIntoSingleValues(expr: string): string[] {
return [expr];
}

function parseAndReduce(expr: string): string {
function parseAndReduce(expr: string): string | boolean | number {
// We check for px unit, then remove it
const hasPx = expr.match('px');
let unitlessExpr = expr.replace(/px/g, '');
Expand All @@ -96,17 +96,26 @@ function parseAndReduce(expr: string): string {
} catch (ex) {
return expr;
}

const formatted =
typeof evaluated === 'number' ? Number.parseFloat(evaluated.toFixed(3)) : evaluated;
// Put back the px unit if needed and if reduced doesn't come with one
return `${typeof evaluated !== 'string' ? Number.parseFloat(evaluated.toFixed(3)) : evaluated}${
unit ?? (hasPx ? 'px' : '')
}`;
const formattedUnit = unit ?? (hasPx ? 'px' : '');

// This ensures stringification is not done when not needed (e.g. type number or boolean kept intact)
return formattedUnit ? `${formatted}${formattedUnit}` : formatted;
}

export function checkAndEvaluateMath(expr: string | number | undefined): string | undefined {
export function checkAndEvaluateMath(
expr: string | number | boolean | undefined,
): string | number | boolean | undefined {
if (expr === undefined) {
return expr;
}
const exprs = splitMultiIntoSingleValues(`${expr}`);
const reducedExprs = exprs.map(_expr => parseAndReduce(_expr));
if (reducedExprs.length === 1) {
return reducedExprs[0];
}
return reducedExprs.join(' ');
}
2 changes: 1 addition & 1 deletion src/css/transformBorder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export function transformBorderForCSS(
}
let { color, width } = border;
const { style } = border;
width = transformDimension(checkAndEvaluateMath(width));
width = transformDimension(checkAndEvaluateMath(width) as number | string | undefined);
color = transformHEXRGBaForCSS(color);
return `${isNothing(width) ? '' : width} ${isNothing(style) ? '' : style} ${
isNothing(color) ? '' : color
Expand Down
8 changes: 4 additions & 4 deletions src/css/transformShadow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ export function transformShadowForCSS(
}
let { x, y, blur, spread } = shadow;
const { color, type } = shadow;
x = transformDimension(checkAndEvaluateMath(x));
y = transformDimension(checkAndEvaluateMath(y));
blur = transformDimension(checkAndEvaluateMath(blur));
spread = transformDimension(checkAndEvaluateMath(spread));
x = transformDimension(checkAndEvaluateMath(x) as number | string | undefined);
y = transformDimension(checkAndEvaluateMath(y) as number | string | undefined);
blur = transformDimension(checkAndEvaluateMath(blur) as number | string | undefined);
spread = transformDimension(checkAndEvaluateMath(spread) as number | string | undefined);
return `${type === 'innerShadow' ? 'inset ' : ''}${isNothing(x) ? 0 : x} ${
isNothing(y) ? 0 : y
} ${isNothing(blur) ? 0 : blur}${isNothing(spread) ? ' ' : ` ${spread} `}${
Expand Down
4 changes: 2 additions & 2 deletions src/css/transformTypography.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ export function transformTypographyForCSS(

let { fontFamily, fontWeight, fontSize, lineHeight } = value;
const { fontStyle } = value;
fontSize = transformDimension(checkAndEvaluateMath(fontSize));
lineHeight = checkAndEvaluateMath(lineHeight);
fontSize = transformDimension(checkAndEvaluateMath(fontSize) as number | string | undefined);
lineHeight = checkAndEvaluateMath(lineHeight) as number | string | undefined;
fontWeight = transformFontWeights(fontWeight);
fontFamily = processFontFamily(fontFamily as string | undefined);

Expand Down
13 changes: 9 additions & 4 deletions test/spec/checkAndEvaluateMath.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ describe('check and evaluate math', () => {
it('checks and evaluates math expressions', () => {
expect(checkAndEvaluateMath('4*1.5px 4*1.5px 4*1.5px')).to.equal('6px 6px 6px');
expect(checkAndEvaluateMath('4px')).to.equal('4px');
expect(checkAndEvaluateMath('4 * 7')).to.equal('28');
expect(checkAndEvaluateMath('4 * 7')).to.equal(28);
expect(checkAndEvaluateMath('4 * 7px')).to.equal('28px');
expect(checkAndEvaluateMath('4 * 7rem')).to.equal('28rem');
expect(checkAndEvaluateMath('(15 + 20 - 17 * 8 / 3) * 7px')).to.equal('-72.333px');
});

it('supports expression of type number', () => {
expect(checkAndEvaluateMath(10)).to.equal('10');
expect(checkAndEvaluateMath(10)).to.equal(10);
});

it('can evaluate math expressions where more than one token has a unit, in case of px', () => {
Expand Down Expand Up @@ -51,11 +51,11 @@ describe('check and evaluate math', () => {
});

it('supports expr-eval expressions', () => {
expect(checkAndEvaluateMath('roundTo(4 / 7, 1)')).to.equal('0.6');
expect(checkAndEvaluateMath('roundTo(4 / 7, 1)')).to.equal(0.6);
expect(checkAndEvaluateMath('8 * 14px roundTo(4 / 7, 1)')).to.equal('112px 0.6');
expect(checkAndEvaluateMath('roundTo(4 / 7, 1) 8 * 14px')).to.equal('0.6 112px');
expect(checkAndEvaluateMath('min(10, 24, 5, 12, 6) 8 * 14px')).to.equal('5 112px');
expect(checkAndEvaluateMath('ceil(roundTo(16/1.2,0)/2)*2')).to.equal('14');
expect(checkAndEvaluateMath('ceil(roundTo(16/1.2,0)/2)*2')).to.equal(14);
});

it('does not unnecessarily remove wrapped quotes around font-family values', () => {
Expand All @@ -67,4 +67,9 @@ describe('check and evaluate math', () => {
it('supports values that contain spaces and strings, e.g. a date format', () => {
expect(checkAndEvaluateMath(`dd/MM/yyyy 'om' HH:mm`)).to.equal(`dd/MM/yyyy om HH:mm`);
});

it('supports boolean values', () => {
expect(checkAndEvaluateMath(false)).to.equal(false);
expect(checkAndEvaluateMath(true)).to.equal(true);
});
});

0 comments on commit 72f4233

Please sign in to comment.