Skip to content

Commit

Permalink
fix: use ref value to only target and restore reference values (#21)
Browse files Browse the repository at this point in the history
  • Loading branch information
jorenbroekema authored Jul 20, 2022
1 parent d7cc196 commit b6cb742
Show file tree
Hide file tree
Showing 8 changed files with 4,674 additions and 3,014 deletions.
5 changes: 5 additions & 0 deletions .changeset/stale-flies-walk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@divriots/style-dictionary-to-figma': minor
---

BREAKING: do not restore original value if it was not a reference value. Before, it used to always restore, which unintentionally also restored style-dictionary transforms. For nested values, restore fully if any reference is found inside the nested value (object or array). If undesired, you can always use `ignoreUseRefValue` (see [README](./README.md)) to fall back to keeping the fully resolved value. Currently, a hybrid solution that restores only the subparts of a value that is partially using references, is not available. Feel free to raise an issue if needed to explain your use case.
2 changes: 1 addition & 1 deletion .eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module.exports = {
extends: ['@open-wc/eslint-config', 'eslint-config-prettier'].map(require.resolve),
extends: ['@open-wc/eslint-config', 'eslint-config-prettier'],
};
7,515 changes: 4,516 additions & 2,999 deletions package-lock.json

Large diffs are not rendered by default.

22 changes: 11 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,22 +33,22 @@
"test:watch": "web-test-runner --watch"
},
"devDependencies": {
"@changesets/cli": "^2.20.0",
"@changesets/cli": "^2.23.0",
"@esm-bundle/chai": "^4.3.4-fix.0",
"@open-wc/eslint-config": "^7.0.0",
"@web/test-runner": "^0.13.27",
"@web/test-runner-playwright": "^0.8.8",
"eslint": "^7.32.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-import": "^2.25.4",
"@web/test-runner": "^0.13.31",
"@web/test-runner-playwright": "^0.8.9",
"eslint": "^8.20.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-import": "^2.26.0",
"husky": "^7.0.4",
"lint-staged": "^12.3.3",
"lint-staged": "^13.0.3",
"npm-run-all": "^4.1.5",
"prettier": "^2.5.1",
"prettier-package-json": "^2.6.3",
"rollup": "^2.67.3",
"prettier": "^2.7.1",
"prettier-package-json": "^2.6.4",
"rollup": "^2.77.0",
"rollup-plugin-cleanup": "^3.2.1",
"typescript": "^4.5.5"
"typescript": "^4.7.4"
},
"keywords": [
"design tokens",
Expand Down
4 changes: 2 additions & 2 deletions scripts/sort-package-json.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/* eslint-disable import/no-extraneous-dependencies */
import { exec } from 'child_process';
import { createRequire } from 'module';
import mod from 'module';

const require = createRequire(import.meta.url);
const require = mod.createRequire(import.meta.url);
const defaults = require('prettier-package-json/build/defaultOptions');

const currOrder = /** @type {[]} */ (defaults.defaultOptions.keyOrder);
Expand Down
26 changes: 25 additions & 1 deletion src/use-ref-value.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,28 @@
/**
* @typedef {import('./style-dictionary-to-figma.js').Obj} Obj
* @typedef {string|Object|Array<unknown>|number} Value
*/

/**
* @param {Value} val
* @returns {boolean}
*/
function isRefValue(val) {
if (Array.isArray(val)) {
return val.some(prop => isRefValue(/** @type {Value} */ (prop)));
}

if (typeof val === 'string') {
return val.startsWith('{') && val.endsWith('}');
}

if (typeof val === 'number') {
return false;
}

return Object.values(val).some(prop => isRefValue(prop));
}

/**
* @param {Obj} obj
* @returns {Obj}
Expand All @@ -10,7 +31,10 @@ export function useRefValue(obj) {
const newObj = { ...obj };
Object.keys(newObj).forEach(key => {
if (key === 'original' && !newObj.ignoreUseRefValue) {
newObj.value = /** @type {Obj} */ (newObj[key]).value;
const originalValue = /** @type {string} */ (/** @type {Obj} */ (newObj[key]).value);
if (isRefValue(originalValue)) {
newObj.value = /** @type {Obj} */ (newObj[key]).value;
}
} else if (typeof newObj[key] === 'object') {
const newValue = useRefValue(/** @type {Obj} */ (newObj[key]));
newObj[key] = Array.isArray(newObj[key]) ? Object.values(newValue) : newValue;
Expand Down
113 changes: 113 additions & 0 deletions test/use-ref-value.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,119 @@ describe('trim-name', () => {
expect(transformedObj).to.eql(expectedObj);
});

it('does not replace value with original value if original value is not a reference', () => {
const obj = {
original: {
value: 'Medium',
},
value: '500',
};
const expectedObj = {
original: {
value: 'Medium',
},
value: '500',
};
const transformedObj = useRefValue(obj);
expect(transformedObj).to.eql(expectedObj);
});

it('does not replace value with original value if original value do not contain references', () => {
const obj = {
original: {
value: {
lineHeight: 1,
fontWeight: '500',
},
},
value: {
lineHeight: 1,
fontWeight: 'Medium',
},
};
const expectedObj = {
original: {
value: {
lineHeight: 1,
fontWeight: '500',
},
},
value: {
lineHeight: 1,
fontWeight: 'Medium',
},
};
const transformedObj = useRefValue(obj);
expect(transformedObj).to.eql(expectedObj);

const obj2 = {
original: {
value: ['{shadow.core.4}', 'pre-transformed-shadow-2'],
},
value: ['0 0 4px rgba(0,0,0,0.6)', '0 0 2px rgba(0,0,0,0.6)'],
};
const expectedObj2 = {
original: {
value: ['{shadow.core.4}', 'pre-transformed-shadow-2'],
},
value: ['{shadow.core.4}', 'pre-transformed-shadow-2'],
};
const transformedObj2 = useRefValue(obj2);
expect(transformedObj2).to.eql(expectedObj2);
});

it('replaces value with original value if original value contains references', () => {
const obj = {
original: {
value: {
fontFamily: '{fontFamily.body}',
fontWeight: '{fontWeight.regular}',
lineHeight: '{size.lineHeight.xsmall}',
fontSize: '{size.font.xsmall}',
},
},
value: {
fontFamily: 'Inter',
fontWeight: 'Medium',
lineHeight: '1',
fontSize: '16px',
},
};
const expectedObj = {
original: {
value: {
fontFamily: '{fontFamily.body}',
fontWeight: '{fontWeight.regular}',
lineHeight: '{size.lineHeight.xsmall}',
fontSize: '{size.font.xsmall}',
},
},
value: {
fontFamily: '{fontFamily.body}',
fontWeight: '{fontWeight.regular}',
lineHeight: '{size.lineHeight.xsmall}',
fontSize: '{size.font.xsmall}',
},
};
const transformedObj = useRefValue(obj);
expect(transformedObj).to.eql(expectedObj);

const obj2 = {
original: {
value: ['{shadow.core.4}', '{shadow.core.2}'],
},
value: ['0 0 4px rgba(0,0,0,0.6)', '0 0 2px rgba(0,0,0,0.6)'],
};
const expectedObj2 = {
original: {
value: ['{shadow.core.4}', '{shadow.core.2}'],
},
value: ['{shadow.core.4}', '{shadow.core.2}'],
};
const transformedObj2 = useRefValue(obj2);
expect(transformedObj2).to.eql(expectedObj2);
});

// See https://github.com/divriots/style-dictionary-to-figma/issues/17
// This "feature" is a workaround for https://github.com/six7/figma-tokens/issues/706
it('it does not use ref value when it encounters ignoreUseRefValue metadata', () => {
Expand Down
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"module": "esnext",
"moduleResolution": "node",
"lib": ["es2017", "dom"],
"allowSyntheticDefaultImports": true,
"allowJs": true,
"checkJs": true,
"noEmit": true,
Expand Down

0 comments on commit b6cb742

Please sign in to comment.