style-dictionary 3.8.0 → 3.9.0

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 (25) hide show
  1. package/README.md +25 -0
  2. package/examples/advanced/assets-base64-embed/package.json +1 -1
  3. package/examples/advanced/auto-rebuild-watcher/package.json +1 -1
  4. package/examples/advanced/component-cti/package.json +1 -1
  5. package/examples/advanced/create-react-app/package.json +1 -1
  6. package/examples/advanced/create-react-native-app/package.json +1 -1
  7. package/examples/advanced/custom-file-header/package.json +1 -1
  8. package/examples/advanced/custom-filters/package.json +1 -1
  9. package/examples/advanced/custom-formats-with-templates/package.json +1 -1
  10. package/examples/advanced/custom-parser/package.json +1 -1
  11. package/examples/advanced/custom-transforms/package.json +1 -1
  12. package/examples/advanced/font-face-rules/package.json +1 -1
  13. package/examples/advanced/format-helpers/package.json +1 -1
  14. package/examples/advanced/matching-build-files/package.json +1 -1
  15. package/examples/advanced/multi-brand-multi-platform/package.json +1 -1
  16. package/examples/advanced/node-modules-as-config-and-properties/package.json +1 -1
  17. package/examples/advanced/npm-module/package.json +1 -1
  18. package/examples/advanced/referencing_aliasing/package.json +1 -1
  19. package/examples/advanced/s3/package.json +1 -1
  20. package/examples/advanced/tokens-deprecation/package.json +1 -1
  21. package/examples/advanced/transitive-transforms/package.json +1 -1
  22. package/examples/advanced/variables-in-outputs/package.json +1 -1
  23. package/examples/advanced/yaml-tokens/package.json +1 -1
  24. package/lib/common/formatHelpers/createPropertyFormatter.js +116 -42
  25. package/package.json +2 -2
package/README.md CHANGED
@@ -2,6 +2,10 @@
2
2
  <a href="https://amzn.github.io/style-dictionary/#/version_3">What's new in Style Dictionary 3.0!</a>
3
3
  </pre>
4
4
 
5
+ <pre>
6
+ <a href="https://github.com/amzn/style-dictionary#version-4">What's coming in Style Dictionary 4.0?</a>
7
+ </pre>
8
+
5
9
  <img src="docs/assets/logo.png" alt="Style Dictionary logo and mascot" title="&quot;Pascal&quot;" width="100" align="right" />
6
10
 
