style-dictionary 3.7.0 → 3.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/examples/advanced/assets-base64-embed/package.json +1 -1
  2. package/examples/advanced/auto-rebuild-watcher/package.json +1 -1
  3. package/examples/advanced/component-cti/package.json +1 -1
  4. package/examples/advanced/create-react-app/package.json +1 -1
  5. package/examples/advanced/create-react-native-app/package.json +1 -1
  6. package/examples/advanced/custom-file-header/package.json +1 -1
  7. package/examples/advanced/custom-filters/package.json +1 -1
  8. package/examples/advanced/custom-formats-with-templates/package.json +1 -1
  9. package/examples/advanced/custom-parser/package.json +1 -1
  10. package/examples/advanced/custom-transforms/package.json +1 -1
  11. package/examples/advanced/font-face-rules/README.md +71 -0
  12. package/examples/advanced/font-face-rules/package.json +13 -0
  13. package/examples/advanced/font-face-rules/sd.config.js +102 -0
  14. package/examples/advanced/font-face-rules/tokens.json +28 -0
  15. package/examples/advanced/format-helpers/package.json +1 -1
  16. package/examples/advanced/matching-build-files/package.json +1 -1
  17. package/examples/advanced/multi-brand-multi-platform/package.json +1 -1
  18. package/examples/advanced/node-modules-as-config-and-properties/package.json +1 -1
  19. package/examples/advanced/npm-module/package.json +1 -1
  20. package/examples/advanced/referencing_aliasing/package.json +1 -1
  21. package/examples/advanced/s3/package.json +1 -1
  22. package/examples/advanced/tokens-deprecation/package.json +1 -1
  23. package/examples/advanced/transitive-transforms/package.json +1 -1
  24. package/examples/advanced/transitive-transforms/tokens/color/font.json5 +2 -1
  25. package/examples/advanced/variables-in-outputs/package.json +1 -1
  26. package/examples/advanced/yaml-tokens/package.json +1 -1
  27. package/lib/common/formatHelpers/formattedVariables.js +5 -1
  28. package/lib/common/formatHelpers/getTypeScriptType.js +2 -2
  29. package/lib/common/formatHelpers/sortByReference.js +7 -0
  30. package/lib/common/transforms.js +2 -2
  31. package/lib/utils/references/getReferences.js +6 -5
  32. package/lib/utils/resolveObject.js +15 -7
  33. package/package.json +1 -1
@@ -11,6 +11,6 @@
11
11
  "author": "",
12
12
  "license": "Apache-2.0",
13
13
  "devDependencies": {
14
- "style-dictionary": "3.7.0"
14
+ "style-dictionary": "3.7.1"
15
15
  }
16
16
  }
@@ -17,6 +17,6 @@
17
17
  "license": "Apache-2.0",
18
18
  "devDependencies": {
19
19
  "chokidar-cli": "^1.2.0",
20
- "style-dictionary": "3.7.0"
20
+ "style-dictionary": "3.7.1"
21
21
  }
22
22
  }
@@ -15,6 +15,6 @@
15
15
  "author": "",
16
16
  "license": "Apache-2.0",
17
17
  "devDependencies": {
18
- "style-dictionary": "3.7.0"
18
+ "style-dictionary": "3.7.1"
19
19
  }
20
20
  }
@@ -10,7 +10,7 @@
10
10
  "styled-components": "^5.3.0"
11
11
  },
12
12
  "devDependencies": {
13
- "style-dictionary": "3.7.0"
13
+ "style-dictionary": "3.7.1"
14
14
  },
15
15
  "resolutions": {
16
16
  "immer": "8.0.1",
@@ -27,7 +27,7 @@
27
27
  "babel-jest": "~25.2.6",
28
28
  "jest": "~25.2.6",
29
29
  "react-test-renderer": "~16.13.1",
30
- "style-dictionary": "3.7.0"
30
+ "style-dictionary": "3.7.1"
31
31
  },
