style-dictionary 4.0.0 → 4.1.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.
- package/README.md +9 -13
- package/examples/README.md +0 -4
- package/examples/advanced/assets-base64-embed/package.json +1 -1
- package/examples/advanced/create-react-app/package.json +1 -1
- package/examples/advanced/create-react-native-app/package.json +1 -1
- package/examples/advanced/custom-parser/package.json +1 -1
- package/examples/advanced/custom-transforms/README.md +1 -1
- package/examples/advanced/custom-transforms/package.json +1 -1
- package/examples/advanced/font-face-rules/package.json +1 -1
- package/examples/advanced/format-helpers/package.json +1 -1
- package/examples/advanced/format-helpers/sd.config.js +1 -1
- package/examples/advanced/matching-build-files/package.json +1 -1
- package/examples/advanced/multi-brand-multi-platform/package.json +1 -1
- package/examples/advanced/node-modules-as-config-and-properties/package.json +1 -1
- package/examples/advanced/npm-module/package.json +1 -1
- package/examples/advanced/referencing_aliasing/package.json +1 -1
- package/examples/advanced/s3/package.json +1 -1
- package/examples/advanced/tokens-deprecation/package.json +1 -1
- package/examples/advanced/transitive-transforms/package.json +2 -2
- package/examples/advanced/transitive-transforms/sd.config.js +36 -23
- package/examples/advanced/transitive-transforms/tokens/color/core.json5 +0 -4
- package/examples/advanced/transitive-transforms/tokens/color/font.json5 +7 -9
- package/examples/advanced/transitive-transforms/tokens/color/overlay.json5 +4 -4
- package/examples/advanced/variables-in-outputs/package.json +1 -1
- package/examples/advanced/yaml-tokens/package.json +1 -1
- package/lib/StyleDictionary.d.ts +78 -16
- package/lib/StyleDictionary.js +113 -57
- package/lib/common/formatHelpers/createPropertyFormatter.d.ts +9 -0
- package/lib/common/formatHelpers/createPropertyFormatter.js +1 -1
- package/lib/common/formatHelpers/fileHeader.js +1 -0
- package/lib/common/formats.d.ts +1 -1
- package/lib/common/formats.js +5 -3
- package/lib/common/templates/scss/map-deep.template.js +12 -6
- package/lib/common/templates/scss/map-flat.template.js +22 -10
- package/lib/common/transforms.js +1 -0
- package/lib/fs.d.ts +2 -0
- package/lib/fs.js +3 -1
- package/lib/utils/combineJSON.js +1 -1
- package/lib/utils/expandObjectTokens.js +7 -1
- package/lib/utils/groupMessages.d.ts +1 -1
- package/lib/utils/groupMessages.js +1 -1
- package/package.json +4 -3
- package/types/Config.d.ts +3 -3
- package/types/File.d.ts +6 -4
- package/types/Volume.d.ts +2 -2
- package/types/typeless-modules/bundled-memfs.d.ts +0 -1
package/README.md
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
<pre>
|
|
2
|
-
<a href="https://
|
|
2
|
+
<a href="https://styledictionary.com/version-4/migration/">What's new in Style Dictionary 4.0!</a>
|
|
3
3
|
</pre>
|
|
4
4
|
|
|
5
|
-
<
|
|
6
|
-
<a href="https://github.com/amzn/style-dictionary#version-4">What's coming in Style Dictionary 4.0?</a>
|
|
7
|
-
</pre>
|
|
8
|
-
|
|
9
|
-
<img src="docs/assets/logo.png" alt="Style Dictionary logo and mascot" title=""Pascal"" width="100" align="right" />
|
|
5
|
+
<img src="docs/src/assets/logo.png" alt="Style Dictionary logo and mascot" title=""Pascal"" width="100" align="right" />
|
|
10
6
|
|
|
11
7
|
[](https://badge.fury.io/js/style-dictionary)
|
|
12
8
|

|
|
@@ -136,7 +132,7 @@ A style dictionary is a collection of design tokens, key/value pairs that descri
|
|
|
136
132
|
|
|
137
133
|
### config.json
|
|
138
134
|
|
|
139
|
-
This tells the style dictionary build system how and what to build. The default file path is `config.json` or `config.js` in the root of the project, but you can name it whatever you want by passing in the `--config` flag to the [CLI](https://
|
|
135
|
+
This tells the style dictionary build system how and what to build. The default file path is `config.json` or `config.js` in the root of the project, but you can name it whatever you want by passing in the `--config` flag to the [CLI](https://styledictionary.com/getting-started/using_the_cli/).
|
|
140
136
|
|
|
141
137
|
```json
|
|
142
138
|
{
|
|
@@ -176,7 +172,7 @@ This tells the style dictionary build system how and what to build. The default
|
|
|
176
172
|
| platform.buildPath | String (optional) | Base path to build the files, must end with a trailing slash. |
|
|
177
173
|
| platform.files | Array (optional) | Files to be generated for this platform. |
|
|
178
174
|
| platform.file.destination | String (optional) | Location to build the file, will be appended to the buildPath. |
|
|
179
|
-
| platform.file.format | String (optional) | Format used to generate the file. Can be a built-in one or you can create your own. [More on formats](https://
|
|
175
|
+
| platform.file.format | String (optional) | Format used to generate the file. Can be a built-in one or you can create your own. [More on formats](https://styledictionary.com/reference/hooks/formats/) |
|
|
180
176
|
| platform.file.options | Object (optional) | A set of extra options associated with the file. |
|
|
181
177
|
| platform.file.options.showFileHeader | Boolean | If the generated file should have a "Do not edit + Timestamp" header (where the format supports it). By default is "true". |
|
|
182
178
|
|
|
@@ -224,7 +220,7 @@ float const SizeFontBase = 16.00f;
|
|
|
224
220
|
|
|
225
221
|
The style dictionary framework comes with some example code to get you started. Install the node module globally, create a directory and `cd` into it.
|
|
226
222
|
|
|
227
|
-
```
|
|
223
|
+
```bash
|
|
228
224
|
$ npm i -g style-dictionary
|
|
229
225
|
$ mkdir MyStyleDictionary
|
|
230
226
|
$ cd MyStyleDictionary
|
|
@@ -232,13 +228,13 @@ $ cd MyStyleDictionary
|
|
|
232
228
|
|
|
233
229
|
Now run:
|
|
234
230
|
|
|
235
|
-
```
|
|
231
|
+
```bash
|
|
236
232
|
$ style-dictionary init basic
|
|
237
233
|
```
|
|
238
234
|
|
|
239
235
|
This command will copy over the example files found in [example](examples/) in this repo. Now you have an example project set up. You can make changes to the style dictionary and rebuild the project by running:
|
|
240
236
|
|
|
241
|
-
```
|
|
237
|
+
```bash
|
|
242
238
|
$ style-dictionary build
|
|
243
239
|
```
|
|
244
240
|
|
|
@@ -313,7 +309,7 @@ StyleDictionary.registerTransform({
|
|
|
313
309
|
StyleDictionary.buildAllPlatforms();
|
|
314
310
|
```
|
|
315
311
|
|
|
316
|
-
For more information on creating your own transforms and formats, take a look at our [docs](https://
|
|
312
|
+
For more information on creating your own transforms and formats, take a look at our [docs](https://styledictionary.com).
|
|
317
313
|
|
|
318
314
|
## Version 4
|
|
319
315
|
|
|
@@ -340,7 +336,7 @@ We are very open to feedback and collaboration, feel free to reach out to us in
|
|
|
340
336
|
|
|
341
337
|
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.
|
|
342
338
|
|
|
343
|
-
<img src="docs/assets/logo.png" alt="Style Dictionary logo and mascot" title=""Pascal"" width="240" />
|
|
339
|
+
<img src="docs/src/assets/logo.png" alt="Style Dictionary logo and mascot" title=""Pascal"" width="240" />
|
|
344
340
|
|
|
345
341
|
## Contributing
|
|
346
342
|
|
package/examples/README.md
CHANGED
|
@@ -31,12 +31,8 @@ This is a more complete package and should have everything you need to get start
|
|
|
31
31
|
If you want to look at more advanced examples of possible applications and customizations of Style Dictionary, the [`examples/advanced`](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/) folder on GitHub contains these extra folders:
|
|
32
32
|
|
|
33
33
|
- [**assets-base64-embed**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/assets-base64-embed) shows how it's possible to embed and distribute assets – like images, icons and fonts – directly as design tokens.
|
|
34
|
-
- [**auto-rebuild-watcher**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/auto-rebuild-watcher) shows how to setup a "watcher" that auto-rebuilds the tokens every time there is a change in the tokens.
|
|
35
|
-
- [**component-cti**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/component-cti) shows how to write component tokens and still use the CTI structure.
|
|
36
34
|
- [**create-react-app**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/create-react-app) shows how to integrate Style Dictionary into a React application.
|
|
37
35
|
- [**create-react-native-app**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/create-react-native-app) shows how to integrate Style Dictionary into a React Native application.
|
|
38
|
-
- [**custom-file-header**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/custom-file-header) shows how to define custom file headers and use them in output files.
|
|
39
|
-
- [**custom-formats-with-templates**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/custom-formats-with-templates) shows how to generate custom output formats using templates, useful when you need to distribute your design tokens into your own pipelines or scripts.
|
|
40
36
|
- [**custom-parser**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/custom-parser) shows how to use custom parsers for token files.
|
|
41
37
|
- [**custom-transforms**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/custom-transforms) shows how to use custom transforms (and transformGroups) to apply custom "transformations" to the design tokens.
|
|
42
38
|
- [**flutter**](https://github.com/amzn/style-dictionary/tree/main/examples/advanced/flutter) shows how to integrate with Flutter applications.
|
|
@@ -9,7 +9,7 @@ Transforms are functions that modify a design token (in a non-destructive way).
|
|
|
9
9
|
The need for custom transforms is that Style Dictionary expects the tokens to be declared according to certain criteria, to use the pre-defined transforms and formats/templates. For example, the _web_ transformGroup consists of the _attribute/cti_, _name/kebab_, _size/px_ and _color/css_ transforms.
|
|
10
10
|
The _size/px_ adds 'px' to the end of the number, and is applied only if `token.attributes.category === 'size'`. This means that your token needs to be expressed without units, and be under the _'size'_ "category. If you need a different logic or you want to organize your tokens differently, probably you can't use the out-of-the-box transformation groups, but you have to declare your custom ones.
|
|
11
11
|
|
|
12
|
-
If [custom formats](
|
|
12
|
+
If [custom formats](https://v4.styledictionary.com/reference/hooks/formats/#custom-formats) are the way to allow users to customize the format of the _output_ of Style Dictionary, custom transforms are the way to allow them to customize both the _input_ (the token names/values/attributes) and the _output_ (the actual values expressed in the design tokens). For this reasons, custom transforms are probably one of the **most powerful features** of Style Dictionary: they make it extremely versatile, allowing limitless possibilities of extension and customization of the entire design token pipeline.
|
|
13
13
|
|
|
14
14
|
#### Running the example
|
|
15
15
|
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import StyleDictionary from 'style-dictionary';
|
|
2
2
|
import { usesReferences } from 'style-dictionary/utils';
|
|
3
|
-
import
|
|
3
|
+
import Color from 'colorjs.io';
|
|
4
4
|
|
|
5
5
|
const colorTransform = (token) => {
|
|
6
6
|
const { value, modify = [] } = token;
|
|
7
|
-
|
|
7
|
+
|
|
8
|
+
// This assumes "hex" format, if you want to support { h, s, l } format you have to do
|
|
9
|
+
// `new Color('hsl', [value.h, value.s, value.l]);`
|
|
10
|
+
const color = new Color(value);
|
|
8
11
|
|
|
9
12
|
// defer until reference is resolved
|
|
10
13
|
if (typeof modify === 'string' && usesReferences(modify)) {
|
|
@@ -18,15 +21,22 @@ const colorTransform = (token) => {
|
|
|
18
21
|
if (usesReferences(type) || usesReferences(amount)) {
|
|
19
22
|
return undefined;
|
|
20
23
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
|
|
25
|
+
switch (type) {
|
|
26
|
+
case 'lighten': {
|
|
27
|
+
const lightness = color.hsl.l;
|
|
28
|
+
const difference = 100 - lightness;
|
|
29
|
+
const newLightness = Math.min(100, lightness + difference * amount);
|
|
30
|
+
color.set('hsl.l', newLightness);
|
|
31
|
+
break;
|
|
32
|
+
}
|
|
33
|
+
case 'transparentize':
|
|
34
|
+
color.alpha = Math.max(0, Math.min(1, Number(amount)));
|
|
35
|
+
break;
|
|
36
|
+
}
|
|
27
37
|
});
|
|
28
38
|
|
|
29
|
-
return color.
|
|
39
|
+
return color.to('srgb').toString({ format: 'hex' });
|
|
30
40
|
};
|
|
31
41
|
|
|
32
42
|
export default {
|
|
@@ -36,21 +46,24 @@ export default {
|
|
|
36
46
|
|
|
37
47
|
// I am directly defining transforms here
|
|
38
48
|
// This would work if you were to call StyleDictionary.registerTransform() as well
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
49
|
+
hooks: {
|
|
50
|
+
transforms: {
|
|
51
|
+
colorTransform: {
|
|
52
|
+
type: `value`,
|
|
53
|
+
// only transforms that have transitive: true will be applied to tokens
|
|
54
|
+
// that alias/reference other tokens
|
|
55
|
+
transitive: true,
|
|
56
|
+
filter: (token) => token.attributes.category === 'color' && token.modify,
|
|
57
|
+
transform: colorTransform,
|
|
58
|
+
},
|
|
48
59
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
60
|
+
// For backwards compatibility, all built-in transforms are not transitive
|
|
61
|
+
// by default. This will make the 'color/css' transform transitive
|
|
62
|
+
'color/css': {
|
|
63
|
+
...StyleDictionary.hooks.transforms[`color/css`],
|
|
64
|
+
transitive: true,
|
|
65
|
+
},
|
|
66
|
+
},
|
|
54
67
|
},
|
|
55
68
|
|
|
56
69
|
platforms: {
|
|
@@ -6,10 +6,6 @@
|
|
|
6
6
|
|
|
7
7
|
red: {
|
|
8
8
|
'100': {
|
|
9
|
-
// hue, saturation, and lightness are defined in
|
|
10
|
-
// tokens/hue.json5, tokens/saturation.json5, and tokens/lightness.json5
|
|
11
|
-
// The {h, s, l} object structure conforms to the input structure for
|
|
12
|
-
// chromajs: https://gka.github.io/chroma.js/#chroma
|
|
13
9
|
value: { h: '{hue.red}', s: '{saturation.7}', l: '{lightness.7}' },
|
|
14
10
|
type: 'color',
|
|
15
11
|
},
|
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
color: {
|
|
3
3
|
font: {
|
|
4
|
-
primary: { value: '{color.core.black
|
|
4
|
+
primary: { value: '{color.core.black}', type: 'color' },
|
|
5
5
|
secondary: {
|
|
6
|
-
value: '{color.font.primary
|
|
6
|
+
value: '{color.font.primary}',
|
|
7
7
|
modify: [
|
|
8
8
|
{
|
|
9
|
-
type: '
|
|
10
|
-
|
|
11
|
-
// for definition of brighten
|
|
12
|
-
amount: 1,
|
|
9
|
+
type: 'lighten',
|
|
10
|
+
amount: 0.2,
|
|
13
11
|
},
|
|
14
12
|
],
|
|
15
13
|
type: 'color',
|
|
@@ -20,10 +18,10 @@
|
|
|
20
18
|
value: '{color.font.secondary}',
|
|
21
19
|
modify: [
|
|
22
20
|
{
|
|
23
|
-
// this will
|
|
21
|
+
// this will lighten the secondary value, which is a lightened version
|
|
24
22
|
// of primary
|
|
25
|
-
type: '
|
|
26
|
-
amount:
|
|
23
|
+
type: 'lighten',
|
|
24
|
+
amount: 0.2,
|
|
27
25
|
},
|
|
28
26
|
],
|
|
29
27
|
type: 'color',
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
color: {
|
|
3
3
|
overlay: {
|
|
4
4
|
primary: {
|
|
5
|
-
value: '{color.core.white
|
|
5
|
+
value: '{color.core.white}',
|
|
6
6
|
modify: [
|
|
7
7
|
{
|
|
8
|
-
type: '
|
|
8
|
+
type: 'transparentize',
|
|
9
9
|
// You can access other parts of your style dictionary in here too:
|
|
10
10
|
amount: '{alpha.1}',
|
|
11
11
|
},
|
|
@@ -14,10 +14,10 @@
|
|
|
14
14
|
},
|
|
15
15
|
|
|
16
16
|
secondary: {
|
|
17
|
-
value: '{color.core.white
|
|
17
|
+
value: '{color.core.white}',
|
|
18
18
|
modify: [
|
|
19
19
|
{
|
|
20
|
-
type: '
|
|
20
|
+
type: 'transparentize',
|
|
21
21
|
// You can access other parts of your style dictionary in here too:
|
|
22
22
|
amount: '{alpha.2}',
|
|
23
23
|
},
|
package/lib/StyleDictionary.d.ts
CHANGED
|
@@ -32,10 +32,10 @@ export default class StyleDictionary extends Register {
|
|
|
32
32
|
get options(): import("../types/Config.ts").Config;
|
|
33
33
|
_options: import("../types/Config.ts").Config | undefined;
|
|
34
34
|
config: string | import("../types/Config.ts").Config;
|
|
35
|
-
/** @type {
|
|
36
|
-
tokens:
|
|
37
|
-
/** @type {
|
|
38
|
-
allTokens:
|
|
35
|
+
/** @type {PreprocessedTokens} */
|
|
36
|
+
tokens: PreprocessedTokens;
|
|
37
|
+
/** @type {PreprocessedTokens[]} */
|
|
38
|
+
allTokens: PreprocessedTokens[];
|
|
39
39
|
/** @type {boolean | undefined} */
|
|
40
40
|
usesDtcg: boolean | undefined;
|
|
41
41
|
/** @type {LogConfig} */
|
|
@@ -64,6 +64,14 @@ export default class StyleDictionary extends Register {
|
|
|
64
64
|
unfilteredAllTokens: TransformedToken[];
|
|
65
65
|
hasInitialized: Promise<any>;
|
|
66
66
|
hasInitializedResolve: (value: any) => void;
|
|
67
|
+
/**
|
|
68
|
+
* Storing the platform specific transformed tokens so we can prevent re-running exportPlatform when we already know the outcome
|
|
69
|
+
* Same thing for platform specific configs, we don't need to call transformConfig again if we already know the outcome
|
|
70
|
+
*/
|
|
71
|
+
/** @type {Record<string,Dictionary>} */
|
|
72
|
+
_dictionaries: Record<string, Dictionary>;
|
|
73
|
+
/** @type {Record<string,PlatformConfig>} */
|
|
74
|
+
_platformConfigs: Record<string, PlatformConfig>;
|
|
67
75
|
/**
|
|
68
76
|
* @param {{verbosity?: LogConfig['verbosity'], warnings?: LogConfig['warnings']}} [opts]
|
|
69
77
|
* @returns
|
|
@@ -95,20 +103,47 @@ export default class StyleDictionary extends Register {
|
|
|
95
103
|
shouldRunExpansion(expandCfg?: import("../types/Config.ts").ExpandConfig | undefined): boolean;
|
|
96
104
|
/**
|
|
97
105
|
* @param {string} platform
|
|
106
|
+
* @param {{ cache?: boolean }} [opts]
|
|
107
|
+
*/
|
|
108
|
+
getPlatformConfig(platform: string, opts?: {
|
|
109
|
+
cache?: boolean;
|
|
110
|
+
} | undefined): import("../types/Config.ts").PlatformConfig;
|
|
111
|
+
/**
|
|
112
|
+
* @param {string} platform
|
|
113
|
+
* @param {{ cache?: boolean }} [opts]
|
|
114
|
+
*/
|
|
115
|
+
getPlatformTokens(platform: string, opts?: {
|
|
116
|
+
cache?: boolean;
|
|
117
|
+
} | undefined): Promise<import("../types/DesignToken.ts").Dictionary>;
|
|
118
|
+
/**
|
|
119
|
+
* Public wrapper around _exportPlatform, returns only tokens object
|
|
120
|
+
* Here for backwards compatibility.
|
|
121
|
+
* @deprecated use getPlatformTokens instead
|
|
122
|
+
*
|
|
123
|
+
* @param {string} platform
|
|
124
|
+
* @param {{ cache?: boolean }} [opts]
|
|
98
125
|
* @returns {Promise<TransformedTokens>}
|
|
99
126
|
*/
|
|
100
|
-
exportPlatform(platform: string
|
|
127
|
+
exportPlatform(platform: string, opts?: {
|
|
128
|
+
cache?: boolean;
|
|
129
|
+
} | undefined): Promise<TransformedTokens>;
|
|
130
|
+
/**
|
|
131
|
+
* @param {string} platform
|
|
132
|
+
* @returns {Promise<Dictionary>}
|
|
133
|
+
*/
|
|
134
|
+
_exportPlatform(platform: string): Promise<Dictionary>;
|
|
101
135
|
/**
|
|
102
136
|
* This will get the dictionary / platformConfig for specified platform name
|
|
103
137
|
* Runs transforms, reference resolutions
|
|
138
|
+
* @deprecated use getPlatformConfig / getPlatformTokens instead
|
|
104
139
|
* @param {string} platform
|
|
140
|
+
* @param {{ cache?: boolean }} [opts]
|
|
105
141
|
* @returns
|
|
106
142
|
*/
|
|
107
|
-
getPlatform(platform: string
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
};
|
|
143
|
+
getPlatform(platform: string, opts?: {
|
|
144
|
+
cache?: boolean;
|
|
145
|
+
} | undefined): Promise<{
|
|
146
|
+
dictionary: import("../types/DesignToken.ts").Dictionary;
|
|
112
147
|
platformConfig: import("../types/Config.ts").PlatformConfig;
|
|
113
148
|
}>;
|
|
114
149
|
/**
|
|
@@ -134,24 +169,51 @@ export default class StyleDictionary extends Register {
|
|
|
134
169
|
}>;
|
|
135
170
|
/**
|
|
136
171
|
* @param {string} platform
|
|
172
|
+
* @param {{ cache?: boolean }} [opts]
|
|
137
173
|
*/
|
|
138
|
-
formatPlatform(platform: string
|
|
174
|
+
formatPlatform(platform: string, opts?: {
|
|
175
|
+
cache?: boolean;
|
|
176
|
+
} | undefined): Promise<{
|
|
139
177
|
output: unknown;
|
|
140
178
|
destination: string | undefined;
|
|
141
179
|
}[]>;
|
|
142
|
-
|
|
180
|
+
/**
|
|
181
|
+
* @param {{ cache?: boolean }} [opts]
|
|
182
|
+
* @returns
|
|
183
|
+
*/
|
|
184
|
+
formatAllPlatforms(opts?: {
|
|
185
|
+
cache?: boolean;
|
|
186
|
+
} | undefined): Promise<{}>;
|
|
143
187
|
/**
|
|
144
188
|
* @param {string} platform
|
|
189
|
+
* @param {{ cache?: boolean }} [opts]
|
|
145
190
|
* @returns
|
|
146
191
|
*/
|
|
147
|
-
buildPlatform(platform: string
|
|
148
|
-
|
|
192
|
+
buildPlatform(platform: string, opts?: {
|
|
193
|
+
cache?: boolean;
|
|
194
|
+
} | undefined): Promise<this>;
|
|
195
|
+
/**
|
|
196
|
+
* @param {{ cache?: boolean }} [opts]
|
|
197
|
+
* @returns
|
|
198
|
+
*/
|
|
199
|
+
buildAllPlatforms(opts?: {
|
|
200
|
+
cache?: boolean;
|
|
201
|
+
} | undefined): Promise<this>;
|
|
149
202
|
/**
|
|
150
203
|
* @param {string} platform
|
|
204
|
+
* @param {{ cache?: boolean }} [opts]
|
|
205
|
+
* @returns
|
|
206
|
+
*/
|
|
207
|
+
cleanPlatform(platform: string, opts?: {
|
|
208
|
+
cache?: boolean;
|
|
209
|
+
} | undefined): Promise<this>;
|
|
210
|
+
/**
|
|
211
|
+
* @param {{ cache?: boolean }} [opts]
|
|
151
212
|
* @returns
|
|
152
213
|
*/
|
|
153
|
-
|
|
154
|
-
|
|
214
|
+
cleanAllPlatforms(opts?: {
|
|
215
|
+
cache?: boolean;
|
|
216
|
+
} | undefined): Promise<this>;
|
|
155
217
|
}
|
|
156
218
|
export type Volume = import("../types/Volume.ts").Volume;
|
|
157
219
|
export type Config = import("../types/Config.ts").Config;
|
package/lib/StyleDictionary.js
CHANGED
|
@@ -78,7 +78,7 @@ export default class StyleDictionary extends Register {
|
|
|
78
78
|
// Placeholder is transformed on prepublish -> see scripts/inject-version.js
|
|
79
79
|
// Another option might be import pkg from './package.json' with { "type": "json" } which would work in both browser and node, but support is not there yet.
|
|
80
80
|
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#browser_compatibility
|
|
81
|
-
static VERSION = '4.
|
|
81
|
+
static VERSION = '4.1.0';
|
|
82
82
|
|
|
83
83
|
/** @returns {Config} */
|
|
84
84
|
get options() {
|
|
@@ -110,9 +110,9 @@ export default class StyleDictionary extends Register {
|
|
|
110
110
|
super();
|
|
111
111
|
this.config = config;
|
|
112
112
|
this.options = {};
|
|
113
|
-
/** @type {
|
|
113
|
+
/** @type {PreprocessedTokens} */
|
|
114
114
|
this.tokens = {};
|
|
115
|
-
/** @type {
|
|
115
|
+
/** @type {PreprocessedTokens[]} */
|
|
116
116
|
this.allTokens = [];
|
|
117
117
|
/** @type {boolean | undefined} */
|
|
118
118
|
this.usesDtcg = undefined;
|
|
@@ -156,6 +156,15 @@ export default class StyleDictionary extends Register {
|
|
|
156
156
|
this.hasInitializedResolve = resolve;
|
|
157
157
|
});
|
|
158
158
|
|
|
159
|
+
/**
|
|
160
|
+
* Storing the platform specific transformed tokens so we can prevent re-running exportPlatform when we already know the outcome
|
|
161
|
+
* Same thing for platform specific configs, we don't need to call transformConfig again if we already know the outcome
|
|
162
|
+
*/
|
|
163
|
+
/** @type {Record<string,Dictionary>} */
|
|
164
|
+
this._dictionaries = {};
|
|
165
|
+
/** @type {Record<string,PlatformConfig>} */
|
|
166
|
+
this._platformConfigs = {};
|
|
167
|
+
|
|
159
168
|
// By default, always call async extend function when constructing new SD instance
|
|
160
169
|
// However, for testability and managing error handling,
|
|
161
170
|
// you can call constructor with { init: false }
|
|
@@ -331,25 +340,28 @@ export default class StyleDictionary extends Register {
|
|
|
331
340
|
}
|
|
332
341
|
}
|
|
333
342
|
}
|
|
343
|
+
this.options = { ...this.options, usesDtcg: this.usesDtcg };
|
|
334
344
|
|
|
335
345
|
// Merge inline, include, and source tokens
|
|
336
|
-
/** @type {PreprocessedTokens
|
|
337
|
-
|
|
346
|
+
let preprocessedTokens = /** @type {PreprocessedTokens} */ (
|
|
347
|
+
deepExtend([{}, inlineTokens, includeTokens, sourceTokens])
|
|
348
|
+
);
|
|
349
|
+
|
|
350
|
+
preprocessedTokens = await preprocess(
|
|
351
|
+
preprocessedTokens,
|
|
352
|
+
this.preprocessors,
|
|
353
|
+
this.hooks.preprocessors,
|
|
354
|
+
this.options,
|
|
355
|
+
);
|
|
338
356
|
if (this.usesDtcg) {
|
|
339
357
|
// this is where they go from type Tokens -> Preprocessed tokens because the prop $type is removed
|
|
340
|
-
|
|
358
|
+
preprocessedTokens = typeDtcgDelegate(preprocessedTokens);
|
|
341
359
|
}
|
|
342
|
-
let preprocessedTokens = /** @type {PreprocessedTokens} */ (tokens);
|
|
343
360
|
if (this.shouldRunExpansion(this.expand)) {
|
|
344
361
|
preprocessedTokens = expandTokens(preprocessedTokens, this.options);
|
|
345
362
|
}
|
|
346
|
-
this.
|
|
347
|
-
this.
|
|
348
|
-
preprocessedTokens,
|
|
349
|
-
this.preprocessors,
|
|
350
|
-
this.hooks.preprocessors,
|
|
351
|
-
this.options,
|
|
352
|
-
);
|
|
363
|
+
this.tokens = preprocessedTokens;
|
|
364
|
+
this.allTokens = flattenTokens(/** @type {PreprocessedTokens} */ (this.tokens), this.usesDtcg);
|
|
353
365
|
this.hasInitializedResolve(null);
|
|
354
366
|
|
|
355
367
|
// For chaining
|
|
@@ -378,27 +390,62 @@ export default class StyleDictionary extends Register {
|
|
|
378
390
|
|
|
379
391
|
/**
|
|
380
392
|
* @param {string} platform
|
|
381
|
-
* @
|
|
393
|
+
* @param {{ cache?: boolean }} [opts]
|
|
382
394
|
*/
|
|
383
|
-
|
|
384
|
-
await this.hasInitialized;
|
|
385
|
-
|
|
395
|
+
getPlatformConfig(platform, opts) {
|
|
386
396
|
if (!platform || !this.platforms?.[platform]) {
|
|
387
|
-
throw new Error(
|
|
397
|
+
throw new Error(`Please supply a valid platform, "${platform}" does not exist`);
|
|
398
|
+
}
|
|
399
|
+
if (!this._platformConfigs[platform] || opts?.cache === false) {
|
|
400
|
+
this._platformConfigs[platform] = transformConfig(this.platforms[platform], this, platform);
|
|
388
401
|
}
|
|
402
|
+
return this._platformConfigs[platform];
|
|
403
|
+
}
|
|
389
404
|
|
|
390
|
-
|
|
391
|
-
|
|
405
|
+
/**
|
|
406
|
+
* @param {string} platform
|
|
407
|
+
* @param {{ cache?: boolean }} [opts]
|
|
408
|
+
*/
|
|
409
|
+
async getPlatformTokens(platform, opts) {
|
|
410
|
+
if (!this._dictionaries[platform] || opts?.cache === false) {
|
|
411
|
+
const dictionary = await this._exportPlatform(platform);
|
|
412
|
+
this._dictionaries[platform] = dictionary;
|
|
413
|
+
}
|
|
414
|
+
return this._dictionaries[platform];
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
/**
|
|
418
|
+
* Public wrapper around _exportPlatform, returns only tokens object
|
|
419
|
+
* Here for backwards compatibility.
|
|
420
|
+
* @deprecated use getPlatformTokens instead
|
|
421
|
+
*
|
|
422
|
+
* @param {string} platform
|
|
423
|
+
* @param {{ cache?: boolean }} [opts]
|
|
424
|
+
* @returns {Promise<TransformedTokens>}
|
|
425
|
+
*/
|
|
426
|
+
async exportPlatform(platform, opts) {
|
|
427
|
+
const dictionary = await this.getPlatformTokens(platform, opts);
|
|
428
|
+
return dictionary.tokens;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* @param {string} platform
|
|
433
|
+
* @returns {Promise<Dictionary>}
|
|
434
|
+
*/
|
|
435
|
+
async _exportPlatform(platform) {
|
|
436
|
+
await this.hasInitialized;
|
|
437
|
+
const platformConfig = this.getPlatformConfig(platform);
|
|
392
438
|
|
|
393
439
|
let platformProcessedTokens = /** @type {PreprocessedTokens} */ (this.tokens);
|
|
394
|
-
|
|
395
|
-
platformProcessedTokens = expandTokens(platformProcessedTokens, this.options, platformConfig);
|
|
396
|
-
}
|
|
440
|
+
|
|
397
441
|
platformProcessedTokens = await preprocess(
|
|
398
442
|
platformProcessedTokens,
|
|
399
443
|
platformConfig.preprocessors,
|
|
400
444
|
this.hooks.preprocessors,
|
|
401
445
|
);
|
|
446
|
+
if (this.shouldRunExpansion(platformConfig.expand)) {
|
|
447
|
+
platformProcessedTokens = expandTokens(platformProcessedTokens, this.options, platformConfig);
|
|
448
|
+
}
|
|
402
449
|
|
|
403
450
|
let exportableResult = /** @type {PreprocessedTokens|TransformedTokens} */ (
|
|
404
451
|
platformProcessedTokens
|
|
@@ -538,35 +585,25 @@ export default class StyleDictionary extends Register {
|
|
|
538
585
|
console.log(chalk.rgb(255, 140, 0).bold(err));
|
|
539
586
|
}
|
|
540
587
|
}
|
|
541
|
-
|
|
542
|
-
return exportableResult;
|
|
588
|
+
return { tokens: exportableResult, allTokens: flattenTokens(exportableResult, this.usesDtcg) };
|
|
543
589
|
}
|
|
544
590
|
|
|
545
591
|
/**
|
|
546
592
|
* This will get the dictionary / platformConfig for specified platform name
|
|
547
593
|
* Runs transforms, reference resolutions
|
|
594
|
+
* @deprecated use getPlatformConfig / getPlatformTokens instead
|
|
548
595
|
* @param {string} platform
|
|
596
|
+
* @param {{ cache?: boolean }} [opts]
|
|
549
597
|
* @returns
|
|
550
598
|
*/
|
|
551
|
-
async getPlatform(platform) {
|
|
599
|
+
async getPlatform(platform, opts) {
|
|
552
600
|
await this.hasInitialized;
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
// We need to transform the object before we resolve the
|
|
561
|
-
// variable names because if a value contains concatenated
|
|
562
|
-
// values like "1px solid {color.border.base}" we want to
|
|
563
|
-
// transform the original value (color.border.base) before
|
|
564
|
-
// replacing that value in the string.
|
|
565
|
-
const tokens = await this.exportPlatform(platform);
|
|
566
|
-
this.allTokens = /** @type {TransformedToken[]} */ (flattenTokens(tokens, this.usesDtcg));
|
|
567
|
-
// This is the dictionary object we pass to the file
|
|
568
|
-
// building and action methods.
|
|
569
|
-
return { dictionary: { tokens, allTokens: this.allTokens }, platformConfig };
|
|
601
|
+
const platformConfig = this.getPlatformConfig(platform, opts);
|
|
602
|
+
const dictionary = await this.getPlatformTokens(platform, opts);
|
|
603
|
+
return {
|
|
604
|
+
dictionary,
|
|
605
|
+
platformConfig,
|
|
606
|
+
};
|
|
570
607
|
}
|
|
571
608
|
|
|
572
609
|
/**
|
|
@@ -755,10 +792,13 @@ export default class StyleDictionary extends Register {
|
|
|
755
792
|
|
|
756
793
|
/**
|
|
757
794
|
* @param {string} platform
|
|
795
|
+
* @param {{ cache?: boolean }} [opts]
|
|
758
796
|
*/
|
|
759
|
-
async formatPlatform(platform) {
|
|
797
|
+
async formatPlatform(platform, opts) {
|
|
760
798
|
await this.hasInitialized;
|
|
761
|
-
const
|
|
799
|
+
const platformConfig = this.getPlatformConfig(platform, opts);
|
|
800
|
+
const dictionary = await this.getPlatformTokens(platform, opts);
|
|
801
|
+
|
|
762
802
|
if (
|
|
763
803
|
platformConfig.buildPath &&
|
|
764
804
|
platformConfig.buildPath.slice(-1) !== '/' &&
|
|
@@ -802,7 +842,11 @@ export default class StyleDictionary extends Register {
|
|
|
802
842
|
return formattedFiles.map(({ output, destination }) => ({ output, destination }));
|
|
803
843
|
}
|
|
804
844
|
|
|
805
|
-
|
|
845
|
+
/**
|
|
846
|
+
* @param {{ cache?: boolean }} [opts]
|
|
847
|
+
* @returns
|
|
848
|
+
*/
|
|
849
|
+
async formatAllPlatforms(opts) {
|
|
806
850
|
await this.hasInitialized;
|
|
807
851
|
if (!this.platforms) {
|
|
808
852
|
throw new Error('Cannot format platforms due to missing property "platforms" on config');
|
|
@@ -812,7 +856,7 @@ export default class StyleDictionary extends Register {
|
|
|
812
856
|
* @param {string} platformKey
|
|
813
857
|
*/
|
|
814
858
|
const getOutputsForPlatform = async (platformKey) => {
|
|
815
|
-
const outputs = await this.formatPlatform(platformKey);
|
|
859
|
+
const outputs = await this.formatPlatform(platformKey, opts);
|
|
816
860
|
return { platform: platformKey, outputs };
|
|
817
861
|
};
|
|
818
862
|
|
|
@@ -830,11 +874,13 @@ export default class StyleDictionary extends Register {
|
|
|
830
874
|
|
|
831
875
|
/**
|
|
832
876
|
* @param {string} platform
|
|
877
|
+
* @param {{ cache?: boolean }} [opts]
|
|
833
878
|
* @returns
|
|
834
879
|
*/
|
|
835
|
-
async buildPlatform(platform) {
|
|
880
|
+
async buildPlatform(platform, opts) {
|
|
836
881
|
await this.hasInitialized;
|
|
837
|
-
const
|
|
882
|
+
const platformConfig = this.getPlatformConfig(platform, opts);
|
|
883
|
+
const dictionary = await this.getPlatformTokens(platform, opts);
|
|
838
884
|
|
|
839
885
|
/**
|
|
840
886
|
* @param {string} destination
|
|
@@ -850,7 +896,7 @@ export default class StyleDictionary extends Register {
|
|
|
850
896
|
return this.volume.promises.writeFile(destination, output);
|
|
851
897
|
};
|
|
852
898
|
|
|
853
|
-
const files = await this.formatPlatform(platform);
|
|
899
|
+
const files = await this.formatPlatform(platform, opts);
|
|
854
900
|
if (files) {
|
|
855
901
|
await Promise.all(
|
|
856
902
|
files.map(({ destination, output }) => {
|
|
@@ -876,10 +922,14 @@ export default class StyleDictionary extends Register {
|
|
|
876
922
|
return this;
|
|
877
923
|
}
|
|
878
924
|
|
|
879
|
-
|
|
925
|
+
/**
|
|
926
|
+
* @param {{ cache?: boolean }} [opts]
|
|
927
|
+
* @returns
|
|
928
|
+
*/
|
|
929
|
+
async buildAllPlatforms(opts) {
|
|
880
930
|
await this.hasInitialized;
|
|
881
931
|
if (this.platforms) {
|
|
882
|
-
await Promise.all(Object.keys(this.platforms).map((key) => this.buildPlatform(key)));
|
|
932
|
+
await Promise.all(Object.keys(this.platforms).map((key) => this.buildPlatform(key, opts)));
|
|
883
933
|
}
|
|
884
934
|
// For chaining
|
|
885
935
|
return this;
|
|
@@ -887,10 +937,12 @@ export default class StyleDictionary extends Register {
|
|
|
887
937
|
|
|
888
938
|
/**
|
|
889
939
|
* @param {string} platform
|
|
940
|
+
* @param {{ cache?: boolean }} [opts]
|
|
890
941
|
* @returns
|
|
891
942
|
*/
|
|
892
|
-
async cleanPlatform(platform) {
|
|
893
|
-
const
|
|
943
|
+
async cleanPlatform(platform, opts) {
|
|
944
|
+
const platformConfig = this.getPlatformConfig(platform, opts);
|
|
945
|
+
const dictionary = await this.getPlatformTokens(platform, opts);
|
|
894
946
|
// collect logs, cleanFiles happens in parallel but we want to log in sequence
|
|
895
947
|
const logs = await cleanFiles(platformConfig, this.volume);
|
|
896
948
|
if (logs) {
|
|
@@ -915,10 +967,14 @@ export default class StyleDictionary extends Register {
|
|
|
915
967
|
return this;
|
|
916
968
|
}
|
|
917
969
|
|
|
918
|
-
|
|
970
|
+
/**
|
|
971
|
+
* @param {{ cache?: boolean }} [opts]
|
|
972
|
+
* @returns
|
|
973
|
+
*/
|
|
974
|
+
async cleanAllPlatforms(opts) {
|
|
919
975
|
await this.hasInitialized;
|
|
920
976
|
if (this.platforms) {
|
|
921
|
-
await Promise.all(Object.keys(this.platforms).map((key) => this.cleanPlatform(key)));
|
|
977
|
+
await Promise.all(Object.keys(this.platforms).map((key) => this.cleanPlatform(key, opts)));
|
|
922
978
|
}
|
|
923
979
|
// For chaining
|
|
924
980
|
return this;
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Split a string comment by newlines and
|
|
3
|
+
* convert to multi-line comment if necessary
|
|
4
|
+
* @param {string} to_ret_token
|
|
5
|
+
* @param {string} comment
|
|
6
|
+
* @param {Formatting} options
|
|
7
|
+
* @returns {string}
|
|
8
|
+
*/
|
|
9
|
+
export function addComment(to_ret_token: string, comment: string, options: Formatting): string;
|
|
1
10
|
/**
|
|
2
11
|
* Creates a function that can be used to format a token. This can be useful
|
|
3
12
|
* to use as the function on `dictionary.allTokens.map`. The formatting
|
|
@@ -40,7 +40,7 @@ const defaultFormatting = {
|
|
|
40
40
|
* @param {Formatting} options
|
|
41
41
|
* @returns {string}
|
|
42
42
|
*/
|
|
43
|
-
function addComment(to_ret_token, comment, options) {
|
|
43
|
+
export function addComment(to_ret_token, comment, options) {
|
|
44
44
|
const { commentStyle, indentation } = options;
|
|
45
45
|
let { commentPosition } = options;
|
|
46
46
|
|
package/lib/common/formats.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export default formats;
|
|
2
2
|
export type Format = import("../../types/Format.ts").Format;
|
|
3
3
|
export type FormatArgs = import("../../types/Format.ts").FormatFnArguments;
|
|
4
|
-
export type
|
|
4
|
+
export type FormattingOverrides = import("../../types/File").FormattingOverrides;
|
|
5
5
|
export type OutputReferences = import("../../types/Format.ts").OutputReferences;
|
|
6
6
|
export type Token = import("../../types/DesignToken.ts").TransformedToken;
|
|
7
7
|
export type Tokens = import("../../types/DesignToken.ts").TransformedTokens;
|
package/lib/common/formats.js
CHANGED
|
@@ -49,7 +49,7 @@ import plistTemplate from './templates/ios/plist.template.js';
|
|
|
49
49
|
/**
|
|
50
50
|
* @typedef {import('../../types/Format.ts').Format} Format
|
|
51
51
|
* @typedef {import('../../types/Format.ts').FormatFnArguments} FormatArgs
|
|
52
|
-
* @typedef {import('../../types/File').
|
|
52
|
+
* @typedef {import('../../types/File').FormattingOverrides} FormattingOverrides
|
|
53
53
|
* @typedef {import('../../types/Format.ts').OutputReferences} OutputReferences
|
|
54
54
|
* @typedef {import('../../types/DesignToken.ts').TransformedToken} Token
|
|
55
55
|
* @typedef {import('../../types/DesignToken.ts').TransformedTokens} Tokens
|
|
@@ -60,11 +60,13 @@ import plistTemplate from './templates/ios/plist.template.js';
|
|
|
60
60
|
*/
|
|
61
61
|
|
|
62
62
|
/**
|
|
63
|
-
*
|
|
64
|
-
*
|
|
63
|
+
* Remove prefix because the prefix option for createPropertyFormatter
|
|
64
|
+
* is not the same as the prefix inside header comment
|
|
65
|
+
* @param {FormattingOverrides} [formatting]
|
|
65
66
|
*/
|
|
66
67
|
function getFormattingCloneWithoutPrefix(formatting) {
|
|
67
68
|
const formattingWithoutPrefix = structuredClone(formatting) ?? {};
|
|
69
|
+
// @ts-expect-error users are not supposed to pass "prefix" but they might because it used to be supported
|
|
68
70
|
delete formattingWithoutPrefix.prefix;
|
|
69
71
|
return formattingWithoutPrefix;
|
|
70
72
|
}
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
* @param {number} depth
|
|
13
13
|
*/
|
|
14
14
|
function processJsonNode(obj, options, depth = 0) {
|
|
15
|
+
const indent = options.formatting?.indentation ?? ' ';
|
|
15
16
|
let output = '';
|
|
16
17
|
if (obj === null) {
|
|
17
18
|
output += `''`;
|
|
@@ -22,15 +23,18 @@ function processJsonNode(obj, options, depth = 0) {
|
|
|
22
23
|
output += `$${obj.name}`;
|
|
23
24
|
} else {
|
|
24
25
|
// if we have found a group of tokens, use the Sass group "(...)" syntax and loop -recursively- on the children
|
|
25
|
-
output +=
|
|
26
|
+
output += `(\n`;
|
|
26
27
|
output += Object.keys(obj)
|
|
27
28
|
.map(function (newKey) {
|
|
28
29
|
const newProp = obj[newKey];
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
return `${indent.repeat(depth + 1)}'${newKey}': ${processJsonNode(
|
|
31
|
+
newProp,
|
|
32
|
+
options,
|
|
33
|
+
depth + 1,
|
|
34
|
+
)}`;
|
|
31
35
|
})
|
|
32
|
-
.join(
|
|
33
|
-
output +=
|
|
36
|
+
.join(`,\n`);
|
|
37
|
+
output += `\n` + indent.repeat(depth) + ')';
|
|
34
38
|
}
|
|
35
39
|
return output;
|
|
36
40
|
}
|
|
@@ -41,6 +45,8 @@ function processJsonNode(obj, options, depth = 0) {
|
|
|
41
45
|
* options: Config & LocalOptions
|
|
42
46
|
* }} opts
|
|
43
47
|
*/
|
|
44
|
-
export default ({ dictionary, options }) =>
|
|
48
|
+
export default ({ dictionary, options }) => {
|
|
49
|
+
return `
|
|
45
50
|
$${options.mapName ?? 'tokens'}: ${processJsonNode(dictionary.tokens, options)};
|
|
46
51
|
`;
|
|
52
|
+
};
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { addComment } from '../../formatHelpers/createPropertyFormatter.js';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* @typedef {import('../../../../types/DesignToken.ts').TransformedToken} TransformedToken
|
|
3
5
|
* @typedef {import('../../../../types/Config.ts').Config} Config
|
|
@@ -11,14 +13,24 @@
|
|
|
11
13
|
* header: string
|
|
12
14
|
* }} opts
|
|
13
15
|
*/
|
|
14
|
-
export default ({ allTokens, options, header }) =>
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
export default ({ allTokens, options, header }) => {
|
|
17
|
+
const _f = options.formatting ?? {};
|
|
18
|
+
const f = {
|
|
19
|
+
..._f,
|
|
20
|
+
indentation: _f.indentation ?? ' ',
|
|
21
|
+
commentStyle: _f.commentStyle ?? 'short',
|
|
22
|
+
commentPosition: _f.commentPosition ?? 'above',
|
|
23
|
+
};
|
|
24
|
+
return `
|
|
25
|
+
${header}$${options.mapName ?? 'tokens'}: (\n${allTokens
|
|
26
|
+
.map((token, i, arr) => {
|
|
27
|
+
const tokenString = `${f.indentation}'${token.name}': ${
|
|
20
28
|
options.usesDtcg ? token.$value : token.value
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
29
|
+
}${i !== arr.length - 1 ? ',' : ''}`;
|
|
30
|
+
if (token.comment && f.commentStyle !== 'none') {
|
|
31
|
+
return addComment(tokenString, token.comment, f);
|
|
32
|
+
}
|
|
33
|
+
return tokenString;
|
|
34
|
+
})
|
|
35
|
+
.join(`\n`)}\n);`;
|
|
36
|
+
};
|
package/lib/common/transforms.js
CHANGED
|
@@ -832,6 +832,7 @@ export default {
|
|
|
832
832
|
}
|
|
833
833
|
const parsedVal = parseFloat(nonParsed);
|
|
834
834
|
if (isNaN(parsedVal)) throwSizeError(token.name, nonParsed, 'rem');
|
|
835
|
+
if (parsedVal === 0) return Number.isInteger(nonParsed) ? 0 : '0';
|
|
835
836
|
return parsedVal + 'rem';
|
|
836
837
|
},
|
|
837
838
|
},
|
package/lib/fs.d.ts
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
*/
|
|
4
4
|
/**
|
|
5
5
|
* Allow to be overridden by setter, set default to memfs for browser env, node:fs for node env
|
|
6
|
+
* Default CJS export when converted to ESM, messes up the types a bit so we need to
|
|
7
|
+
* cast the default import to type of Volume by first casting to unknown...
|
|
6
8
|
*/
|
|
7
9
|
export let fs: Volume;
|
|
8
10
|
export function setFs(_fs: Volume, isNodeFS?: boolean | undefined): void;
|
package/lib/fs.js
CHANGED
|
@@ -6,8 +6,10 @@ import memfs from '@bundled-es-modules/memfs';
|
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Allow to be overridden by setter, set default to memfs for browser env, node:fs for node env
|
|
9
|
+
* Default CJS export when converted to ESM, messes up the types a bit so we need to
|
|
10
|
+
* cast the default import to type of Volume by first casting to unknown...
|
|
9
11
|
*/
|
|
10
|
-
export let fs = /** @type {Volume} */ (memfs);
|
|
12
|
+
export let fs = /** @type {Volume} */ (/** @type {unknown} */ (memfs));
|
|
11
13
|
|
|
12
14
|
/**
|
|
13
15
|
* since ES modules exports are read-only, use a setter
|
package/lib/utils/combineJSON.js
CHANGED
|
@@ -33,7 +33,7 @@ import { detectDtcgSyntax } from './detectDtcgSyntax.js';
|
|
|
33
33
|
function traverseObj(obj, fn) {
|
|
34
34
|
for (let key in obj) {
|
|
35
35
|
const prop = obj[key];
|
|
36
|
-
if (prop) {
|
|
36
|
+
if (prop != null) {
|
|
37
37
|
fn.apply(null, [obj, key, prop]);
|
|
38
38
|
if (typeof prop === 'object') {
|
|
39
39
|
traverseObj(prop, fn);
|
|
@@ -211,7 +211,13 @@ function expandTokensRecurse(slice, original, opts, platform) {
|
|
|
211
211
|
if (value) {
|
|
212
212
|
// if our token is a ref, we have to resolve it first in order to expand its value
|
|
213
213
|
if (typeof value === 'string' && usesReferences(value)) {
|
|
214
|
-
|
|
214
|
+
try {
|
|
215
|
+
value = resolveReferences(value, original, { usesDtcg: uses$ });
|
|
216
|
+
} catch (e) {
|
|
217
|
+
// do nothing, references may be broken but now is not the time to
|
|
218
|
+
// complain about it, as we're just doing this here so we can expand
|
|
219
|
+
// tokens that reference object-value tokens that need to be expanded
|
|
220
|
+
}
|
|
215
221
|
}
|
|
216
222
|
|
|
217
223
|
if (
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export const verbosityInfo: "Use log.verbosity \"verbose\" or use CLI option --verbose for more details.";
|
|
1
|
+
export const verbosityInfo: "Use log.verbosity \"verbose\" or use CLI option --verbose for more details.\nRefer to: https://styledictionary.com/reference/logging/";
|
|
2
2
|
export class GroupMessages {
|
|
3
3
|
/** @type {{[key: string]: string[]}} */
|
|
4
4
|
groupedMessages: {
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* and limitations under the License.
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
-
export const verbosityInfo = `Use log.verbosity "verbose" or use CLI option --verbose for more details
|
|
14
|
+
export const verbosityInfo = `Use log.verbosity "verbose" or use CLI option --verbose for more details.\nRefer to: https://styledictionary.com/reference/logging/`;
|
|
15
15
|
|
|
16
16
|
export class GroupMessages {
|
|
17
17
|
constructor() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "style-dictionary",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.1.0",
|
|
4
4
|
"description": "Style once, use everywhere. A build system for creating cross-platform styles.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"style dictionary",
|
|
@@ -59,6 +59,8 @@
|
|
|
59
59
|
"test:coverage": "cd coverage/lcov-report && npx http-server -o -c-1",
|
|
60
60
|
"test:update-snapshots": "web-test-runner --update-snapshots",
|
|
61
61
|
"test:node": "mocha -r mocha-hooks.mjs './__integration__/**/*.test.js' './__tests__/**/*.test.js' './__node_tests__/**/*.test.js'",
|
|
62
|
+
"test:perf": "mocha -r mocha-hooks.mjs './__perf_tests__/**/*.test.js'",
|
|
63
|
+
"test:perf:debug": "web-test-runner --config wtr-perf.config.mjs --watch",
|
|
62
64
|
"install-cli": "npm install -g $(npm pack)",
|
|
63
65
|
"release": "npm run build && changeset publish",
|
|
64
66
|
"prepare": "husky install",
|
|
@@ -102,7 +104,7 @@
|
|
|
102
104
|
"dependencies": {
|
|
103
105
|
"@bundled-es-modules/deepmerge": "^4.3.1",
|
|
104
106
|
"@bundled-es-modules/glob": "^10.4.2",
|
|
105
|
-
"@bundled-es-modules/memfs": "^4.
|
|
107
|
+
"@bundled-es-modules/memfs": "^4.9.4",
|
|
106
108
|
"@zip.js/zip.js": "^2.7.44",
|
|
107
109
|
"chalk": "^5.3.0",
|
|
108
110
|
"change-case": "^5.3.0",
|
|
@@ -147,7 +149,6 @@
|
|
|
147
149
|
"lint-staged": "^12.3.1",
|
|
148
150
|
"lit": "^3.1.2",
|
|
149
151
|
"mdast": "^3.0.0",
|
|
150
|
-
"memfs": "^4.6.0",
|
|
151
152
|
"mermaid": "^10.9.1",
|
|
152
153
|
"mocha": "^10.2.0",
|
|
153
154
|
"monaco-editor": "^0.47.0",
|
package/types/Config.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { DesignToken, DesignTokens, PreprocessedTokens } from './DesignToken.ts';
|
|
2
2
|
import type { Filter } from './Filter.ts';
|
|
3
|
-
import type { FileHeader, File,
|
|
3
|
+
import type { FileHeader, File, FormattingOverrides } from './File.ts';
|
|
4
4
|
import type { Parser } from './Parser.ts';
|
|
5
5
|
import type { Preprocessor } from './Preprocessor.ts';
|
|
6
6
|
import type { Transform } from './Transform.ts';
|
|
@@ -21,7 +21,7 @@ export interface LocalOptions {
|
|
|
21
21
|
fileHeader?: string | FileHeader;
|
|
22
22
|
outputReferences?: OutputReferences;
|
|
23
23
|
outputReferenceFallbacks?: boolean;
|
|
24
|
-
formatting?:
|
|
24
|
+
formatting?: FormattingOverrides;
|
|
25
25
|
[key: string]: any;
|
|
26
26
|
}
|
|
27
27
|
export interface RegexOptions {
|
|
@@ -80,7 +80,7 @@ export interface Config {
|
|
|
80
80
|
hooks?: Hooks;
|
|
81
81
|
expand?: ExpandConfig;
|
|
82
82
|
platforms?: Record<string, PlatformConfig>;
|
|
83
|
-
parsers?:
|
|
83
|
+
parsers?: string[];
|
|
84
84
|
preprocessors?: string[];
|
|
85
85
|
usesDtcg?: boolean;
|
|
86
86
|
}
|
package/types/File.d.ts
CHANGED
|
@@ -2,16 +2,18 @@ import type { TransformedToken } from './DesignToken.ts';
|
|
|
2
2
|
import type { FormatFn } from './Format.ts';
|
|
3
3
|
import type { LocalOptions, Config } from './Config.ts';
|
|
4
4
|
import type { Filter } from './Filter.ts';
|
|
5
|
-
export interface FormattingOptions {
|
|
5
|
+
export interface FormattingOptions extends FormattingOverrides {
|
|
6
6
|
prefix?: string;
|
|
7
7
|
suffix?: string;
|
|
8
8
|
lineSeparator?: string;
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
separator?: string;
|
|
10
|
+
}
|
|
11
|
+
export interface FormattingOverrides {
|
|
11
12
|
commentStyle?: 'short' | 'long' | 'none';
|
|
12
13
|
commentPosition?: 'above' | 'inline';
|
|
13
14
|
indentation?: string;
|
|
14
|
-
|
|
15
|
+
header?: string;
|
|
16
|
+
footer?: string;
|
|
15
17
|
fileHeaderTimestamp?: boolean;
|
|
16
18
|
}
|
|
17
19
|
export type FileHeader = (defaultMessage: string[], options?: Config) => Promise<string[]> | string[];
|
package/types/Volume.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export type Volume = (
|
|
1
|
+
import type { Volume as _Volume } from '@bundled-es-modules/memfs';
|
|
2
|
+
export type Volume = (InstanceType<typeof _Volume> | typeof import('node:fs')) & {
|
|
3
3
|
__custom_fs__?: boolean;
|
|
4
4
|
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
declare module '@bundled-es-modules/memfs';
|