From ed3928bd1ece07b04caedde12025797d1ee02d71 Mon Sep 17 00:00:00 2001 From: notlee Date: Tue, 19 Oct 2021 18:21:29 +0100 Subject: [PATCH 1/5] feat(formats): Add `outputReferences` support to `scss/map-deep` Use the `formattedVariables` within the `scss/map-deep` formatter to add support for the `outputReferences` option. Closes: https://github.com/amzn/style-dictionary/issues/712 A side effect of this change is that `scss/map-deep` also supports the `themeable` token property. For backward compatibility changes have been made so tokens default to being themeable with `scss/map-deep`, unlike for `scss/variables` where tokens are not themeable by default. See https://github.com/amzn/style-dictionary/issues/474 --- .../__snapshots__/scss.test.js.snap | 393 +++++++++++++++++- __integration__/scss.test.js | 24 +- .../formats/__snapshots__/all.test.js.snap | 8 +- .../__snapshots__/scssMaps.test.js.snap | 4 +- .../formatHelpers/createPropertyFormatter.js | 8 +- .../formatHelpers/formattedVariables.js | 7 +- lib/common/formats.js | 13 +- lib/common/templates/scss/map-deep.template | 18 +- 8 files changed, 441 insertions(+), 34 deletions(-) diff --git a/__integration__/__snapshots__/scss.test.js.snap b/__integration__/__snapshots__/scss.test.js.snap index ee431b3cf..e06d9c1e4 100644 --- a/__integration__/__snapshots__/scss.test.js.snap +++ b/__integration__/__snapshots__/scss.test.js.snap @@ -1,8 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`integration scss scss/map-deep should match snapshot 1`] = ` -" -/** +"/** * Do not edit directly * Generated on Sat, 01 Jan 2000 00:00:00 GMT */ @@ -386,6 +385,396 @@ $design-system-tokens: ( ) ) ); + +" +`; + +exports[`integration scss scss/map-deep with outputReferences should match snapshot 1`] = ` +"/** + * Do not edit directly + * Generated on Sat, 01 Jan 2000 00:00:00 GMT + */ + +$size-padding-xl: 1rem !default; +$size-padding-large: 1rem !default; +$size-padding-medium: 1rem !default; +$size-padding-small: 0.5rem !default; +$size-font-xl: 2.25rem !default; +$size-font-large: 1.5rem !default; +$size-font-medium: 1rem !default; +$size-font-small: 0.75rem !default; +$size-border-radius-large: 30rem !default; +$color-core-yellow-1100: #2d1a05 !default; +$color-core-yellow-1000: #542a00 !default; +$color-core-yellow-900: #944c0c !default; +$color-core-yellow-800: #ba7506 !default; +$color-core-yellow-700: #dd9903 !default; +$color-core-yellow-600: #ffbc00 !default; +$color-core-yellow-500: #ffcd1c !default; +$color-core-yellow-400: #ffd943 !default; +$color-core-yellow-300: #ffe16e !default; +$color-core-yellow-200: #ffe99a !default; +$color-core-yellow-100: #fdefcd !default; +$color-core-yellow-0: #fff8e2 !default; +$color-core-neutral-1100: #040404 !default; +$color-core-neutral-1000: #162020 !default; +$color-core-neutral-900: #273333 !default; +$color-core-neutral-800: #364141 !default; +$color-core-neutral-700: #515e5f !default; +$color-core-neutral-600: #6e797a !default; +$color-core-neutral-500: #929a9b !default; +$color-core-neutral-400: #b0b6b7 !default; +$color-core-neutral-300: #c8cccc !default; +$color-core-neutral-200: #dee1e1 !default; +$color-core-neutral-100: #f3f4f4 !default; +$color-core-neutral-0: #ffffff !default; +$color-core-orange-1100: #2d130e !default; +$color-core-orange-1000: #601700 !default; +$color-core-orange-900: #962c0b !default; +$color-core-orange-800: #ce5511 !default; +$color-core-orange-700: #ed7024 !default; +$color-core-orange-600: #f57d33 !default; +$color-core-orange-500: #fc8943 !default; +$color-core-orange-400: #ff9c5d !default; +$color-core-orange-300: #ffb180 !default; +$color-core-orange-200: #ffc6a4 !default; +$color-core-orange-100: #fcdccc !default; +$color-core-orange-0: #ffede3 !default; +$color-core-red-1100: #2b1111 !default; +$color-core-red-1000: #6d1313 !default; +$color-core-red-900: #992222 !default; +$color-core-red-800: #c63434 !default; +$color-core-red-700: #db3e3e !default; +$color-core-red-600: #ed4c42 !default; +$color-core-red-500: #f76054 !default; +$color-core-red-400: #ff7f6e !default; +$color-core-red-300: #ff9c8f !default; +$color-core-red-200: #ffb8b1 !default; +$color-core-red-100: #ffd5d2 !default; +$color-core-red-0: #ffeae9 !default; +$color-core-pink-1100: #2b1721 !default; +$color-core-pink-1000: #561231 !default; +$color-core-pink-900: #931847 !default; +$color-core-pink-800: #b22f5b !default; +$color-core-pink-700: #ce3665 !default; +$color-core-pink-600: #e0447c !default; +$color-core-pink-500: #ef588b !default; +$color-core-pink-400: #ff76ae !default; +$color-core-pink-300: #ff95c1 !default; +$color-core-pink-200: #ffb5d5 !default; +$color-core-pink-100: #fcdbeb !default; +$color-core-pink-0: #ffe9f3 !default; +$color-core-magenta-1100: #29192d !default; +$color-core-magenta-1000: #451551 !default; +$color-core-magenta-900: #6c2277 !default; +$color-core-magenta-800: #8f3896 !default; +$color-core-magenta-700: #ac44a8 !default; +$color-core-magenta-600: #c44eb9 !default; +$color-core-magenta-500: #db61db !default; +$color-core-magenta-400: #f282f5 !default; +$color-core-magenta-300: #edadf2 !default; +$color-core-magenta-200: #f4c4f7 !default; +$color-core-magenta-100: #f9e3fc !default; +$color-core-magenta-0: #fef0ff !default; +$color-core-purple-1100: #1d1d38 !default; +$color-core-purple-1000: #2d246b !default; +$color-core-purple-900: #483a9c !default; +$color-core-purple-800: #5e4eba !default; +$color-core-purple-700: #6f5ed3 !default; +$color-core-purple-600: #816fea !default; +$color-core-purple-500: #9180f4 !default; +$color-core-purple-400: #a193f2 !default; +$color-core-purple-300: #c1c1f7 !default; +$color-core-purple-200: #d8d7f9 !default; +$color-core-purple-100: #eaeaf9 !default; +$color-core-purple-0: #f2f2f9 !default; +$color-core-blue-1100: #002138 !default; +$color-core-blue-1000: #0a3960 !default; +$color-core-blue-900: #0c5689 !default; +$color-core-blue-800: #116daa !default; +$color-core-blue-700: #2079c3 !default; +$color-core-blue-600: #2b87d3 !default; +$color-core-blue-500: #3896e3 !default; +$color-core-blue-400: #56adf5 !default; +$color-core-blue-300: #a1d2f8 !default; +$color-core-blue-200: #c7e4f9 !default; +$color-core-blue-100: #dcf2ff !default; +$color-core-blue-0: #e9f8ff !default; +$color-core-aqua-1100: #002838 !default; +$color-core-aqua-1000: #083d4f !default; +$color-core-aqua-900: #035e73 !default; +$color-core-aqua-800: #0f6e84 !default; +$color-core-aqua-700: #0b8599 !default; +$color-core-aqua-600: #0797ae !default; +$color-core-aqua-500: #17b8ce !default; +$color-core-aqua-400: #33d6e2 !default; +$color-core-aqua-300: #76e5e2 !default; +$color-core-aqua-200: #a5f2f2 !default; +$color-core-aqua-100: #c5f9f9 !default; +$color-core-aqua-0: #d9fcfb !default; +$color-core-teal-1100: #002528 !default; +$color-core-teal-1000: #083f3f !default; +$color-core-teal-900: #026661 !default; +$color-core-teal-800: #067c7c !default; +$color-core-teal-700: #0b968f !default; +$color-core-teal-600: #00a99c !default; +$color-core-teal-500: #08c4b2 !default; +$color-core-teal-400: #24e0c5 !default; +$color-core-teal-300: #7dead5 !default; +$color-core-teal-200: #b3f2e6 !default; +$color-core-teal-100: #cdf7ef !default; +$color-core-teal-0: #e5f9f5 !default; +$color-core-green-1100: #002b20 !default; +$color-core-green-1000: #08422f !default; +$color-core-green-900: #006b40 !default; +$color-core-green-800: #008b46 !default; +$color-core-green-700: #0ca750 !default; +$color-core-green-600: #2bb656 !default; +$color-core-green-500: #59cb59 !default; +$color-core-green-400: #75dd66 !default; +$color-core-green-300: #98e58e !default; +$color-core-green-200: #c2f2bd !default; +$color-core-green-100: #d7f4d7 !default; +$color-core-green-0: #ebf9eb !default; +$color-font-success: $color-core-green-1000 !default; +$color-font-warning: $color-core-orange-1000 !default; +$color-font-danger: $color-core-red-1000 !default; +$color-font-tertiary: $color-core-neutral-800 !default; +$color-font-secondary: $color-core-neutral-900 !default; +$color-font-primary: $color-core-neutral-1100 !default; +$color-brand-secondary: $color-core-purple-700 !default; +$color-brand-primary: $color-core-aqua-700 !default; +$color-border-primary: $color-core-neutral-300 !default; +$color-background-info: $color-core-blue-0 !default; +$color-background-success: $color-core-green-0 !default; +$color-background-warning: $color-core-orange-0 !default; +$color-background-danger: $color-core-red-0 !default; +$color-background-tertiary: $color-core-neutral-200 !default; +$color-background-secondary: $color-core-neutral-100 !default; +$color-background-primary: $color-core-neutral-0 !default; +$color-font-interactive-disabled: $color-font-tertiary !default; +$color-font-interactive-active: $color-brand-secondary !default; +$color-font-interactive-hover: $color-brand-primary !default; +$color-font-interactive: $color-brand-primary !default; +$color-background-disabled: $color-background-tertiary !default; + +$design-system-tokens: ( + 'color': ( + 'background': ( + 'primary': $color-background-primary, + 'secondary': $color-background-secondary, + 'tertiary': $color-background-tertiary, + 'danger': $color-background-danger, + 'warning': $color-background-warning, + 'success': $color-background-success, + 'info': $color-background-info, + 'disabled': $color-background-disabled + ), + 'border': ( + 'primary': $color-border-primary, + 'secondary': ( + + ), + 'tertiary': ( + + ) + ), + 'brand': ( + 'primary': $color-brand-primary, + 'secondary': $color-brand-secondary + ), + 'core': ( + 'green': ( + '0': $color-core-green-0, + '100': $color-core-green-100, + '200': $color-core-green-200, + '300': $color-core-green-300, + '400': $color-core-green-400, + '500': $color-core-green-500, + '600': $color-core-green-600, + '700': $color-core-green-700, + '800': $color-core-green-800, + '900': $color-core-green-900, + '1000': $color-core-green-1000, + '1100': $color-core-green-1100 + ), + 'teal': ( + '0': $color-core-teal-0, + '100': $color-core-teal-100, + '200': $color-core-teal-200, + '300': $color-core-teal-300, + '400': $color-core-teal-400, + '500': $color-core-teal-500, + '600': $color-core-teal-600, + '700': $color-core-teal-700, + '800': $color-core-teal-800, + '900': $color-core-teal-900, + '1000': $color-core-teal-1000, + '1100': $color-core-teal-1100 + ), + 'aqua': ( + '0': $color-core-aqua-0, + '100': $color-core-aqua-100, + '200': $color-core-aqua-200, + '300': $color-core-aqua-300, + '400': $color-core-aqua-400, + '500': $color-core-aqua-500, + '600': $color-core-aqua-600, + '700': $color-core-aqua-700, + '800': $color-core-aqua-800, + '900': $color-core-aqua-900, + '1000': $color-core-aqua-1000, + '1100': $color-core-aqua-1100 + ), + 'blue': ( + '0': $color-core-blue-0, + '100': $color-core-blue-100, + '200': $color-core-blue-200, + '300': $color-core-blue-300, + '400': $color-core-blue-400, + '500': $color-core-blue-500, + '600': $color-core-blue-600, + '700': $color-core-blue-700, + '800': $color-core-blue-800, + '900': $color-core-blue-900, + '1000': $color-core-blue-1000, + '1100': $color-core-blue-1100 + ), + 'purple': ( + '0': $color-core-purple-0, + '100': $color-core-purple-100, + '200': $color-core-purple-200, + '300': $color-core-purple-300, + '400': $color-core-purple-400, + '500': $color-core-purple-500, + '600': $color-core-purple-600, + '700': $color-core-purple-700, + '800': $color-core-purple-800, + '900': $color-core-purple-900, + '1000': $color-core-purple-1000, + '1100': $color-core-purple-1100 + ), + 'magenta': ( + '0': $color-core-magenta-0, + '100': $color-core-magenta-100, + '200': $color-core-magenta-200, + '300': $color-core-magenta-300, + '400': $color-core-magenta-400, + '500': $color-core-magenta-500, + '600': $color-core-magenta-600, + '700': $color-core-magenta-700, + '800': $color-core-magenta-800, + '900': $color-core-magenta-900, + '1000': $color-core-magenta-1000, + '1100': $color-core-magenta-1100 + ), + 'pink': ( + '0': $color-core-pink-0, + '100': $color-core-pink-100, + '200': $color-core-pink-200, + '300': $color-core-pink-300, + '400': $color-core-pink-400, + '500': $color-core-pink-500, + '600': $color-core-pink-600, + '700': $color-core-pink-700, + '800': $color-core-pink-800, + '900': $color-core-pink-900, + '1000': $color-core-pink-1000, + '1100': $color-core-pink-1100 + ), + 'red': ( + '0': $color-core-red-0, + '100': $color-core-red-100, + '200': $color-core-red-200, + '300': $color-core-red-300, + '400': $color-core-red-400, + '500': $color-core-red-500, + '600': $color-core-red-600, + '700': $color-core-red-700, + '800': $color-core-red-800, + '900': $color-core-red-900, + '1000': $color-core-red-1000, + '1100': $color-core-red-1100 + ), + 'orange': ( + '0': $color-core-orange-0, + '100': $color-core-orange-100, + '200': $color-core-orange-200, + '300': $color-core-orange-300, + '400': $color-core-orange-400, + '500': $color-core-orange-500, + '600': $color-core-orange-600, + '700': $color-core-orange-700, + '800': $color-core-orange-800, + '900': $color-core-orange-900, + '1000': $color-core-orange-1000, + '1100': $color-core-orange-1100 + ), + 'neutral': ( + '0': $color-core-neutral-0, + '100': $color-core-neutral-100, + '200': $color-core-neutral-200, + '300': $color-core-neutral-300, + '400': $color-core-neutral-400, + '500': $color-core-neutral-500, + '600': $color-core-neutral-600, + '700': $color-core-neutral-700, + '800': $color-core-neutral-800, + '900': $color-core-neutral-900, + '1000': $color-core-neutral-1000, + '1100': $color-core-neutral-1100 + ), + 'yellow': ( + '0': $color-core-yellow-0, + '100': $color-core-yellow-100, + '200': $color-core-yellow-200, + '300': $color-core-yellow-300, + '400': $color-core-yellow-400, + '500': $color-core-yellow-500, + '600': $color-core-yellow-600, + '700': $color-core-yellow-700, + '800': $color-core-yellow-800, + '900': $color-core-yellow-900, + '1000': $color-core-yellow-1000, + '1100': $color-core-yellow-1100 + ) + ), + 'font': ( + 'primary': $color-font-primary, + 'secondary': $color-font-secondary, + 'tertiary': $color-font-tertiary, + 'interactive': ( + '_': $color-font-interactive, + 'hover': $color-font-interactive-hover, + 'active': $color-font-interactive-active, + 'disabled': $color-font-interactive-disabled + ), + 'danger': $color-font-danger, + 'warning': $color-font-warning, + 'success': $color-font-success + ) + ), + 'size': ( + 'border': ( + 'radius': ( + 'large': $size-border-radius-large + ) + ), + 'font': ( + 'small': $size-font-small, + 'medium': $size-font-medium, + 'large': $size-font-large, + 'xl': $size-font-xl + ), + 'padding': ( + 'small': $size-padding-small, + 'medium': $size-padding-medium, + 'large': $size-padding-large, + 'xl': $size-padding-xl + ) + ) +); + " `; diff --git a/__integration__/scss.test.js b/__integration__/scss.test.js index f6e442ae9..6e4f71977 100644 --- a/__integration__/scss.test.js +++ b/__integration__/scss.test.js @@ -48,6 +48,13 @@ describe(`integration`, () => { destination: `map-deep.scss`, format: `scss/map-deep`, mapName: 'design-system-tokens' + },{ + destination: `map-deep-with-references.scss`, + format: `scss/map-deep`, + mapName: 'design-system-tokens', + options: { + outputReferences: true + } }] } } @@ -117,10 +124,25 @@ describe(`integration`, () => { it(`should match snapshot`, () => { expect(output).toMatchSnapshot(); }); + + describe(`with outputReferences`, () => { + const output = fs.readFileSync(`${buildPath}map-deep-with-references.scss`, { encoding: 'UTF-8' }); + it(`should have a valid scss syntax`, () => { + const result = scss.renderSync({ + data: output, + }); + expect(result.css).toBeDefined(); + }); + + it(`should match snapshot`, () => { + expect(output).toMatchSnapshot(); + }); + }); + }); }); }); afterAll(() => { fs.emptyDirSync(buildPath); -}); \ No newline at end of file +}); diff --git a/__tests__/formats/__snapshots__/all.test.js.snap b/__tests__/formats/__snapshots__/all.test.js.snap index 42cc329bd..bd18eabdf 100644 --- a/__tests__/formats/__snapshots__/all.test.js.snap +++ b/__tests__/formats/__snapshots__/all.test.js.snap @@ -616,8 +616,7 @@ exports[`formats all should match less/variables snapshot 1`] = ` `; exports[`formats all should match sass/map-deep snapshot 1`] = ` -" -/** +"/** * Do not edit directly * Generated on Sat, 01 Jan 2000 00:00:00 GMT */ @@ -629,6 +628,7 @@ $tokens: ( 'red': $color_red ) ); + " `; @@ -655,8 +655,7 @@ exports[`formats all should match scss/icons snapshot 1`] = ` `; exports[`formats all should match scss/map-deep snapshot 1`] = ` -" -/** +"/** * Do not edit directly * Generated on Sat, 01 Jan 2000 00:00:00 GMT */ @@ -668,6 +667,7 @@ $tokens: ( 'red': $color_red ) ); + " `; diff --git a/__tests__/formats/__snapshots__/scssMaps.test.js.snap b/__tests__/formats/__snapshots__/scssMaps.test.js.snap index 8a24215f5..dac0c0362 100644 --- a/__tests__/formats/__snapshots__/scssMaps.test.js.snap +++ b/__tests__/formats/__snapshots__/scssMaps.test.js.snap @@ -1,8 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`formats scss/map-deep scss/map-deep snapshot 1`] = ` -" -/** +"/** * Do not edit directly * Generated on Sat, 01 Jan 2000 00:00:00 GMT */ @@ -32,6 +31,7 @@ $tokens: ( ) ) ); + " `; diff --git a/lib/common/formatHelpers/createPropertyFormatter.js b/lib/common/formatHelpers/createPropertyFormatter.js index 107da4bc1..b9a9916ba 100644 --- a/lib/common/formatHelpers/createPropertyFormatter.js +++ b/lib/common/formatHelpers/createPropertyFormatter.js @@ -45,9 +45,10 @@ const defaultFormatting = { * @param {Dictionary} options.dictionary - The dictionary object sent to the formatter function * @param {String} options.format - Available formats are: 'css', 'sass', 'less', and 'stylus'. If you want to customize the format and can't use one of those predefined formats, use the `formatting` option * @param {Object} options.formatting - Custom formatting properties that define parts of a declaration line in code. The configurable strings are: prefix, indentation, separator, suffix, and commentStyle. Those are used to generate a line like this: `${indentation}${prefix}${prop.name}${separator} ${prop.value}${suffix}` + * @param {Boolean} options.themeable_default [false] - Whether tokens should default to being themeable. * @returns {Function} */ -function createPropertyFormatter({outputReferences, dictionary, format, formatting={}}) { +function createPropertyFormatter({ outputReferences, dictionary, format, formatting = {}, themeable_default = false }) { let {prefix, commentStyle, indentation, separator, suffix} = Object.assign({}, defaultFormatting, formatting); switch(format) { @@ -117,7 +118,8 @@ function createPropertyFormatter({outputReferences, dictionary, format, formatti to_ret_prop += prop.attributes.category === 'asset' ? `"${value}"` : value; - if (format == 'sass' && prop.themeable === true) { + const themeable = typeof prop.themeable === 'boolean' ? prop.themeable : themeable_default; + if (format === 'sass' && themeable) { to_ret_prop += ' !default'; } @@ -135,4 +137,4 @@ function createPropertyFormatter({outputReferences, dictionary, format, formatti } } -module.exports = createPropertyFormatter; \ No newline at end of file +module.exports = createPropertyFormatter; diff --git a/lib/common/formatHelpers/formattedVariables.js b/lib/common/formatHelpers/formattedVariables.js index 02830b3d0..f685cb2f5 100644 --- a/lib/common/formatHelpers/formattedVariables.js +++ b/lib/common/formatHelpers/formattedVariables.js @@ -27,6 +27,7 @@ const defaultFormatting = { * @param {Object} options.dictionary - The dictionary object that gets passed to the formatter method. * @param {Boolean} options.outputReferences - Whether or not to output references * @param {Object} options.formatting - Custom formatting properties that define parts of a declaration line in code. This will get passed to `formatHelpers.createPropertyFormatter` and used for the `lineSeparator` between lines of code. + * @param {Boolean} options.themeable_default [false] - Whether tokens should default to being themeable. * @returns {String} * @example * ```js @@ -38,7 +39,7 @@ const defaultFormatting = { * }); * ``` */ -function formattedVariables({format, dictionary, outputReferences=false, formatting={}}) { +function formattedVariables({ format, dictionary, outputReferences = false, formatting = {}, themeable_default = false}) { let {allTokens} = dictionary; let {lineSeparator} = Object.assign({}, defaultFormatting, formatting); @@ -56,9 +57,9 @@ function formattedVariables({format, dictionary, outputReferences=false, formatt } return allTokens - .map(createPropertyFormatter({ outputReferences, dictionary, format, formatting })) + .map(createPropertyFormatter({ outputReferences, dictionary, format, formatting, themeable_default })) .filter(function(strVal) { return !!strVal }) .join(lineSeparator); } -module.exports = formattedVariables; \ No newline at end of file +module.exports = formattedVariables; diff --git a/lib/common/formats.js b/lib/common/formats.js index 063b16bfe..4c38b423a 100644 --- a/lib/common/formats.js +++ b/lib/common/formats.js @@ -84,6 +84,8 @@ module.exports = { * * @memberof Formats * @kind member + * @param {Object} options + * @param {Boolean} [options.outputReferences=false] - Whether or not to keep [references](/#/formats?id=references-in-output-files) (a -> b -> c) in the output. * @example * ```scss * $color-background-base: #f0f0f0 !default; @@ -100,8 +102,13 @@ module.exports = { * ``` */ 'scss/map-deep': function({dictionary, options, file}) { - const template = _template(fs.readFileSync(__dirname + '/templates/scss/map-deep.template')); - return template({dictionary, file, options, fileHeader}); + const mapTemplate = _template(fs.readFileSync(__dirname + '/templates/scss/map-deep.template')); + + const { outputReferences } = options; + return fileHeader({ file, commentStyle: 'long' }) + + formattedVariables({ format: 'sass', dictionary, outputReferences, themeable_default: true }) + + '\n' + + mapTemplate({dictionary, file}); }, // This will soon be removed, is left here only for backwards compatibility @@ -1165,4 +1172,4 @@ declare const ${moduleName}: ${JSON.stringify(treeWalker(dictionary.tokens), nul // Mark which formats are nested module.exports['json/nested'].nested = true; module.exports['javascript/module'].nested = true; -module.exports['javascript/object'].nested = true; \ No newline at end of file +module.exports['javascript/object'].nested = true; diff --git a/lib/common/templates/scss/map-deep.template b/lib/common/templates/scss/map-deep.template index 4a2654739..e07ac7ac1 100644 --- a/lib/common/templates/scss/map-deep.template +++ b/lib/common/templates/scss/map-deep.template @@ -13,21 +13,7 @@ // express or implied. See the License for the specific language governing // permissions and limitations under the License. %> -<%= fileHeader({file, commentStyle: 'long'}) %><% - // output the list of tokens as Sass variables - // - dictionary.allTokens.forEach(function(prop) { - var output = ''; - output += '$' + prop.name + ': ' + (prop.attributes.category==='asset' ? '"'+prop.value+'"' : prop.value) + ' !default;' - if(prop.comment) { - output += ' // ' + prop.comment; - } - output += '\n'; - print(output); - }); - - print('\n'); - +<% // output the list of tokens as a Sass nested map // (the values are pointing to the variables) // @@ -52,4 +38,4 @@ } return output; } -%> \ No newline at end of file +%> From 6911a2f6b747da2a4adc19d324d30c567d4aaca8 Mon Sep 17 00:00:00 2001 From: Lee Moody Date: Tue, 26 Oct 2021 12:48:27 +0100 Subject: [PATCH 2/5] feat: add a `themeable` option to the `scss/map-deep` format An option to add/remove the `!default` flag on Sass variables by default. This may be overridden by setting a `themeable` attribute in a token's definition. Defaults to `true` for backward compatibility. Unlike the `scss/variables` which does not output Sass variables with the `!default` flag by default. --- .../__snapshots__/scss.test.js.snap | 389 ++++++++++++++++++ __integration__/scss.test.js | 21 + docs/formats.md | 24 +- .../formatHelpers/createPropertyFormatter.js | 8 +- .../formatHelpers/formattedVariables.js | 6 +- lib/common/formats.js | 6 +- 6 files changed, 444 insertions(+), 10 deletions(-) diff --git a/__integration__/__snapshots__/scss.test.js.snap b/__integration__/__snapshots__/scss.test.js.snap index e06d9c1e4..b962587e8 100644 --- a/__integration__/__snapshots__/scss.test.js.snap +++ b/__integration__/__snapshots__/scss.test.js.snap @@ -778,6 +778,395 @@ $design-system-tokens: ( " `; +exports[`integration scss scss/map-deep without themeable should match snapshot 1`] = ` +"/** + * Do not edit directly + * Generated on Sat, 01 Jan 2000 00:00:00 GMT + */ + +$color-background-primary: #ffffff !default; +$color-background-secondary: #f3f4f4; +$color-background-tertiary: #dee1e1; +$color-background-danger: #ffeae9; +$color-background-warning: #ffede3; +$color-background-success: #ebf9eb; +$color-background-info: #e9f8ff; +$color-background-disabled: #dee1e1; +$color-border-primary: #c8cccc; +$color-brand-primary: #0b8599; +$color-brand-secondary: #6f5ed3; +$color-core-green-0: #ebf9eb; +$color-core-green-100: #d7f4d7; +$color-core-green-200: #c2f2bd; +$color-core-green-300: #98e58e; +$color-core-green-400: #75dd66; +$color-core-green-500: #59cb59; +$color-core-green-600: #2bb656; +$color-core-green-700: #0ca750; +$color-core-green-800: #008b46; +$color-core-green-900: #006b40; +$color-core-green-1000: #08422f; +$color-core-green-1100: #002b20; +$color-core-teal-0: #e5f9f5; +$color-core-teal-100: #cdf7ef; +$color-core-teal-200: #b3f2e6; +$color-core-teal-300: #7dead5; +$color-core-teal-400: #24e0c5; +$color-core-teal-500: #08c4b2; +$color-core-teal-600: #00a99c; +$color-core-teal-700: #0b968f; +$color-core-teal-800: #067c7c; +$color-core-teal-900: #026661; +$color-core-teal-1000: #083f3f; +$color-core-teal-1100: #002528; +$color-core-aqua-0: #d9fcfb; +$color-core-aqua-100: #c5f9f9; +$color-core-aqua-200: #a5f2f2; +$color-core-aqua-300: #76e5e2; +$color-core-aqua-400: #33d6e2; +$color-core-aqua-500: #17b8ce; +$color-core-aqua-600: #0797ae; +$color-core-aqua-700: #0b8599; +$color-core-aqua-800: #0f6e84; +$color-core-aqua-900: #035e73; +$color-core-aqua-1000: #083d4f; +$color-core-aqua-1100: #002838; +$color-core-blue-0: #e9f8ff; +$color-core-blue-100: #dcf2ff; +$color-core-blue-200: #c7e4f9; +$color-core-blue-300: #a1d2f8; +$color-core-blue-400: #56adf5; +$color-core-blue-500: #3896e3; +$color-core-blue-600: #2b87d3; +$color-core-blue-700: #2079c3; +$color-core-blue-800: #116daa; +$color-core-blue-900: #0c5689; +$color-core-blue-1000: #0a3960; +$color-core-blue-1100: #002138; +$color-core-purple-0: #f2f2f9; +$color-core-purple-100: #eaeaf9; +$color-core-purple-200: #d8d7f9; +$color-core-purple-300: #c1c1f7; +$color-core-purple-400: #a193f2; +$color-core-purple-500: #9180f4; +$color-core-purple-600: #816fea; +$color-core-purple-700: #6f5ed3; +$color-core-purple-800: #5e4eba; +$color-core-purple-900: #483a9c; +$color-core-purple-1000: #2d246b; +$color-core-purple-1100: #1d1d38; +$color-core-magenta-0: #fef0ff; +$color-core-magenta-100: #f9e3fc; +$color-core-magenta-200: #f4c4f7; +$color-core-magenta-300: #edadf2; +$color-core-magenta-400: #f282f5; +$color-core-magenta-500: #db61db; +$color-core-magenta-600: #c44eb9; +$color-core-magenta-700: #ac44a8; +$color-core-magenta-800: #8f3896; +$color-core-magenta-900: #6c2277; +$color-core-magenta-1000: #451551; +$color-core-magenta-1100: #29192d; +$color-core-pink-0: #ffe9f3; +$color-core-pink-100: #fcdbeb; +$color-core-pink-200: #ffb5d5; +$color-core-pink-300: #ff95c1; +$color-core-pink-400: #ff76ae; +$color-core-pink-500: #ef588b; +$color-core-pink-600: #e0447c; +$color-core-pink-700: #ce3665; +$color-core-pink-800: #b22f5b; +$color-core-pink-900: #931847; +$color-core-pink-1000: #561231; +$color-core-pink-1100: #2b1721; +$color-core-red-0: #ffeae9; +$color-core-red-100: #ffd5d2; +$color-core-red-200: #ffb8b1; +$color-core-red-300: #ff9c8f; +$color-core-red-400: #ff7f6e; +$color-core-red-500: #f76054; +$color-core-red-600: #ed4c42; +$color-core-red-700: #db3e3e; +$color-core-red-800: #c63434; +$color-core-red-900: #992222; +$color-core-red-1000: #6d1313; +$color-core-red-1100: #2b1111; +$color-core-orange-0: #ffede3; +$color-core-orange-100: #fcdccc; +$color-core-orange-200: #ffc6a4; +$color-core-orange-300: #ffb180; +$color-core-orange-400: #ff9c5d; +$color-core-orange-500: #fc8943; +$color-core-orange-600: #f57d33; +$color-core-orange-700: #ed7024; +$color-core-orange-800: #ce5511; +$color-core-orange-900: #962c0b; +$color-core-orange-1000: #601700; +$color-core-orange-1100: #2d130e; +$color-core-neutral-0: #ffffff; +$color-core-neutral-100: #f3f4f4; +$color-core-neutral-200: #dee1e1; +$color-core-neutral-300: #c8cccc; +$color-core-neutral-400: #b0b6b7; +$color-core-neutral-500: #929a9b; +$color-core-neutral-600: #6e797a; +$color-core-neutral-700: #515e5f; +$color-core-neutral-800: #364141; +$color-core-neutral-900: #273333; +$color-core-neutral-1000: #162020; +$color-core-neutral-1100: #040404; +$color-core-yellow-0: #fff8e2; +$color-core-yellow-100: #fdefcd; +$color-core-yellow-200: #ffe99a; +$color-core-yellow-300: #ffe16e; +$color-core-yellow-400: #ffd943; +$color-core-yellow-500: #ffcd1c; +$color-core-yellow-600: #ffbc00; +$color-core-yellow-700: #dd9903; +$color-core-yellow-800: #ba7506; +$color-core-yellow-900: #944c0c; +$color-core-yellow-1000: #542a00; +$color-core-yellow-1100: #2d1a05; +$color-font-primary: #040404; +$color-font-secondary: #273333; +$color-font-tertiary: #364141; +$color-font-interactive: #0b8599; +$color-font-interactive-hover: #0b8599; +$color-font-interactive-active: #6f5ed3; +$color-font-interactive-disabled: #364141; +$color-font-danger: #6d1313; +$color-font-warning: #601700; +$color-font-success: #08422f; +$size-border-radius-large: 30rem; +$size-font-small: 0.75rem; +$size-font-medium: 1rem; +$size-font-large: 1.5rem; +$size-font-xl: 2.25rem; +$size-padding-small: 0.5rem; +$size-padding-medium: 1rem; +$size-padding-large: 1rem; +$size-padding-xl: 1rem; + +$design-system-tokens: ( + 'color': ( + 'background': ( + 'primary': $color-background-primary, + 'secondary': $color-background-secondary, + 'tertiary': $color-background-tertiary, + 'danger': $color-background-danger, + 'warning': $color-background-warning, + 'success': $color-background-success, + 'info': $color-background-info, + 'disabled': $color-background-disabled + ), + 'border': ( + 'primary': $color-border-primary, + 'secondary': ( + + ), + 'tertiary': ( + + ) + ), + 'brand': ( + 'primary': $color-brand-primary, + 'secondary': $color-brand-secondary + ), + 'core': ( + 'green': ( + '0': $color-core-green-0, + '100': $color-core-green-100, + '200': $color-core-green-200, + '300': $color-core-green-300, + '400': $color-core-green-400, + '500': $color-core-green-500, + '600': $color-core-green-600, + '700': $color-core-green-700, + '800': $color-core-green-800, + '900': $color-core-green-900, + '1000': $color-core-green-1000, + '1100': $color-core-green-1100 + ), + 'teal': ( + '0': $color-core-teal-0, + '100': $color-core-teal-100, + '200': $color-core-teal-200, + '300': $color-core-teal-300, + '400': $color-core-teal-400, + '500': $color-core-teal-500, + '600': $color-core-teal-600, + '700': $color-core-teal-700, + '800': $color-core-teal-800, + '900': $color-core-teal-900, + '1000': $color-core-teal-1000, + '1100': $color-core-teal-1100 + ), + 'aqua': ( + '0': $color-core-aqua-0, + '100': $color-core-aqua-100, + '200': $color-core-aqua-200, + '300': $color-core-aqua-300, + '400': $color-core-aqua-400, + '500': $color-core-aqua-500, + '600': $color-core-aqua-600, + '700': $color-core-aqua-700, + '800': $color-core-aqua-800, + '900': $color-core-aqua-900, + '1000': $color-core-aqua-1000, + '1100': $color-core-aqua-1100 + ), + 'blue': ( + '0': $color-core-blue-0, + '100': $color-core-blue-100, + '200': $color-core-blue-200, + '300': $color-core-blue-300, + '400': $color-core-blue-400, + '500': $color-core-blue-500, + '600': $color-core-blue-600, + '700': $color-core-blue-700, + '800': $color-core-blue-800, + '900': $color-core-blue-900, + '1000': $color-core-blue-1000, + '1100': $color-core-blue-1100 + ), + 'purple': ( + '0': $color-core-purple-0, + '100': $color-core-purple-100, + '200': $color-core-purple-200, + '300': $color-core-purple-300, + '400': $color-core-purple-400, + '500': $color-core-purple-500, + '600': $color-core-purple-600, + '700': $color-core-purple-700, + '800': $color-core-purple-800, + '900': $color-core-purple-900, + '1000': $color-core-purple-1000, + '1100': $color-core-purple-1100 + ), + 'magenta': ( + '0': $color-core-magenta-0, + '100': $color-core-magenta-100, + '200': $color-core-magenta-200, + '300': $color-core-magenta-300, + '400': $color-core-magenta-400, + '500': $color-core-magenta-500, + '600': $color-core-magenta-600, + '700': $color-core-magenta-700, + '800': $color-core-magenta-800, + '900': $color-core-magenta-900, + '1000': $color-core-magenta-1000, + '1100': $color-core-magenta-1100 + ), + 'pink': ( + '0': $color-core-pink-0, + '100': $color-core-pink-100, + '200': $color-core-pink-200, + '300': $color-core-pink-300, + '400': $color-core-pink-400, + '500': $color-core-pink-500, + '600': $color-core-pink-600, + '700': $color-core-pink-700, + '800': $color-core-pink-800, + '900': $color-core-pink-900, + '1000': $color-core-pink-1000, + '1100': $color-core-pink-1100 + ), + 'red': ( + '0': $color-core-red-0, + '100': $color-core-red-100, + '200': $color-core-red-200, + '300': $color-core-red-300, + '400': $color-core-red-400, + '500': $color-core-red-500, + '600': $color-core-red-600, + '700': $color-core-red-700, + '800': $color-core-red-800, + '900': $color-core-red-900, + '1000': $color-core-red-1000, + '1100': $color-core-red-1100 + ), + 'orange': ( + '0': $color-core-orange-0, + '100': $color-core-orange-100, + '200': $color-core-orange-200, + '300': $color-core-orange-300, + '400': $color-core-orange-400, + '500': $color-core-orange-500, + '600': $color-core-orange-600, + '700': $color-core-orange-700, + '800': $color-core-orange-800, + '900': $color-core-orange-900, + '1000': $color-core-orange-1000, + '1100': $color-core-orange-1100 + ), + 'neutral': ( + '0': $color-core-neutral-0, + '100': $color-core-neutral-100, + '200': $color-core-neutral-200, + '300': $color-core-neutral-300, + '400': $color-core-neutral-400, + '500': $color-core-neutral-500, + '600': $color-core-neutral-600, + '700': $color-core-neutral-700, + '800': $color-core-neutral-800, + '900': $color-core-neutral-900, + '1000': $color-core-neutral-1000, + '1100': $color-core-neutral-1100 + ), + 'yellow': ( + '0': $color-core-yellow-0, + '100': $color-core-yellow-100, + '200': $color-core-yellow-200, + '300': $color-core-yellow-300, + '400': $color-core-yellow-400, + '500': $color-core-yellow-500, + '600': $color-core-yellow-600, + '700': $color-core-yellow-700, + '800': $color-core-yellow-800, + '900': $color-core-yellow-900, + '1000': $color-core-yellow-1000, + '1100': $color-core-yellow-1100 + ) + ), + 'font': ( + 'primary': $color-font-primary, + 'secondary': $color-font-secondary, + 'tertiary': $color-font-tertiary, + 'interactive': ( + '_': $color-font-interactive, + 'hover': $color-font-interactive-hover, + 'active': $color-font-interactive-active, + 'disabled': $color-font-interactive-disabled + ), + 'danger': $color-font-danger, + 'warning': $color-font-warning, + 'success': $color-font-success + ) + ), + 'size': ( + 'border': ( + 'radius': ( + 'large': $size-border-radius-large + ) + ), + 'font': ( + 'small': $size-font-small, + 'medium': $size-font-medium, + 'large': $size-font-large, + 'xl': $size-font-xl + ), + 'padding': ( + 'small': $size-padding-small, + 'medium': $size-padding-medium, + 'large': $size-padding-large, + 'xl': $size-padding-xl + ) + ) +); + +" +`; + exports[`integration scss scss/map-flat should match snapshot 1`] = ` " /** diff --git a/__integration__/scss.test.js b/__integration__/scss.test.js index 6e4f71977..941993dee 100644 --- a/__integration__/scss.test.js +++ b/__integration__/scss.test.js @@ -55,6 +55,13 @@ describe(`integration`, () => { options: { outputReferences: true } + },{ + destination: `map-deep-not-themeable.scss`, + format: `scss/map-deep`, + mapName: 'design-system-tokens', + options: { + themeable: false + } }] } } @@ -139,6 +146,20 @@ describe(`integration`, () => { }); }); + describe(`without themeable`, () => { + const output = fs.readFileSync(`${buildPath}map-deep-not-themeable.scss`, { encoding: 'UTF-8' }); + it(`should have a valid scss syntax`, () => { + const result = scss.renderSync({ + data: output, + }); + expect(result.css).toBeDefined(); + }); + + it(`should match snapshot`, () => { + expect(output).toMatchSnapshot(); + }); + }); + }); }); }); diff --git a/docs/formats.md b/docs/formats.md index 11c98de2f..a59f41ba2 100644 --- a/docs/formats.md +++ b/docs/formats.md @@ -767,7 +767,29 @@ $tokens: ( Creates a SCSS file with a deep map based on the style dictionary. -Name the map by adding a 'mapName' attribute on the file object in your config. + + + + + + + + + + + + + + + + + + +
ParamTypeDefaultDescription
optionsObject
[options.mapName]Stringtokens

