mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-11-06 06:09:31 +08:00
Issue number: internal --------- ## What is the new behavior? <!-- Please describe the behavior or changes that are being added by this PR. --> This pull request updates the design token build pipeline to support Style Dictionary v5 and modernizes the scripts by migrating them to ES modules. The changes ensure compatibility with the latest dependencies and improve maintainability by refactoring the build scripts and utilities. **Dependency and Build Pipeline Updates:** * Upgraded `outsystems-design-tokens` to version `^1.3.2` and `style-dictionary` to version `^5.0.0` in `package.json` to support the latest features and fixes. * Updated the `build.tokens` npm script to use the new ES module entry point (`index.mjs`) instead of the old CommonJS file (`index.js`). **Migration to ES Modules:** * Migrated the main design token build script from `index.js` to `index.mjs`, refactoring imports/exports and adjusting to Style Dictionary v5 API changes. [[1]](diffhunk://#diff-80accbbc258884565c215c7eb6280722805ddf618d72bf6506c7dd1fb7faaa54L1-L201) [[2]](diffhunk://#diff-0b9870c62ff80af860467e2541bba0b9ba5e7280b12bea6eeb124b1d174efbcfR1-R194) * Renamed and refactored the utility functions file from `utils.js` to `utils.mjs`, converting all utility functions to ES module exports for compatibility. [[1]](diffhunk://#diff-8b5c339d9dd13300954577213f84a443321a0d6477acd7553787fbcc00ce8cabL4-R10) [[2]](diffhunk://#diff-8b5c339d9dd13300954577213f84a443321a0d6477acd7553787fbcc00ce8cabL22-R22) [[3]](diffhunk://#diff-8b5c339d9dd13300954577213f84a443321a0d6477acd7553787fbcc00ce8cabL47-R53) [[4]](diffhunk://#diff-8b5c339d9dd13300954577213f84a443321a0d6477acd7553787fbcc00ce8cabL65-R65) [[5]](diffhunk://#diff-8b5c339d9dd13300954577213f84a443321a0d6477acd7553787fbcc00ce8cabL76-R76) [[6]](diffhunk://#diff-8b5c339d9dd13300954577213f84a443321a0d6477acd7553787fbcc00ce8cabL85-R85) [[7]](diffhunk://#diff-8b5c339d9dd13300954577213f84a443321a0d6477acd7553787fbcc00ce8cabL95-R95) [[8]](diffhunk://#diff-8b5c339d9dd13300954577213f84a443321a0d6477acd7553787fbcc00ce8cabL118-R118) [[9]](diffhunk://#diff-8b5c339d9dd13300954577213f84a443321a0d6477acd7553787fbcc00ce8cabL144-R144) [[10]](diffhunk://#diff-8b5c339d9dd13300954577213f84a443321a0d6477acd7553787fbcc00ce8cabL155-R155) [[11]](diffhunk://#diff-8b5c339d9dd13300954577213f84a443321a0d6477acd7553787fbcc00ce8cabL221-R221) **Style Dictionary Configuration and Output Improvements:** * Adjusted the Style Dictionary configuration and format registration to match the new API, including changes to file header handling and output structure for SCSS variables and utility classes. * Changed variable prefix to --token ## Does this introduce a breaking change? - [ ] Yes - [x] No <!-- If this introduces a breaking change: 1. Describe the impact and migration path for existing applications below. 2. Update the BREAKING.md file with the breaking change. 3. Add "BREAKING CHANGE: [...]" to the commit description when merging. See https://github.com/ionic-team/ionic-framework/blob/main/docs/CONTRIBUTING.md#footer for more information. --> --------- Co-authored-by: ionitron <hi@ionicframework.com>
186 lines
7.0 KiB
JavaScript
186 lines
7.0 KiB
JavaScript
/* eslint-disable @typescript-eslint/no-var-requires */
|
|
// For generating Design Tokens, we use Style Dictionary for several reasons:
|
|
// - It's prepared to easily generate tokens for multiple types of outputs (CSS, SCSS, iOS, Android, documentation, etc.).
|
|
// - 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.
|
|
// - It is probably the most well-known and widely used Design Tokens tool. It has also been regularly maintained for a long time.
|
|
// - It can easily scale to different necessities we might have in the future.
|
|
import * as utils from './utils.mjs';
|
|
const {
|
|
generateShadowValue,
|
|
generateFontSizeValue,
|
|
generateFontFamilyValue,
|
|
generateTypographyOutput,
|
|
generateValue,
|
|
generateColorUtilityClasses,
|
|
generateDefaultSpaceUtilityClasses,
|
|
generateSpaceUtilityClasses,
|
|
removeConsecutiveRepeatedWords,
|
|
setVariablePrefixValue,
|
|
setClassesAndScssPrefixValue: setClassesPrefixValue,
|
|
generateRadiusUtilityClasses,
|
|
generateBorderUtilityClasses,
|
|
generateFontUtilityClasses,
|
|
generateShadowUtilityClasses,
|
|
generateUtilityClasses
|
|
} = utils;
|
|
import StyleDictionary from 'style-dictionary';
|
|
|
|
const customHeader = `// Do not edit directly, this file was auto-generated.`;
|
|
// Set the prefix for classes
|
|
setClassesPrefixValue('ion');
|
|
// Set the prefix for variables
|
|
setVariablePrefixValue('token');
|
|
|
|
// SCSS variables format
|
|
StyleDictionary.registerFormat({
|
|
name: 'scssVariablesFormat',
|
|
format: function ({ dictionary }) { // Use 'format' for Style Dictionary v3
|
|
console.log('Generating SCSS variables...');
|
|
|
|
const primitiveProperties = dictionary.allTokens.filter((prop) => prop.path[0] === 'primitives');
|
|
const scaleProperties = dictionary.allTokens.filter((prop) => prop.path[0] === 'scale');
|
|
const borderProperties = dictionary.allTokens.filter((prop) => prop.path[0] === 'border');
|
|
const semanticsProperties = dictionary.allTokens.filter((prop) => prop.path[0] === 'semantics');
|
|
const nonPrimitiveScaleBorderSemanticsProperties = dictionary.allTokens.filter(
|
|
(prop) => !['primitives', 'scale', 'border', 'semantics'].includes(prop.path[0])
|
|
);
|
|
const typographyProperties = nonPrimitiveScaleBorderSemanticsProperties.filter((prop) => prop.$type === 'typography');
|
|
const otherProperties = nonPrimitiveScaleBorderSemanticsProperties.filter((prop) => prop.$type !== 'typography');
|
|
|
|
// Order: primitives → semantics → scale → border → other → typography
|
|
const sortedProperties = [
|
|
...primitiveProperties,
|
|
...semanticsProperties,
|
|
...scaleProperties,
|
|
...borderProperties,
|
|
...otherProperties,
|
|
...typographyProperties
|
|
];
|
|
|
|
const prefixedVariables = sortedProperties.map((prop) => {
|
|
// Remove consecutive repeated words from the token name, like border-border-color
|
|
const propName = removeConsecutiveRepeatedWords(prop.name);
|
|
|
|
switch (prop.$type) {
|
|
case 'boxShadow':
|
|
return generateShadowValue(prop, propName);
|
|
case 'fontFamilies':
|
|
return generateFontFamilyValue(prop, propName, 'scss');
|
|
case 'fontSizes':
|
|
return generateFontSizeValue(prop, propName, 'scss');
|
|
case 'typography':
|
|
return generateTypographyOutput(prop, propName, true);
|
|
default:
|
|
return generateValue(prop, propName);
|
|
}
|
|
});
|
|
|
|
// In v3, the header is added automatically by Style Dictionary.
|
|
// The format function should only return the file content.
|
|
return [
|
|
customHeader + '\n\n',
|
|
'@use "../themes/functions.sizes" as font;\n',
|
|
prefixedVariables.join('\n') + '\n',
|
|
].join('');
|
|
},
|
|
});
|
|
|
|
// Create utility-classes
|
|
StyleDictionary.registerFormat({
|
|
name: 'cssUtilityClassesFormat',
|
|
format: function ({ dictionary }) { // Use 'format' for Style Dictionary v3
|
|
console.log('Generating Utility-Classes...');
|
|
|
|
// Arrays to store specific utility classes
|
|
const typographyUtilityClasses = [];
|
|
const otherUtilityClasses = [];
|
|
|
|
// Generate utility classes for each token
|
|
dictionary.allTokens.map((prop) => {
|
|
const tokenCategory = prop.attributes.category;
|
|
|
|
if (prop.$type === 'fontFamilies' || tokenCategory === 'scale' || tokenCategory === 'backdrop') {
|
|
// Not creating for the tokens below, as they make no sense to exist as utility-classes.
|
|
return;
|
|
}
|
|
|
|
// Remove consecutive repeated words from the token name, like border-border-color
|
|
const propName = removeConsecutiveRepeatedWords(prop.name);
|
|
|
|
if (prop.$type === 'typography') {
|
|
// Typography tokens are handled differently, as each might have a different tokenType
|
|
return typographyUtilityClasses.push(generateTypographyOutput(prop, propName, false));
|
|
} else if (tokenCategory.startsWith('round') || tokenCategory.startsWith('rectangular') || tokenCategory.startsWith('soft')) {
|
|
// Generate utility classes for border-radius shape tokens, as they have their own token json file, based on primitive tokens
|
|
return otherUtilityClasses.push(generateRadiusUtilityClasses(propName));
|
|
}
|
|
|
|
let utilityClass = '';
|
|
switch (tokenCategory) {
|
|
case 'color':
|
|
case 'primitives':
|
|
case 'semantics':
|
|
case 'text':
|
|
case 'bg':
|
|
case 'icon':
|
|
case 'state':
|
|
utilityClass = generateColorUtilityClasses(prop, propName);
|
|
break;
|
|
case 'border':
|
|
utilityClass = generateBorderUtilityClasses(prop, propName);
|
|
break;
|
|
case 'font':
|
|
utilityClass = generateFontUtilityClasses(prop, propName);
|
|
break;
|
|
case 'space':
|
|
utilityClass = generateSpaceUtilityClasses(prop, propName);
|
|
break;
|
|
case 'shadow':
|
|
case 'elevation':
|
|
utilityClass = generateShadowUtilityClasses(propName);
|
|
break;
|
|
default:
|
|
utilityClass = generateUtilityClasses(tokenCategory, propName);
|
|
}
|
|
|
|
return otherUtilityClasses.push(utilityClass);
|
|
});
|
|
|
|
const defaultSpaceUtilityClasses = generateDefaultSpaceUtilityClasses();
|
|
otherUtilityClasses.push(defaultSpaceUtilityClasses);
|
|
|
|
// Concatenate typography utility classes at the beginning
|
|
const finalOutput = typographyUtilityClasses.concat(otherUtilityClasses).join('\n');
|
|
|
|
// In v3, the header is added automatically by Style Dictionary.
|
|
// The format function should only return the file content.
|
|
return [
|
|
customHeader + '\n\n',
|
|
'@import "./ionic.vars";\n@import "../themes/mixins";\n',
|
|
finalOutput,
|
|
].join('');
|
|
},
|
|
});
|
|
|
|
// APPLY THE CONFIGURATION
|
|
const config = {
|
|
source: ["node_modules/outsystems-design-tokens/tokens/**/*.json"],
|
|
platforms: {
|
|
scss: {
|
|
transformGroup: "scss",
|
|
buildPath: './src/foundations/',
|
|
files: [
|
|
{
|
|
destination: "ionic.vars.scss",
|
|
format: "scssVariablesFormat",
|
|
},
|
|
{
|
|
destination: "ionic.utility.scss",
|
|
format: "cssUtilityClassesFormat",
|
|
}
|
|
]
|
|
}
|
|
}
|
|
};
|
|
|
|
export default config; |