32
32
  "jest": {
33
33
  "preset": "react-native"
@@ -10,6 +10,6 @@
10
10
  "author": "",
11
11
  "license": "ISC",
12
12
  "devDependencies": {
13
- "style-dictionary": "3.7.0"
13
+ "style-dictionary": "3.7.1"
14
14
  }
15
15
  }
@@ -15,6 +15,6 @@
15
15
  "author": "",
16
16
  "license": "Apache-2.0",
17
17
  "devDependencies": {
18
- "style-dictionary": "3.7.0"
18
+ "style-dictionary": "3.7.1"
19
19
  }
20
20
  }
@@ -18,6 +18,6 @@
18
18
  "handlebars": "^4.7.7",
19
19
  "lodash": "^4.17.21",
20
20
  "pug": "^3.0.2",
21
- "style-dictionary": "3.7.0"
21
+ "style-dictionary": "3.7.1"
22
22
  }
23
23
  }
@@ -9,6 +9,6 @@
9
9
  "author": "",
10
10
  "license": "Apache-2.0",
11
11
  "devDependencies": {
12
- "style-dictionary": "3.7.0"
12
+ "style-dictionary": "3.7.1"
13
13
  }
14
14
  }
@@ -15,6 +15,6 @@
15
15
  "author": "",
16
16
  "license": "Apache-2.0",
17
17
  "devDependencies": {
18
- "style-dictionary": "3.7.0"
18
+ "style-dictionary": "3.7.1"
19
19
  }
20
20
  }