Name the Sass map

+
[options.showFileHeader]Booleantrue

Whether or not to include a comment that has the build date

+
[options.themeable]Booleantrue

Whether or not to add the `!default` flag on Sass variables by default. This may be overridden by setting a `themeable` attribute in a token's definition.

+
[options.outputReferences]Booleanfalse

Whether or not to keep references (a -> b -> c) in the output.

+
**Example** ```scss diff --git a/lib/common/formatHelpers/createPropertyFormatter.js b/lib/common/formatHelpers/createPropertyFormatter.js index b9a9916ba..3dd1d8af6 100644 --- a/lib/common/formatHelpers/createPropertyFormatter.js +++ b/lib/common/formatHelpers/createPropertyFormatter.js @@ -45,10 +45,10 @@ const defaultFormatting = { * @param {Dictionary} options.dictionary - The dictionary object sent to the formatter function * @param {String} options.format - Available formats are: 'css', 'sass', 'less', and 'stylus'. If you want to customize the format and can't use one of those predefined formats, use the `formatting` option * @param {Object} options.formatting - Custom formatting properties that define parts of a declaration line in code. The configurable strings are: prefix, indentation, separator, suffix, and commentStyle. Those are used to generate a line like this: `${indentation}${prefix}${prop.name}${separator} ${prop.value}${suffix}` - * @param {Boolean} options.themeable_default [false] - Whether tokens should default to being themeable. + * @param {Boolean} options.themeable [false] - Whether tokens should default to being themeable. * @returns {Function} */ -function createPropertyFormatter({ outputReferences, dictionary, format, formatting = {}, themeable_default = false }) { +function createPropertyFormatter({ outputReferences, dictionary, format, formatting = {}, themeable = false }) { let {prefix, commentStyle, indentation, separator, suffix} = Object.assign({}, defaultFormatting, formatting); switch(format) { @@ -118,8 +118,8 @@ function createPropertyFormatter({ outputReferences, dictionary, format, formatt to_ret_prop += prop.attributes.category === 'asset' ? `"${value}"` : value; - const themeable = typeof prop.themeable === 'boolean' ? prop.themeable : themeable_default; - if (format === 'sass' && themeable) { + const themeable_prop = typeof prop.themeable === 'boolean' ? prop.themeable : themeable; + if (format === 'sass' && themeable_prop) { to_ret_prop += ' !default'; } diff --git a/lib/common/formatHelpers/formattedVariables.js b/lib/common/formatHelpers/formattedVariables.js index f685cb2f5..a6b18ee1a 100644 --- a/lib/common/formatHelpers/formattedVariables.js +++ b/lib/common/formatHelpers/formattedVariables.js @@ -27,7 +27,7 @@ const defaultFormatting = { * @param {Object} options.dictionary - The dictionary object that gets passed to the formatter method. * @param {Boolean} options.outputReferences - Whether or not to output references * @param {Object} options.formatting - Custom formatting properties that define parts of a declaration line in code. This will get passed to `formatHelpers.createPropertyFormatter` and used for the `lineSeparator` between lines of code. - * @param {Boolean} options.themeable_default [false] - Whether tokens should default to being themeable. + * @param {Boolean} options.themeable [false] - Whether tokens should default to being themeable. * @returns {String} * @example * ```js @@ -39,7 +39,7 @@ const defaultFormatting = { * }); * ``` */ -function formattedVariables({ format, dictionary, outputReferences = false, formatting = {}, themeable_default = false}) { +function formattedVariables({ format, dictionary, outputReferences = false, formatting = {}, themeable = false}) { let {allTokens} = dictionary; let {lineSeparator} = Object.assign({}, defaultFormatting, formatting); @@ -57,7 +57,7 @@ function formattedVariables({ format, dictionary, outputReferences = false, form } return allTokens - .map(createPropertyFormatter({ outputReferences, dictionary, format, formatting, themeable_default })) + .map(createPropertyFormatter({ outputReferences, dictionary, format, formatting, themeable })) .filter(function(strVal) { return !!strVal }) .join(lineSeparator); } diff --git a/lib/common/formats.js b/lib/common/formats.js index 4c38b423a..46791d8a9 100644 --- a/lib/common/formats.js +++ b/lib/common/formats.js @@ -86,6 +86,7 @@ module.exports = { * @kind member * @param {Object} options * @param {Boolean} [options.outputReferences=false] - Whether or not to keep [references](/#/formats?id=references-in-output-files) (a -> b -> c) in the output. + * @param {Boolean} [options.themeable=true] - Whether or not tokens should default to being themeable, if not otherwise specified per token. * @example * ```scss * $color-background-base: #f0f0f0 !default; @@ -104,9 +105,10 @@ module.exports = { 'scss/map-deep': function({dictionary, options, file}) { const mapTemplate = _template(fs.readFileSync(__dirname + '/templates/scss/map-deep.template')); - const { outputReferences } = options; + // Default the "themeable" option to true for backward compatibility. + const { outputReferences, themeable = true } = options; return fileHeader({ file, commentStyle: 'long' }) + - formattedVariables({ format: 'sass', dictionary, outputReferences, themeable_default: true }) + formattedVariables({ format: 'sass', dictionary, outputReferences, themeable }) + '\n' + mapTemplate({dictionary, file}); }, From 19c60be8d7912eb965ee8a1acac5786b8cf04560 Mon Sep 17 00:00:00 2001 From: Lee Moody Date: Tue, 26 Oct 2021 12:58:19 +0100 Subject: [PATCH 3/5] fix: restore preview `scss/map-deep` output newlines - remove trailing new line - add leading new line --- __integration__/__snapshots__/scss.test.js.snap | 12 ++++++------ __tests__/formats/__snapshots__/all.test.js.snap | 8 ++++---- .../formats/__snapshots__/scssMaps.test.js.snap | 4 ++-- lib/common/formats.js | 3 ++- lib/common/templates/scss/map-deep.template | 2 +- 5 files changed, 15 insertions(+), 14 deletions(-) diff --git a/__integration__/__snapshots__/scss.test.js.snap b/__integration__/__snapshots__/scss.test.js.snap index b962587e8..c920344a1 100644 --- a/__integration__/__snapshots__/scss.test.js.snap +++ b/__integration__/__snapshots__/scss.test.js.snap @@ -1,7 +1,8 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`integration scss scss/map-deep should match snapshot 1`] = ` -"/** +" +/** * Do not edit directly * Generated on Sat, 01 Jan 2000 00:00:00 GMT */ @@ -385,12 +386,12 @@ $design-system-tokens: ( ) ) ); - " `; exports[`integration scss scss/map-deep with outputReferences should match snapshot 1`] = ` -"/** +" +/** * Do not edit directly * Generated on Sat, 01 Jan 2000 00:00:00 GMT */ @@ -774,12 +775,12 @@ $design-system-tokens: ( ) ) ); - " `; exports[`integration scss scss/map-deep without themeable should match snapshot 1`] = ` -"/** +" +/** * Do not edit directly * Generated on Sat, 01 Jan 2000 00:00:00 GMT */ @@ -1163,7 +1164,6 @@ $design-system-tokens: ( ) ) ); - " `; diff --git a/__tests__/formats/__snapshots__/all.test.js.snap b/__tests__/formats/__snapshots__/all.test.js.snap index bd18eabdf..42cc329bd 100644 --- a/__tests__/formats/__snapshots__/all.test.js.snap +++ b/__tests__/formats/__snapshots__/all.test.js.snap @@ -616,7 +616,8 @@ exports[`formats all should match less/variables snapshot 1`] = ` `; exports[`formats all should match sass/map-deep snapshot 1`] = ` -"/** +" +/** * Do not edit directly * Generated on Sat, 01 Jan 2000 00:00:00 GMT */ @@ -628,7 +629,6 @@ $tokens: ( 'red': $color_red ) ); - " `; @@ -655,7 +655,8 @@ exports[`formats all should match scss/icons snapshot 1`] = ` `; exports[`formats all should match scss/map-deep snapshot 1`] = ` -"/** +" +/** * Do not edit directly * Generated on Sat, 01 Jan 2000 00:00:00 GMT */ @@ -667,7 +668,6 @@ $tokens: ( 'red': $color_red ) ); - " `; diff --git a/__tests__/formats/__snapshots__/scssMaps.test.js.snap b/__tests__/formats/__snapshots__/scssMaps.test.js.snap index dac0c0362..8a24215f5 100644 --- a/__tests__/formats/__snapshots__/scssMaps.test.js.snap +++ b/__tests__/formats/__snapshots__/scssMaps.test.js.snap @@ -1,7 +1,8 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`formats scss/map-deep scss/map-deep snapshot 1`] = ` -"/** +" +/** * Do not edit directly * Generated on Sat, 01 Jan 2000 00:00:00 GMT */ @@ -31,7 +32,6 @@ $tokens: ( ) ) ); - " `; diff --git a/lib/common/formats.js b/lib/common/formats.js index 46791d8a9..9d1b73f68 100644 --- a/lib/common/formats.js +++ b/lib/common/formats.js @@ -107,7 +107,8 @@ module.exports = { // Default the "themeable" option to true for backward compatibility. const { outputReferences, themeable = true } = options; - return fileHeader({ file, commentStyle: 'long' }) + + return '\n' + + fileHeader({ file, commentStyle: 'long' }) + formattedVariables({ format: 'sass', dictionary, outputReferences, themeable }) + '\n' + mapTemplate({dictionary, file}); diff --git a/lib/common/templates/scss/map-deep.template b/lib/common/templates/scss/map-deep.template index e07ac7ac1..386c0d5af 100644 --- a/lib/common/templates/scss/map-deep.template +++ b/lib/common/templates/scss/map-deep.template @@ -38,4 +38,4 @@ } return output; } -%> +%> \ No newline at end of file From b288f572e2c2fdb5299ac789ebe2777d806d1706 Mon Sep 17 00:00:00 2001 From: Lee Moody Date: Tue, 26 Oct 2021 13:12:42 +0100 Subject: [PATCH 4/5] feat: add a `themeable` option to the `scss/variables` format Whether or not to add the `!default` flag on Sass variables by default. This may be overridden by setting a `themeable` attribute in a token's definition. Matches the `themeable` option of the `scss/map-deep` format but defaults to `false`, retaining its existing behaviour. --- .../__snapshots__/scss.test.js.snap | 169 ++++++++++++++++++ __integration__/scss.test.js | 23 ++- docs/formats.md | 7 +- lib/common/formats.js | 5 +- 4 files changed, 199 insertions(+), 5 deletions(-) diff --git a/__integration__/__snapshots__/scss.test.js.snap b/__integration__/__snapshots__/scss.test.js.snap index c920344a1..a36409dea 100644 --- a/__integration__/__snapshots__/scss.test.js.snap +++ b/__integration__/__snapshots__/scss.test.js.snap @@ -1693,3 +1693,172 @@ $color-font-interactive-hover: $color-brand-primary; $color-font-interactive: $color-brand-primary; $color-background-disabled: $color-background-tertiary;" `; + +exports[`integration scss scss/variables with themeable should match snapshot 1`] = ` +" +// Do not edit directly +// Generated on Sat, 01 Jan 2000 00:00:00 GMT + +$color-background-primary: #ffffff !default; +$color-background-secondary: #f3f4f4 !default; +$color-background-tertiary: #dee1e1 !default; +$color-background-danger: #ffeae9 !default; +$color-background-warning: #ffede3 !default; +$color-background-success: #ebf9eb !default; +$color-background-info: #e9f8ff !default; +$color-background-disabled: #dee1e1 !default; +$color-border-primary: #c8cccc !default; +$color-brand-primary: #0b8599 !default; +$color-brand-secondary: #6f5ed3 !default; +$color-core-green-0: #ebf9eb !default; +$color-core-green-100: #d7f4d7 !default; +$color-core-green-200: #c2f2bd !default; +$color-core-green-300: #98e58e !default; +$color-core-green-400: #75dd66 !default; +$color-core-green-500: #59cb59 !default; +$color-core-green-600: #2bb656 !default; +$color-core-green-700: #0ca750 !default; +$color-core-green-800: #008b46 !default; +$color-core-green-900: #006b40 !default; +$color-core-green-1000: #08422f !default; +$color-core-green-1100: #002b20 !default; +$color-core-teal-0: #e5f9f5 !default; +$color-core-teal-100: #cdf7ef !default; +$color-core-teal-200: #b3f2e6 !default; +$color-core-teal-300: #7dead5 !default; +$color-core-teal-400: #24e0c5 !default; +$color-core-teal-500: #08c4b2 !default; +$color-core-teal-600: #00a99c !default; +$color-core-teal-700: #0b968f !default; +$color-core-teal-800: #067c7c !default; +$color-core-teal-900: #026661 !default; +$color-core-teal-1000: #083f3f !default; +$color-core-teal-1100: #002528 !default; +$color-core-aqua-0: #d9fcfb !default; +$color-core-aqua-100: #c5f9f9 !default; +$color-core-aqua-200: #a5f2f2 !default; +$color-core-aqua-300: #76e5e2 !default; +$color-core-aqua-400: #33d6e2 !default; +$color-core-aqua-500: #17b8ce !default; +$color-core-aqua-600: #0797ae !default; +$color-core-aqua-700: #0b8599 !default; +$color-core-aqua-800: #0f6e84 !default; +$color-core-aqua-900: #035e73 !default; +$color-core-aqua-1000: #083d4f !default; +$color-core-aqua-1100: #002838 !default; +$color-core-blue-0: #e9f8ff !default; +$color-core-blue-100: #dcf2ff !default; +$color-core-blue-200: #c7e4f9 !default; +$color-core-blue-300: #a1d2f8 !default; +$color-core-blue-400: #56adf5 !default; +$color-core-blue-500: #3896e3 !default; +$color-core-blue-600: #2b87d3 !default; +$color-core-blue-700: #2079c3 !default; +$color-core-blue-800: #116daa !default; +$color-core-blue-900: #0c5689 !default; +$color-core-blue-1000: #0a3960 !default; +$color-core-blue-1100: #002138 !default; +$color-core-purple-0: #f2f2f9 !default; +$color-core-purple-100: #eaeaf9 !default; +$color-core-purple-200: #d8d7f9 !default; +$color-core-purple-300: #c1c1f7 !default; +$color-core-purple-400: #a193f2 !default; +$color-core-purple-500: #9180f4 !default; +$color-core-purple-600: #816fea !default; +$color-core-purple-700: #6f5ed3 !default; +$color-core-purple-800: #5e4eba !default; +$color-core-purple-900: #483a9c !default; +$color-core-purple-1000: #2d246b !default; +$color-core-purple-1100: #1d1d38 !default; +$color-core-magenta-0: #fef0ff !default; +$color-core-magenta-100: #f9e3fc !default; +$color-core-magenta-200: #f4c4f7 !default; +$color-core-magenta-300: #edadf2 !default; +$color-core-magenta-400: #f282f5 !default; +$color-core-magenta-500: #db61db !default; +$color-core-magenta-600: #c44eb9 !default; +$color-core-magenta-700: #ac44a8 !default; +$color-core-magenta-800: #8f3896 !default; +$color-core-magenta-900: #6c2277 !default; +$color-core-magenta-1000: #451551 !default; +$color-core-magenta-1100: #29192d !default; +$color-core-pink-0: #ffe9f3 !default; +$color-core-pink-100: #fcdbeb !default; +$color-core-pink-200: #ffb5d5 !default; +$color-core-pink-300: #ff95c1 !default; +$color-core-pink-400: #ff76ae !default; +$color-core-pink-500: #ef588b !default; +$color-core-pink-600: #e0447c !default; +$color-core-pink-700: #ce3665 !default; +$color-core-pink-800: #b22f5b !default; +$color-core-pink-900: #931847 !default; +$color-core-pink-1000: #561231 !default; +$color-core-pink-1100: #2b1721 !default; +$color-core-red-0: #ffeae9 !default; +$color-core-red-100: #ffd5d2 !default; +$color-core-red-200: #ffb8b1 !default; +$color-core-red-300: #ff9c8f !default; +$color-core-red-400: #ff7f6e !default; +$color-core-red-500: #f76054 !default; +$color-core-red-600: #ed4c42 !default; +$color-core-red-700: #db3e3e !default; +$color-core-red-800: #c63434 !default; +$color-core-red-900: #992222 !default; +$color-core-red-1000: #6d1313 !default; +$color-core-red-1100: #2b1111 !default; +$color-core-orange-0: #ffede3 !default; +$color-core-orange-100: #fcdccc !default; +$color-core-orange-200: #ffc6a4 !default; +$color-core-orange-300: #ffb180 !default; +$color-core-orange-400: #ff9c5d !default; +$color-core-orange-500: #fc8943 !default; +$color-core-orange-600: #f57d33 !default; +$color-core-orange-700: #ed7024 !default; +$color-core-orange-800: #ce5511 !default; +$color-core-orange-900: #962c0b !default; +$color-core-orange-1000: #601700 !default; +$color-core-orange-1100: #2d130e !default; +$color-core-neutral-0: #ffffff !default; +$color-core-neutral-100: #f3f4f4 !default; +$color-core-neutral-200: #dee1e1 !default; +$color-core-neutral-300: #c8cccc !default; +$color-core-neutral-400: #b0b6b7 !default; +$color-core-neutral-500: #929a9b !default; +$color-core-neutral-600: #6e797a !default; +$color-core-neutral-700: #515e5f !default; +$color-core-neutral-800: #364141 !default; +$color-core-neutral-900: #273333 !default; +$color-core-neutral-1000: #162020 !default; +$color-core-neutral-1100: #040404 !default; +$color-core-yellow-0: #fff8e2 !default; +$color-core-yellow-100: #fdefcd !default; +$color-core-yellow-200: #ffe99a !default; +$color-core-yellow-300: #ffe16e !default; +$color-core-yellow-400: #ffd943 !default; +$color-core-yellow-500: #ffcd1c !default; +$color-core-yellow-600: #ffbc00 !default; +$color-core-yellow-700: #dd9903 !default; +$color-core-yellow-800: #ba7506 !default; +$color-core-yellow-900: #944c0c !default; +$color-core-yellow-1000: #542a00 !default; +$color-core-yellow-1100: #2d1a05 !default; +$color-font-primary: #040404 !default; +$color-font-secondary: #273333 !default; +$color-font-tertiary: #364141 !default; +$color-font-interactive: #0b8599 !default; +$color-font-interactive-hover: #0b8599 !default; +$color-font-interactive-active: #6f5ed3 !default; +$color-font-interactive-disabled: #364141 !default; +$color-font-danger: #6d1313 !default; +$color-font-warning: #601700 !default; +$color-font-success: #08422f !default; +$size-border-radius-large: 30rem !default; +$size-font-small: 0.75rem !default; +$size-font-medium: 1rem !default; +$size-font-large: 1.5rem !default; +$size-font-xl: 2.25rem !default; +$size-padding-small: 0.5rem !default; +$size-padding-medium: 1rem !default; +$size-padding-large: 1rem !default; +$size-padding-xl: 1rem !default;" +`; diff --git a/__integration__/scss.test.js b/__integration__/scss.test.js index 941993dee..f52faecf7 100644 --- a/__integration__/scss.test.js +++ b/__integration__/scss.test.js @@ -27,7 +27,14 @@ describe(`integration`, () => { files: [{ destination: `variables.scss`, format: `scss/variables` - },{ + }, + { + destination: `variables-themeable.scss`, + format: `scss/variables`, + options: { + themeable: true + } + }, { destination: `variablesWithReferences.scss`, format: `scss/variables`, options: { @@ -81,6 +88,20 @@ describe(`integration`, () => { expect(output).toMatchSnapshot(); }); + describe(`with themeable`, () => { + const output = fs.readFileSync(`${buildPath}variables-themeable.scss`, {encoding:'UTF-8'}); + it(`should have a valid scss syntax`, () => { + const result = scss.renderSync({ + data: output, + }); + expect(result.css).toBeDefined(); + }); + + it(`should match snapshot`, () => { + expect(output).toMatchSnapshot(); + }); + }); + describe(`with outputReferences`, () => { const output = fs.readFileSync(`${buildPath}variablesWithReferences.scss`, {encoding:'UTF-8'}); it(`should have a valid scss syntax`, () => { diff --git a/docs/formats.md b/docs/formats.md index a59f41ba2..63b2de2e0 100644 --- a/docs/formats.md +++ b/docs/formats.md @@ -767,6 +767,8 @@ $tokens: ( Creates a SCSS file with a deep map based on the style dictionary. +Note that `options.themeable` defaults to `true` by default, unlike the [scss/variables](scss/variables) format, for backwards compatibility. + @@ -813,8 +815,6 @@ $tokens: { Creates a SCSS file with variable definitions based on the style dictionary. -Add `!default` to any variable by setting a `themeable: true` attribute in the token's definition. -
@@ -826,6 +826,9 @@ Add `!default` to any variable by setting a `themeable: true` attribute in the t + +
optionsObject
[options.showFileHeader]Booleantrue