7
11
  [![npm version](https://img.shields.io/npm/v/style-dictionary.svg?style=flat-square)](https://badge.fury.io/js/style-dictionary)
@@ -293,6 +297,27 @@ StyleDictionary.buildAllPlatforms();
293
297
 
294
298
  For more information on creating your own transforms and formats, take a look at our [docs](https://amzn.github.io/style-dictionary/).
295
299
 
300
+ ## Version 4
301
+
302
+ In May 2021, we started [an issue / RFC, "What would you like to see in Style-Dictionary 4.0?"](https://github.com/amzn/style-dictionary/issues/643) to gather feedback on what the community would like to see.
303
+ Fortunately, in August 2023, the folks at [Tokens Studio](https://tokens.studio/) contacted us about co-maintaining this project, and leading the v4 release (and beyond)!
304
+
305
+ We have started working on the biggest and most important changes, like migrating to ESM, making the library browser-compatible out of the box, and supporting asynchronicity in Style-Dictionary's various APIs. There will be multiple prereleases to battle-test these changes before a final v4.0 is released.
306
+
307
+ You can follow [this roadmap board](https://github.com/orgs/amzn/projects/4/views/1?layout=board) to keep an eye on the developments for v4.0, we will also keep adding to this board when we encounter changes we'd like to see in v4.0 that would entail a breaking change. Absence of something in this roadmap does not mean we don't see value in it, but rather that it could also be added in a (non-breaking) minor release within v4.x.x.
308
+
309
+ ### From the folks at Tokens Studio
310
+
311
+ Hi everyone! I'm Joren from Tokens Studio, a big fan of this project (see [Style-Dictionary-Play](https://www.style-dictionary-play.dev/), [Token Configurator](https://configurator.tokens.studio/), [sd-transforms](https://github.com/tokens-studio/sd-transforms)) and the main pusher behind leading a 4.0 release of this project, I think it would be good to explain from our perspective why we've made the move to collaborate with Amazon on this.
312
+
313
+ At Tokens Studio, we're a huge fan of Design Tokens and the workflows they enable. We believe exporting design tokens to various platforms is a key ingredient in ensuring that the journey from design to implementation code is smooth.
314
+ In our minds, Style-Dictionary has been the most popular and most flexible library for reaching that goal, and so we want to build on top of that.
315
+ Rather than starting our own spinoff tool, we much prefer bringing Style-Dictionary further, together with its vibrant community of contributors, which is why we reached out to Danny Banks.
316
+
317
+ I think it's important to stress that it is our shared vision to keep Style-Dictionary as an agnostic (so not "Tokens Studio"-specific) and flexible tool. As Tokens Studio, while we are highly incentivized to see this project progress further to strengthen our product journey, we value the open source community highly and want to make sure this library remains the go-to tool for exporting Design Tokens, whether you use Tokens Studio or not.
318
+
319
+ We are very open to feedback and collaboration, feel free to reach out to us in [our Slack](https://tokens-studio.slack.com/archives/C0336AEQ06Q)!
320
+
296
321
  ## Mascot
297
322
 
298
323
  The mascot for Style Dictionary is ["Pascal"](https://github.com/amzn/style-dictionary/issues/97) the chameleon (seen below). You can also find them blending in as the logo throughout the documentation.
@@ -11,6 +11,6 @@
11
11
  "author": "",
12
12
  "license": "Apache-2.0",
13
13
  "devDependencies": {
14
- "style-dictionary": "3.8.0"
14
+ "style-dictionary": "3.9.0"
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.8.0"
20
+ "style-dictionary": "3.9.0"
21
21
  }
22
22
  }
@@ -15,6 +15,6 @@
15
15
  "author": "",
16
16
  "license": "Apache-2.0",
17
17
  "devDependencies": {
18
- "style-dictionary": "3.8.0"
18
+ "style-dictionary": "3.9.0"
19
19
  }
20
20
  }
@@ -10,7 +10,7 @@
10
10
  "styled-components": "^5.3.0"
11
11
  },
12
12
  "devDependencies": {
13
- "style-dictionary": "3.8.0"
13
+ "style-dictionary": "3.9.0"
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.8.0"
30
+ "style-dictionary": "3.9.0"
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.8.0"
13
+ "style-dictionary": "3.9.0"
14
14
  }
15
15
  }
@@ -15,6 +15,6 @@
15
15
  "author": "",
16
16
  "license": "Apache-2.0",
17
17
  "devDependencies": {
18
- "style-dictionary": "3.8.0"
18
+ "style-dictionary": "3.9.0"
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.8.0"
21
+ "style-dictionary": "3.9.0"
22
22
  }
23
23
  }
@@ -9,6 +9,6 @@
9
9
  "author": "",
10
10
  "license": "Apache-2.0",
11
11
  "devDependencies": {
12
- "style-dictionary": "3.8.0"
12
+ "style-dictionary": "3.9.0"
13
13
  }
14
14
  }
@@ -15,6 +15,6 @@
15
15
  "author": "",
16
16
  "license": "Apache-2.0",
17
17
  "devDependencies": {
18
- "style-dictionary": "3.8.0"
18
+ "style-dictionary": "3.9.0"
19
19
  }
20
20
  }
@@ -8,6 +8,6 @@
8
8
  },
9
9
  "license": "Apache-2.0",
10
10
  "devDependencies": {
11
- "style-dictionary": "3.8.0"
11
+ "style-dictionary": "3.9.0"
12
12
  }
13
13
  }
@@ -10,6 +10,6 @@
10
10
  "author": "",
11
11
  "license": "Apache-2.0",
12
12
  "devDependencies": {
13
- "style-dictionary": "3.8.0"
13
+ "style-dictionary": "3.9.0"
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.8.0"
19
+ "style-dictionary": "3.9.0"
20
20
  }
21
21
  }
@@ -15,6 +15,6 @@
15
15
  "author": "",
16
16
  "license": "Apache-2.0",
17
17
  "devDependencies": {
18
- "style-dictionary": "3.8.0"
18
+ "style-dictionary": "3.9.0"
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.8.0",
22
+ "style-dictionary": "3.9.0",
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.8.0"
19
+ "style-dictionary": "3.9.0"
20
20
  }
21
21
  }
@@ -15,6 +15,6 @@
15
15
  "author": "",
16
16
  "license": "Apache-2.0",
17
17
  "devDependencies": {
18
- "style-dictionary": "3.8.0"
18
+ "style-dictionary": "3.9.0"
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.8.0"
18
+ "style-dictionary": "3.9.0"
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.8.0"
19
+ "style-dictionary": "3.9.0"
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.8.0"
14
+ "style-dictionary": "3.9.0"
15
15
  }
16
16
  }
@@ -10,6 +10,6 @@
10
10
  "author": "",
