mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-15 09:34:19 +08:00

<!-- Please do not submit updates to dependencies unless it fixes an issue. --> <!-- Please try to limit your pull request to one type (bugfix, feature, etc). Submit multiple pull requests if needed. --> ## What is the new behavior? <!-- Please describe the behavior or changes that are being added by this PR. --> - Updated missing font tokens on `_designTokens.json`. - Updated `tokens.js` script for building utility-classes for newly added font tokens. - Fixed space token typo. - Updated ionic.typography file to start using design tokens and remove duplicated code from the tokens generated files. - Updated Ionic Typography tests ## 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/.github/CONTRIBUTING.md#footer for more information. --> ## Other information <!-- Any other information that is important to this PR such as screenshots of how the component looks before and after the change. -->
175 lines
5.7 KiB
JavaScript
175 lines
5.7 KiB
JavaScript
/* 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.
|
|
*/
|
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
const StyleDictionary = require('style-dictionary');
|
|
|
|
const { fileHeader } = StyleDictionary.formatHelpers;
|
|
|
|
// Empty for as an example of how we can add some extra variables, not from the tokens JSON
|
|
const customVariables = ``;
|
|
|
|
// Prefix for all generated variables
|
|
const variablesPrefix = 'ionic';
|
|
|
|
// CSS vanilla :root format
|
|
StyleDictionary.registerFormat({
|
|
name: 'rootFormat',
|
|
formatter({ dictionary, file }) {
|
|
// Add a prefix to all variable names
|
|
const prefixedVariables = dictionary.allProperties.map((prop) => {
|
|
return ` --${variablesPrefix}-${prop.name}: ${prop.value};`;
|
|
});
|
|
|
|
return (
|
|
fileHeader({ file }) +
|
|
':root {\n' +
|
|
prefixedVariables.join('\n') + // Join all prefixed variables with a newline
|
|
customVariables +
|
|
'\n}\n'
|
|
);
|
|
},
|
|
});
|
|
|
|
// scss variables format
|
|
StyleDictionary.registerFormat({
|
|
name: 'scssVariablesFormat',
|
|
formatter({ dictionary, file }) {
|
|
// Add a prefix to all variable names
|
|
const prefixedVariables = dictionary.allProperties.map((prop) => {
|
|
return `$${variablesPrefix}-${prop.name}: var(--${variablesPrefix}-${prop.name}, ${prop.value});`;
|
|
});
|
|
|
|
return (
|
|
fileHeader({ file }) +
|
|
prefixedVariables.join('\n') + // Join all prefixed variables with a newline
|
|
customVariables +
|
|
'\n'
|
|
);
|
|
},
|
|
});
|
|
|
|
// Create utility-classes
|
|
StyleDictionary.registerFormat({
|
|
name: 'cssUtilityClassesFormat',
|
|
formatter({ dictionary, file }) {
|
|
const utilityClasses = dictionary.allProperties.map((prop) => {
|
|
let tokenType = prop.attributes.category;
|
|
const className = `${prop.name}`;
|
|
let utilityClass = '';
|
|
|
|
switch (tokenType) {
|
|
case 'color':
|
|
utilityClass = `.${variablesPrefix}-${className} {\n color: $ionic-${prop.name};\n}
|
|
.${variablesPrefix}-background-${className} {\n background-color: $ionic-${prop.name};\n}`;
|
|
break;
|
|
case 'border':
|
|
const borderAttribute = prop.attributes.type === 'radius' ? 'border-radius' : 'border-width';
|
|
utilityClass = `.${variablesPrefix}-${className} {\n ${borderAttribute}: $ionic-${prop.name};\n}`;
|
|
break;
|
|
case 'font':
|
|
let fontAttribute;
|
|
switch (prop.attributes.type) {
|
|
case 'size':
|
|
fontAttribute = 'font-size';
|
|
break;
|
|
case 'weight':
|
|
fontAttribute = 'font-weight';
|
|
break;
|
|
case 'line-height':
|
|
fontAttribute = 'line-height';
|
|
break;
|
|
case 'letter-spacing':
|
|
fontAttribute = 'letter-spacing';
|
|
break;
|
|
case 'family':
|
|
return;
|
|
}
|
|
utilityClass = `.${variablesPrefix}-${className} {\n ${fontAttribute}: $ionic-${prop.name};\n}`;
|
|
break;
|
|
case 'elevation':
|
|
utilityClass = `.${variablesPrefix}-${className} {\n box-shadow: $ionic-${prop.name};\n}`;
|
|
break;
|
|
case 'space':
|
|
utilityClass = `.${variablesPrefix}-margin-${className} {\n margin: $ionic-${prop.name};\n};
|
|
.${variablesPrefix}-padding-${className} {\n padding: $ionic-${prop.name};\n}`;
|
|
break;
|
|
default:
|
|
utilityClass = `.${variablesPrefix}-${className} {\n ${tokenType}: $ionic-${prop.name};\n}`;
|
|
}
|
|
|
|
return utilityClass;
|
|
});
|
|
|
|
return [fileHeader({ file }), '@import "./ionic.vars";\n', utilityClasses.join('\n')].join('\n');
|
|
},
|
|
});
|
|
|
|
// Make Style Dictionary comply with the $ format on properties from W3C Guidelines
|
|
const w3cTokenJsonParser = {
|
|
pattern: /\.json|\.tokens\.json|\.tokens$/,
|
|
parse(_a) {
|
|
var contents = _a.contents;
|
|
// replace $value with value so that style dictionary recognizes it
|
|
var preparedContent = (contents || '{}')
|
|
.replace(/"\$?value":/g, '"value":')
|
|
// convert $description to comment
|
|
.replace(/"\$?description":/g, '"comment":');
|
|
//
|
|
return JSON.parse(preparedContent);
|
|
},
|
|
};
|
|
|
|
StyleDictionary.registerParser(w3cTokenJsonParser);
|
|
|
|
// Generate Tokens
|
|
StyleDictionary.extend({
|
|
source: ['./src/foundations/*.json'],
|
|
platforms: {
|
|
css: {
|
|
buildPath: './src/foundations/',
|
|
transformGroup: 'css',
|
|
files: [
|
|
{
|
|
destination: 'ionic.root.scss',
|
|
format: 'rootFormat',
|
|
options: {
|
|
outputReferences: true,
|
|
fileHeader: `myFileHeader`,
|
|
},
|
|
},
|
|
],
|
|
},
|
|
scss: {
|
|
buildPath: './src/foundations/',
|
|
transformGroup: 'scss',
|
|
files: [
|
|
{
|
|
destination: 'ionic.vars.scss',
|
|
format: 'scssVariablesFormat',
|
|
options: {
|
|
outputReferences: true,
|
|
fileHeader: `myFileHeader`,
|
|
},
|
|
},
|
|
{
|
|
destination: 'ionic.utility.scss',
|
|
format: 'cssUtilityClassesFormat',
|
|
options: {
|
|
outputReferences: true,
|
|
fileHeader: `myFileHeader`,
|
|
},
|
|
},
|
|
],
|
|
},
|
|
},
|
|
fileHeader: {
|
|
myFileHeader: () => {
|
|
return [`This is an auto-generated file, please do not change it directly.`, `Ionic Design System`];
|
|
},
|
|
},
|
|
}).buildAllPlatforms();
|