Skip to content

Commit 3282d87

Browse files
committed
migrate tokens scripts to esmodules logic
1 parent 53afc31 commit 3282d87

File tree

2 files changed

+181
-209
lines changed

2 files changed

+181
-209
lines changed

core/scripts/tokens/index.js

Lines changed: 162 additions & 169 deletions
Original file line numberDiff line numberDiff line change
@@ -4,177 +4,168 @@
44
// - It also works very well out of the box with any kind of Design Tokens formats, like Figma Tokens, as well as APIs to adjust to more custom ones.
55
// - It is probably the most well-known and widely used Design Tokens tool. It has also been regularly maintained for a long time.
66
// - It can easily scale to different necessities we might have in the future.
7-
(async () => {
8-
const {
9-
generateShadowValue,
10-
generateFontSizeValue,
11-
generateFontFamilyValue,
12-
generateTypographyOutput,
13-
generateValue,
14-
generateColorUtilityClasses,
15-
generateDefaultSpaceUtilityClasses,
16-
generateSpaceUtilityClasses,
17-
removeConsecutiveRepeatedWords,
18-
setPrefixValue,
19-
generateRadiusUtilityClasses,
20-
generateBorderUtilityClasses,
21-
generateFontUtilityClasses,
22-
generateShadowUtilityClasses,
23-
generateUtilityClasses
24-
} = require('./utils.js');
25-
26-
const StyleDictionary = (await import('style-dictionary')).default;
27-
28-
// Set the prefix for variables and classes
29-
setPrefixValue('ion');
30-
31-
// Register a custom file header
32-
StyleDictionary.registerFileHeader({
33-
name: 'custom-header',
34-
fileHeader: async (defaultMessages = []) => {
35-
return [...defaultMessages, 'Do not edit directly, this file was auto-generated.'];
36-
},
37-
});
38-
39-
// SCSS variables format
40-
StyleDictionary.registerFormat({
41-
name: 'scssVariablesFormat',
42-
format: async function ({ dictionary, file }) {
43-
44-
console.log('Generating SCSS variables...');
45-
46-
const primitiveProperties = dictionary.allTokens.filter((prop) => prop.path[0] === 'primitives');
47-
const scaleProperties = dictionary.allTokens.filter((prop) => prop.path[0] === 'scale');
48-
const borderProperties = dictionary.allTokens.filter((prop) => prop.path[0] === 'border');
49-
const semanticsProperties = dictionary.allTokens.filter((prop) => prop.path[0] === 'semantics');
50-
const nonPrimitiveScaleBorderSemanticsProperties = dictionary.allTokens.filter(
51-
(prop) => !['primitives', 'scale', 'border', 'semantics'].includes(prop.path[0])
52-
);
53-
const typographyProperties = nonPrimitiveScaleBorderSemanticsProperties.filter((prop) => prop.$type === 'typography');
54-
const otherProperties = nonPrimitiveScaleBorderSemanticsProperties.filter((prop) => prop.$type !== 'typography');
55-
56-
// Order: primitives → semantics → scale → border → other → typography
57-
const sortedProperties = [
58-
...primitiveProperties,
59-
...semanticsProperties,
60-
...scaleProperties,
61-
...borderProperties,
62-
...otherProperties,
63-
...typographyProperties
64-
];
65-
66-
const prefixedVariables = sortedProperties.map((prop) => {
67-
// Remove consecutive repeated words from the token name, like border-border-color
68-
const propName = removeConsecutiveRepeatedWords(prop.name);
69-
70-
switch (prop.$type) {
71-
case 'boxShadow':
72-
return generateShadowValue(prop, propName);
73-
case 'fontFamilies':
74-
return generateFontFamilyValue(prop, propName, 'scss');
75-
case 'fontSizes':
76-
return generateFontSizeValue(prop, propName, 'scss');
77-
case 'typography':
78-
return generateTypographyOutput(prop, propName, true);
79-
default:
80-
return generateValue(prop, propName);
81-
}
82-
});
83-
84-
const fileHeader = await file.options.fileHeader();
85-
86-
return [
87-
`/*\n${fileHeader.join('\n')}\n*/`,
88-
'@use "../themes/functions.sizes" as font;\n',
89-
prefixedVariables.join('\n') + '\n',
90-
].join('\n');
91-
},
92-
});
93-
94-
// Create utility-classes
95-
StyleDictionary.registerFormat({
96-
name: 'cssUtilityClassesFormat',
97-
format: async function ({ dictionary, file }) {
98-
99-
console.log('Generating Utility-Classes...');
100-
101-
// Arrays to store specific utility classes
102-
const typographyUtilityClasses = [];
103-
const otherUtilityClasses = [];
104-
105-
// Generate utility classes for each token
106-
dictionary.allTokens.map((prop) => {
107-
108-
const tokenCategory = prop.attributes.category;
109-
110-
if (prop.$type === 'fontFamilies' || tokenCategory === 'scale' || tokenCategory === 'backdrop') {
111-
// Not creating for the tokens below, as they make no sense to exist as utility-classes.
112-
return;
113-
}
114-
115-
// Remove consecutive repeated words from the token name, like border-border-color
116-
const propName = removeConsecutiveRepeatedWords(prop.name);
117-
118-
if (prop.$type === 'typography') {
119-
// Typography tokens are handled differently, as each might have a different tokenType
120-
return typographyUtilityClasses.push(generateTypographyOutput(prop, propName, false));
121-
122-
} else if (tokenCategory.startsWith('round') || tokenCategory.startsWith('rectangular') || tokenCategory.startsWith('soft')) {
123-
// Generate utility classes for border-radius shape tokens, as they have their own token json file, based on primitive tokens
124-
return otherUtilityClasses.push(generateRadiusUtilityClasses(propName));
125-
}
126-
127-
let utilityClass = '';
128-
switch (tokenCategory) {
129-
case 'color':
130-
case 'primitives':
131-
case 'semantics':
132-
case 'text':
133-
case 'bg':
134-
case 'icon':
135-
case 'state':
136-
utilityClass = generateColorUtilityClasses(prop, propName);
137-
break;
138-
case 'border':
139-
utilityClass = generateBorderUtilityClasses(prop, propName);
140-
break;
141-
case 'font':
142-
utilityClass = generateFontUtilityClasses(prop, propName);
143-
break;
144-
case 'space':
145-
utilityClass = generateSpaceUtilityClasses(prop, propName);
146-
break;
147-
case 'shadow':
148-
case 'elevation':
149-
utilityClass = generateShadowUtilityClasses(propName);
150-
break;
151-
default:
152-
utilityClass = generateUtilityClasses(tokenCategory, propName);
153-
}
154-
155-
return otherUtilityClasses.push(utilityClass);
156-
});
157-
158-
const defaultSpaceUtilityClasses = generateDefaultSpaceUtilityClasses();
159-
otherUtilityClasses.push(defaultSpaceUtilityClasses);
160-
161-
// Concatenate typography utility classes at the beginning
162-
const finalOutput = typographyUtilityClasses.concat(otherUtilityClasses).join('\n');
163-
164-
const fileHeader = await file.options.fileHeader();
165-
166-
return [
167-
`/*\n${fileHeader.join('\n')}\n*/`,
168-
'@import "./ionic.vars";\n@import "../themes/mixins";\n',
169-
finalOutput,
170-
].join('\n');
171-
},
172-
});
173-
174-
})();
7+
import * as utils from './utils.js';
8+
const {
9+
generateShadowValue,
10+
generateFontSizeValue,
11+
generateFontFamilyValue,
12+
generateTypographyOutput,
13+
generateValue,
14+
generateColorUtilityClasses,
15+
generateDefaultSpaceUtilityClasses,
16+
generateSpaceUtilityClasses,
17+
removeConsecutiveRepeatedWords,
18+
setPrefixValue,
19+
generateRadiusUtilityClasses,
20+
generateBorderUtilityClasses,
21+
generateFontUtilityClasses,
22+
generateShadowUtilityClasses,
23+
generateUtilityClasses
24+
} = utils;
25+
import StyleDictionary from 'style-dictionary';
26+
27+
// Set the prefix for variables and classes
28+
setPrefixValue('token');
29+
30+
// Register a custom file header
31+
StyleDictionary.registerFileHeader({
32+
name: 'custom-header',
33+
fileHeader: (defaultMessages = []) => {
34+
return [...defaultMessages, 'Do not edit directly, this file was auto-generated.'];
35+
},
36+
});
37+
38+
// SCSS variables format
39+
StyleDictionary.registerFormat({
40+
name: 'scssVariablesFormat',
41+
format: function ({ dictionary }) { // Use 'format' for Style Dictionary v3
42+
console.log('Generating SCSS variables...');
43+
44+
const primitiveProperties = dictionary.allTokens.filter((prop) => prop.path[0] === 'primitives');
45+
const scaleProperties = dictionary.allTokens.filter((prop) => prop.path[0] === 'scale');
46+
const borderProperties = dictionary.allTokens.filter((prop) => prop.path[0] === 'border');
47+
const semanticsProperties = dictionary.allTokens.filter((prop) => prop.path[0] === 'semantics');
48+
const nonPrimitiveScaleBorderSemanticsProperties = dictionary.allTokens.filter(
49+
(prop) => !['primitives', 'scale', 'border', 'semantics'].includes(prop.path[0])
50+
);
51+
const typographyProperties = nonPrimitiveScaleBorderSemanticsProperties.filter((prop) => prop.$type === 'typography');
52+
const otherProperties = nonPrimitiveScaleBorderSemanticsProperties.filter((prop) => prop.$type !== 'typography');
53+
54+
// Order: primitives → semantics → scale → border → other → typography
55+
const sortedProperties = [
56+
...primitiveProperties,
57+
...semanticsProperties,
58+
...scaleProperties,
59+
...borderProperties,
60+
...otherProperties,
61+
...typographyProperties
62+
];
63+
64+
const prefixedVariables = sortedProperties.map((prop) => {
65+
// Remove consecutive repeated words from the token name, like border-border-color
66+
const propName = removeConsecutiveRepeatedWords(prop.name);
67+
68+
switch (prop.$type) {
69+
case 'boxShadow':
70+
return generateShadowValue(prop, propName);
71+
case 'fontFamilies':
72+
return generateFontFamilyValue(prop, propName, 'scss');
73+
case 'fontSizes':
74+
return generateFontSizeValue(prop, propName, 'scss');
75+
case 'typography':
76+
return generateTypographyOutput(prop, propName, true);
77+
default:
78+
return generateValue(prop, propName);
79+
}
80+
});
81+
82+
// In v3, the header is added automatically by Style Dictionary.
83+
// The format function should only return the file content.
84+
return [
85+
'@use "../themes/functions.sizes" as font;\n',
86+
prefixedVariables.join('\n') + '\n',
87+
].join('');
88+
},
89+
});
90+
91+
// Create utility-classes
92+
StyleDictionary.registerFormat({
93+
name: 'cssUtilityClassesFormat',
94+
format: function ({ dictionary }) { // Use 'format' for Style Dictionary v3
95+
console.log('Generating Utility-Classes...');
96+
97+
// Arrays to store specific utility classes
98+
const typographyUtilityClasses = [];
99+
const otherUtilityClasses = [];
100+
101+
// Generate utility classes for each token
102+
dictionary.allTokens.map((prop) => {
103+
const tokenCategory = prop.attributes.category;
104+
105+
if (prop.$type === 'fontFamilies' || tokenCategory === 'scale' || tokenCategory === 'backdrop') {
106+
// Not creating for the tokens below, as they make no sense to exist as utility-classes.
107+
return;
108+
}
109+
110+
// Remove consecutive repeated words from the token name, like border-border-color
111+
const propName = removeConsecutiveRepeatedWords(prop.name);
112+
113+
if (prop.$type === 'typography') {
114+
// Typography tokens are handled differently, as each might have a different tokenType
115+
return typographyUtilityClasses.push(generateTypographyOutput(prop, propName, false));
116+
} else if (tokenCategory.startsWith('round') || tokenCategory.startsWith('rectangular') || tokenCategory.startsWith('soft')) {
117+
// Generate utility classes for border-radius shape tokens, as they have their own token json file, based on primitive tokens
118+
return otherUtilityClasses.push(generateRadiusUtilityClasses(propName));
119+
}
120+
121+
let utilityClass = '';
122+
switch (tokenCategory) {
123+
case 'color':
124+
case 'primitives':
125+
case 'semantics':
126+
case 'text':
127+
case 'bg':
128+
case 'icon':
129+
case 'state':
130+
utilityClass = generateColorUtilityClasses(prop, propName);
131+
break;
132+
case 'border':
133+
utilityClass = generateBorderUtilityClasses(prop, propName);
134+
break;
135+
case 'font':
136+
utilityClass = generateFontUtilityClasses(prop, propName);
137+
break;
138+
case 'space':
139+
utilityClass = generateSpaceUtilityClasses(prop, propName);
140+
break;
141+
case 'shadow':
142+
case 'elevation':
143+
utilityClass = generateShadowUtilityClasses(propName);
144+
break;
145+
default:
146+
utilityClass = generateUtilityClasses(tokenCategory, propName);
147+
}
148+
149+
return otherUtilityClasses.push(utilityClass);
150+
});
151+
152+
const defaultSpaceUtilityClasses = generateDefaultSpaceUtilityClasses();
153+
otherUtilityClasses.push(defaultSpaceUtilityClasses);
154+
155+
// Concatenate typography utility classes at the beginning
156+
const finalOutput = typographyUtilityClasses.concat(otherUtilityClasses).join('\n');
157+
158+
// In v3, the header is added automatically by Style Dictionary.
159+
// The format function should only return the file content.
160+
return [
161+
'@import "./ionic.vars";\n@import "../themes/mixins";\n',
162+
finalOutput,
163+
].join('');
164+
},
165+
});
175166

176167
// APPLY THE CONFIGURATION
177-
module.exports = {
168+
const config = {
178169
source: ["node_modules/outsystems-design-tokens/tokens/**/*.json"],
179170
platforms: {
180171
scss: {
@@ -199,3 +190,5 @@ module.exports = {
199190
}
200191
}
201192
};
193+
194+
export default config;

0 commit comments

Comments
 (0)