From 2a2fbcc2f42cf3e62386edd848798048ea796671 Mon Sep 17 00:00:00 2001 From: Danny Banks Date: Tue, 19 Apr 2022 15:42:37 -0700 Subject: [PATCH 1/2] fix(references): getReferences now searches the entire object rather than 1 level deep --- .../__snapshots__/objectValues.test.js.snap | 26 ++++++++++ __integration__/objectValues.test.js | 51 +++++++++++++++++++ lib/common/formatHelpers/sortByReference.js | 5 ++ lib/utils/references/getReferences.js | 8 ++- 4 files changed, 88 insertions(+), 2 deletions(-) diff --git a/__integration__/__snapshots__/objectValues.test.js.snap b/__integration__/__snapshots__/objectValues.test.js.snap index 7fc7c7478..4364e38f0 100644 --- a/__integration__/__snapshots__/objectValues.test.js.snap +++ b/__integration__/__snapshots__/objectValues.test.js.snap @@ -76,6 +76,32 @@ exports[`integration object values css/variables hsl syntax with references shou " `; +exports[`integration object values css/variables shadow should match snapshot 1`] = ` +"/** + * Do not edit directly + * Generated on Sat, 01 Jan 2000 00:00:00 GMT + */ + +:root { + --shadow-light: #ff0000, #40bf40; + --shadow-dark: #40bf40, #ff0000; +} +" +`; + +exports[`integration object values css/variables shadow should match snapshot with references 1`] = ` +"/** + * Do not edit directly + * Generated on Sat, 01 Jan 2000 00:00:00 GMT + */ + +:root { + --shadow-light: var(--color-red), var(--color-green); + --shadow-dark: var(--color-green), var(--color-red); +} +" +`; + exports[`integration object values scss/variables should match snapshot 1`] = ` " // Do not edit directly diff --git a/__integration__/objectValues.test.js b/__integration__/objectValues.test.js index addad4e3d..d97582f11 100644 --- a/__integration__/objectValues.test.js +++ b/__integration__/objectValues.test.js @@ -49,6 +49,22 @@ describe('integration', () => { style: "solid" } }, + }, + shadow: { + light: { + value: [{ + color: "{color.red.value}" + },{ + color: "{color.green.value}" + }] + }, + dark: { + value: [{ + color: "{color.green.value}" + },{ + color: "{color.red.value}" + }] + } } }, transform: { @@ -75,6 +91,14 @@ describe('integration', () => { transformer: (token) => { return `${token.value.width} ${token.value.style} ${token.value.color}` } + }, + shadow: { + type: 'value', + transitive: true, + matcher: (token) => token.attributes.category === 'shadow', + transformer: (token) => { + return token.value.map(obj => obj.color).join(', ') + } } }, platforms: { @@ -129,6 +153,21 @@ describe('integration', () => { }] }, + cssShadow: { + buildPath, + transforms: StyleDictionary.transformGroup.css.concat([`shadow`,`hslToHex`]), + files: [{ + destination: 'shadow.css', + format: 'css/variables', + filter: (token) => token.attributes.category === `shadow`, + },{ + destination: 'shadowWithReferences.css', + format: 'css/variables', + filter: (token) => token.attributes.category === `shadow`, + options + }] + }, + scss: { buildPath, transforms: StyleDictionary.transformGroup.css.concat([`cssBorder`,`hslToHex`]), @@ -188,6 +227,18 @@ describe('integration', () => { }); }); }); + + describe('shadow', () => { + it(`should match snapshot`, () => { + const output = fs.readFileSync(`${buildPath}shadow.css`, {encoding:'UTF-8'}); + expect(output).toMatchSnapshot(); + }); + + it(`should match snapshot with references`, () => { + const output = fs.readFileSync(`${buildPath}shadowWithReferences.css`, {encoding:'UTF-8'}); + expect(output).toMatchSnapshot(); + }); + }) }); describe('scss/variables', () => { diff --git a/lib/common/formatHelpers/sortByReference.js b/lib/common/formatHelpers/sortByReference.js index 16eeb80a2..3455a27b4 100644 --- a/lib/common/formatHelpers/sortByReference.js +++ b/lib/common/formatHelpers/sortByReference.js @@ -30,6 +30,11 @@ const aComesFirst = -1; const bComesFirst = 1; + // return early if a or b ar undefined + if (typeof a === 'undefined' || typeof b === 'undefined') { + return aComesFirst; + } + // If token a uses a reference and token b doesn't, b might come before a // read on.. if (a.original && dictionary.usesReference(a.original.value)) { diff --git a/lib/utils/references/getReferences.js b/lib/utils/references/getReferences.js index ab5bea973..f7cde32ff 100644 --- a/lib/utils/references/getReferences.js +++ b/lib/utils/references/getReferences.js @@ -30,14 +30,14 @@ const GroupMessages = require('../groupMessages'); * @param {string} value the value that contains a reference * @returns {any} */ -function getReferences(value) { +function getReferences(value, references=[]) { // `this` is the dictionary object passed to formats and actions const self = this; const regex = createReferenceRegex({}); // because a token's value can contain multiple references due to string interpolation // "{size.padding.base.value} {color.border.primary.value}" // references is an array of 0 or more references - const references = []; + // const references = []; // this will update the references array with the referenced tokens it finds. function findReference(match, variable) { @@ -70,6 +70,10 @@ function getReferences(value) { if (value.hasOwnProperty(key) && typeof value[key] === 'string') { value[key].replace(regex, findReference); } + // if it is an object, we go further down the rabbit hole + if (value.hasOwnProperty(key) && typeof value[key] === 'object') { + self.getReferences(value[key], references); + } } } From 615b6fb1ffce132017e9e4f8c0ea117f8e4348b3 Mon Sep 17 00:00:00 2001 From: Danny Banks Date: Tue, 10 May 2022 14:17:03 -0700 Subject: [PATCH 2/2] chore(references): cleaning up code --- lib/common/formatHelpers/sortByReference.js | 4 +++- lib/utils/references/getReferences.js | 5 +---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/common/formatHelpers/sortByReference.js b/lib/common/formatHelpers/sortByReference.js index 3455a27b4..72f4fe549 100644 --- a/lib/common/formatHelpers/sortByReference.js +++ b/lib/common/formatHelpers/sortByReference.js @@ -31,8 +31,10 @@ const bComesFirst = 1; // return early if a or b ar undefined - if (typeof a === 'undefined' || typeof b === 'undefined') { + if (typeof a === 'undefined') { return aComesFirst; + } else if (typeof b === 'undefined') { + return bComesFirst; } // If token a uses a reference and token b doesn't, b might come before a diff --git a/lib/utils/references/getReferences.js b/lib/utils/references/getReferences.js index f7cde32ff..993a03ae6 100644 --- a/lib/utils/references/getReferences.js +++ b/lib/utils/references/getReferences.js @@ -28,16 +28,13 @@ const GroupMessages = require('../groupMessages'); * * @memberof Dictionary * @param {string} value the value that contains a reference + * @param {object[]} references array of token's references because a token's value can contain multiple references due to string interpolation * @returns {any} */ function getReferences(value, references=[]) { // `this` is the dictionary object passed to formats and actions const self = this; const regex = createReferenceRegex({}); - // because a token's value can contain multiple references due to string interpolation - // "{size.padding.base.value} {color.border.primary.value}" - // references is an array of 0 or more references - // const references = []; // this will update the references array with the referenced tokens it finds. function findReference(match, variable) {