Whether or not to include a comment that has the build date

+
[options.themeable]Booleanfalse

Whether or not to add the `!default` flag on Sass variables by default. This may be overridden by setting a `themeable` attribute in a token's definition.

[options.outputReferences]Booleanfalse

Whether or not to keep references (a -> b -> c) in the output.

diff --git a/lib/common/formats.js b/lib/common/formats.js index 9d1b73f68..761e8b7de 100644 --- a/lib/common/formats.js +++ b/lib/common/formats.js @@ -130,6 +130,7 @@ module.exports = { * @param {Object} options * @param {Boolean} [options.showFileHeader=true] - Whether or not to include a comment that has the build date * @param {Boolean} [options.outputReferences=false] - Whether or not to keep [references](/#/formats?id=references-in-output-files) (a -> b -> c) in the output. + * @param {Boolean} [options.themeable=false] - Whether or not tokens should default to being themeable, if not otherwise specified per token. * @example * ```scss * $color-background-base: #f0f0f0; @@ -137,9 +138,9 @@ module.exports = { * ``` */ 'scss/variables': function({dictionary, options, file}) { - const { outputReferences } = options; + const { outputReferences, themeable = false } = options; return fileHeader({file, commentStyle: 'short'}) + - formattedVariables({format: 'sass', dictionary, outputReferences}); + formattedVariables({format: 'sass', dictionary, outputReferences, themeable}); }, /** From 29f18aadfe30d77eb6f9f9cf4aed4b12e50ad9b1 Mon Sep 17 00:00:00 2001 From: Lee Moody Date: Tue, 26 Oct 2021 13:16:18 +0100 Subject: [PATCH 5/5] chore: rename files in integration test for consistency seems kebab case is used more than camel case --- __integration__/scss.test.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/__integration__/scss.test.js b/__integration__/scss.test.js index f52faecf7..4519ec9ab 100644 --- a/__integration__/scss.test.js +++ b/__integration__/scss.test.js @@ -35,13 +35,13 @@ describe(`integration`, () => { themeable: true } }, { - destination: `variablesWithReferences.scss`, + destination: `variables-with-references.scss`, format: `scss/variables`, options: { outputReferences: true } },{ - destination: `filteredVariablesWithReferences.scss`, + destination: `filtered-variables-with-references.scss`, format: `scss/variables`, filter: (token) => token.path[1] === 'background', options: { @@ -103,7 +103,7 @@ describe(`integration`, () => { }); describe(`with outputReferences`, () => { - const output = fs.readFileSync(`${buildPath}variablesWithReferences.scss`, {encoding:'UTF-8'}); + const output = fs.readFileSync(`${buildPath}variables-with-references.scss`, {encoding:'UTF-8'}); it(`should have a valid scss syntax`, () => { const result = scss.renderSync({ data: output, @@ -117,7 +117,7 @@ describe(`integration`, () => { }); describe(`with filter and output references`, () => { - const output = fs.readFileSync(`${buildPath}filteredVariablesWithReferences.scss`, {encoding:'UTF-8'}); + const output = fs.readFileSync(`${buildPath}filtered-variables-with-references.scss`, {encoding:'UTF-8'}); it(`should match snapshot`, () => { expect(output).toMatchSnapshot(); });