11
11
  "license": "MIT",
12
12
  "devDependencies": {
13
- "style-dictionary": "3.8.0"
13
+ "style-dictionary": "3.9.0"
14
14
  }
15
15
  }
@@ -9,7 +9,7 @@
9
9
  "author": "",
10
10
  "license": "Apache-2.0",
11
11
  "devDependencies": {
12
- "style-dictionary": "3.8.0",
12
+ "style-dictionary": "3.9.0",
13
13
  "yaml": "^1.10.0"
14
14
  }
15
15
  }
@@ -14,9 +14,68 @@
14
14
  const defaultFormatting = {
15
15
  prefix: '',
16
16
  commentStyle: 'long',
17
+ commentPosition: 'inline',
17
18
  indentation: '',
18
19
  separator: ' =',
19
20
  suffix: ';'
21
+ };
22
+
23
+ /**
24
+ * Split a string comment by newlines and
25
+ * convert to multi-line comment if necessary
26
+ * @param {string} to_ret_prop
27
+ * @param {Object} options
28
+ * @param {string} options.comment
29
+ * @param {string} options.indentation
30
+ * @param {string} options.style 'short' | 'long'
31
+ * @param {string} options.position 'above' | 'inline'
32
+ * @returns {string}
33
+ */
34
+ function addComment(to_ret_prop, options) {
35
+ const { comment, style, indentation } = options;
36
+ let { position } = options;
37
+
38
+ const commentsByNewLine = comment.split("\n");
39
+ if (commentsByNewLine.length > 1) {
40
+ position = 'above';
41
+ }
42
+
43
+ let processedComment;
44
+ switch (style) {
45
+ case 'short':
46
+ if (position === 'inline') {
47
+ processedComment = `// ${comment}`;
48
+ } else {
49
+ processedComment = commentsByNewLine.reduce(
50
+ (acc, curr) => `${acc}${indentation}// ${curr}\n`,
51
+ ''
52
+ );
53
+ // remove trailing newline
54
+ processedComment = processedComment.replace(/\n$/g, '');
55
+ }
56
+ break;
57
+ case 'long':
58
+ if (commentsByNewLine.length > 1) {
59
+ processedComment = commentsByNewLine.reduce(
60
+ (acc, curr) => `${acc}${indentation} * ${curr}\n`,
61
+ `${indentation}/**\n`
62
+ );
63
+ processedComment += `${indentation} */`;
64
+ } else {
65
+ processedComment = `${position === 'above' ? indentation : ''
66
+ }/* ${comment} */`;
67
+ }
68
+ break;
69
+ }
70
+
71
+ if (position === 'above') {
72
+ // put the comment above the prop if it's multi-line or if commentStyle ended with -above
73
+ to_ret_prop = `${processedComment}\n${to_ret_prop}`;
74
+ } else {
75
+ to_ret_prop = `${to_ret_prop} ${processedComment}`;
76
+ }
77
+
78
+ return to_ret_prop;
20
79
  }
21
80
 