@@ -0,0 +1,71 @@
1
+ ## Generating @font-face rules
2
+
3
+ To generate `@font-face` rules, we will need a few moving parts (described below). The final output will look like:
4
+
5
+ ```css
6
+ /** build/css/fonts.css */
7
+ @font-face {
8
+ font-family: "Roboto";
9
+ font-style: normal;
10
+ font-weight: 400;
11
+ src: url("../fonts/Roboto.woff2") format("woff2"),
12
+ url("../fonts/Roboto.woff") format("woff");
13
+ font-display: fallback;
14
+ }
15
+ ```
16
+
17
+ ```scss
18
+ // build/scss/_fonts.scss
19
+ @font-face {
20
+ font-family: "Roboto";
21
+ font-style: normal;
22
+ font-weight: 400;
23
+ src: url("#{$font-path}/fonts/Roboto.woff2") format("woff2"),
24
+ url("#{$font-path}/fonts/Roboto.woff") format("woff");
25
+ font-display: fallback;
26
+ }
27
+ ```
28
+
29
+ #### Running the example
30
+
31
+ Set up the required dependencies by running the command `npm install` in your local CLI environment (if you prefer to use _yarn_, update the commands accordingly).
32
+
33
+ At this point, if you want to build the tokens you can run `npm run build`. This command will generate the files in the `build` folder.
34
+
35
+ Note, running this example will generate a "While building fonts.css, token collisions were found; output may be unexpected." warning. The warning is expected and can be ignored.
36
+
37
+ #### How does it work
38
+
39
+ - Each font is defined using a specific structure:
40
+ ```json
41
+ {
42
+ "asset": {
43
+ "font": {
44
+ "<family>": {
45
+ "<weight>": {
46
+ "<style>": {
47
+ "value": "<path>",
48
+ "formats": ["<list of formats, e.g. woff2, woff>"]
49
+ }
50
+ }
51
+ }
52
+ }
53
+ }
54
+ }
55
+ ```
56
+ - A custom _transform_ will promote the family name, weight and style to their own named attributes on the token object.
57
+ - A custom _format_ will generate the `@font-face` rules.
58
+ - A _platform_ ties it all together.
59
+
60
+ #### What to look at
61
+
62
+ Open `tokens.json`:
63
+
64
+ - To distinguish font-face tokens from other font tokens, the "**asset**" category is used.
65
+ - Each font-face token is structured so that the font's _family name_, _weight_ (400, 700, etc.), and _style_ (normal or italics) can be determined at runtime.
66
+
67
+ Compare this example's `tokens.json` to the generated files `css/fonts.css`, and `scss/_fonts.scss`.
68
+
69
+ Next up, open `sd.config.js` to see how the "css-font-face" and "scss-font-face" platforms are configured. Note the `transforms`, `format`, `filter`, and the custom `options.fontPathPrefix` properties.
70
+
71
+ Lastly, in the same file, check out the code for the `attribute/font` transform, and `font-face` format.
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "font-face-rules",
3
+ "version": "1.0.0",
4
+ "description": "Example showing one way to generate @font-face rules",
5
+ "main": "sd.config.js",
6
+ "scripts": {
7
+ "build": "style-dictionary build --config ./sd.config.js"
8
+ },
9
+ "license": "Apache-2.0",
10
+ "devDependencies": {
11
+ "style-dictionary": "3.7.1"
12
+ }
13
+ }
@@ -0,0 +1,102 @@
1
+ const StyleDictionary = require('style-dictionary');
2
+
3
+ // Register an "attribute" transform to codify the font's details
4
+ // as named attributes.
5
+ StyleDictionary.registerTransform({
6
+ name: 'attribute/font',
7
+ type: 'attribute',
8
+ transformer: prop => ({
9
+ category: prop.path[0],
10
+ type: prop.path[1],
11
+ family: prop.path[2],
12
+ weight: prop.path[3],
13
+ style: prop.path[4]
14
+ })
15
+ });
16
+
17
+ // Register a custom format to generate @font-face rules.
18
+ StyleDictionary.registerFormat({
19
+ name: 'font-face',
20
+ formatter: ({ dictionary: { allTokens }, options }) => {
21
+ const fontPathPrefix = options.fontPathPrefix || '../';
22
+
23
+ // https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/src
24
+ const formatsMap = {
25
+ 'woff2': 'woff2',
26
+ 'woff': 'woff',
27
+ 'ttf': 'truetype',
28
+ 'otf': 'opentype',
29
+ 'svg': 'svg',
30
+ 'eot': 'embedded-opentype'
31
+ };
32
+
33
+ return allTokens.reduce((fontList, prop) => {
34
+ const {
35
+ attributes: { family, weight, style },
36
+ formats,
37
+ value: path
38
+ } = prop;
39
+
40
+ const urls = formats
41
+ .map(extension => `url("${fontPathPrefix}${path}.${extension}") format("${formatsMap[extension]}")`);
42
+
43
+ const fontCss = [
44
+ '@font-face {',
45
+ `\n\tfont-family: "${family}";`,
46
+ `\n\tfont-style: ${style};`,
47
+ `\n\tfont-weight: ${weight};`,
48
+ `\n\tsrc: ${urls.join(',\n\t\t\t ')};`,
49
+ '\n\tfont-display: fallback;',
50
+ '\n}\n'
51
+ ].join('');
52
+
53
+ fontList.push(fontCss);
54
+
55
+ return fontList;
56
+ }, []).join('\n');
57
+ }
58
+ });
59
+
60
+ module.exports = {
61
+ source: ['tokens.json'],
62
+ platforms: {
63
+ 'css-font-face': {
64
+ transforms: ['attribute/font'],
65
+ buildPath: 'build/css/',
66
+ files: [
67
+ {
68
+ destination: 'fonts.css',
69
+ format: 'font-face',
70
+ filter: {
71
+ attributes: {
72
+ category: 'asset',
73
+ type: 'font'
74
+ }
75
+ },
76
+ options: {
77
+ fontPathPrefix: '../'
78
+ }
79
+ }
80
+ ]
81
+ },
82
+ 'scss-font-face': {
83
+ transforms: ['attribute/font'],
84
+ buildPath: 'build/scss/',
85
+ files: [
86
+ {
87
+ destination: '_fonts.scss',
88
+ format: 'font-face',
89
+ filter: {
90
+ attributes: {
91
+ category: 'asset',
92
+ type: 'font'
93
+ }
94
+ },
95
+ options: {
96
+ fontPathPrefix: '#{$font-path}/'
97
+ }
98
+ }
99
+ ]
100
+ }
101
+ }
102
+ }
@@ -0,0 +1,28 @@
1
+ {
2
+ "asset": {
3
+ "font": {
4
+ "Roboto": {
5
+ "400": {
6
+ "normal": {
7
+ "value": "fonts/roboto-V20-latin-regular",
8
+ "formats": ["woff2", "woff"]
9
+ },
10
+ "italic": {
11
+ "value": "fonts/roboto-V20-latin-italic",
12
+ "formats": ["woff2", "woff"]
13
+ }
14
+ },
15
+ "700": {
16
+ "normal": {
17
+ "value": "fonts/roboto-V20-latin-700",
18
+ "formats": ["woff2", "woff"]
19
+ },
20
+ "italic": {
21
+ "value": "fonts/roboto-V20-latin-700italic",
22
+ "formats": ["woff2", "woff"]
23
+ }
24
+ }
25
+ }
26
+ }
27
+ }
28
+ }
@@ -10,6 +10,6 @@
10
10
  "author": "",
