Skip to content

Commit

Permalink
fix: outputReferences for DTCG spec tokens (#1127)
Browse files Browse the repository at this point in the history
  • Loading branch information
jorenbroekema authored Mar 19, 2024
1 parent 79bb201 commit 8e297d6
Show file tree
Hide file tree
Showing 7 changed files with 136 additions and 30 deletions.
5 changes: 5 additions & 0 deletions .changeset/famous-falcons-join.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'style-dictionary': patch
---

Fix outputReferences for DTCG spec tokens, by using token.original.$value instead of token.original.value.
1 change: 1 addition & 0 deletions __tests__/buildFile.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ ${dictionary.allTokens.map((tok) => ` ${tok.name}: "${tok.value}";`).join('\n')
name: 'someName',
type: 'color',
path: ['some', 'name', 'path1'],
original: { value: 'value1' },
value: 'value1',
},
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,49 @@ snapshots["common formatHelpers createPropertyFormatter commentStyle supports DT
--color-blue: #0000FF;`;
/* end snapshot common formatHelpers createPropertyFormatter commentStyle supports DTCG spec $description property for comments 3 */

snapshots["common formatHelpers createPropertyFormatter DTCG supports DTCG spec $description property for comments 1"] =
` --color-red: #FF0000; /* Foo bar qux red */`;
/* end snapshot common formatHelpers createPropertyFormatter DTCG supports DTCG spec $description property for comments 1 */

snapshots["common formatHelpers createPropertyFormatter DTCG supports DTCG spec $description property for comments 2"] =
` --color-green: #00FF00; /* Foo bar qux green */`;
/* end snapshot common formatHelpers createPropertyFormatter DTCG supports DTCG spec $description property for comments 2 */

snapshots["common formatHelpers createPropertyFormatter DTCG supports DTCG spec $description property for comments 3"] =
` /**
* Foo
* bar
* qux
* blue
*/
--color-blue: #0000FF;`;
/* end snapshot common formatHelpers createPropertyFormatter DTCG supports DTCG spec $description property for comments 3 */

snapshots["common formatHelpers createPropertyFormatter DTCG supports DTCG spec $value for outputReferences 1"] =
` --color-red: #FF0000; /* Foo bar qux red */`;
/* end snapshot common formatHelpers createPropertyFormatter DTCG supports DTCG spec $value for outputReferences 1 */

snapshots["common formatHelpers createPropertyFormatter DTCG supports DTCG spec $value for outputReferences 2"] =
` --color-green: #00FF00; /* Foo bar qux green */`;
/* end snapshot common formatHelpers createPropertyFormatter DTCG supports DTCG spec $value for outputReferences 2 */

snapshots["common formatHelpers createPropertyFormatter DTCG supports DTCG spec $value for outputReferences 3"] =
` /**
* Foo
* bar
* qux
* blue
*/
--color-blue: #0000FF;`;
/* end snapshot common formatHelpers createPropertyFormatter DTCG supports DTCG spec $value for outputReferences 3 */

snapshots["common formatHelpers createPropertyFormatter DTCG supports DTCG spec $value for outputReferences"] =
` /**
* Foo
* bar
* qux
* ref
*/
--color-ref: var(--color-red);`;
/* end snapshot common formatHelpers createPropertyFormatter DTCG supports DTCG spec $value for outputReferences */

90 changes: 67 additions & 23 deletions __tests__/common/formatHelpers/createPropertyFormatter.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -246,18 +246,27 @@ describe('common', () => {
value: '#FF0000',
comment: 'Foo bar qux',
path: ['color', 'red'],
original: {
value: '#FF0000',
},
},
green: {
name: 'color-green',
value: '#00FF00',
comment: 'Foo bar qux',
path: ['color', 'green'],
original: {
value: '#00FF00',
},
},
blue: {
name: 'color-blue',
value: '#0000FF',
comment: 'Foo\nbar\nqux',
path: ['color', 'blue'],
original: {
value: '#0000FF',
},
},
},
};
Expand Down Expand Up @@ -307,44 +316,79 @@ describe('common', () => {
await expect(cssRed).to.matchSnapshot(1);
await expect(sassRed).to.matchSnapshot(2);
});
});