22
81
  /**
@@ -57,33 +116,33 @@ function createPropertyFormatter({
57
116
  formatting = {},
58
117
  themeable = false
59
118
  }) {
60
- let {prefix, commentStyle, indentation, separator, suffix} = Object.assign({}, defaultFormatting, formatting);
61
-
62
- switch(format) {
119
+ const formatDefaults = {};
120
+ switch (format) {
63
121
  case 'css':
64
- prefix = '--';
65
- indentation = ' ';
66
- separator = ':';
122
+ formatDefaults.prefix = '--';
123
+ formatDefaults.indentation = ' ';
124
+ formatDefaults.separator = ':';
67
125
  break;
68
126
  case 'sass':
69
- prefix = '$';
70
- commentStyle = 'short';
71
- indentation = '';
72
- separator = ':';
127
+ formatDefaults.prefix = '$';
128
+ formatDefaults.commentStyle = 'short';
129
+ formatDefaults.indentation = '';
130
+ formatDefaults.separator = ':';
73
131
  break;
74
132
  case 'less':
75
- prefix = '@';
76
- commentStyle = 'short';
77
- indentation = '';
78
- separator = ':';
133
+ formatDefaults.prefix = '@';
134
+ formatDefaults.commentStyle = 'short';
135
+ formatDefaults.indentation = '';
136
+ formatDefaults.separator = ':';
79
137
  break;
80
138
  case 'stylus':
81
- prefix = '$';
82
- commentStyle = 'short';
83
- indentation = '';
84
- separator = '=';
139
+ formatDefaults.prefix = '$';
140
+ formatDefaults.commentStyle = 'short';
141
+ formatDefaults.indentation = '';
142
+ formatDefaults.separator = '=';
85
143
  break;
86
144
  }
145
+ let {prefix, commentStyle, commentPosition, indentation, separator, suffix} = Object.assign({}, defaultFormatting, formatDefaults, formatting);
87
146
 
88
147
  return function(prop) {
89
148
  let to_ret_prop = `${indentation}${prefix}${prop.name}${separator} `;
@@ -104,28 +163,42 @@ function createPropertyFormatter({
104
163
  if (outputReferences && dictionary.usesReference(prop.original.value)) {
105
164
  // Formats that use this function expect `value` to be a string
106
165
  // or else you will get '[object Object]' in the output
107
- if (typeof value === 'string') {
108
- const refs = dictionary.getReferences(prop.original.value);
109
- refs.forEach(ref => {
110
- // value should be a string that contains the resolved reference
111
- // because Style Dictionary resolved this in the resolution step.
112
- // Here we are undoing that by replacing the value with
113
- // the reference's name
114
- if (ref.value && ref.name) {
115
- value = value.replace(ref.value, function() {
116
- if (format === 'css') {
117
- if (outputReferenceFallbacks) {
118
- return `var(${prefix}${ref.name}, ${ref.value})`;
119
- } else {
120
- return `var(${prefix}${ref.name})`;
121
- }
166
+ const refs = dictionary.getReferences(prop.original.value);
167
+
168
+ // original can either be an object value, which requires transitive value transformation in web CSS formats
169
+ // or a different (primitive) type, meaning it can be stringified.
170
+ const originalIsObject = typeof prop.original.value === 'object' && prop.original.value !== null;
171
+
172
+ if (!originalIsObject) {
173
+ // when original is object value, we replace value by matching ref.value and putting a var instead.
174
+ // Due to the original.value being an object, it requires transformation, so undoing the transformation
175
+ // by replacing value with original.value is not possible.
176
+
177
+ // when original is string value, we replace value by matching original.value and putting a var instead
178
+ // this is more friendly to transitive transforms that transform the string values
179
+ value = prop.original.value;
180
+ }
181
+
182
+ refs.forEach(ref => {
183
+ // value should be a string that contains the resolved reference
184
+ // because Style Dictionary resolved this in the resolution step.
185
+ // Here we are undoing that by replacing the value with
186
+ // the reference's name
187
+ if (ref.value && ref.name) {
188
+ const replaceFunc = function() {
189
+ if (format === 'css') {
190
+ if (outputReferenceFallbacks) {
191
+ return `var(${prefix}${ref.name}, ${ref.value})`;
122
192
  } else {
123
- return `${prefix}${ref.name}`;
193
+ return `var(${prefix}${ref.name})`;
124
194
  }
125
- });
195
+ } else {
196
+ return `${prefix}${ref.name}`;
197
+ }
126
198
  }
127
- });
128
- }
199
+ value = value.replace(originalIsObject ? ref.value : new RegExp(`{${ref.path.join('.')}(.value)?}`, 'g'), replaceFunc);
200
+ }
201
+ });
129
202
  }
130
203
 
131
204
  to_ret_prop += prop.attributes.category === 'asset' ? `"${value}"` : value;
@@ -138,11 +211,12 @@ function createPropertyFormatter({
138
211
  to_ret_prop += suffix;
139
212
 
140
213
  if (prop.comment && commentStyle !== 'none') {
141
- if (commentStyle === 'short') {
142
- to_ret_prop = to_ret_prop.concat(` // ${prop.comment}`);
143
- } else {
144
- to_ret_prop = to_ret_prop.concat(` /* ${prop.comment} */`);
145
- }
214
+ to_ret_prop = addComment(to_ret_prop, {
215
+ comment: prop.comment,
216
+ style: commentStyle,
217
+ position: commentPosition,
218
+ indentation,
219
+ });
146
220
  }
147
221
 
148
222
  return to_ret_prop;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "style-dictionary",
3
- "version": "3.8.0",
3
+ "version": "3.9.0",
4
4
  "description": "Style once, use everywhere. A build system for creating cross-platform styles.",
5
5
  "keywords": [
6
6
  "style dictionary",
@@ -146,7 +146,7 @@
146
146
  "json5-jest": "^1.0.1",
147
147
  "less": "^4.1.2",
148
148
  "lint-staged": "^12.3.1",
149
- "node-sass": "^7.0.1",
149
+ "node-sass": "^9.0.0",
150
150
  "standard-version": "^9.3.2",
151
151
  "stylus": "^0.56.0",
152
152
  "tsd": "^0.19.1",