style-dictionary 3.0.0 → 3.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 +3 -0
- package/bin/style-dictionary +2 -2
- package/examples/advanced/assets-base64-embed/package.json +1 -1
- package/examples/advanced/auto-rebuild-watcher/package.json +2 -2
- package/examples/advanced/component-cti/package.json +1 -1
- package/examples/advanced/create-react-app/package.json +3 -3
- package/examples/advanced/create-react-native-app/package.json +1 -1
- package/examples/advanced/custom-file-header/package.json +1 -1
- package/examples/advanced/custom-formats-with-templates/package.json +1 -1
- package/examples/advanced/custom-parser/package.json +1 -1
- package/examples/advanced/custom-transforms/build.js +1 -1
- package/examples/advanced/custom-transforms/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/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/config.js +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 +1 -1
- package/examples/advanced/variables-in-outputs/README.md +9 -5
- package/examples/advanced/variables-in-outputs/package.json +1 -1
- package/examples/advanced/variables-in-outputs/sd.config.js +8 -4
- package/examples/advanced/yaml-tokens/package.json +1 -1
- package/lib/common/formatHelpers/createPropertyFormatter.js +5 -3
- package/lib/common/formatHelpers/fileHeader.js +1 -1
- package/lib/common/formatHelpers/formattedVariables.js +4 -3
- package/lib/common/formatHelpers/getTypeScriptType.js +77 -0
- package/lib/common/formatHelpers/index.js +2 -1
- package/lib/common/formats.js +24 -12
- package/lib/common/templates/scss/map-deep.template +1 -15
- package/lib/common/transforms.js +25 -2
- package/lib/extend.js +1 -0
- package/lib/utils/combineJSON.js +1 -0
- package/lib/utils/createFormatArgs.js +5 -1
- package/lib/utils/es6_.js +6 -1
- package/lib/utils/jsonc.js +14 -0
- package/lib/utils/references/getReferences.js +1 -1
- package/lib/utils/resolveObject.js +11 -0
- package/package.json +4 -2
- package/types/Config.d.ts +2 -2
- package/types/File.d.ts +2 -1
- package/types/FileHeader.d.ts +1 -1
- package/types/Format.d.ts +2 -1
- package/types/FormatHelpers.d.ts +1 -1
- package/types/Platform.d.ts +1 -0
- package/types/TransformGroup.d.ts +1 -2
- package/types/_helpers.ts +1 -3
- package/types/index.d.ts +25 -4
- package/types/index.test-d.ts +4 -0
package/README.md
CHANGED
|
@@ -22,6 +22,9 @@ For detailed usage head to https://amzn.github.io/style-dictionary
|
|
|
22
22
|
## Watch the Demo on Youtube
|
|
23
23
|
[](http://youtu.be/1HREvonfqhY)
|
|
24
24
|
|
|
25
|
+
## Experiment in the playground
|
|
26
|
+
Try the browser-based Style Dictionary playground: [https://www.style-dictionary-play.dev/](https://www.style-dictionary-play.dev/), built by the folks at [\<div\>RIOTS](https://divriots.com/).
|
|
27
|
+
|
|
25
28
|
## Contents
|
|
26
29
|
* [Installation](#installation)
|
|
27
30
|
* [Usage](#usage)
|
package/bin/style-dictionary
CHANGED
|
@@ -29,7 +29,7 @@ function getConfigPath(options) {
|
|
|
29
29
|
process.exit(1);
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
|
-
|
|
32
|
+
|
|
33
33
|
return configPath;
|
|
34
34
|
}
|
|
35
35
|
|
|
@@ -72,7 +72,7 @@ program
|
|
|
72
72
|
|
|
73
73
|
// error on unknown commands
|
|
74
74
|
program.on('command:*', function () {
|
|
75
|
-
console.error('Invalid command: %s\nSee --help for a list of available commands.',
|
|
75
|
+
console.error('Invalid command: %s\nSee --help for a list of available commands.', process.argv.slice(2).join(' '));
|
|
76
76
|
process.exit(1);
|
|
77
77
|
});
|
|
78
78
|
|
|
@@ -10,13 +10,13 @@
|
|
|
10
10
|
"scripts": {
|
|
11
11
|
"build": "node_modules/.bin/style-dictionary build",
|
|
12
12
|
"clean": "rm -rf build",
|
|
13
|
-
"watch": "npm run build && chokidar \"
|
|
13
|
+
"watch": "npm run build && chokidar \"tokens/**/*.json\" -c \"npm run build\"",
|
|
14
14
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
15
15
|
},
|
|
16
16
|
"author": "",
|
|
17
17
|
"license": "Apache-2.0",
|
|
18
18
|
"devDependencies": {
|
|
19
19
|
"chokidar-cli": "^1.2.0",
|
|
20
|
-
"style-dictionary": "3.
|
|
20
|
+
"style-dictionary": "3.1.0"
|
|
21
21
|
}
|
|
22
22
|
}
|
|
@@ -3,14 +3,14 @@
|
|
|
3
3
|
"description": "",
|
|
4
4
|
"version": "1.0.0",
|
|
5
5
|
"dependencies": {
|
|
6
|
-
"node-sass": "^
|
|
6
|
+
"node-sass": "^6.0.1",
|
|
7
7
|
"react": "^17.0.1",
|
|
8
8
|
"react-dom": "^17.0.1",
|
|
9
9
|
"react-scripts": "^4.0.3",
|
|
10
|
-
"styled-components": "^5.
|
|
10
|
+
"styled-components": "^5.3.0"
|
|
11
11
|
},
|
|
12
12
|
"devDependencies": {
|
|
13
|
-
"style-dictionary": "3.
|
|
13
|
+
"style-dictionary": "3.1.0"
|
|
14
14
|
},
|
|
15
15
|
"resolutions": {
|
|
16
16
|
"immer": "8.0.1",
|
|
@@ -95,7 +95,7 @@ StyleDictionary.registerTransformGroup({
|
|
|
95
95
|
|
|
96
96
|
StyleDictionary.registerFormat({
|
|
97
97
|
name: 'custom/android/xml',
|
|
98
|
-
formatter: function(dictionary) {
|
|
98
|
+
formatter: function({ dictionary }) {
|
|
99
99
|
return dictionary.allTokens.map(function(token) {
|
|
100
100
|
return `<item name="${token.name}">${token.value}</item>`;
|
|
101
101
|
}).join('\n');
|
|
@@ -30,7 +30,7 @@ module.exports = {
|
|
|
30
30
|
// proper style. If the file has a custom file header defined, or
|
|
31
31
|
// showFileHeader option, it will honor those.
|
|
32
32
|
return fileHeader({file, commentStyle: 'short'}) +
|
|
33
|
-
dictionary.
|
|
33
|
+
dictionary.allTokens
|
|
34
34
|
// sortByReference returns a function that can be used as to sort
|
|
35
35
|
// an array. This will sort the array so that references always
|
|
36
36
|
// come after their instantiation so that there are no errors
|
|
@@ -81,7 +81,7 @@ module.exports = {
|
|
|
81
81
|
|
|
82
82
|
StyleDictionary.registerFormat({
|
|
83
83
|
name: "custom/cjsmodule",
|
|
84
|
-
formatter: function
|
|
84
|
+
formatter: function({ dictionary }) {
|
|
85
85
|
return `module.exports = {${dictionary.allTokens.map(
|
|
86
86
|
(token) => `\n\t${token.name}: "${token.value}"`
|
|
87
87
|
)}\n};`;
|
|
@@ -24,17 +24,21 @@ The `sd.config.js` file has everything you need to see. The tokens included in t
|
|
|
24
24
|
Here is an example that shows how to get an alias's name within a custom format:
|
|
25
25
|
```javascript
|
|
26
26
|
//...
|
|
27
|
-
function(dictionary) {
|
|
27
|
+
function({ dictionary }) {
|
|
28
28
|
return dictionary.allTokens.map(token => {
|
|
29
29
|
let value = JSON.stringify(token.value);
|
|
30
30
|
// the `dictionary` object now has `usesReference()` and
|
|
31
31
|
// `getReferences()` methods. `usesReference()` will return true if
|
|
32
32
|
// the value has a reference in it. `getReferences()` will return
|
|
33
|
-
// an array of references to the whole tokens so that you can access
|
|
34
|
-
//
|
|
33
|
+
// an array of references to the whole tokens so that you can access their
|
|
34
|
+
// names or any other attributes.
|
|
35
35
|
if (dictionary.usesReference(token.original.value)) {
|
|
36
|
-
const
|
|
37
|
-
|
|
36
|
+
const refs = dictionary.getReferences(token.original.value);
|
|
37
|
+
refs.forEach(ref => {
|
|
38
|
+
value = value.replace(ref.value, function() {
|
|
39
|
+
return `${ref.name}`;
|
|
40
|
+
});
|
|
41
|
+
});
|
|
38
42
|
}
|
|
39
43
|
return `export const ${token.name} = ${value};`
|
|
40
44
|
}).join(`\n`)
|
|
@@ -9,11 +9,15 @@ module.exports = {
|
|
|
9
9
|
// the `dictionary` object now has `usesReference()` and
|
|
10
10
|
// `getReferences()` methods. `usesReference()` will return true if
|
|
11
11
|
// the value has a reference in it. `getReferences()` will return
|
|
12
|
-
// an array of references to the whole tokens so that you can access
|
|
13
|
-
//
|
|
12
|
+
// an array of references to the whole tokens so that you can access
|
|
13
|
+
// their names or any other attributes.
|
|
14
14
|
if (dictionary.usesReference(token.original.value)) {
|
|
15
|
-
const
|
|
16
|
-
|
|
15
|
+
const refs = dictionary.getReferences(token.original.value);
|
|
16
|
+
refs.forEach(ref => {
|
|
17
|
+
value = value.replace(ref.value, function() {
|
|
18
|
+
return `${ref.name}`;
|
|
19
|
+
});
|
|
20
|
+
});
|
|
17
21
|
}
|
|
18
22
|
}
|
|
19
23
|
|
|
@@ -45,9 +45,10 @@ const defaultFormatting = {
|
|
|
45
45
|
* @param {Dictionary} options.dictionary - The dictionary object sent to the formatter function
|
|
46
46
|
* @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
|
|
47
47
|
* @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}`
|
|
48
|
+
* @param {Boolean} options.themeable [false] - Whether tokens should default to being themeable.
|
|
48
49
|
* @returns {Function}
|
|
49
50
|
*/
|
|
50
|
-
function createPropertyFormatter({outputReferences, dictionary, format, formatting={}}) {
|
|
51
|
+
function createPropertyFormatter({ outputReferences, dictionary, format, formatting = {}, themeable = false }) {
|
|
51
52
|
let {prefix, commentStyle, indentation, separator, suffix} = Object.assign({}, defaultFormatting, formatting);
|
|
52
53
|
|
|
53
54
|
switch(format) {
|
|
@@ -117,7 +118,8 @@ function createPropertyFormatter({outputReferences, dictionary, format, formatti
|
|
|
117
118
|
|
|
118
119
|
to_ret_prop += prop.attributes.category === 'asset' ? `"${value}"` : value;
|
|
119
120
|
|
|
120
|
-
|
|
121
|
+
const themeable_prop = typeof prop.themeable === 'boolean' ? prop.themeable : themeable;
|
|
122
|
+
if (format === 'sass' && themeable_prop) {
|
|
121
123
|
to_ret_prop += ' !default';
|
|
122
124
|
}
|
|
123
125
|
|
|
@@ -135,4 +137,4 @@ function createPropertyFormatter({outputReferences, dictionary, format, formatti
|
|
|
135
137
|
}
|
|
136
138
|
}
|
|
137
139
|
|
|
138
|
-
module.exports = createPropertyFormatter;
|
|
140
|
+
module.exports = createPropertyFormatter;
|
|
@@ -38,7 +38,7 @@ const defaultFormatting = {
|
|
|
38
38
|
* StyleDictionary.registerFormat({
|
|
39
39
|
* name: 'myCustomFormat',
|
|
40
40
|
* formatter: function({ dictionary, file }) {
|
|
41
|
-
* return fileHeader({file, 'short') +
|
|
41
|
+
* return fileHeader({file, commentStyle: 'short'}) +
|
|
42
42
|
* dictionary.allTokens.map(token => `${token.name} = ${token.value}`)
|
|
43
43
|
* .join('\n');
|
|
44
44
|
* }
|
|
@@ -27,6 +27,7 @@ const defaultFormatting = {
|
|
|
27
27
|
* @param {Object} options.dictionary - The dictionary object that gets passed to the formatter method.
|
|
28
28
|
* @param {Boolean} options.outputReferences - Whether or not to output references
|
|
29
29
|
* @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.
|
|
30
|
+
* @param {Boolean} options.themeable [false] - Whether tokens should default to being themeable.
|
|
30
31
|
* @returns {String}
|
|
31
32
|
* @example
|
|
32
33
|
* ```js
|
|
@@ -38,7 +39,7 @@ const defaultFormatting = {
|
|
|
38
39
|
* });
|
|
39
40
|
* ```
|
|
40
41
|
*/
|
|
41
|
-
function formattedVariables({format, dictionary, outputReferences=false, formatting={}}) {
|
|
42
|
+
function formattedVariables({ format, dictionary, outputReferences = false, formatting = {}, themeable = false}) {
|
|
42
43
|
let {allTokens} = dictionary;
|
|
43
44
|
|
|
44
45
|
let {lineSeparator} = Object.assign({}, defaultFormatting, formatting);
|
|
@@ -56,9 +57,9 @@ function formattedVariables({format, dictionary, outputReferences=false, formatt
|
|
|
56
57
|
}
|
|
57
58
|
|
|
58
59
|
return allTokens
|
|
59
|
-
.map(createPropertyFormatter({ outputReferences, dictionary, format, formatting }))
|
|
60
|
+
.map(createPropertyFormatter({ outputReferences, dictionary, format, formatting, themeable }))
|
|
60
61
|
.filter(function(strVal) { return !!strVal })
|
|
61
62
|
.join(lineSeparator);
|
|
62
63
|
}
|
|
63
64
|
|
|
64
|
-
module.exports = formattedVariables;
|
|
65
|
+
module.exports = formattedVariables;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with
|
|
5
|
+
* the License. A copy of the License is located at
|
|
6
|
+
*
|
|
7
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
*
|
|
9
|
+
* or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
10
|
+
* CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
|
|
11
|
+
* and limitations under the License.
|
|
12
|
+
*/
|
|
13
|
+
const { unique } = require('../../utils/es6_');
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Given some value, returns a basic valid TypeScript type for that value.
|
|
17
|
+
* Supports numbers, strings, booleans, arrays and objects of any of those types.
|
|
18
|
+
*
|
|
19
|
+
* @memberof module:formatHelpers
|
|
20
|
+
* @example
|
|
21
|
+
* ```javascript
|
|
22
|
+
* StyleDictionary.registerFormat({
|
|
23
|
+
* name: 'myCustomFormat',
|
|
24
|
+
* formatter: function({ dictionary, options }) {
|
|
25
|
+
* return dictionary.allProperties.map(function(prop) {
|
|
26
|
+
* var to_ret_prop = 'export const ' + prop.name + ' : ' + getTypeScriptType(prop.value) + ';';
|
|
27
|
+
* if (prop.comment)
|
|
28
|
+
* to_ret_prop = to_ret_prop.concat(' // ' + prop.comment);
|
|
29
|
+
* return to_ret_prop;
|
|
30
|
+
* }).join('\n');
|
|
31
|
+
* }
|
|
32
|
+
* });
|
|
33
|
+
*
|
|
34
|
+
* @param {*} value A value to check the type of.
|
|
35
|
+
* @return {String} A valid name for a TypeScript type.
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
function getTypeScriptType(value) {
|
|
39
|
+
if (Array.isArray(value)) return getArrayType(value)
|
|
40
|
+
if (typeof value === 'object') return getObjectType(value)
|
|
41
|
+
if (['string', 'number', 'boolean'].includes(typeof value)) return typeof value
|
|
42
|
+
|
|
43
|
+
return 'any'
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* @param {Object} value An object with uknown type properties
|
|
48
|
+
* @returns {String} A representation of the type model for the passed object
|
|
49
|
+
*/
|
|
50
|
+
function getObjectType(value) {
|
|
51
|
+
const entries = Object.entries(value)
|
|
52
|
+
return `{ ${entries.map(([key, property], index) => {
|
|
53
|
+
const isLast = entries.length === index + 1
|
|
54
|
+
return `${key}: ${getTypeScriptType(property)}${!isLast ? ', ' : ''}`
|
|
55
|
+
}).join('')} }`
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* @param {Array} value An array to check each property of
|
|
60
|
+
* @returns {String} A valid type for the passed array and it's items
|
|
61
|
+
*/
|
|
62
|
+
function getArrayType(passedArray) {
|
|
63
|
+
if (passedArray.length > 0) {
|
|
64
|
+
const firstValueType = getTypeScriptType(passedArray[0]);
|
|
65
|
+
if (passedArray.every((v) => getTypeScriptType(v) === firstValueType)) {
|
|
66
|
+
return firstValueType + '[]';
|
|
67
|
+
} else {
|
|
68
|
+
return `(${unique(passedArray.map((item, index) => {
|
|
69
|
+
const isLast = passedArray.length === index + 1;
|
|
70
|
+
return `${getTypeScriptType(item)}${!isLast ? ' | ' : ''}`
|
|
71
|
+
})).join('')})[]`
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return 'any[]';
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
module.exports = getTypeScriptType;
|
|
@@ -15,10 +15,11 @@
|
|
|
15
15
|
*
|
|
16
16
|
* @module formatHelpers
|
|
17
17
|
*/
|
|
18
|
-
module.exports = {
|
|
18
|
+
module.exports = {
|
|
19
19
|
createPropertyFormatter: require('./createPropertyFormatter'),
|
|
20
20
|
fileHeader: require('./fileHeader'),
|
|
21
21
|
formattedVariables: require('./formattedVariables'),
|
|
22
|
+
getTypeScriptType: require('./getTypeScriptType'),
|
|
22
23
|
iconsWithPrefix: require('./iconsWithPrefix'),
|
|
23
24
|
sortByReference: require('./sortByReference'),
|
|
24
25
|
sortByName: require('./sortByName'),
|
package/lib/common/formats.js
CHANGED
|
@@ -15,7 +15,7 @@ const fs = require('fs');
|
|
|
15
15
|
const path = require('path');
|
|
16
16
|
const _template = require('lodash/template');
|
|
17
17
|
const GroupMessages = require('../utils/groupMessages');
|
|
18
|
-
const { fileHeader, formattedVariables, iconsWithPrefix, minifyDictionary, sortByReference, createPropertyFormatter, sortByName } = require('./formatHelpers');
|
|
18
|
+
const { fileHeader, formattedVariables, getTypeScriptType, iconsWithPrefix, minifyDictionary, sortByReference, createPropertyFormatter, sortByName } = require('./formatHelpers');
|
|
19
19
|
|
|
20
20
|
const SASS_MAP_FORMAT_DEPRECATION_WARNINGS = GroupMessages.GROUP.SassMapFormatDeprecationWarnings;
|
|
21
21
|
|
|
@@ -32,6 +32,7 @@ module.exports = {
|
|
|
32
32
|
* @param {Object} options
|
|
33
33
|
* @param {Boolean} [options.showFileHeader=true] - Whether or not to include a comment that has the build date
|
|
34
34
|
* @param {Boolean} [options.outputReferences=false] - Whether or not to keep [references](/#/formats?id=references-in-output-files) (a -> b -> c) in the output.
|
|
35
|
+
* @param {string} [options.selector] - Override the root css selector
|
|
35
36
|
* @example
|
|
36
37
|
* ```css
|
|
37
38
|
* :root {
|
|
@@ -83,6 +84,9 @@ module.exports = {
|
|
|
83
84
|
*
|
|
84
85
|
* @memberof Formats
|
|
85
86
|
* @kind member
|
|
87
|
+
* @param {Object} options
|
|
88
|
+
* @param {Boolean} [options.outputReferences=false] - Whether or not to keep [references](/#/formats?id=references-in-output-files) (a -> b -> c) in the output.
|
|
89
|
+
* @param {Boolean} [options.themeable=true] - Whether or not tokens should default to being themeable, if not otherwise specified per token.
|
|
86
90
|
* @example
|
|
87
91
|
* ```scss
|
|
88
92
|
* $color-background-base: #f0f0f0 !default;
|
|
@@ -99,8 +103,15 @@ module.exports = {
|
|
|
99
103
|
* ```
|
|
100
104
|
*/
|
|
101
105
|
'scss/map-deep': function({dictionary, options, file}) {
|
|
102
|
-
const
|
|
103
|
-
|
|
106
|
+
const mapTemplate = _template(fs.readFileSync(__dirname + '/templates/scss/map-deep.template'));
|
|
107
|
+
|
|
108
|
+
// Default the "themeable" option to true for backward compatibility.
|
|
109
|
+
const { outputReferences, themeable = true } = options;
|
|
110
|
+
return '\n' +
|
|
111
|
+
fileHeader({ file, commentStyle: 'long' }) +
|
|
112
|
+
formattedVariables({ format: 'sass', dictionary, outputReferences, themeable })
|
|
113
|
+
+ '\n' +
|
|
114
|
+
mapTemplate({dictionary, file});
|
|
104
115
|
},
|
|
105
116
|
|
|
106
117
|
// This will soon be removed, is left here only for backwards compatibility
|
|
@@ -119,6 +130,7 @@ module.exports = {
|
|
|
119
130
|
* @param {Object} options
|
|
120
131
|
* @param {Boolean} [options.showFileHeader=true] - Whether or not to include a comment that has the build date
|
|
121
132
|
* @param {Boolean} [options.outputReferences=false] - Whether or not to keep [references](/#/formats?id=references-in-output-files) (a -> b -> c) in the output.
|
|
133
|
+
* @param {Boolean} [options.themeable=false] - Whether or not tokens should default to being themeable, if not otherwise specified per token.
|
|
122
134
|
* @example
|
|
123
135
|
* ```scss
|
|
124
136
|
* $color-background-base: #f0f0f0;
|
|
@@ -126,9 +138,9 @@ module.exports = {
|
|
|
126
138
|
* ```
|
|
127
139
|
*/
|
|
128
140
|
'scss/variables': function({dictionary, options, file}) {
|
|
129
|
-
const { outputReferences } = options;
|
|
141
|
+
const { outputReferences, themeable = false } = options;
|
|
130
142
|
return fileHeader({file, commentStyle: 'short'}) +
|
|
131
|
-
formattedVariables({format: 'sass', dictionary, outputReferences});
|
|
143
|
+
formattedVariables({format: 'sass', dictionary, outputReferences, themeable});
|
|
132
144
|
},
|
|
133
145
|
|
|
134
146
|
/**
|
|
@@ -393,7 +405,7 @@ module.exports = {
|
|
|
393
405
|
'typescript/es6-declarations': function({dictionary, file}) {
|
|
394
406
|
return fileHeader({file}) +
|
|
395
407
|
dictionary.allProperties.map(function(prop) {
|
|
396
|
-
var to_ret_prop = 'export const ' + prop.name + ' :
|
|
408
|
+
var to_ret_prop = 'export const ' + prop.name + ' : ' + getTypeScriptType(prop.value) + ';';
|
|
397
409
|
if (prop.comment)
|
|
398
410
|
to_ret_prop = to_ret_prop.concat(' // ' + prop.comment);
|
|
399
411
|
return to_ret_prop;
|
|
@@ -445,7 +457,7 @@ module.exports = {
|
|
|
445
457
|
* const JsonToTS = require('json-to-ts');
|
|
446
458
|
* StyleDictionaryPackage.registerFormat({
|
|
447
459
|
* name: 'typescript/accurate-module-declarations',
|
|
448
|
-
* formatter: function(dictionary) {
|
|
460
|
+
* formatter: function({ dictionary }) {
|
|
449
461
|
* return 'declare const root: RootObject\n' +
|
|
450
462
|
* 'export default root\n' +
|
|
451
463
|
* JsonToTS(dictionary.properties).join('\n');
|
|
@@ -641,9 +653,9 @@ declare const ${moduleName}: ${JSON.stringify(treeWalker(dictionary.tokens), nul
|
|
|
641
653
|
* ```xml
|
|
642
654
|
* <?xml version="1.0" encoding="UTF-8"?>
|
|
643
655
|
* <resources>
|
|
644
|
-
* <integer name="time_duration_short">1000</
|
|
645
|
-
* <integer name="time_duration_medium">2000</
|
|
646
|
-
* <integer name="time_duration_long">4000</
|
|
656
|
+
* <integer name="time_duration_short">1000</integer>
|
|
657
|
+
* <integer name="time_duration_medium">2000</integer>
|
|
658
|
+
* <integer name="time_duration_long">4000</integer>
|
|
647
659
|
* ```
|
|
648
660
|
*/
|
|
649
661
|
'android/integers': function({dictionary, options, file}) {
|
|
@@ -900,7 +912,7 @@ declare const ${moduleName}: ${JSON.stringify(treeWalker(dictionary.tokens), nul
|
|
|
900
912
|
* @example
|
|
901
913
|
* ```swift
|
|
902
914
|
* public class StyleDictionary {
|
|
903
|
-
* public static let colorBackgroundDanger = UIColor(red: 1.000, green: 0.918, blue: 0.914, alpha:1)
|
|
915
|
+
* public static let colorBackgroundDanger = UIColor(red: 1.000, green: 0.918, blue: 0.914, alpha: 1)
|
|
904
916
|
* }
|
|
905
917
|
* ```
|
|
906
918
|
*/
|
|
@@ -1164,4 +1176,4 @@ declare const ${moduleName}: ${JSON.stringify(treeWalker(dictionary.tokens), nul
|
|
|
1164
1176
|
// Mark which formats are nested
|
|
1165
1177
|
module.exports['json/nested'].nested = true;
|
|
1166
1178
|
module.exports['javascript/module'].nested = true;
|
|
1167
|
-
module.exports['javascript/object'].nested = true;
|
|
1179
|
+
module.exports['javascript/object'].nested = true;
|
|
@@ -13,21 +13,7 @@
|
|
|
13
13
|
// express or implied. See the License for the specific language governing
|
|
14
14
|
// permissions and limitations under the License.
|
|
15
15
|
%>
|
|
16
|
-
|
|
17
|
-
// output the list of tokens as Sass variables
|
|
18
|
-
//
|
|
19
|
-
dictionary.allTokens.forEach(function(prop) {
|
|
20
|
-
var output = '';
|
|
21
|
-
output += '$' + prop.name + ': ' + (prop.attributes.category==='asset' ? '"'+prop.value+'"' : prop.value) + ' !default;'
|
|
22
|
-
if(prop.comment) {
|
|
23
|
-
output += ' // ' + prop.comment;
|
|
24
|
-
}
|
|
25
|
-
output += '\n';
|
|
26
|
-
print(output);
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
print('\n');
|
|
30
|
-
|
|
16
|
+
<%
|
|
31
17
|
// output the list of tokens as a Sass nested map
|
|
32
18
|
// (the values are pointing to the variables)
|
|
33
19
|
//
|
package/lib/common/transforms.js
CHANGED
|
@@ -457,7 +457,7 @@ module.exports = {
|
|
|
457
457
|
* ```swift
|
|
458
458
|
* // Matches: token.attributes.category === 'color'
|
|
459
459
|
* // Returns:
|
|
460
|
-
* UIColor(red: 0.667, green: 0.667, blue: 0.667, alpha:0.6)
|
|
460
|
+
* UIColor(red: 0.667, green: 0.667, blue: 0.667, alpha: 0.6)
|
|
461
461
|
* ```
|
|
462
462
|
*
|
|
463
463
|
* @memberof Transforms
|
|
@@ -470,7 +470,30 @@ module.exports = {
|
|
|
470
470
|
const rFixed = (r / 255.0).toFixed(3);
|
|
471
471
|
const gFixed = (g / 255.0).toFixed(3);
|
|
472
472
|
const bFixed = (b / 255.0).toFixed(3);
|
|
473
|
-
return `UIColor(red: ${rFixed}, green: ${gFixed}, blue: ${bFixed}, alpha
|
|
473
|
+
return `UIColor(red: ${rFixed}, green: ${gFixed}, blue: ${bFixed}, alpha: ${a})`;
|
|
474
|
+
}
|
|
475
|
+
},
|
|
476
|
+
|
|
477
|
+
/**
|
|
478
|
+
* Transforms the value into an UIColor swift class for iOS
|
|
479
|
+
*
|
|
480
|
+
* ```swift
|
|
481
|
+
* // Matches: token.attributes.category === 'color'
|
|
482
|
+
* // Returns:
|
|
483
|
+
* Color(red: 0.667, green: 0.667, blue: 0.667, opacity: 0.6)
|
|
484
|
+
* ```
|
|
485
|
+
*
|
|
486
|
+
* @memberof Transforms
|
|
487
|
+
*/
|
|
488
|
+
'color/ColorSwiftUI': {
|
|
489
|
+
type: 'value',
|
|
490
|
+
matcher: isColor,
|
|
491
|
+
transformer: function (token) {
|
|
492
|
+
const { r, g, b, a } = Color(token.value).toRgb();
|
|
493
|
+
const rFixed = (r / 255.0).toFixed(3);
|
|
494
|
+
const gFixed = (g / 255.0).toFixed(3);
|
|
495
|
+
const bFixed = (b / 255.0).toFixed(3);
|
|
496
|
+
return `Color(red: ${rFixed}, green: ${gFixed}, blue: ${bFixed}, opacity: ${a})`;
|
|
474
497
|
}
|
|
475
498
|
},
|
|
476
499
|
|
package/lib/extend.js
CHANGED
package/lib/utils/combineJSON.js
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
const deepExtend = require('./deepExtend');
|
|
15
15
|
|
|
16
16
|
function createFormatArgs({ dictionary, platform, file = {} }) {
|
|
17
|
-
const {allProperties, properties, usesReference, getReferences} = dictionary;
|
|
17
|
+
const {allProperties, properties, allTokens, tokens, usesReference, getReferences} = dictionary;
|
|
18
18
|
// This will merge platform and file-level configuration
|
|
19
19
|
// where the file configuration takes precedence
|
|
20
20
|
const {options} = platform;
|
|
@@ -26,6 +26,10 @@ function createFormatArgs({ dictionary, platform, file = {} }) {
|
|
|
26
26
|
getReferences,
|
|
27
27
|
allProperties,
|
|
28
28
|
properties,
|
|
29
|
+
// adding tokens and allTokens as the new way starting in v3,
|
|
30
|
+
// keeping properties and allProperties around for backwards-compatibility
|
|
31
|
+
allTokens,
|
|
32
|
+
tokens,
|
|
29
33
|
platform,
|
|
30
34
|
file,
|
|
31
35
|
options: file.options || {}
|
package/lib/utils/es6_.js
CHANGED
|
@@ -101,7 +101,7 @@ const assign = function () {
|
|
|
101
101
|
|
|
102
102
|
/* global Set */
|
|
103
103
|
const pull = function (arr, ...removeList){
|
|
104
|
-
var removeSet = new Set(removeList)
|
|
104
|
+
var removeSet = new Set(removeList)
|
|
105
105
|
for (let i=arr.length-1;i>=0;i--) {
|
|
106
106
|
if (removeSet.has(arr[i])) {
|
|
107
107
|
arr.splice(i, 1)
|
|
@@ -109,6 +109,10 @@ const pull = function (arr, ...removeList){
|
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
+
const unique = function (arr){
|
|
113
|
+
return [...new Set(arr)]
|
|
114
|
+
}
|
|
115
|
+
|
|
112
116
|
const upperFirst = function (str) {
|
|
113
117
|
return str ? str[0].toUpperCase() + str.substr(1) : ''
|
|
114
118
|
}
|
|
@@ -157,4 +161,5 @@ module.exports = {
|
|
|
157
161
|
kebabCase: ChangeCase.paramCase,
|
|
158
162
|
pull: pull,
|
|
159
163
|
matches: matches,
|
|
164
|
+
unique: unique,
|
|
160
165
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const fs = require("fs");
|
|
2
|
+
const jsonc = require("jsonc-parser");
|
|
3
|
+
|
|
4
|
+
module.exports = {
|
|
5
|
+
register(module, filename) {
|
|
6
|
+
const content = fs.readFileSync(filename, "utf8");
|
|
7
|
+
try {
|
|
8
|
+
module.exports = jsonc.parse(content);
|
|
9
|
+
} catch (err) {
|
|
10
|
+
err.message = filename + ": " + err.message;
|
|
11
|
+
throw err;
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
};
|
|
@@ -67,7 +67,7 @@ function getReferences(value) {
|
|
|
67
67
|
// function which iterates over the object to see if there is a reference
|
|
68
68
|
if (typeof value === 'object') {
|
|
69
69
|
for (const key in value) {
|
|
70
|
-
if (value.hasOwnProperty(key)) {
|
|
70
|
+
if (value.hasOwnProperty(key) && typeof value[key] === 'string') {
|
|
71
71
|
value[key].replace(regex, findReference);
|
|
72
72
|
}
|
|
73
73
|
}
|
|
@@ -94,8 +94,19 @@ function compile_value(value, stack) {
|
|
|
94
94
|
// Find what the value is referencing
|
|
95
95
|
const pathName = getPath(variable, options);
|
|
96
96
|
const context = getName(current_context, options);
|
|
97
|
+
const refHasValue = pathName[pathName.length-1] === 'value';
|
|
97
98
|
ref = resolveReference(pathName, updated_object);
|
|
98
99
|
|
|
100
|
+
// If the reference doesn't end in 'value'
|
|
101
|
+
// and
|
|
102
|
+
// the reference points to someplace that has a `value` attribute
|
|
103
|
+
// we should take the '.value' of the reference
|
|
104
|
+
// per the W3C draft spec where references do not have .value
|
|
105
|
+
// https://design-tokens.github.io/community-group/format/#aliases-references
|
|
106
|
+
if (!refHasValue && ref && ref.hasOwnProperty('value')) {
|
|
107
|
+
ref = ref.value;
|
|
108
|
+
}
|
|
109
|
+
|
|
99
110
|
if (typeof ref !== 'undefined') {
|
|
100
111
|
if (typeof ref === 'string') {
|
|
101
112
|
to_ret = value.replace(match, ref);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "style-dictionary",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"description": "Style once, use everywhere. A build system for creating cross-platform styles.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"style dictionary",
|
|
@@ -79,6 +79,7 @@
|
|
|
79
79
|
],
|
|
80
80
|
"transform": {
|
|
81
81
|
"^.+\\.json5$": "json5-jest",
|
|
82
|
+
"^.+\\.jsonc$": "json5-jest",
|
|
82
83
|
"^.+\\.jsx?$": "babel-jest"
|
|
83
84
|
}
|
|
84
85
|
},
|
|
@@ -141,9 +142,10 @@
|
|
|
141
142
|
"jsdoc-escape-at": "^1.0.1",
|
|
142
143
|
"jsdoc-to-markdown": "^7.0.1",
|
|
143
144
|
"json5-jest": "^1.0.1",
|
|
145
|
+
"jsonc-parser": "^3.0.0",
|
|
144
146
|
"less": "^3.11.2",
|
|
145
147
|
"lint-staged": "^10.2.7",
|
|
146
|
-
"node-sass": "^
|
|
148
|
+
"node-sass": "^6.0.1",
|
|
147
149
|
"standard-version": "^9.0.0",
|
|
148
150
|
"stylus": "^0.54.8",
|
|
149
151
|
"tsd": "^0.15.1",
|
package/types/Config.d.ts
CHANGED
|
@@ -16,7 +16,7 @@ import { Transform } from './Transform';
|
|
|
16
16
|
import { TransformGroup } from './TransformGroup';
|
|
17
17
|
import { Filter } from './Filter';
|
|
18
18
|
import { FileHeader } from './FileHeader';
|
|
19
|
-
import {
|
|
19
|
+
import { Formatter } from './Format';
|
|
20
20
|
import { Action } from './Action';
|
|
21
21
|
import { Platform } from './Platform';
|
|
22
22
|
import { DesignTokens } from './DesignToken';
|
|
@@ -25,7 +25,7 @@ export interface Config {
|
|
|
25
25
|
parsers?: Parser[];
|
|
26
26
|
transform?: Record<string, Transform>;
|
|
27
27
|
transformGroup?: Record<string, TransformGroup>;
|
|
28
|
-
format?: Record<string,
|
|
28
|
+
format?: Record<string, Formatter>;
|
|
29
29
|
filter?: Record<string, Filter>;
|
|
30
30
|
fileHeader?: Record<string, FileHeader>;
|
|
31
31
|
action?: Record<string, Action>;
|
package/types/File.d.ts
CHANGED
|
@@ -15,8 +15,9 @@ import { Options } from './Options';
|
|
|
15
15
|
import { TransformedToken } from './TransformedToken';
|
|
16
16
|
|
|
17
17
|
export interface File {
|
|
18
|
+
className?: string;
|
|
18
19
|
destination: string;
|
|
19
20
|
format?: string;
|
|
20
21
|
filter?: string | Partial<TransformedToken> | ((token: TransformedToken) => boolean);
|
|
21
22
|
options?: Options;
|
|
22
|
-
}
|
|
23
|
+
}
|
package/types/FileHeader.d.ts
CHANGED
package/types/Format.d.ts
CHANGED
package/types/FormatHelpers.d.ts
CHANGED
package/types/Platform.d.ts
CHANGED
package/types/_helpers.ts
CHANGED
package/types/index.d.ts
CHANGED
|
@@ -28,7 +28,7 @@ import {Platform as _Platform} from './Platform';
|
|
|
28
28
|
import {Transform as _Transform} from './Transform';
|
|
29
29
|
import {TransformedToken as _TransformedToken, TransformedTokens as _TransformedTokens} from './TransformedToken';
|
|
30
30
|
import {TransformGroup as _TransformGroup} from './TransformGroup';
|
|
31
|
-
import {Named} from './_helpers';
|
|
31
|
+
import {Named as _Named} from './_helpers';
|
|
32
32
|
|
|
33
33
|
// Because this library is used in Node and needs to be accessible
|
|
34
34
|
// as a CommonJS module, we are declaring it as a namespace so that
|
|
@@ -51,6 +51,7 @@ declare namespace StyleDictionary {
|
|
|
51
51
|
type TransformedToken = _TransformedToken;
|
|
52
52
|
type TransformedTokens = _TransformedTokens;
|
|
53
53
|
type TransformGroup = _TransformGroup;
|
|
54
|
+
type Named<T> = _Named<T>
|
|
54
55
|
|
|
55
56
|
interface Core {
|
|
56
57
|
VERSION: string;
|
|
@@ -61,7 +62,7 @@ declare namespace StyleDictionary {
|
|
|
61
62
|
options: Config;
|
|
62
63
|
|
|
63
64
|
transform: Record<string, Transform>;
|
|
64
|
-
transformGroup: Record<string, TransformGroup>;
|
|
65
|
+
transformGroup: Record<string, TransformGroup['transforms']>;
|
|
65
66
|
format: Record<string, Format>;
|
|
66
67
|
action: Record<string, Action>;
|
|
67
68
|
filter: Record<string, Filter>;
|
|
@@ -162,10 +163,30 @@ declare namespace StyleDictionary {
|
|
|
162
163
|
*/
|
|
163
164
|
registerFilter(filter: Named<Filter>): this;
|
|
164
165
|
|
|
166
|
+
/**
|
|
167
|
+
* Add a custom file header to Style Dictionary. File headers are used to write a
|
|
168
|
+
* custom messasge on top of the generated files.
|
|
169
|
+
* @param {String} fileHeader.name The name of the file header to be added
|
|
170
|
+
* @param {Function} fileHeader.fileHeader The file header function
|
|
171
|
+
* @example
|
|
172
|
+
* ```js
|
|
173
|
+
* StyleDictionary.registerFileHeader({
|
|
174
|
+
* name: 'custmoHeader',
|
|
175
|
+
* fileHeader: function(defaultMessage) {
|
|
176
|
+
* return return [
|
|
177
|
+
* `hello`,
|
|
178
|
+
* ...defaultMessage
|
|
179
|
+
* ]
|
|
180
|
+
* }
|
|
181
|
+
* })
|
|
182
|
+
* ```
|
|
183
|
+
*/
|
|
184
|
+
registerFileHeader(fileHeader: Named<{ fileHeader: FileHeader }>): this;
|
|
185
|
+
|
|
165
186
|
/**
|
|
166
187
|
* Adds a custom parser to parse style dictionary files. This allows you to modify
|
|
167
188
|
* the design token data before it gets to Style Dictionary or write your
|
|
168
|
-
* token files in a language other than JSON, JSON5, or CommonJS modules.
|
|
189
|
+
* token files in a language other than JSON, JSONC, JSON5, or CommonJS modules.
|
|
169
190
|
*
|
|
170
191
|
* @param {Regex} parser.pattern - A file path regular expression to match which files this parser should be be used on. This is similar to how webpack loaders work. `/\.json$/` will match any file ending in '.json', for example.
|
|
171
192
|
* @param {Function} parser.parse - Function to parse the file contents. Takes 1 argument, which is an object with 2 attributes: contents which is the string of the file contents and filePath. The function should return a plain Javascript object.
|
|
@@ -305,4 +326,4 @@ declare namespace StyleDictionary {
|
|
|
305
326
|
}
|
|
306
327
|
|
|
307
328
|
declare var StyleDictionary: StyleDictionary.Core;
|
|
308
|
-
export = StyleDictionary;
|
|
329
|
+
export = StyleDictionary;
|
package/types/index.test-d.ts
CHANGED