11
11
  "license": "Apache-2.0",
12
12
  "devDependencies": {
13
- "style-dictionary": "3.7.0"
13
+ "style-dictionary": "3.7.1"
14
14
  }
15
15
  }
@@ -16,6 +16,6 @@
16
16
  "author": "Kelly Harrop <kn.harrop@gmail.com>",
17
17
  "license": "Apache-2.0",
18
18
  "devDependencies": {
19
- "style-dictionary": "3.7.0"
19
+ "style-dictionary": "3.7.1"
20
20
  }
21
21
  }
@@ -15,6 +15,6 @@
15
15
  "author": "",
16
16
  "license": "Apache-2.0",
17
17
  "devDependencies": {
18
- "style-dictionary": "3.7.0"
18
+ "style-dictionary": "3.7.1"
19
19
  }
20
20
  }
@@ -19,7 +19,7 @@
19
19
  },
20
20
  "homepage": "https://github.com/dbanksdesign/style-dictionary-node#readme",
21
21
  "devDependencies": {
22
- "style-dictionary": "3.7.0",
22
+ "style-dictionary": "3.7.1",
23
23
  "tinycolor2": "^1.4.1"
24
24
  }
25
25
  }
@@ -16,6 +16,6 @@
16
16
  "author": "",
17
17
  "license": "Apache-2.0",
18
18
  "devDependencies": {
19
- "style-dictionary": "3.7.0"
19
+ "style-dictionary": "3.7.1"
20
20
  }
21
21
  }
@@ -15,6 +15,6 @@
15
15
  "author": "",
16
16
  "license": "Apache-2.0",
17
17
  "devDependencies": {
18
- "style-dictionary": "3.7.0"
18
+ "style-dictionary": "3.7.1"
19
19
  }
20
20
  }
@@ -15,6 +15,6 @@
15
15
  "devDependencies": {
16
16
  "aws-sdk": "^2.7.21",
17
17
  "fs-extra": "^1.0.0",
18
- "style-dictionary": "3.7.0"
18
+ "style-dictionary": "3.7.1"
19
19
  }
20
20
  }
@@ -16,6 +16,6 @@
16
16
  "license": "Apache-2.0",
17
17
  "devDependencies": {
18
18
  "lodash": "^4.17.11",
19
- "style-dictionary": "3.7.0"
19
+ "style-dictionary": "3.7.1"
20
20
  }
21
21
  }
@@ -11,6 +11,6 @@
11
11
  "license": "ISC",
