@madgex/design-system 9.3.1 → 10.0.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.
@@ -0,0 +1,215 @@
1
+ const fs = require('node:fs/promises');
2
+ const path = require('node:path');
3
+ const { glob } = require('glob');
4
+ const { writeTransformedFileBrandColorLightnessTokens } = require('./color-transforms');
5
+
6
+ const defaultDistDir = path.resolve(__dirname, '../dist/_tokens/');
7
+ /**
8
+ * Base Style Dictionary Config which includes our base tokens.
9
+ * @type {import('style-dictionary').Config}
10
+ */
11
+ const baseConfig = Object.freeze({
12
+ log: {
13
+ verbosity: 'verbose',
14
+ },
15
+ // This include path needs to be in posix because combineJSON util inside style dictionary only accepts that
16
+ include: [path.posix.resolve(__dirname, '../src/tokens/*.json')],
17
+ hooks: {
18
+ transforms: {
19
+ /**
20
+ * escape when we need to pass through the token value without transformation.
21
+ *
22
+ * Try not to use this.
23
+ *
24
+ * @example
25
+ * ```json
26
+ * {
27
+ * "myStrangeItem": {
28
+ * "$value": "special-new-css-value",
29
+ * "$type": "raw"
30
+ * }
31
+ * }
32
+ */
33
+ 'css/rawData': {
34
+ type: 'value',
35
+ filter: (token) => token.type === 'raw',
36
+ transform: (token) => token.rawData,
37
+ },
38
+ },
39
+ },
40
+ /**
41
+ * various outputs
42
+ *
43
+ * transforms match the `type` on each token, built in transforms: https://styledictionary.com/reference/hooks/transforms/predefined/
44
+ *
45
+ *
46
+ */
47
+ platforms: {
48
+ /**
49
+ * Primary CSS Variables render
50
+ */
51
+ 'css-variables': {
52
+ transforms: ['name/kebab', 'color/css', 'css/rawData'],
53
+ buildPath: path.join(defaultDistDir, 'css/'),
54
+ prefix: 'mds',
55
+ files: [
56
+ {
57
+ destination: 'variables.css',
58
+ format: 'css/variables',
59
+ filter: 'removePrivate',
60
+ },
61
+ ],
62
+ },
63
+ /**
64
+ * used to render another scss source file! Constants for use in main DS scss build
65
+ */
66
+ 'scss-variables': {
67
+ transforms: ['name/kebab'],
68
+ buildPath: `${path.resolve(__dirname, '../src/scss/constants/')}/`,
69
+ prefix: 'constant',
70
+ files: [
71
+ {
72
+ destination: '_sd-tokens.scss',
73
+ format: 'scss/map-deep',
74
+ options: {
75
+ themeable: false,
76
+ },
77
+ filter(token) {
78
+ // only keep "private" tokens aka constants
79
+ return !!(token && token.private);
80
+ },
81
+ },
82
+ ],
83
+ },
84
+ /**
85
+ * used by:
86
+ *
87
+ * #### 'template-renderer'
88
+ * https://github.com/wiley/madgex-template-renderer/blob/e5eb868e6b789a8d751efc98768672d877196fa5/lib/services/dataUtils.js#L101
89
+ *
90
+ * #### display-image-render-api
91
+ * https://github.com/wiley/madgex-display-image-render-api/blob/27e6e219400a98a41f39861c8b362a0849888ea3/lib/services/templates.js#L157
92
+ */
93
+ 'json-variables': {
94
+ // transformGroup: 'js',
95
+ transforms: ['name/kebab', 'color/css'],
96
+ buildPath: path.join(defaultDistDir, 'json/'),
97
+ files: [
98
+ {
99
+ destination: 'variables.json',
100
+ format: 'json/nested',
101
+ // https://github.com/amzn/style-dictionary/blob/f2395f3d4638e1fa57a86bd821b28e2f043067c4/lib/common/filters.js#L28
102
+ filter: 'removePrivate',
103
+ },
104
+ ],
105
+ },
106
+ /**
107
+ * used by Jack's Chrome Extension
108
+ */
109
+ 'json-variables-flat': {
110
+ // transformGroup: 'js',
111
+ transforms: ['name/kebab', 'color/css'],
112
+ buildPath: path.join(defaultDistDir, 'json/'),
113
+ files: [
114
+ {
115
+ destination: 'variables-flat.json',
116
+ format: 'json/flat',
117
+ // https://github.com/amzn/style-dictionary/blob/f2395f3d4638e1fa57a86bd821b28e2f043067c4/lib/common/filters.js#L28
118
+ filter: 'removePrivate',
119
+ },
120
+ ],
121
+ },
122
+ /**
123
+ * only used for fractal docs visualisation of tokens
124
+ */
125
+ 'js-module': {
126
+ transforms: ['name/pascal'],
127
+ buildPath: path.join(defaultDistDir, 'js/'),
128
+ prefix: 'mds',
129
+ files: [
130
+ {
131
+ destination: '_tokens-module.js',
132
+ format: 'javascript/module',
133
+ },
134
+ ],
135
+ },
136
+ },
137
+ });
138
+
139
+ /**
140
+ *
141
+ * Create an instance of Style Dictionary with base Design System tokens already loaded.
142
+ *
143
+ * Supplied `source` paths will have brand color transformation applied
144
+ *
145
+ * existing Design System `platforms` which can be overriden (e.g. override buildPath)
146
+ *
147
+ * - 'css-variables'
148
+ * - 'scss-variables'
149
+ * - 'json-variables'
150
+ * - 'json-variables-flat'
151
+ * - 'js-module'
152
+ *
153
+ * @param {import('style-dictionary').Config} incomingConfig
154
+ * @param {import('style-dictionary').PlatformConfig} incomingConfig.platforms
155
+ * @param {Array<string>} incomingConfig.source
156
+ *
157
+ * @returns {{styleDictionary:import('style-dictionary').default, cleanTempFiles: Function}} Style Dictionary Config
158
+ *
159
+ * @example
160
+ * ```javascript
161
+ * // frontend-rollout-tool only wants to build 2 platforms to specific directories
162
+ * const { styleDictionary, cleanTempFiles } = await createStyleDictionary({
163
+ * // override platform defaults, like buildPath
164
+ * platforms: {
165
+ * 'css-variables': { buildPath: Path.join(buildPath, 'css-vars/') },
166
+ * 'json-variables': { buildPath: Path.join(buildPath, 'json/') },
167
+ * },
168
+ * source: [Path.join(srcTokensPath, 'brand.json')]
169
+ * })
170
+ * await styleDictionary.buildPlatform('css-variables');
171
+ * await styleDictionary.buildPlatform('json-variables');
172
+ * await cleanTempFiles();
173
+ *
174
+ * ///////////////////////////////
175
+ *
176
+ * // Design System wants to build all platforms to default directories
177
+ * const { styleDictionary, cleanTempFiles } = await createStyleDictionary();
178
+ * await styleDictionary.buildAllPlatforms();
179
+ * await cleanTempFiles();
180
+ * ```
181
+ */
182
+ async function createStyleDictionary(incomingConfig = {}) {
183
+ const StyleDictionaryPackage = (await import('style-dictionary')).default;
184
+
185
+ // create Style Dictionary instance using base tokens, includes all our all platforms
186
+ let styleDictionary = new StyleDictionaryPackage(baseConfig);
187
+
188
+ // if source was supplied (e.g. by frontend-rollout-tool brand.json), make sure brand lightness is generated
189
+ const transformedSource = [];
190
+ // use `glob` on `source` as this is what style-dictionary uses, keep api compatability
191
+ const sourceFilePaths = await glob(incomingConfig?.source || []);
192
+
193
+ for (const sourceFilePath of sourceFilePaths) {
194
+ // forced to write new source files to disk (required for style-dictionary, unfortunately)
195
+ const newSourceFilePath = await writeTransformedFileBrandColorLightnessTokens(sourceFilePath);
196
+ transformedSource.push(newSourceFilePath);
197
+ }
198
+
199
+ const cleanTempFiles = async () => {
200
+ for (const sourceFilePath of sourceFilePaths) {
201
+ try {
202
+ await fs.unlink(sourceFilePath);
203
+ } catch (error) {
204
+ console.warn('couldnt clean temp file ', sourceFilePath);
205
+ }
206
+ }
207
+ };
208
+ // merged incomingConfig & transformed incomingConfig.source to our base styleDictionary
209
+ styleDictionary = await styleDictionary.extend({ ...incomingConfig, source: transformedSource });
210
+
211
+ await styleDictionary.hasInitialized;
212
+ return { styleDictionary, cleanTempFiles };
213
+ }
214
+
215
+ module.exports.createStyleDictionary = createStyleDictionary;
package/tasks/tokens.js CHANGED
@@ -1,32 +1,14 @@
1
- const path = require('path');
2
- const fs = require('fs');
3
- const { promisify } = require('util');
4
- const StyleDictionaryPackage = require('style-dictionary');
5
- const { registerTransforms } = require('./registerTransforms');
6
- const transformTokens = require('./colorTransforms');
7
-
8
- const readFileAsync = promisify(fs.readFile);
9
- const writeFileAsync = promisify(fs.writeFile);
10
-
11
- async function transformBaseTokens(filePath) {
12
- const baseTokens = await readFileAsync(filePath, { encoding: 'utf8' });
13
- const transformed = JSON.stringify(transformTokens(JSON.parse(baseTokens)), null, ' ')
14
- // Add a space after every key, before the `:`
15
- .replace(/: "(?:[^"]+|\\")*",?$/gm, ' $&');
16
-
17
- return writeFileAsync(filePath, transformed);
18
- }
1
+ const { createStyleDictionary } = require('../style-dictionary');
19
2
 
3
+ /**
4
+ * build tokens via style-dictionary
5
+ *
6
+ */
20
7
  async function tokens() {
21
- try {
22
- await transformBaseTokens(path.resolve(__dirname, '../src/tokens/color.json'));
23
- const StyleDictionary = StyleDictionaryPackage.extend(path.resolve(__dirname, '../src/tokens/_config'));
8
+ const { styleDictionary, cleanTempFiles } = await createStyleDictionary();
24
9
 
25
- await registerTransforms(StyleDictionary);
26
- await StyleDictionary.buildAllPlatforms();
27
- } catch (e) {
28
- console.error(e);
29
- }
10
+ await styleDictionary.buildAllPlatforms();
11
+ await cleanTempFiles();
30
12
  }
31
13
 
32
14
  exports.tokens = tokens;