Skip to content

Commit

Permalink
fix: references inside color modifiers
Browse files Browse the repository at this point in the history
  • Loading branch information
jorenbroekema committed Jan 23, 2024
1 parent f614f70 commit 416836b
Show file tree
Hide file tree
Showing 17 changed files with 90 additions and 33 deletions.
5 changes: 5 additions & 0 deletions .changeset/thirty-chairs-end.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@tokens-studio/sd-transforms': patch
---

Support references in color modifiers now that style-dictionary transformers can defer themselves.
8 changes: 4 additions & 4 deletions package-lock.json

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

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
"expr-eval-fork": "^2.0.2",
"is-mergeable-object": "^1.1.1",
"postcss-calc-ast-parser": "^0.1.4",
"style-dictionary": "4.0.0-prerelease.8"
"style-dictionary": "4.0.0-prerelease.9"
},
"devDependencies": {
"@changesets/cli": "^2.26.0",
Expand Down
9 changes: 9 additions & 0 deletions src/color-modifiers/transformColorModifiers.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { DesignToken } from 'style-dictionary/types';
import { usesReferences } from 'style-dictionary/utils';
import { modifyColor } from './modifyColor.js';
import { ColorModifier } from '@tokens-studio/types';
import { ColorModifierOptions } from '../TransformOptions.js';
Expand All @@ -10,6 +11,14 @@ export function transformColorModifiers(
options?: ColorModifierOptions,
): string | undefined {
const modifier = token.$extensions['studio.tokens']?.modify as ColorModifier;

// If some of the modifier props contain references or the modifier itself is a reference
// we should return undefined to manually defer this transformation until the references are resolved
// see: https://github.com/amzn/style-dictionary/blob/v4/docs/transforms.md#defer-transitive-transformation-manually
if (usesReferences(modifier) || Object.values(modifier).some(prop => usesReferences(prop))) {
return undefined;
}

if (options?.format) {
modifier.format = options.format;
}
Expand Down
3 changes: 2 additions & 1 deletion src/registerTransforms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ export async function registerTransforms(
name: 'ts/size/px',
type: 'value',
matcher: token =>
typeof token.type === 'string' &&
['sizing', 'spacing', 'borderRadius', 'borderWidth', 'fontSizes', 'dimension'].includes(
token.type,
),
Expand Down Expand Up @@ -166,7 +167,7 @@ export async function registerTransforms(
name: 'ts/shadow/css/shorthand',
type: 'value',
transitive: true,
matcher: token => ['boxShadow'].includes(token.type),
matcher: token => typeof token.type === 'string' && ['boxShadow'].includes(token.type),
transformer: token =>
Array.isArray(token.value)
? token.value.map(single => transformShadowForCSS(single)).join(', ')
Expand Down
23 changes: 14 additions & 9 deletions test/integration/color-modifier-references.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type StyleDictionary from 'style-dictionary';
import { expect } from '@esm-bundle/chai';
import StyleDictionary from 'style-dictionary';
import { promises } from 'fs';
import path from 'path';
import { promises } from 'node:fs';
import path from 'node:path';
import { cleanup, init } from './utils.js';

const outputDir = 'test/integration/tokens/';
Expand All @@ -25,27 +25,32 @@ const cfg = {
},
};

let dict: StyleDictionary.Core | undefined;
let dict: StyleDictionary | undefined;

describe('typography references', () => {
beforeEach(() => {
beforeEach(async () => {
if (dict) {
cleanup(dict);
}
dict = init(cfg);
dict = await init(cfg);
});

afterEach(() => {
afterEach(async () => {
if (dict) {
cleanup(dict);
await cleanup(dict);
}
});

it('supports references inside color modifiers', async () => {
const file = await promises.readFile(outputFilePath, 'utf-8');
expect(file).to.include(
`--sdAlpha: 0.3;
--sdColor: #FFFFFF4d;`,
--sdColor: #ffffff4d;`,
);
});

it('supports color modifier that is a reference itself, containing another reference', async () => {
const file = await promises.readFile(outputFilePath, 'utf-8');
expect(file).to.include(`--sdColor2: #0000004d;`);
});
});
4 changes: 2 additions & 2 deletions test/integration/cross-file-refs.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type StyleDictionary from 'style-dictionary';
import { expect } from '@esm-bundle/chai';
import { promises } from 'fs';
import path from 'path';
import { promises } from 'node:fs';
import path from 'node:path';
import { cleanup, init } from './utils.js';

const outputDir = 'test/integration/tokens/';
Expand Down
4 changes: 2 additions & 2 deletions test/integration/custom-group.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { expect } from '@esm-bundle/chai';
import StyleDictionary from 'style-dictionary';
import { transforms, registerTransforms } from '../../src/index.js';
import { promises } from 'fs';
import path from 'path';
import { promises } from 'node:fs';
import path from 'node:path';
import { cleanup } from './utils.js';

const outputDir = 'test/integration/tokens/';
Expand Down
4 changes: 2 additions & 2 deletions test/integration/exclude-parent-keys.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { expect } from '@esm-bundle/chai';
import { promises } from 'fs';
import path from 'path';
import { promises } from 'node:fs';
import path from 'node:path';
import { cleanup, init } from './utils.js';

const outputDir = 'test/integration/tokens/';
Expand Down
4 changes: 2 additions & 2 deletions test/integration/expand-composition.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type StyleDictionary from 'style-dictionary';
import { expect } from '@esm-bundle/chai';
import { promises } from 'fs';
import path from 'path';
import { promises } from 'node:fs';
import path from 'node:path';
import { cleanup, init } from './utils.js';

const outputDir = 'test/integration/tokens/';
Expand Down
4 changes: 2 additions & 2 deletions test/integration/math-in-complex-values.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type StyleDictionary from 'style-dictionary';
import { expect } from '@esm-bundle/chai';
import { promises } from 'fs';
import path from 'path';
import { promises } from 'node:fs';
import path from 'node:path';
import { cleanup, init } from './utils.js';

const outputDir = 'test/integration/tokens/';
Expand Down
4 changes: 2 additions & 2 deletions test/integration/object-value-references.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type StyleDictionary from 'style-dictionary';
import { expect } from '@esm-bundle/chai';
import { promises } from 'fs';
import path from 'path';
import { promises } from 'node:fs';
import path from 'node:path';
import { cleanup, init } from './utils.js';

const outputDir = 'test/integration/tokens/';
Expand Down
4 changes: 2 additions & 2 deletions test/integration/output-references.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type StyleDictionary from 'style-dictionary';
import { expect } from '@esm-bundle/chai';
import { promises } from 'fs';
import path from 'path';
import { promises } from 'node:fs';
import path from 'node:path';
import { cleanup, init } from './utils.js';

const outputDir = 'test/integration/tokens/';
Expand Down
4 changes: 2 additions & 2 deletions test/integration/sd-transforms.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type StyleDictionary from 'style-dictionary';
import { expect } from '@esm-bundle/chai';
import { promises } from 'fs';
import path from 'path';
import { promises } from 'node:fs';
import path from 'node:path';
import { cleanup, init } from './utils.js';

const outputDir = 'test/integration/tokens/';
Expand Down
4 changes: 2 additions & 2 deletions test/integration/swift-UI-color.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import StyleDictionary from 'style-dictionary';
import { expect } from '@esm-bundle/chai';
import Color from 'tinycolor2';
import { promises } from 'fs';
import path from 'path';
import { promises } from 'node:fs';
import path from 'node:path';
import { cleanup, init } from './utils.js';

const outputDir = 'test/integration/tokens/';
Expand Down
17 changes: 17 additions & 0 deletions test/integration/tokens/color-modifier-references.tokens.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,22 @@
}
}
}
},
"modifier": {
"value": {
"type": "alpha",
"value": "{alpha}",
"space": "srgb",
"format": "hex"
}
},
"color2": {
"value": "#000000",
"type": "color",
"$extensions": {
"studio.tokens": {
"modify": "{modifier}"
}
}
}
}
20 changes: 20 additions & 0 deletions test/spec/color-modifiers/transformColorModifiers.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -310,4 +310,24 @@ describe('transform color modifiers', () => {

expect(transformColorModifiers(token)).to.equal('rgb(50% 0% 25% / 0.5)');
});

// https://github.com/amzn/style-dictionary/blob/v4/docs/transforms.md#defer-transitive-transformation-manually
it('should return undefined if the transformation needs to be deferred', () => {
const token = {
value: '#C14242',
type: 'color',
$extensions: {
'studio.tokens': {
modify: {
type: 'darken',
value: '{darkenAmount}',
space: 'srgb',
format: 'srgb',
},
},
},
};

expect(transformColorModifiers(token)).to.be.undefined;
});
});

0 comments on commit 416836b

Please sign in to comment.