12
12
  "devDependencies": {
13
13
  "chroma-js": "^2.1.0",
14
- "style-dictionary": "3.7.0"
14
+ "style-dictionary": "3.7.1"
15
15
  }
16
16
  }
@@ -13,7 +13,8 @@
13
13
  },
14
14
  tertiary: {
15
15
  // transitive transforms allow you to modify a modified reference
16
- value: "{color.font.secondary.value}",
16
+ // You can use references with or without `.value`
17
+ value: "{color.font.secondary}",
17
18
  modify: [{
18
19
  // this will brighten the secondary value, which is a brightened version
19
20
  // of primary
@@ -10,6 +10,6 @@
10
10
  "author": "",
11
11
  "license": "MIT",
12
12
  "devDependencies": {
13
- "style-dictionary": "3.7.0"
13
+ "style-dictionary": "3.7.1"
14
14
  }
15
15
  }
@@ -9,7 +9,7 @@
9
9
  "author": "",
10
10
  "license": "Apache-2.0",
11
11
  "devDependencies": {
12
- "style-dictionary": "3.7.0",
12
+ "style-dictionary": "3.7.1",
13
13
  "yaml": "^1.10.0"
14
14
  }
15
15
  }
@@ -34,7 +34,11 @@ const defaultFormatting = {
34
34
  * StyleDictionary.registerFormat({
35
35
  * name: 'myCustomFormat',
36
36
  * formatter: function({ dictionary, options }) {
37
- * return formattedVariables('less', dictionary, options.outputReferences);
37
+ * return formattedVariables({
38
+ * format: 'less',
39
+ * dictionary,
40
+ * outputReferences: options.outputReferences
41
+ * });
38
42
  * }
39
43
  * });
40
44
  * ```
@@ -30,10 +30,10 @@ const { unique } = require('../../utils/es6_');
30
30
  * }).join('\n');
31
31
  * }
32
32
  * });
33
- *
33
+ *```
34
34
  * @param {*} value A value to check the type of.
35
35
  * @return {String} A valid name for a TypeScript type.
36
- * ```
36
+ *
37
37
  */
38
38
  function getTypeScriptType(value) {
39
39
  if (Array.isArray(value)) return getArrayType(value)
@@ -30,6 +30,13 @@
30
30
  const aComesFirst = -1;
31
31
  const bComesFirst = 1;
32
32
 
33
+ // return early if a or b ar undefined
34
+ if (typeof a === 'undefined') {
35
+ return aComesFirst;
36
+ } else if (typeof b === 'undefined') {
37
+ return bComesFirst;
38
+ }
39
+
33
40
  // If token a uses a reference and token b doesn't, b might come before a
34
41
  // read on..
35
42
  if (a.original && dictionary.usesReference(a.original.value)) {
@@ -629,7 +629,7 @@ module.exports = {
629
629
  },
630
630
 
631
631
  /**
632
- * Transforms the value from a REM size on web into a scale-independent pixel (sp) value for font sizes on Android. It WILL scale the number by a factor of 16 (common base font size on web).
632
+ * Transforms the value from a REM size on web into a scale-independent pixel (sp) value for font sizes on Android. It WILL scale the number by a factor of 16 (or the value of 'basePxFontSize' on the platform in your config).
633
633
  *
634
634
  * ```js
635
635
  * // Matches: token.attributes.category === 'size' && token.attributes.type === 'font'
@@ -739,7 +739,7 @@ module.exports = {
739
739
  },
740
740
 
741
741
  /**
742
- * Transforms the value from a REM size on web into a scale-independent pixel (sp) value for font sizes in Compose. It WILL scale the number by a factor of 16 (common base font size on web).
742
+ * Transforms the value from a REM size on web into a scale-independent pixel (sp) value for font sizes in Compose. It WILL scale the number by a factor of 16 (or the value of 'basePxFontSize' on the platform in your config).
743
743
  *
744
744
  * ```kotlin
745
745
  * // Matches: prop.attributes.category === 'size' && prop.attributes.type === 'font'
@@ -28,16 +28,13 @@ const GroupMessages = require('../groupMessages');
28
28
  *
29
29
  * @memberof Dictionary
30
30
  * @param {string} value the value that contains a reference
31
+ * @param {object[]} references array of token's references because a token's value can contain multiple references due to string interpolation
31
32
  * @returns {any}
32
33
  */
33
- function getReferences(value) {
34
+ function getReferences(value, references=[]) {
34
35
  // `this` is the dictionary object passed to formats and actions
35
36
  const self = this;
36
37
  const regex = createReferenceRegex({});
37
- // because a token's value can contain multiple references due to string interpolation
38
- // "{size.padding.base.value} {color.border.primary.value}"
39
- // references is an array of 0 or more references
40
- const references = [];
41
38
 
42
39
  // this will update the references array with the referenced tokens it finds.
43
40
  function findReference(match, variable) {
@@ -70,6 +67,10 @@ function getReferences(value) {
70
67
  if (value.hasOwnProperty(key) && typeof value[key] === 'string') {
71
68
  value[key].replace(regex, findReference);
72
69
  }
70
+ // if it is an object, we go further down the rabbit hole
71
+ if (value.hasOwnProperty(key) && typeof value[key] === 'object') {
72
+ self.getReferences(value[key], references);
73
+ }
73
74
  }
74
75
  }
75
76
 
@@ -85,16 +85,20 @@ function compile_value(value, stack) {
85
85
  // references can be part of the value such as "1px solid {color.border.light}"
86
86
  value.replace(regex, function(match, variable) {
87
87
  variable = variable.trim();
88
- if (options.ignorePaths.indexOf(variable) !== -1) {
89
- return value;
90
- }
91
-
92
- stack.push(variable);
93
88
 
94
89
  // Find what the value is referencing
95
90
  const pathName = getPath(variable, options);
96
91
  const context = getName(current_context, options);
97
92
  const refHasValue = pathName[pathName.length-1] === 'value';
93
+
94
+ if (refHasValue && options.ignorePaths.indexOf(variable) !== -1) {
95
+ return value;
96
+ } else if (!refHasValue && options.ignorePaths.indexOf(`${variable}.value`) !== -1) {
97
+ return value;
98
+ }
99
+
100
+ stack.push(variable);
101
+
98
102
  ref = resolveReference(pathName, updated_object);
99
103
 
100
104
  // If the reference doesn't end in 'value'
@@ -108,7 +112,7 @@ function compile_value(value, stack) {
108
112
  }
109
113
 
110
114
  if (typeof ref !== 'undefined') {
111
- if (typeof ref === 'string') {
115
+ if (typeof ref === 'string' || typeof ref === 'number') {
112
116
  to_ret = value.replace(match, ref);
113
117
 
114
118
  // Recursive, therefore we can compute multi-layer variables like a = b, b = c, eventually a = c
@@ -145,8 +149,12 @@ function compile_value(value, stack) {
145
149
  to_ret = compile_value( to_ret, stack );
146
150
  }
147
151
  }
152
+ // if evaluated value is a number and equal to the reference, we want to keep the type
153
+ if (typeof ref === 'number' && ref.toString() === to_ret) {
154
+ to_ret = ref;
155
+ }
148
156
  } else {
149
- // if evaluated value is not a string, we want to keep the type
157
+ // if evaluated value is not a string or number, we want to keep the type
150
158
  to_ret = ref;
151
159
  }
152
160
  } else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "style-dictionary",
3
- "version": "3.7.0",
3
+ "version": "3.7.1",
4
4
  "description": "Style once, use everywhere. A build system for creating cross-platform styles.",
5
5
  "keywords": [
6
6
  "style dictionary",