it('supports DTCG spec $description property for comments', async () => {
const descriptionDictionary = {
color: {
red: {
name: 'color-red',
value: '#FF0000',
$description: 'Foo bar qux red',
path: ['color', 'red'],
describe('DTCG', () => {
const dtcgDictionary = {
color: {
red: {
name: 'color-red',
$value: '#FF0000',
original: {
$value: '#FF0000',
},
green: {
name: 'color-green',
value: '#00FF00',
$description: 'Foo bar qux green',
path: ['color', 'green'],
$description: 'Foo bar qux red',
path: ['color', 'red'],
},
green: {
name: 'color-green',
$value: '#00FF00',
original: {
$value: '#00FF00',
},
blue: {
name: 'color-blue',
value: '#0000FF',
$description: 'Foo\nbar\nqux\nblue',
path: ['color', 'blue'],
$description: 'Foo bar qux green',
path: ['color', 'green'],
},
blue: {
name: 'color-blue',
$value: '#0000FF',
original: {
$value: '#0000FF',
},
$description: 'Foo\nbar\nqux\nblue',
path: ['color', 'blue'],
},
};
ref: {
name: 'color-ref',
$value: '#FF0000',
original: {
$value: '{color.red}',
},
$description: 'Foo\nbar\nqux\nref',
path: ['color', 'ref'],
},
},
};
it('supports DTCG spec $description property for comments', async () => {
// long commentStyle
const cssFormatter = createPropertyFormatter({
format: 'css',
dictionary: { tokens: descriptionDictionary },
dictionary: { tokens: dtcgDictionary },
usesDtcg: true,
});

const cssRed = cssFormatter(descriptionDictionary.color.red);
const cssGreen = cssFormatter(descriptionDictionary.color.green);
const cssBlue = cssFormatter(descriptionDictionary.color.blue);
const cssRed = cssFormatter(dtcgDictionary.color.red);
const cssGreen = cssFormatter(dtcgDictionary.color.green);
const cssBlue = cssFormatter(dtcgDictionary.color.blue);

await expect(cssRed).to.matchSnapshot(1);
await expect(cssGreen).to.matchSnapshot(2);
await expect(cssBlue).to.matchSnapshot(3);
});

it('supports DTCG spec $value for outputReferences', async () => {
// long commentStyle
const cssFormatter = createPropertyFormatter({
format: 'css',
outputReferences: true,
dictionary: { tokens: dtcgDictionary },
usesDtcg: true,
});

const cssRef = cssFormatter(dtcgDictionary.color.ref);

await expect(cssRef).to.matchSnapshot();
});
});
});
});
Expand Down
8 changes: 8 additions & 0 deletions __tests__/formats/androidResources.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,21 @@ const customTokens = {
name: 'backgroundColorSecondary',
value: '#F2F3F4',
type: 'color',
original: {
value: '#F2F3F4',
type: 'color',
},
},
},
fontColor: {
primary: {
name: 'fontColorPrimary',
value: '#000000',
type: 'color',
original: {
value: '#000000',
type: 'color',
},
},
},
};
Expand Down
11 changes: 6 additions & 5 deletions lib/common/formatHelpers/createPropertyFormatter.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
* and limitations under the License.
*/
import { _getReferences } from '../../utils/references/getReferences.js';
import { resolveReferences } from '../../utils/references/resolveReferences.js';
import usesReferences from '../../utils/references/usesReferences.js';

/**
Expand Down Expand Up @@ -162,6 +163,7 @@ export default function createPropertyFormatter({
return function (token) {
let to_ret_token = `${indentation}${prefix}${token.name}${separator} `;
let value = usesDtcg ? token.$value : token.value;
const originalValue = usesDtcg ? token.original.$value : token.original.value;

/**
* A single value can have multiple references either by interpolation:
Expand All @@ -175,15 +177,14 @@ export default function createPropertyFormatter({
* This will see if there are references and if there are, replace
* the resolved value with the reference's name.
*/
if (outputReferences && usesReferences(token.original.value)) {
if (outputReferences && usesReferences(originalValue)) {
// Formats that use this function expect `value` to be a string
// or else you will get '[object Object]' in the output
const refs = _getReferences(token.original.value, tokens, { unfilteredTokens }, []);
const refs = _getReferences(originalValue, tokens, { unfilteredTokens }, []);

// original can either be an object value, which requires transitive value transformation in web CSS formats
// or a different (primitive) type, meaning it can be stringified.
const originalIsObject =
typeof token.original.value === 'object' && token.original.value !== null;
const originalIsObject = typeof originalValue === 'object' && originalValue !== null;

if (!originalIsObject) {
// when original is object value, we replace value by matching ref.value and putting a var instead.
Expand All @@ -192,7 +193,7 @@ export default function createPropertyFormatter({

// when original is string value, we replace value by matching original.value and putting a var instead
// this is more friendly to transitive transforms that transform the string values
value = token.original.value;
value = originalValue;
}

refs.forEach((ref) => {
Expand Down
5 changes: 3 additions & 2 deletions lib/common/templates/android/resources.template.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,9 @@ export default (opts) => {
* @returns {string}
*/
function tokenToValue(token, tokens) {
if (file?.options && file.options.outputReferences && usesReferences(token.original.value)) {
return `@${tokenToType(token)}/${getReferences(token.original.value, tokens)[0].name}`;
let originalValue = options.usesDtcg ? token.original.$value : token.original.value;
if (file?.options && file.options.outputReferences && usesReferences(originalValue)) {
return `@${tokenToType(token)}/${getReferences(originalValue, tokens)[0].name}`;
} else {
return options.usesDtcg ? token.$value : token.value;
}
Expand Down

0 comments on commit 8e297d6

Please sign in to comment.