feat(tokens): update tokens architecture and usage (#29950)
Issue number: internal --------- <!-- 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. --> - Removed old tokens stored on foundations folder. Now the jsons with the tokens come from the new dependency: https://github.com/OutSystems/outsystems-design-tokens. - The tokens from UX Team completely changed the structure and in some cases the values. Everything was replaced on the project to use the new tokens. - Snapshots updated and differences reviewed with UX Team. A fix was done on the testing css, to make sure the correct _Inter_ font-family was actually used. This resulted in some differences on the text for some componentes, that had snapshots with the native fonts. - Removed generation of scss file on tokens script, that contained the :root selector with the custom CSS properties, as they were not used on the Ionic context. - Removed generation of html file with tokens preview, as there wasn't a great value on this (we have storybook on other contexts) and it allowed to reduce a lot of code and complexity from the tokens script. - The token command was adapted to use the command available from the https://github.com/OutSystems/outsystems-design-tokens package, using the `--config` prop, where we pass the path to our Ionic token script, where we generate the needed scss variables and utility-classes (by default the tokens repo tries to be as agnostic as possible, and only generates the css variables, without the prefix and added details we need on the Ionic side). - Removed the token command from the npm run build, as it unnecessarily added time on that command to run. Besides, it should not be common that we need to run this command in the future. - Updated reference to latest version of [Style Dictionary 4.1.3](https://v4.styledictionary.com/version-4/statement/). Version 4 comes with a lot of improvements, but also breaking-changes, so it was needed to adapt the tokens script. The code on the script is also now cleaner. - Changed prefix from ionic to ion. The term ionic was used initially, to help differentiate from the old ios/md stuff, but I feel with the current scss architecture, that is no longer needed, and we can use the same prefix across themes. This requires to run `npm install ` again. ## Does this introduce a breaking change? - [x] Yes - [ ] 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> Co-authored-by: Maria Hutt <thetaPC@users.noreply.github.com>
1432
core/package-lock.json
generated
@ -66,20 +66,21 @@
|
|||||||
"fs-extra": "^9.0.1",
|
"fs-extra": "^9.0.1",
|
||||||
"jest": "^29.7.0",
|
"jest": "^29.7.0",
|
||||||
"jest-cli": "^29.7.0",
|
"jest-cli": "^29.7.0",
|
||||||
|
"outsystems-design-tokens": "^1.0.1",
|
||||||
"prettier": "^2.8.8",
|
"prettier": "^2.8.8",
|
||||||
"rollup": "^2.26.4",
|
"rollup": "^2.26.4",
|
||||||
"sass": "^1.33.0",
|
"sass": "^1.33.0",
|
||||||
"serve": "^14.0.1",
|
"serve": "^14.0.1",
|
||||||
"style-dictionary": "^3.9.2",
|
"style-dictionary": "^4.1.3",
|
||||||
"stylelint": "^13.13.1",
|
"stylelint": "^13.13.1",
|
||||||
"stylelint-order": "^4.1.0"
|
"stylelint-order": "^4.1.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "npm run clean && npm run build.tokens && npm run build.css && stencil build --es5 --docs-json dist/docs.json",
|
"build": "npm run clean && npm run build.css && stencil build --es5 --docs-json dist/docs.json",
|
||||||
"build.css": "npm run css.sass && npm run css.minify",
|
"build.css": "npm run css.sass && npm run css.minify",
|
||||||
"build.debug": "npm run clean && stencil build --debug",
|
"build.debug": "npm run clean && stencil build --debug",
|
||||||
"build.docs.json": "stencil build --docs-json dist/docs.json",
|
"build.docs.json": "stencil build --docs-json dist/docs.json",
|
||||||
"build.tokens": "node ./scripts/tokens/index.js && npm run lint.fix && npm run prettier.tokens",
|
"build.tokens": "npx build.tokens --config scripts/tokens/index.js && npm run prettier.tokens",
|
||||||
"clean": "node scripts/clean.js",
|
"clean": "node scripts/clean.js",
|
||||||
"css.minify": "cleancss -O2 -o ./css/ionic.bundle.css ./css/ionic.bundle.css",
|
"css.minify": "cleancss -O2 -o ./css/ionic.bundle.css ./css/ionic.bundle.css",
|
||||||
"css.sass": "sass --embed-sources --style compressed src/css:./css",
|
"css.sass": "sass --embed-sources --style compressed src/css:./css",
|
||||||
|
@ -49,8 +49,15 @@ html.ios.ios {
|
|||||||
font-family: -apple-system, BlinkMacSystemFont, "iosTestingFont", sans-serif;
|
font-family: -apple-system, BlinkMacSystemFont, "iosTestingFont", sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
:root.ionic {
|
/* Override above styles for testing scopes */
|
||||||
|
:root.ionic,
|
||||||
|
:root.ionic.ios,
|
||||||
|
:root.ionic.md,
|
||||||
|
html.ionic,
|
||||||
|
html.ionic.ios,
|
||||||
|
html.ionic.md {
|
||||||
--ionic-global-background-color: var(--background);
|
--ionic-global-background-color: var(--background);
|
||||||
|
--ion-font-family: initial;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -4,372 +4,183 @@
|
|||||||
// - 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 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 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.
|
// - It can easily scale to different necessities we might have in the future.
|
||||||
|
(async () => {
|
||||||
const fs = require('fs');
|
const {
|
||||||
const path = require('path');
|
|
||||||
const StyleDictionary = require('style-dictionary');
|
|
||||||
|
|
||||||
const targetPath = './src/foundations/';
|
|
||||||
|
|
||||||
const {
|
|
||||||
variablesPrefix,
|
|
||||||
getRgbaValue,
|
|
||||||
hexToRgb,
|
|
||||||
generateShadowValue,
|
generateShadowValue,
|
||||||
generateFontSizeValue,
|
generateFontSizeValue,
|
||||||
generateFontFamilyValue,
|
generateFontFamilyValue,
|
||||||
generateTypographyValue,
|
generateTypographyOutput,
|
||||||
generateRgbValue,
|
generateValue,
|
||||||
generateColorUtilityClasses,
|
generateColorUtilityClasses,
|
||||||
generateFontUtilityClass,
|
|
||||||
generateSpaceUtilityClasses,
|
generateSpaceUtilityClasses,
|
||||||
generateTypographyUtilityClass,
|
removeConsecutiveRepeatedWords,
|
||||||
} = require('./utilities');
|
setPrefixValue,
|
||||||
|
generateRadiusUtilityClasses,
|
||||||
|
generateBorderSizeUtilityClasses,
|
||||||
|
generateFontUtilityClasses,
|
||||||
|
generateShadowUtilityClasses,
|
||||||
|
generateUtilityClasses
|
||||||
|
} = require('./utils.js');
|
||||||
|
|
||||||
const { fileHeader } = StyleDictionary.formatHelpers;
|
const StyleDictionary = (await import('style-dictionary')).default;
|
||||||
|
|
||||||
// CSS vanilla :root format
|
// Set the prefix for variables and classes
|
||||||
StyleDictionary.registerFormat({
|
setPrefixValue('ion');
|
||||||
name: 'rootFormat',
|
|
||||||
formatter({ dictionary, file }) {
|
// Register a custom file header
|
||||||
/*
|
StyleDictionary.registerFileHeader({
|
||||||
* This will loop through all tokens and based on the type it will
|
name: 'custom-header',
|
||||||
* call a utility function that will return the expected format for the CSS Variable
|
fileHeader: async (defaultMessages = []) => {
|
||||||
*/
|
return [...defaultMessages, 'Do not edit directly, this file was auto-generated.'];
|
||||||
const prefixedVariables = dictionary.allProperties
|
},
|
||||||
.filter((prop) => prop['$type'] !== 'typography')
|
|
||||||
.map((prop) => {
|
|
||||||
if (prop.attributes.category.startsWith('Elevation')) {
|
|
||||||
const cssShadow = prop.value.map(generateShadowValue).join(', ');
|
|
||||||
return `--${variablesPrefix}-${prop.name}: ${cssShadow};`;
|
|
||||||
} else if (prop.attributes.category.match('font-family')) {
|
|
||||||
return generateFontFamilyValue(prop);
|
|
||||||
} else if (prop.attributes.category.match('font-size')) {
|
|
||||||
return generateFontSizeValue(prop);
|
|
||||||
} else {
|
|
||||||
const rgb = hexToRgb(prop.value);
|
|
||||||
prop.value = getRgbaValue(prop.value);
|
|
||||||
return ` --${variablesPrefix}-${prop.name}: ${prop.value};${
|
|
||||||
rgb ? `\n --${variablesPrefix}-${prop.name}-rgb: ${rgb.r}, ${rgb.g}, ${rgb.b};` : ``
|
|
||||||
}`;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return [
|
// SCSS variables format
|
||||||
fileHeader({ file }),
|
StyleDictionary.registerFormat({
|
||||||
'@use "../themes/functions.sizes" as font;\n',
|
|
||||||
':root {\n' + prefixedVariables.join('\n') + '\n}\n',
|
|
||||||
].join('\n');
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// SCSS variables format
|
|
||||||
StyleDictionary.registerFormat({
|
|
||||||
name: 'scssVariablesFormat',
|
name: 'scssVariablesFormat',
|
||||||
formatter({ dictionary, file }) {
|
format: async function({ dictionary, file}) {
|
||||||
const typographyProperties = dictionary.allProperties.filter((prop) => prop['$type'] === 'typography');
|
|
||||||
const otherProperties = dictionary.allProperties.filter((prop) => prop['$type'] !== 'typography');
|
console.log('Generating SCSS variables...');
|
||||||
|
|
||||||
|
// Separate typography tokens from the rest
|
||||||
|
const typographyProperties = dictionary.allTokens.filter((prop) => prop.$type === 'typography');
|
||||||
|
const otherProperties = dictionary.allTokens.filter((prop) => prop.$type !== 'typography');
|
||||||
|
|
||||||
// Make sure the reused scss variables are defined first, to avoid compilation errors
|
// Make sure the reused scss variables are defined first, to avoid compilation errors
|
||||||
const sortedProperties = [...otherProperties, ...typographyProperties];
|
const sortedProperties = [...otherProperties, ...typographyProperties];
|
||||||
|
|
||||||
const prefixedVariables = sortedProperties.map((prop) => {
|
const prefixedVariables = sortedProperties.map((prop) => {
|
||||||
if (prop.attributes.category.startsWith('Elevation')) {
|
// Remove consecutive repeated words from the token name, like border-border-color
|
||||||
const cssShadow = prop.value.map(generateShadowValue).join(', ');
|
const propName = removeConsecutiveRepeatedWords(prop.name);
|
||||||
return `$${variablesPrefix}-${prop.name}: var(--${variablesPrefix}-${prop.name}, ${cssShadow});`;
|
|
||||||
} else if (prop.attributes.category.match('font-family')) {
|
switch (prop.$type) {
|
||||||
return generateFontFamilyValue(prop, 'scss');
|
case 'boxShadow':
|
||||||
} else if (prop.attributes.category.match('font-size')) {
|
return generateShadowValue(prop, propName);
|
||||||
return generateFontSizeValue(prop, 'scss');
|
case 'fontFamilies':
|
||||||
} else if (prop['$type'] === 'typography') {
|
return generateFontFamilyValue(prop, propName, 'scss');
|
||||||
return generateTypographyValue(prop, dictionary);
|
case 'fontSizes':
|
||||||
} else {
|
return generateFontSizeValue(prop, propName, 'scss');
|
||||||
return generateRgbValue(prop);
|
case 'typography':
|
||||||
|
return generateTypographyOutput(prop, propName, true);
|
||||||
|
default:
|
||||||
|
return generateValue(prop, propName);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const fileHeader = await file.options.fileHeader();
|
||||||
|
|
||||||
return [
|
return [
|
||||||
fileHeader({ file }),
|
`/*\n${fileHeader.join('\n')}\n*/`,
|
||||||
'@use "../themes/functions.sizes" as font;\n',
|
'@use "../themes/functions.sizes" as font;\n',
|
||||||
prefixedVariables.join('\n') + '\n',
|
prefixedVariables.join('\n') + '\n',
|
||||||
].join('\n');
|
].join('\n');
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// Create utility-classes
|
// Create utility-classes
|
||||||
StyleDictionary.registerFormat({
|
StyleDictionary.registerFormat({
|
||||||
name: 'cssUtilityClassesFormat',
|
name: 'cssUtilityClassesFormat',
|
||||||
formatter({ dictionary, file }) {
|
format: async function({ dictionary, file}) {
|
||||||
const utilityClasses = dictionary.allProperties.map((prop) => {
|
|
||||||
let tokenType = prop.attributes.category;
|
|
||||||
const className = `${prop.name}`;
|
|
||||||
let utilityClass = '';
|
|
||||||
|
|
||||||
if (tokenType.startsWith('Elevation')) {
|
console.log('Generating Utility-Classes...');
|
||||||
return `.${variablesPrefix}-${className} {\n box-shadow: $ionic-${prop.name};\n}`;
|
|
||||||
} else if (prop['$type'] === 'typography') {
|
// Arrays to store specific utility classes
|
||||||
return generateTypographyUtilityClass(prop, dictionary);
|
const typographyUtilityClasses = [];
|
||||||
/*
|
const otherUtilityClasses = [];
|
||||||
* Not creating for the tokens below, as they make no sense to exist as utility-classes.
|
|
||||||
* Font-family should be defined on global scope, not component.
|
// Generate utility classes for each token
|
||||||
* Scale its an abstract token group, to be used by other tokens, like the space ones.
|
dictionary.allTokens.map((prop) => {
|
||||||
*/
|
|
||||||
} else if (prop.attributes.category.match('font-family') || tokenType === 'scale') {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const tokenTypeLower = tokenType.toLowerCase();
|
// Remove consecutive repeated words from the token name, like border-border-color
|
||||||
|
const propName = removeConsecutiveRepeatedWords(prop.name);
|
||||||
|
|
||||||
switch (tokenTypeLower) {
|
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 'color':
|
||||||
|
case 'primitives':
|
||||||
|
case 'semantics':
|
||||||
|
case 'text':
|
||||||
|
case 'bg':
|
||||||
|
case 'icon':
|
||||||
case 'state':
|
case 'state':
|
||||||
case 'guidelines':
|
utilityClass = generateColorUtilityClasses(prop, propName);
|
||||||
case 'disabled':
|
|
||||||
case 'hover':
|
|
||||||
case 'pressed':
|
|
||||||
utilityClass = generateColorUtilityClasses(prop, className);
|
|
||||||
break;
|
break;
|
||||||
case 'border-size':
|
case 'border-size':
|
||||||
utilityClass = `.${variablesPrefix}-${className} {\n border-width: $ionic-${prop.name};\n}`;
|
utilityClass = generateBorderSizeUtilityClasses(propName);
|
||||||
break;
|
break;
|
||||||
case 'font':
|
case 'font':
|
||||||
utilityClass = generateFontUtilityClass(prop, className);
|
utilityClass = generateFontUtilityClasses(prop, propName);
|
||||||
break;
|
break;
|
||||||
case 'space':
|
case 'space':
|
||||||
utilityClass = generateSpaceUtilityClasses(prop, className);
|
utilityClass = generateSpaceUtilityClasses(prop, propName);
|
||||||
|
break;
|
||||||
|
case 'shadow':
|
||||||
|
case 'elevation':
|
||||||
|
utilityClass = generateShadowUtilityClasses(propName);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
utilityClass = `.${variablesPrefix}-${className} {\n ${tokenType}: $ionic-${prop.name};\n}`;
|
utilityClass = generateUtilityClasses(tokenCategory, propName);
|
||||||
}
|
}
|
||||||
|
|
||||||
return utilityClass;
|
return otherUtilityClasses.push(utilityClass);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Concatenate typography utility classes at the beginning
|
||||||
|
const finalOutput = typographyUtilityClasses.concat(otherUtilityClasses).join('\n');
|
||||||
|
|
||||||
|
const fileHeader = await file.options.fileHeader();
|
||||||
|
|
||||||
return [
|
return [
|
||||||
fileHeader({ file }),
|
`/*\n${fileHeader.join('\n')}\n*/`,
|
||||||
'@import "./ionic.vars";\n@import "../themes/mixins";\n',
|
'@import "./ionic.vars";\n@import "../themes/mixins";\n',
|
||||||
utilityClasses.join('\n'),
|
finalOutput,
|
||||||
].join('\n');
|
].join('\n');
|
||||||
},
|
},
|
||||||
});
|
|
||||||
|
|
||||||
// Register the custom format to generate HTML
|
|
||||||
// Load the HTML template
|
|
||||||
const template = fs.readFileSync(path.join(__dirname, 'preview.template.html'), 'utf8');
|
|
||||||
|
|
||||||
StyleDictionary.registerFormat({
|
|
||||||
name: 'html/tokens',
|
|
||||||
formatter: function ({ dictionary }) {
|
|
||||||
// Function to extract numerical value from token name
|
|
||||||
const extractValue = (tokenName) => {
|
|
||||||
const match = tokenName.match(/-([0-9]+)/);
|
|
||||||
return match ? parseInt(match[1], 10) : Number.MAX_SAFE_INTEGER;
|
|
||||||
};
|
|
||||||
|
|
||||||
let colorTokens = `
|
|
||||||
<table>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Color</th>
|
|
||||||
<th>Hex</th>
|
|
||||||
<th>Token Name</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
`;
|
|
||||||
let fontSizeTokens = '';
|
|
||||||
let boxShadowTokens = '';
|
|
||||||
let borderSizeTokens = '';
|
|
||||||
let borderRadiusTokens = '';
|
|
||||||
let borderStyleTokens = '';
|
|
||||||
let fontWeightTokens = '';
|
|
||||||
let letterSpacingTokens = '';
|
|
||||||
let spaceTokens = '';
|
|
||||||
|
|
||||||
// Collect border-radius and space tokens for separate sorting
|
|
||||||
let borderRadiusTokenList = [];
|
|
||||||
let spaceTokenList = [];
|
|
||||||
|
|
||||||
dictionary.allProperties.forEach((token) => {
|
|
||||||
if (token.attributes.category === 'color') {
|
|
||||||
colorTokens += `
|
|
||||||
<tr>
|
|
||||||
<td><div class="color-swatch" style="background-color: ${token.value};"></div></td>
|
|
||||||
<td>${token.value}</td>
|
|
||||||
<td>${token.name}</td>
|
|
||||||
</tr>
|
|
||||||
`;
|
|
||||||
} else if (token.attributes.category === 'font-size') {
|
|
||||||
fontSizeTokens += `
|
|
||||||
<div class="font-size-token" style="font-size: ${token.value};">
|
|
||||||
${token.name} (${token.value})
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
} else if (token.attributes.category.startsWith('Elevation')) {
|
|
||||||
const cssShadow = token.value.map(generateShadowValue).join(', ');
|
|
||||||
boxShadowTokens += `
|
|
||||||
<div class="shadow-token" style="box-shadow: ${cssShadow};">
|
|
||||||
${token.name}
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
} else if (token.attributes.category === 'border-size' || token.attributes.category === 'border-width') {
|
|
||||||
borderSizeTokens += `
|
|
||||||
<div class="border-token" style="border-width: ${token.value};">
|
|
||||||
${token.name} (${token.value})
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
} else if (token.attributes.category === 'border-radius') {
|
|
||||||
borderRadiusTokenList.push(token); // Collect border-radius tokens
|
|
||||||
} else if (token.attributes.category === 'border-style') {
|
|
||||||
borderStyleTokens += `
|
|
||||||
<div class="border-token" style="border: 1px ${token.value} #000;">
|
|
||||||
${token.name} (${token.value})
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
} else if (token.attributes.category === 'font-weight') {
|
|
||||||
fontWeightTokens += `
|
|
||||||
<div class="weight-token" style="font-weight: ${token.value};">
|
|
||||||
${token.name} (${token.value})
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
} else if (token.attributes.category === 'letter-spacing') {
|
|
||||||
// Convert % to px
|
|
||||||
const letterSpacingValue = token.value.replace('%', '') + 'px';
|
|
||||||
letterSpacingTokens += `
|
|
||||||
<div class="letter-spacing-token" style="letter-spacing: ${letterSpacingValue};">
|
|
||||||
${token.name} (${letterSpacingValue})
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
} else if (token.attributes.category === 'space') {
|
|
||||||
spaceTokenList.push(token); // Collect space tokens
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Sort border-radius and space tokens
|
})();
|
||||||
borderRadiusTokenList.sort((a, b) => extractValue(a.name) - extractValue(b.name));
|
|
||||||
spaceTokenList.sort((a, b) => extractValue(a.name) - extractValue(b.name));
|
|
||||||
|
|
||||||
// Generate HTML for sorted border-radius tokens
|
// APPLY THE CONFIGURATION
|
||||||
borderRadiusTokenList.forEach((token) => {
|
module.exports = {
|
||||||
borderRadiusTokens += `
|
source: ["node_modules/outsystems-design-tokens/tokens/**/*.json"],
|
||||||
<div class="border-token" style="border-radius: ${token.value};">
|
|
||||||
${token.name} (${token.value})
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Generate HTML for sorted space tokens
|
|
||||||
spaceTokenList.forEach((token) => {
|
|
||||||
spaceTokens += `
|
|
||||||
<div class="spacing-wrapper">
|
|
||||||
<div class="space-token" style="margin: ${token.value};">
|
|
||||||
${token.name} (${token.value})
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
});
|
|
||||||
|
|
||||||
colorTokens += '</tbody></table>';
|
|
||||||
|
|
||||||
return template
|
|
||||||
.replace('{{colorTokens}}', colorTokens)
|
|
||||||
.replace('{{fontSizeTokens}}', fontSizeTokens)
|
|
||||||
.replace('{{boxShadowTokens}}', boxShadowTokens)
|
|
||||||
.replace('{{borderSizeTokens}}', borderSizeTokens)
|
|
||||||
.replace('{{borderRadiusTokens}}', borderRadiusTokens)
|
|
||||||
.replace('{{borderStyleTokens}}', borderStyleTokens)
|
|
||||||
.replace('{{fontWeightTokens}}', fontWeightTokens)
|
|
||||||
.replace('{{letterSpacingTokens}}', letterSpacingTokens)
|
|
||||||
.replace('{{spaceTokens}}', spaceTokens);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// Custom transform to ensure unique token names
|
|
||||||
StyleDictionary.registerTransform({
|
|
||||||
name: 'name/cti/kebab-unique',
|
|
||||||
type: 'name',
|
|
||||||
transformer: function (prop, options) {
|
|
||||||
return [options.prefix].concat(prop.path).join('-').toLowerCase();
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// Register the custom transform group for html file generation
|
|
||||||
StyleDictionary.registerTransformGroup({
|
|
||||||
name: 'custom',
|
|
||||||
transforms: ['attribute/cti', 'name/cti/kebab-unique', 'size/rem', 'color/css'],
|
|
||||||
});
|
|
||||||
|
|
||||||
// Make Style Dictionary comply with the $ format on properties from W3C Guidelines
|
|
||||||
const w3cTokenJsonParser = {
|
|
||||||
pattern: /\.json|\.tokens\.json|\.tokens$/,
|
|
||||||
parse({ 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/tokens/*.json', './src/foundations/tokens/theme/*.json'],
|
|
||||||
platforms: {
|
platforms: {
|
||||||
css: {
|
|
||||||
buildPath: targetPath,
|
|
||||||
transformGroup: 'css',
|
|
||||||
files: [
|
|
||||||
{
|
|
||||||
destination: 'ionic.root.scss',
|
|
||||||
format: 'rootFormat',
|
|
||||||
options: {
|
|
||||||
outputReferences: true,
|
|
||||||
fileHeader: `myFileHeader`,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
scss: {
|
scss: {
|
||||||
buildPath: targetPath,
|
transformGroup: "scss",
|
||||||
transformGroup: 'scss',
|
buildPath: './src/foundations/',
|
||||||
files: [
|
files: [
|
||||||
{
|
{
|
||||||
destination: 'ionic.vars.scss',
|
destination: "ionic.vars.scss",
|
||||||
format: 'scssVariablesFormat',
|
format: "scssVariablesFormat",
|
||||||
options: {
|
options: {
|
||||||
outputReferences: true,
|
fileHeader: `custom-header`,
|
||||||
fileHeader: `myFileHeader`,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
destination: 'ionic.utility.scss',
|
destination: "ionic.utility.scss",
|
||||||
format: 'cssUtilityClassesFormat',
|
format: "cssUtilityClassesFormat",
|
||||||
options: {
|
options: {
|
||||||
outputReferences: true,
|
fileHeader: `custom-header`
|
||||||
fileHeader: `myFileHeader`,
|
}
|
||||||
},
|
}
|
||||||
},
|
]
|
||||||
],
|
}
|
||||||
},
|
}
|
||||||
html: {
|
};
|
||||||
transformGroup: 'custom',
|
|
||||||
buildPath: targetPath,
|
|
||||||
files: [
|
|
||||||
{
|
|
||||||
destination: 'tokens.preview.html',
|
|
||||||
format: 'html/tokens',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
fileHeader: {
|
|
||||||
myFileHeader: () => {
|
|
||||||
return [`This is an auto-generated file, please do not change it directly.`, `Ionic Design System`];
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}).buildAllPlatforms();
|
|
||||||
|
@ -1,63 +0,0 @@
|
|||||||
table {
|
|
||||||
width: 100%;
|
|
||||||
border-collapse: collapse;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
th,
|
|
||||||
td {
|
|
||||||
padding: 10px;
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
th {
|
|
||||||
background-color: #f4f4f4;
|
|
||||||
}
|
|
||||||
|
|
||||||
thead th {
|
|
||||||
position: sticky;
|
|
||||||
top: 0;
|
|
||||||
background-color: #f4f4f4;
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.color-swatch {
|
|
||||||
width: 50px;
|
|
||||||
height: 50px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.font-size-token,
|
|
||||||
.weight-token,
|
|
||||||
.letter-spacing-token {
|
|
||||||
margin: 10px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.border-token,
|
|
||||||
.shadow-token {
|
|
||||||
margin: 10px;
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.border-token {
|
|
||||||
border: 1px solid #000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.spacing-wrapper {
|
|
||||||
background-color: lightblue;
|
|
||||||
}
|
|
||||||
|
|
||||||
.spacing-wrapper > div {
|
|
||||||
background-color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.token-wrapper:has(.spacing-wrapper) {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
hr {
|
|
||||||
background-color: #ccc;
|
|
||||||
margin: 20px 0;
|
|
||||||
}
|
|
@ -1,52 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<meta
|
|
||||||
name="viewport"
|
|
||||||
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"
|
|
||||||
/>
|
|
||||||
<title>Design Tokens</title>
|
|
||||||
<link href="../../../../../css/ionic.bundle.css" rel="stylesheet" />
|
|
||||||
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
|
|
||||||
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
|
|
||||||
<link rel="stylesheet" href="../../scripts/tokens/preview.styles.css" />
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<ion-app>
|
|
||||||
<ion-header>
|
|
||||||
<ion-toolbar>
|
|
||||||
<ion-title>Design Tokens - Preview</ion-title>
|
|
||||||
</ion-toolbar>
|
|
||||||
</ion-header>
|
|
||||||
<ion-content class="ion-padding-horizontal">
|
|
||||||
<h1>Color Tokens</h1>
|
|
||||||
<div class="token-wrapper">{{colorTokens}}</div>
|
|
||||||
<hr />
|
|
||||||
<h1>Font Size Tokens</h1>
|
|
||||||
<div class="token-wrapper">{{fontSizeTokens}}</div>
|
|
||||||
<hr />
|
|
||||||
<h1>Font Weight Tokens</h1>
|
|
||||||
<div class="token-wrapper">{{fontWeightTokens}}</div>
|
|
||||||
<hr />
|
|
||||||
<h1>Letter Spacing Tokens</h1>
|
|
||||||
<div class="token-wrapper">{{letterSpacingTokens}}</div>
|
|
||||||
<hr />
|
|
||||||
<h1>Box Shadow Tokens</h1>
|
|
||||||
<div class="token-wrapper">{{boxShadowTokens}}</div>
|
|
||||||
<hr />
|
|
||||||
<h1>Border Size Tokens</h1>
|
|
||||||
<div class="token-wrapper">{{borderSizeTokens}}</div>
|
|
||||||
<hr />
|
|
||||||
<h1>Border Radius Tokens</h1>
|
|
||||||
<div class="token-wrapper">{{borderRadiusTokens}}</div>
|
|
||||||
<hr />
|
|
||||||
<h1>Border Style Tokens</h1>
|
|
||||||
<div class="token-wrapper">{{borderStyleTokens}}</div>
|
|
||||||
<hr />
|
|
||||||
<h1>Space Tokens</h1>
|
|
||||||
<div class="token-wrapper">{{spaceTokens}}</div>
|
|
||||||
</ion-content>
|
|
||||||
</ion-app>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,191 +0,0 @@
|
|||||||
const variablesPrefix = 'ionic'; // Variable that holds the prefix used on all css and scss variables generated
|
|
||||||
|
|
||||||
// Generates a valid rgba() color
|
|
||||||
function getRgbaValue(propValue) {
|
|
||||||
// Check if its rgba color
|
|
||||||
const isRgba = hexToRgba(propValue);
|
|
||||||
// If it is, then compose rgba() color, otherwise use the normal color
|
|
||||||
if (isRgba !== null) {
|
|
||||||
return (propValue = `rgba(${isRgba.r}, ${isRgba.g}, ${isRgba.b},${isRgba.a})`);
|
|
||||||
} else {
|
|
||||||
return propValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Translates an hex color value to rgb
|
|
||||||
function hexToRgb(hex) {
|
|
||||||
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
|
||||||
return result
|
|
||||||
? {
|
|
||||||
r: parseInt(result[1], 16),
|
|
||||||
g: parseInt(result[2], 16),
|
|
||||||
b: parseInt(result[3], 16),
|
|
||||||
}
|
|
||||||
: null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Translates an hex color value to rgba
|
|
||||||
function hexToRgba(hex) {
|
|
||||||
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
|
||||||
return result
|
|
||||||
? {
|
|
||||||
r: parseInt(result[1], 16),
|
|
||||||
g: parseInt(result[2], 16),
|
|
||||||
b: parseInt(result[3], 16),
|
|
||||||
a: Math.round((parseInt(result[4], 16) * 100) / 255) / 100,
|
|
||||||
}
|
|
||||||
: null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generates a valid box-shadow value from a shadow Design Token structure
|
|
||||||
function generateShadowValue(shadow) {
|
|
||||||
const color = getRgbaValue(shadow.color);
|
|
||||||
|
|
||||||
return `${shadow.offsetX} ${shadow.offsetY} ${shadow.blur} ${shadow.spread} ${color}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generates a valid font-size value from a font-size Design Token structure, while transforming the pixels to rem
|
|
||||||
function generateFontSizeValue(prop, variableType = 'css') {
|
|
||||||
return variableType === 'scss'
|
|
||||||
? `$${variablesPrefix}-${prop.name}: var(--${variablesPrefix}-${prop.name}, font.px-to-rem(${parseInt(
|
|
||||||
prop.value
|
|
||||||
)}));`
|
|
||||||
: `--${variablesPrefix}-${prop.name}: #{font.px-to-rem(${parseInt(prop.value)})};`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generates a valid font-family value from a font-family Design Token structure
|
|
||||||
function generateFontFamilyValue(prop, variableType = 'css') {
|
|
||||||
// Remove the last word from the token, as it contains the name of the font, which we don't want to be included on the generated variables
|
|
||||||
const propName = prop.name.split('-').slice(0, -1).join('-');
|
|
||||||
return variableType === 'scss'
|
|
||||||
? `$${variablesPrefix}-${propName}: var(--${variablesPrefix}-${propName}, "${prop.value}", sans-serif);`
|
|
||||||
: `--${variablesPrefix}-${propName}: "${prop.value}", sans-serif;`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generates a typography based scss map from a typography Design Token structure
|
|
||||||
function generateTypographyValue(prop, dictionary) {
|
|
||||||
const typography = prop.value;
|
|
||||||
const fontSizeMap = getTypeMap(dictionary, 'font-size');
|
|
||||||
const fontWeightMap = getTypeMap(dictionary, 'font-weight');
|
|
||||||
const lineHeightMap = getTypeMap(dictionary, 'line-height');
|
|
||||||
const letterSpacingMap = getTypeMap(dictionary, 'letter-spacing');
|
|
||||||
const fontStyle = prop.attributes.item?.toLowerCase() === 'italic' ? 'italic' : 'normal';
|
|
||||||
|
|
||||||
// This exact format is needed so that it compiles the tokens with the expected lint rules
|
|
||||||
return `
|
|
||||||
$${variablesPrefix}-${prop.name}: (
|
|
||||||
font-size: $ionic-font-size-${fontSizeMap[typography.fontSize]},
|
|
||||||
font-style: ${fontStyle},
|
|
||||||
font-weight: $ionic-font-weight-${fontWeightMap[typography.fontWeight]},
|
|
||||||
letter-spacing: $ionic-letter-spacing-${letterSpacingMap[typography.letterSpacing] || 0},
|
|
||||||
line-height: $ionic-line-height-${lineHeightMap[typography.lineHeight]},
|
|
||||||
text-transform: ${typography.textTransform},
|
|
||||||
text-decoration: ${typography.textDecoration}
|
|
||||||
);
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// To abstract the need to loop across all tokens from a given type
|
|
||||||
function getTypeMap(dictionary, type) {
|
|
||||||
return Object.fromEntries(
|
|
||||||
Object.entries(dictionary.properties[type]).map(([key, token]) => [token.value, token.attributes.type])
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generates a final value, based if the Design Token is of type color or not
|
|
||||||
function generateValue(prop) {
|
|
||||||
const rgb = hexToRgb(prop.value);
|
|
||||||
|
|
||||||
let rgbDeclaration = '';
|
|
||||||
|
|
||||||
if (rgb) {
|
|
||||||
// If the token is color, also add a rgb variable using the same color
|
|
||||||
rgbDeclaration = `\n$${variablesPrefix}-${prop.name}-rgb: var(--${variablesPrefix}-${prop.name}-rgb, ${rgb.r}, ${rgb.g}, ${rgb.b});`;
|
|
||||||
}
|
|
||||||
|
|
||||||
prop.value = getRgbaValue(prop.value);
|
|
||||||
|
|
||||||
return `$${variablesPrefix}-${prop.name}: var(--${variablesPrefix}-${prop.name}, ${prop.value});${rgbDeclaration}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generates a typography based css utility-class from a typography Design Token structure
|
|
||||||
function generateTypographyUtilityClass(prop, dictionary) {
|
|
||||||
const typography = prop.value;
|
|
||||||
const fontSizeMap = getTypeMap(dictionary, 'font-size');
|
|
||||||
const fontWeightMap = getTypeMap(dictionary, 'font-weight');
|
|
||||||
const lineHeightMap = getTypeMap(dictionary, 'line-height');
|
|
||||||
const letterSpacingMap = getTypeMap(dictionary, 'letter-spacing');
|
|
||||||
const fontStyle = prop.attributes.item?.toLowerCase() === 'italic' ? 'italic' : 'normal';
|
|
||||||
|
|
||||||
// This exact format is needed so that it compiles the tokens with the expected lint rules
|
|
||||||
return `
|
|
||||||
.${variablesPrefix}-${prop.name} {
|
|
||||||
font-size: $ionic-font-size-${fontSizeMap[typography.fontSize]};
|
|
||||||
font-style: ${fontStyle};
|
|
||||||
font-weight: $ionic-font-weight-${fontWeightMap[typography.fontWeight]};
|
|
||||||
letter-spacing: $ionic-letter-spacing-${letterSpacingMap[typography.letterSpacing] || 0};
|
|
||||||
line-height: $ionic-line-height-${lineHeightMap[typography.lineHeight]};
|
|
||||||
text-transform: ${typography.textTransform};
|
|
||||||
text-decoration: ${typography.textDecoration};
|
|
||||||
};
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generates a color based css utility-class from a color Design Token structure
|
|
||||||
function generateColorUtilityClasses(prop, className) {
|
|
||||||
return `.${variablesPrefix}-${className} {\n color: $ionic-${prop.name};\n}
|
|
||||||
.${variablesPrefix}-background-${className} {\n background-color: $ionic-${prop.name};\n}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generates a font based css utility-class from a font Design Token structure
|
|
||||||
function generateFontUtilityClass(prop, className) {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
return `.${variablesPrefix}-${className} {\n ${fontAttribute}: $ionic-${prop.name};\n}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generates a margin or padding based css utility-class from a space Design Token structure
|
|
||||||
function generateSpaceUtilityClasses(prop, className) {
|
|
||||||
// This exact format is needed so that it compiles the tokens with the expected lint rules
|
|
||||||
const marginPaddingTemplate = (type) => `
|
|
||||||
.${variablesPrefix}-${type}-${className} {
|
|
||||||
--${type}-start: #{$ionic-${prop.name}};
|
|
||||||
--${type}-end: #{$ionic-${prop.name}};
|
|
||||||
--${type}-top: #{$ionic-${prop.name}};
|
|
||||||
--${type}-bottom: #{$ionic-${prop.name}};
|
|
||||||
|
|
||||||
@include ${type}($ionic-${prop.name});
|
|
||||||
};`;
|
|
||||||
|
|
||||||
return `${marginPaddingTemplate('margin')}\n${marginPaddingTemplate('padding')}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Export all methods to be used on the tokens.js script
|
|
||||||
module.exports = {
|
|
||||||
variablesPrefix,
|
|
||||||
getRgbaValue,
|
|
||||||
hexToRgb,
|
|
||||||
hexToRgba,
|
|
||||||
generateShadowValue,
|
|
||||||
generateFontSizeValue,
|
|
||||||
generateFontFamilyValue,
|
|
||||||
generateTypographyValue,
|
|
||||||
generateRgbValue: generateValue,
|
|
||||||
generateColorUtilityClasses,
|
|
||||||
generateFontUtilityClass,
|
|
||||||
generateSpaceUtilityClasses,
|
|
||||||
generateTypographyUtilityClass,
|
|
||||||
};
|
|
212
core/scripts/tokens/utils.js
Normal file
@ -0,0 +1,212 @@
|
|||||||
|
let variablesPrefix; // Variable that holds the prefix used on all css and scss variables generated
|
||||||
|
|
||||||
|
// Set the variable prefix value
|
||||||
|
function setPrefixValue(prefix) {
|
||||||
|
variablesPrefix = prefix;
|
||||||
|
return variablesPrefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generates a valid rgba() color
|
||||||
|
function getRgbaValue(propValue) {
|
||||||
|
// Check if its rgba color
|
||||||
|
const isRgba = hexToRgba(propValue);
|
||||||
|
// If it is, then compose rgba() color, otherwise use the normal color
|
||||||
|
if (isRgba !== null) {
|
||||||
|
return (propValue = `rgba(${isRgba.r}, ${isRgba.g}, ${isRgba.b},${isRgba.a})`);
|
||||||
|
} else {
|
||||||
|
return propValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Translates an hex color value to rgb
|
||||||
|
function hexToRgb(hex) {
|
||||||
|
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
||||||
|
return result
|
||||||
|
? {
|
||||||
|
r: parseInt(result[1], 16),
|
||||||
|
g: parseInt(result[2], 16),
|
||||||
|
b: parseInt(result[3], 16),
|
||||||
|
}
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Translates an hex color value to rgba
|
||||||
|
function hexToRgba(hex) {
|
||||||
|
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
||||||
|
return result
|
||||||
|
? {
|
||||||
|
r: parseInt(result[1], 16),
|
||||||
|
g: parseInt(result[2], 16),
|
||||||
|
b: parseInt(result[3], 16),
|
||||||
|
a: Math.round((parseInt(result[4], 16) * 100) / 255) / 100,
|
||||||
|
}
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Utility function to remove consecutive repeated words
|
||||||
|
function removeConsecutiveRepeatedWords(str) {
|
||||||
|
return str.replace(/(\b\w+\b)(-\1)+/g, '$1');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generates a valid box-shadow value from a shadow Design Token structure
|
||||||
|
function generateShadowValue(prop, propName) {
|
||||||
|
const cssShadow = prop.$value.map(shadow => {
|
||||||
|
// Assuming shadow is an object with properties like offsetX, offsetY, blurRadius, spreadRadius, color
|
||||||
|
const color = getRgbaValue(shadow.color);
|
||||||
|
return `${shadow.x}px ${shadow.y}px ${shadow.blur}px ${shadow.spread}px ${color}`;
|
||||||
|
}).join(', ');
|
||||||
|
|
||||||
|
return `$${variablesPrefix}-${propName}: var(--${variablesPrefix}-${propName}, ${cssShadow});`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generates a valid font-size value from a font-size Design Token structure, while transforming the pixels to rem
|
||||||
|
function generateFontSizeValue(prop, propName, variableType = 'css') {
|
||||||
|
return variableType === 'scss'
|
||||||
|
? `$${variablesPrefix}-${propName}: var(--${variablesPrefix}-${propName}, font.px-to-rem(${parseInt(
|
||||||
|
prop.$value
|
||||||
|
)}));`
|
||||||
|
: `--${propName}: #{font.px-to-rem(${parseInt(prop.$value)})};`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generates a valid font-family value from a font-family Design Token structure
|
||||||
|
function generateFontFamilyValue(prop, propName, variableType = 'css') {
|
||||||
|
// Remove the last word from the token, as it contains the name of the font, which we don't want to be included on the generated variables
|
||||||
|
const _propName = propName.split('-').slice(0, -1).join('-');
|
||||||
|
|
||||||
|
return variableType === 'scss'
|
||||||
|
? `$${variablesPrefix}-${_propName}: var(--${variablesPrefix}-${_propName}, "${prop.$value}", sans-serif);`
|
||||||
|
: `--${variablesPrefix}-${_propName}: "${prop.$value}", sans-serif;`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generates a final value, based if the Design Token is of type color or not
|
||||||
|
function generateValue(prop, propName) {
|
||||||
|
const rgb = hexToRgb(prop.$value);
|
||||||
|
|
||||||
|
let rgbDeclaration = '';
|
||||||
|
|
||||||
|
if (rgb) {
|
||||||
|
// If the token is color, also add a rgb variable using the same color
|
||||||
|
rgbDeclaration = `\n$${variablesPrefix}-${propName}-rgb: var(--${variablesPrefix}-${propName}-rgb, ${rgb.r}, ${rgb.g}, ${rgb.b});`;
|
||||||
|
prop.value = getRgbaValue(prop.$value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return `$${variablesPrefix}-${propName}: var(--${variablesPrefix}-${propName}, ${prop.$value});${rgbDeclaration}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generates a typography based css utility-class or scss variable from a typography token structure
|
||||||
|
function generateTypographyOutput(prop, propName, isVariable) {
|
||||||
|
const typography = prop.original.$value;
|
||||||
|
|
||||||
|
// Extract the part after the last dot and trim any extraneous characters
|
||||||
|
const extractLastPart = (str) => str.split('.').pop().replace(/[^\w-]/g, '');
|
||||||
|
|
||||||
|
const _initialWrapper = isVariable ? ': (' : ` {`;
|
||||||
|
const _endWrapper = isVariable ? ')' : `}`;
|
||||||
|
const _prefix = isVariable ? '$' : `.`;
|
||||||
|
const _endChar = isVariable ? ',' : ';';
|
||||||
|
|
||||||
|
// This exact format is needed so that it compiles the tokens with the expected lint rules
|
||||||
|
return `
|
||||||
|
${_prefix}${variablesPrefix}-${propName}${_initialWrapper}
|
||||||
|
font-size: $${variablesPrefix}-font-size-${extractLastPart(typography.fontSize)}${_endChar}
|
||||||
|
font-style: ${prop.attributes.item?.toLowerCase() === 'italic' ? 'italic' : 'normal'}${_endChar}
|
||||||
|
font-weight: $${variablesPrefix}-font-weight-${extractLastPart(typography.fontWeight)}${_endChar}
|
||||||
|
letter-spacing: $${variablesPrefix}-font-letter-spacing-${extractLastPart(typography.letterSpacing) || 0}${_endChar}
|
||||||
|
line-height: $${variablesPrefix}-font-line-height-${extractLastPart(typography.lineHeight)}${_endChar}
|
||||||
|
text-transform: ${typography.textCase}${_endChar}
|
||||||
|
text-decoration: ${typography.textDecoration}${_endChar}
|
||||||
|
${_endWrapper};
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generates a color based css utility-class from a color Design Token structure
|
||||||
|
function generateColorUtilityClasses(prop, className) {
|
||||||
|
return `.${variablesPrefix}-${className} {\n color: $${variablesPrefix}-${prop.name};\n}
|
||||||
|
.${variablesPrefix}-background-${className} {\n background-color: $${variablesPrefix}-${prop.name};\n}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generates a margin or padding based css utility-class from a space Design Token structure
|
||||||
|
function generateSpaceUtilityClasses(prop, className) {
|
||||||
|
// This exact format is needed so that it compiles the tokens with the expected lint rules
|
||||||
|
// It will generate classes for margin and padding, for equal sizing on all side and each direction
|
||||||
|
const marginPaddingTemplate = (type) => `
|
||||||
|
.${variablesPrefix}-${type}-${className} {
|
||||||
|
--${type}-top: #{$${variablesPrefix}-${prop.name}};
|
||||||
|
--${type}-end: #{$${variablesPrefix}-${prop.name}};
|
||||||
|
--${type}-bottom: #{$${variablesPrefix}-${prop.name}};
|
||||||
|
--${type}-start: #{$${variablesPrefix}-${prop.name}};
|
||||||
|
|
||||||
|
@include ${type}($${variablesPrefix}-${prop.name});
|
||||||
|
};
|
||||||
|
|
||||||
|
.${variablesPrefix}-${type}-top-${className} {
|
||||||
|
--${type}-top: #{$${variablesPrefix}-${prop.name}};
|
||||||
|
|
||||||
|
@include ${type}($${variablesPrefix}-${prop.name}, null, null, null);
|
||||||
|
};
|
||||||
|
|
||||||
|
.${variablesPrefix}-${type}-end-${className} {
|
||||||
|
--${type}-end: #{$${variablesPrefix}-${prop.name}};
|
||||||
|
|
||||||
|
@include ${type}(null, $${variablesPrefix}-${prop.name}, null, null);
|
||||||
|
};
|
||||||
|
|
||||||
|
.${variablesPrefix}-${type}-bottom-${className} {
|
||||||
|
--${type}-bottom: #{$${variablesPrefix}-${prop.name}};
|
||||||
|
|
||||||
|
@include ${type}(null, null, $${variablesPrefix}-${prop.name}, null);
|
||||||
|
};
|
||||||
|
|
||||||
|
.${variablesPrefix}-${type}-start-${className} {
|
||||||
|
--${type}-start: #{$${variablesPrefix}-${prop.name}};
|
||||||
|
|
||||||
|
@include ${type}(null, null, null, $${variablesPrefix}-${prop.name});
|
||||||
|
};
|
||||||
|
`;
|
||||||
|
|
||||||
|
return `${marginPaddingTemplate('margin')}\n${marginPaddingTemplate('padding')}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generates a valid box-shadow value from a shadow Design Token structure
|
||||||
|
function generateRadiusUtilityClasses(propName) {
|
||||||
|
return `.${variablesPrefix}-${propName} {\n border-radius: $${variablesPrefix}-${propName};\n}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generates a font based css utility-class from a font Design Token structure
|
||||||
|
function generateBorderSizeUtilityClasses(propName) {
|
||||||
|
return `.${variablesPrefix}-${propName} {\n border-width: $${variablesPrefix}-${propName};\n}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generates a font based css utility-class from a font Design Token structure
|
||||||
|
function generateFontUtilityClasses(prop, propName) {
|
||||||
|
return `.${variablesPrefix}-${propName} {\n ${prop.attributes.type}: $${variablesPrefix}-${propName};\n}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generates a valid box-shadow value from a shadow Design Token structure
|
||||||
|
function generateShadowUtilityClasses(propName) {
|
||||||
|
return `.${variablesPrefix}-${propName} {\n box-shadow: $${variablesPrefix}-${propName};\n}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generates a utility class for a given token category and name
|
||||||
|
function generateUtilityClasses(tokenCategory, propName){
|
||||||
|
return `.${variablesPrefix}-${propName} {\n ${tokenCategory}: $${variablesPrefix}-${propName};\n}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
getRgbaValue,
|
||||||
|
hexToRgb,
|
||||||
|
generateShadowValue,
|
||||||
|
generateFontSizeValue,
|
||||||
|
generateFontFamilyValue,
|
||||||
|
generateTypographyOutput,
|
||||||
|
generateValue,
|
||||||
|
setPrefixValue,
|
||||||
|
generateRadiusUtilityClasses,
|
||||||
|
generateColorUtilityClasses,
|
||||||
|
generateSpaceUtilityClasses,
|
||||||
|
removeConsecutiveRepeatedWords,
|
||||||
|
generateBorderSizeUtilityClasses,
|
||||||
|
generateFontUtilityClasses,
|
||||||
|
generateShadowUtilityClasses,
|
||||||
|
generateUtilityClasses
|
||||||
|
};
|
@ -7,7 +7,7 @@
|
|||||||
:host {
|
:host {
|
||||||
min-width: 272px;
|
min-width: 272px;
|
||||||
|
|
||||||
background-color: globals.$ionic-color-base-white;
|
background-color: globals.$ion-primitives-base-white;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inset Accordion Group
|
// Inset Accordion Group
|
||||||
@ -15,6 +15,6 @@
|
|||||||
|
|
||||||
// Shape and padding only apply if the group is inset
|
// Shape and padding only apply if the group is inset
|
||||||
:host(.accordion-group-expand-inset) {
|
:host(.accordion-group-expand-inset) {
|
||||||
@include globals.border-radius(globals.$ionic-border-radius-400);
|
@include globals.border-radius(globals.$ion-border-radius-400);
|
||||||
@include globals.padding(globals.$ionic-space-100);
|
@include globals.padding(globals.$ion-space-100);
|
||||||
}
|
}
|
||||||
|
Before Width: | Height: | Size: 8.3 KiB After Width: | Height: | Size: 8.5 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 8.3 KiB After Width: | Height: | Size: 8.3 KiB |
Before Width: | Height: | Size: 6.0 KiB After Width: | Height: | Size: 6.2 KiB |
Before Width: | Height: | Size: 8.7 KiB After Width: | Height: | Size: 8.6 KiB |
Before Width: | Height: | Size: 6.2 KiB After Width: | Height: | Size: 6.2 KiB |
Before Width: | Height: | Size: 8.9 KiB After Width: | Height: | Size: 9.1 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 8.9 KiB After Width: | Height: | Size: 9.0 KiB |
Before Width: | Height: | Size: 6.6 KiB After Width: | Height: | Size: 6.8 KiB |
Before Width: | Height: | Size: 9.4 KiB After Width: | Height: | Size: 9.3 KiB |
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 6.8 KiB |
Before Width: | Height: | Size: 7.7 KiB After Width: | Height: | Size: 7.7 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 7.5 KiB |
@ -12,16 +12,16 @@
|
|||||||
// to properly inset the border relative to the entire
|
// to properly inset the border relative to the entire
|
||||||
// accordion, rather than just the header.
|
// accordion, rather than just the header.
|
||||||
:host::after {
|
:host::after {
|
||||||
@include globals.margin(null, globals.$ionic-space-400, null, globals.$ionic-space-400);
|
@include globals.margin(null, globals.$ion-space-400, null, globals.$ion-space-400);
|
||||||
@include globals.position(null, 0, 0, 0);
|
@include globals.position(null, 0, 0, 0);
|
||||||
|
|
||||||
display: block;
|
display: block;
|
||||||
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
||||||
height: globals.$ionic-border-size-025;
|
height: globals.$ion-border-size-025;
|
||||||
|
|
||||||
background-color: globals.$ionic-color-neutral-300;
|
background-color: globals.$ion-primitives-neutral-300;
|
||||||
|
|
||||||
content: "";
|
content: "";
|
||||||
|
|
||||||
@ -42,32 +42,32 @@
|
|||||||
// The border is removed from the item in the header because
|
// The border is removed from the item in the header because
|
||||||
// we are adding a border to the ::after element of the accordion.
|
// we are adding a border to the ::after element of the accordion.
|
||||||
::slotted(ion-item[slot="header"]) {
|
::slotted(ion-item[slot="header"]) {
|
||||||
--border-radius: #{globals.$ionic-border-radius-0};
|
--border-radius: #{globals.$ion-border-radius-0};
|
||||||
--color: #{globals.$ionic-color-neutral-1200};
|
--color: #{globals.$ion-primitives-neutral-1200};
|
||||||
--border-width: 0;
|
--border-width: 0;
|
||||||
--inner-border-width: 0;
|
--inner-border-width: 0;
|
||||||
--min-height: #{globals.$ionic-scale-700};
|
--min-height: #{globals.$ion-scale-700};
|
||||||
--padding-top: #{globals.$ionic-space-300};
|
--padding-top: #{globals.$ion-space-300};
|
||||||
--padding-end: #{globals.$ionic-space-400};
|
--padding-end: #{globals.$ion-space-400};
|
||||||
--padding-bottom: #{globals.$ionic-space-300};
|
--padding-bottom: #{globals.$ion-space-300};
|
||||||
--padding-start: #{globals.$ionic-space-400};
|
--padding-start: #{globals.$ion-space-400};
|
||||||
|
|
||||||
@include globals.typography(globals.$ionic-heading-h6-medium);
|
@include globals.typography(globals.$ion-heading-h6-medium);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shape only applies when inside an inset accordion group
|
// Shape only applies when inside an inset accordion group
|
||||||
:host(.in-accordion-group-expand-inset) ::slotted(ion-item[slot="header"]) {
|
:host(.in-accordion-group-expand-inset) ::slotted(ion-item[slot="header"]) {
|
||||||
--border-radius: #{globals.$ionic-border-radius-400};
|
--border-radius: #{globals.$ion-border-radius-400};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Accordion Content
|
// Accordion Content
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
|
|
||||||
#content {
|
#content {
|
||||||
@include globals.padding(null, globals.$ionic-space-400, globals.$ionic-space-300, globals.$ionic-space-400);
|
@include globals.padding(null, globals.$ion-space-400, globals.$ion-space-300, globals.$ion-space-400);
|
||||||
@include globals.typography(globals.$ionic-body-md-regular);
|
@include globals.typography(globals.$ion-body-md-regular);
|
||||||
|
|
||||||
color: globals.$ionic-color-neutral-1000;
|
color: globals.$ion-primitives-neutral-1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disabled Accordion
|
// Disabled Accordion
|
||||||
|
Before Width: | Height: | Size: 8.3 KiB After Width: | Height: | Size: 8.5 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 8.3 KiB After Width: | Height: | Size: 8.3 KiB |
Before Width: | Height: | Size: 8.3 KiB After Width: | Height: | Size: 8.5 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 8.3 KiB After Width: | Height: | Size: 8.3 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 8.3 KiB After Width: | Height: | Size: 8.6 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 8.3 KiB After Width: | Height: | Size: 8.4 KiB |
Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 8.3 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 8.1 KiB |
Before Width: | Height: | Size: 8.3 KiB After Width: | Height: | Size: 8.6 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 8.4 KiB After Width: | Height: | Size: 8.4 KiB |
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 9.0 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 8.8 KiB After Width: | Height: | Size: 8.9 KiB |
Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 8.3 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 8.2 KiB After Width: | Height: | Size: 8.2 KiB |
Before Width: | Height: | Size: 9.2 KiB After Width: | Height: | Size: 9.5 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 9.3 KiB After Width: | Height: | Size: 9.4 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 32 KiB |
@ -5,26 +5,26 @@
|
|||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
|
|
||||||
:host {
|
:host {
|
||||||
--padding-top: #{globals.$ionic-space-0};
|
--padding-top: #{globals.$ion-space-0};
|
||||||
--padding-bottom: #{globals.$ionic-space-0};
|
--padding-bottom: #{globals.$ion-space-0};
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
||||||
background: globals.$ionic-color-neutral-100;
|
background: globals.$ion-primitives-neutral-100;
|
||||||
color: globals.$ionic-color-neutral-800;
|
color: globals.$ion-primitives-neutral-800;
|
||||||
|
|
||||||
font-weight: globals.$ionic-font-weight-medium;
|
font-weight: globals.$ion-font-weight-medium;
|
||||||
|
|
||||||
line-height: globals.$ionic-line-height-700;
|
line-height: globals.$ion-font-line-height-700;
|
||||||
}
|
}
|
||||||
|
|
||||||
:host(:not(.avatar-image)) {
|
:host(:not(.avatar-image)) {
|
||||||
@include padding(var(--padding-top), var(--padding-end), var(--padding-bottom), var(--padding-start));
|
@include padding(var(--padding-top), var(--padding-end), var(--padding-bottom), var(--padding-start));
|
||||||
|
|
||||||
border: globals.$ionic-border-size-025 globals.$ionic-border-style-solid globals.$ionic-color-neutral-800;
|
border: globals.$ion-border-size-025 globals.$ion-border-style-solid globals.$ion-primitives-neutral-800;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Avatar Sizes
|
// Avatar Sizes
|
||||||
@ -32,74 +32,74 @@
|
|||||||
|
|
||||||
/* 2-Extra Small */
|
/* 2-Extra Small */
|
||||||
:host(.avatar-xxsmall) {
|
:host(.avatar-xxsmall) {
|
||||||
--padding-end: #{globals.$ionic-space-050};
|
--padding-end: #{globals.$ion-space-050};
|
||||||
--padding-start: #{globals.$ionic-space-050};
|
--padding-start: #{globals.$ion-space-050};
|
||||||
|
|
||||||
width: globals.$ionic-scale-400;
|
width: globals.$ion-scale-400;
|
||||||
height: globals.$ionic-scale-400;
|
height: globals.$ion-scale-400;
|
||||||
|
|
||||||
font-size: globals.$ionic-font-size-300;
|
font-size: globals.$ion-font-size-300;
|
||||||
|
|
||||||
line-height: globals.$ionic-line-height-500;
|
line-height: globals.$ion-font-line-height-500;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Extra Small */
|
/* Extra Small */
|
||||||
:host(.avatar-xsmall) {
|
:host(.avatar-xsmall) {
|
||||||
--padding-end: #{globals.$ionic-space-050};
|
--padding-end: #{globals.$ion-space-050};
|
||||||
--padding-start: #{globals.$ionic-space-050};
|
--padding-start: #{globals.$ion-space-050};
|
||||||
|
|
||||||
width: globals.$ionic-scale-600;
|
width: globals.$ion-scale-600;
|
||||||
height: globals.$ionic-scale-600;
|
height: globals.$ion-scale-600;
|
||||||
|
|
||||||
font-size: globals.$ionic-font-size-300;
|
font-size: globals.$ion-font-size-300;
|
||||||
|
|
||||||
line-height: globals.$ionic-line-height-500;
|
line-height: globals.$ion-font-line-height-500;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Small */
|
/* Small */
|
||||||
:host(.avatar-small) {
|
:host(.avatar-small) {
|
||||||
--padding-end: #{globals.$ionic-space-150};
|
--padding-end: #{globals.$ion-space-150};
|
||||||
--padding-start: #{globals.$ionic-space-150};
|
--padding-start: #{globals.$ion-space-150};
|
||||||
|
|
||||||
width: globals.$ionic-scale-800;
|
width: globals.$ion-scale-800;
|
||||||
height: globals.$ionic-scale-800;
|
height: globals.$ion-scale-800;
|
||||||
|
|
||||||
font-size: globals.$ionic-font-size-400;
|
font-size: globals.$ion-font-size-400;
|
||||||
|
|
||||||
line-height: globals.$ionic-line-height-600;
|
line-height: globals.$ion-font-line-height-600;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Medium */
|
/* Medium */
|
||||||
:host(.avatar-medium) {
|
:host(.avatar-medium) {
|
||||||
--padding-end: #{globals.$ionic-space-200};
|
--padding-end: #{globals.$ion-space-200};
|
||||||
--padding-start: #{globals.$ionic-space-200};
|
--padding-start: #{globals.$ion-space-200};
|
||||||
|
|
||||||
width: globals.$ionic-scale-1000;
|
width: globals.$ion-scale-1000;
|
||||||
height: globals.$ionic-scale-1000;
|
height: globals.$ion-scale-1000;
|
||||||
|
|
||||||
font-size: globals.$ionic-font-size-450;
|
font-size: globals.$ion-font-size-450;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Large */
|
/* Large */
|
||||||
:host(.avatar-large) {
|
:host(.avatar-large) {
|
||||||
--padding-end: #{globals.$ionic-space-250};
|
--padding-end: #{globals.$ion-space-250};
|
||||||
--padding-start: #{globals.$ionic-space-250};
|
--padding-start: #{globals.$ion-space-250};
|
||||||
|
|
||||||
width: globals.$ionic-scale-1200;
|
width: globals.$ion-scale-1200;
|
||||||
height: globals.$ionic-scale-1200;
|
height: globals.$ion-scale-1200;
|
||||||
|
|
||||||
font-size: globals.$ionic-font-size-500;
|
font-size: globals.$ion-font-size-500;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Extra Large */
|
/* Extra Large */
|
||||||
:host(.avatar-xlarge) {
|
:host(.avatar-xlarge) {
|
||||||
--padding-end: #{globals.$ionic-space-300};
|
--padding-end: #{globals.$ion-space-300};
|
||||||
--padding-start: #{globals.$ionic-space-300};
|
--padding-start: #{globals.$ion-space-300};
|
||||||
|
|
||||||
width: globals.$ionic-scale-1400;
|
width: globals.$ion-scale-1400;
|
||||||
height: globals.$ionic-scale-1400;
|
height: globals.$ion-scale-1400;
|
||||||
|
|
||||||
font-size: globals.$ionic-font-size-550;
|
font-size: globals.$ion-font-size-550;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Avatar Shapes
|
// Avatar Shapes
|
||||||
@ -108,19 +108,19 @@
|
|||||||
:host(.avatar-xxsmall.avatar-soft),
|
:host(.avatar-xxsmall.avatar-soft),
|
||||||
:host(.avatar-xsmall.avatar-soft),
|
:host(.avatar-xsmall.avatar-soft),
|
||||||
:host(.avatar-small.avatar-soft) {
|
:host(.avatar-small.avatar-soft) {
|
||||||
--border-radius: #{globals.$ionic-border-radius-100};
|
--border-radius: #{globals.$ion-border-radius-100};
|
||||||
}
|
}
|
||||||
|
|
||||||
:host(.avatar-soft) {
|
:host(.avatar-soft) {
|
||||||
--border-radius: #{globals.$ionic-border-radius-200};
|
--border-radius: #{globals.$ion-border-radius-200};
|
||||||
}
|
}
|
||||||
|
|
||||||
:host(.avatar-round) {
|
:host(.avatar-round) {
|
||||||
--border-radius: #{globals.$ionic-border-radius-full};
|
--border-radius: #{globals.$ion-border-radius-full};
|
||||||
}
|
}
|
||||||
|
|
||||||
:host(.avatar-rectangular) {
|
:host(.avatar-rectangular) {
|
||||||
--border-radius: #{globals.$ionic-border-radius-0};
|
--border-radius: #{globals.$ion-border-radius-0};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Avatar Icon
|
// Avatar Icon
|
||||||
@ -131,26 +131,26 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
:host(.avatar-xsmall) ::slotted(ion-icon) {
|
:host(.avatar-xsmall) ::slotted(ion-icon) {
|
||||||
width: globals.$ionic-scale-400;
|
width: globals.$ion-scale-400;
|
||||||
height: globals.$ionic-scale-400;
|
height: globals.$ion-scale-400;
|
||||||
}
|
}
|
||||||
|
|
||||||
:host(.avatar-small) ::slotted(ion-icon) {
|
:host(.avatar-small) ::slotted(ion-icon) {
|
||||||
width: globals.$ionic-scale-500;
|
width: globals.$ion-scale-500;
|
||||||
height: globals.$ionic-scale-500;
|
height: globals.$ion-scale-500;
|
||||||
}
|
}
|
||||||
|
|
||||||
:host(.avatar-medium) ::slotted(ion-icon) {
|
:host(.avatar-medium) ::slotted(ion-icon) {
|
||||||
width: globals.$ionic-scale-600;
|
width: globals.$ion-scale-600;
|
||||||
height: globals.$ionic-scale-600;
|
height: globals.$ion-scale-600;
|
||||||
}
|
}
|
||||||
|
|
||||||
:host(.avatar-large) ::slotted(ion-icon) {
|
:host(.avatar-large) ::slotted(ion-icon) {
|
||||||
width: globals.$ionic-scale-800;
|
width: globals.$ion-scale-800;
|
||||||
height: globals.$ionic-scale-800;
|
height: globals.$ion-scale-800;
|
||||||
}
|
}
|
||||||
|
|
||||||
:host(.avatar-xlarge) ::slotted(ion-icon) {
|
:host(.avatar-xlarge) ::slotted(ion-icon) {
|
||||||
width: globals.$ionic-scale-1000;
|
width: globals.$ion-scale-1000;
|
||||||
height: globals.$ionic-scale-1000;
|
height: globals.$ion-scale-1000;
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,6 @@
|
|||||||
@import "./backdrop";
|
@import "./backdrop";
|
||||||
|
|
||||||
:host {
|
:host {
|
||||||
background-color: rgba(globals.$ionic-color-base-black-rgb, 0.7);
|
background-color: rgba(globals.$ion-primitives-base-black-rgb, 0.7);
|
||||||
backdrop-filter: blur(2px);
|
backdrop-filter: blur(2px);
|
||||||
}
|
}
|
||||||
|
@ -7,17 +7,17 @@
|
|||||||
:host {
|
:host {
|
||||||
--background: #{globals.ion-color(primary, base)};
|
--background: #{globals.ion-color(primary, base)};
|
||||||
--color: #{globals.ion-color(primary, contrast)};
|
--color: #{globals.ion-color(primary, contrast)};
|
||||||
--padding-start: #{globals.$ionic-space-200};
|
--padding-start: #{globals.$ion-space-200};
|
||||||
--padding-end: #{globals.$ionic-space-200};
|
--padding-end: #{globals.$ion-space-200};
|
||||||
--padding-top: #{globals.$ionic-space-0};
|
--padding-top: #{globals.$ion-space-0};
|
||||||
--padding-bottom: #{globals.$ionic-space-0};
|
--padding-bottom: #{globals.$ion-space-0};
|
||||||
|
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
||||||
font-weight: globals.$ionic-font-weight-medium;
|
font-weight: globals.$ion-font-weight-medium;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Badge Shapes
|
// Badge Shapes
|
||||||
@ -25,23 +25,23 @@
|
|||||||
|
|
||||||
/* Soft Badge */
|
/* Soft Badge */
|
||||||
:host(.badge-soft) {
|
:host(.badge-soft) {
|
||||||
@include globals.border-radius(globals.$ionic-border-radius-200);
|
@include globals.border-radius(globals.$ion-border-radius-200);
|
||||||
}
|
}
|
||||||
|
|
||||||
:host(.badge-xxsmall.badge-soft),
|
:host(.badge-xxsmall.badge-soft),
|
||||||
:host(.badge-xsmall.badge-soft),
|
:host(.badge-xsmall.badge-soft),
|
||||||
:host(.badge-small.badge-soft) {
|
:host(.badge-small.badge-soft) {
|
||||||
@include globals.border-radius(globals.$ionic-border-radius-100);
|
@include globals.border-radius(globals.$ion-border-radius-100);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Round Badge */
|
/* Round Badge */
|
||||||
:host(.badge-round) {
|
:host(.badge-round) {
|
||||||
@include globals.border-radius(globals.$ionic-border-radius-full);
|
@include globals.border-radius(globals.$ion-border-radius-full);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Rectangular Badge */
|
/* Rectangular Badge */
|
||||||
:host(.badge-rectangular) {
|
:host(.badge-rectangular) {
|
||||||
@include globals.border-radius(globals.$ionic-border-radius-0);
|
@include globals.border-radius(globals.$ion-border-radius-0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Badge Sizes
|
// Badge Sizes
|
||||||
@ -49,69 +49,69 @@
|
|||||||
|
|
||||||
/* 2-Extra Small Badge */
|
/* 2-Extra Small Badge */
|
||||||
:host(.badge-xxsmall) {
|
:host(.badge-xxsmall) {
|
||||||
--padding-start: #{globals.$ionic-space-050};
|
--padding-start: #{globals.$ion-space-050};
|
||||||
--padding-end: #{globals.$ionic-space-050};
|
--padding-end: #{globals.$ion-space-050};
|
||||||
|
|
||||||
min-width: globals.$ionic-scale-400;
|
min-width: globals.$ion-scale-400;
|
||||||
height: globals.$ionic-scale-400;
|
height: globals.$ion-scale-400;
|
||||||
|
|
||||||
font-size: globals.$ionic-font-size-300;
|
font-size: globals.$ion-font-size-300;
|
||||||
|
|
||||||
line-height: globals.$ionic-line-height-400;
|
line-height: globals.$ion-font-line-height-400;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Extra Small Badge */
|
/* Extra Small Badge */
|
||||||
:host(.badge-xsmall) {
|
:host(.badge-xsmall) {
|
||||||
--padding-start: #{globals.$ionic-space-100};
|
--padding-start: #{globals.$ion-space-100};
|
||||||
--padding-end: #{globals.$ionic-space-100};
|
--padding-end: #{globals.$ion-space-100};
|
||||||
|
|
||||||
min-width: globals.$ionic-scale-600;
|
min-width: globals.$ion-scale-600;
|
||||||
height: globals.$ionic-scale-600;
|
height: globals.$ion-scale-600;
|
||||||
|
|
||||||
font-size: globals.$ionic-font-size-350;
|
font-size: globals.$ion-font-size-350;
|
||||||
|
|
||||||
line-height: globals.$ionic-line-height-600;
|
line-height: globals.$ion-font-line-height-600;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Small Badge */
|
/* Small Badge */
|
||||||
:host(.badge-small) {
|
:host(.badge-small) {
|
||||||
--padding-start: #{globals.$ionic-space-100};
|
--padding-start: #{globals.$ion-space-100};
|
||||||
--padding-end: #{globals.$ionic-space-100};
|
--padding-end: #{globals.$ion-space-100};
|
||||||
|
|
||||||
min-width: globals.$ionic-scale-800;
|
min-width: globals.$ion-scale-800;
|
||||||
height: globals.$ionic-scale-800;
|
height: globals.$ion-scale-800;
|
||||||
|
|
||||||
font-size: globals.$ionic-font-size-400;
|
font-size: globals.$ion-font-size-400;
|
||||||
|
|
||||||
line-height: globals.$ionic-line-height-600;
|
line-height: globals.$ion-font-line-height-600;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Medium Badge */
|
/* Medium Badge */
|
||||||
:host(.badge-medium) {
|
:host(.badge-medium) {
|
||||||
min-width: globals.$ionic-scale-1000;
|
min-width: globals.$ion-scale-1000;
|
||||||
height: globals.$ionic-scale-1000;
|
height: globals.$ion-scale-1000;
|
||||||
|
|
||||||
font-size: globals.$ionic-font-size-450;
|
font-size: globals.$ion-font-size-450;
|
||||||
|
|
||||||
line-height: globals.$ionic-line-height-700;
|
line-height: globals.$ion-font-line-height-700;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Large Badge */
|
/* Large Badge */
|
||||||
:host(.badge-large) {
|
:host(.badge-large) {
|
||||||
min-width: globals.$ionic-scale-1200;
|
min-width: globals.$ion-scale-1200;
|
||||||
height: globals.$ionic-scale-1200;
|
height: globals.$ion-scale-1200;
|
||||||
|
|
||||||
font-size: globals.$ionic-font-size-500;
|
font-size: globals.$ion-font-size-500;
|
||||||
|
|
||||||
line-height: globals.$ionic-line-height-700;
|
line-height: globals.$ion-font-line-height-700;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Extra Large Badge */
|
/* Extra Large Badge */
|
||||||
:host(.badge-xlarge) {
|
:host(.badge-xlarge) {
|
||||||
min-width: globals.$ionic-scale-1400;
|
min-width: globals.$ion-scale-1400;
|
||||||
height: globals.$ionic-scale-1400;
|
height: globals.$ion-scale-1400;
|
||||||
|
|
||||||
font-size: globals.$ionic-font-size-550;
|
font-size: globals.$ion-font-size-550;
|
||||||
|
|
||||||
line-height: globals.$ionic-line-height-700;
|
line-height: globals.$ion-font-line-height-700;
|
||||||
}
|
}
|
||||||
|
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 71 KiB |
Before Width: | Height: | Size: 85 KiB After Width: | Height: | Size: 87 KiB |
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 65 KiB |
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 71 KiB |
Before Width: | Height: | Size: 85 KiB After Width: | Height: | Size: 88 KiB |
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 65 KiB |
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 65 KiB |
Before Width: | Height: | Size: 80 KiB After Width: | Height: | Size: 81 KiB |
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 66 KiB |
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 65 KiB |
Before Width: | Height: | Size: 80 KiB After Width: | Height: | Size: 82 KiB |
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 65 KiB |
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 55 KiB |
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 73 KiB |
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 53 KiB |
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 55 KiB |
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 74 KiB |
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 53 KiB |
@ -5,18 +5,18 @@
|
|||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
:host {
|
:host {
|
||||||
--padding-bottom: var(--padding-top);
|
--padding-bottom: var(--padding-top);
|
||||||
--padding-end: #{globals.$ionic-space-500};
|
--padding-end: #{globals.$ion-space-500};
|
||||||
--padding-start: var(--padding-end);
|
--padding-start: var(--padding-end);
|
||||||
--padding-top: #{globals.$ionic-space-0};
|
--padding-top: #{globals.$ion-space-0};
|
||||||
--focus-ring-color: #{globals.$ionic-state-focus-1};
|
--focus-ring-color: #{globals.$ion-border-focus-default};
|
||||||
--focus-ring-width: #{globals.$ionic-border-size-050};
|
--focus-ring-width: #{globals.$ion-border-size-050};
|
||||||
|
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
min-height: globals.$ionic-scale-1000;
|
min-height: globals.$ion-scale-1000;
|
||||||
|
|
||||||
font-family: globals.$ionic-font-family;
|
font-family: globals.$ion-font-family;
|
||||||
font-size: globals.$ionic-font-size-350;
|
font-size: globals.$ion-font-size-350;
|
||||||
|
|
||||||
// Target area
|
// Target area
|
||||||
&::after {
|
&::after {
|
||||||
@ -24,7 +24,7 @@
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
||||||
height: 100%;
|
height: 100%;
|
||||||
min-height: globals.$ionic-scale-1200;
|
min-height: globals.$ion-scale-1200;
|
||||||
|
|
||||||
transform: translateY(-50%);
|
transform: translateY(-50%);
|
||||||
|
|
||||||
@ -56,9 +56,9 @@
|
|||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
|
|
||||||
:host(.button-outline) {
|
:host(.button-outline) {
|
||||||
--border-width: #{globals.$ionic-border-size-025};
|
--border-width: #{globals.$ion-border-size-025};
|
||||||
--border-style: #{globals.$ionic-border-style-solid};
|
--border-style: #{globals.$ion-border-style-solid};
|
||||||
--background-activated: #{globals.$ionic-color-neutral-200};
|
--background-activated: #{globals.$ion-primitives-neutral-200};
|
||||||
--background-focused: transparent;
|
--background-focused: transparent;
|
||||||
--background-hover: #{globals.ion-color(primary, base)};
|
--background-hover: #{globals.ion-color(primary, base)};
|
||||||
--background-hover-opacity: 0.04;
|
--background-hover-opacity: 0.04;
|
||||||
@ -70,7 +70,7 @@
|
|||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
|
|
||||||
:host(.button-clear) {
|
:host(.button-clear) {
|
||||||
--background-activated: #{globals.$ionic-color-neutral-200};
|
--background-activated: #{globals.$ion-primitives-neutral-200};
|
||||||
--background-focused: transparent;
|
--background-focused: transparent;
|
||||||
--background-hover: #{globals.ion-color(primary, base)};
|
--background-hover: #{globals.ion-color(primary, base)};
|
||||||
--background-hover-opacity: 0.04;
|
--background-hover-opacity: 0.04;
|
||||||
@ -87,7 +87,7 @@
|
|||||||
|
|
||||||
:host(.button-outline.ion-color) ion-ripple-effect,
|
:host(.button-outline.ion-color) ion-ripple-effect,
|
||||||
:host(.button-clear.ion-color) ion-ripple-effect {
|
:host(.button-clear.ion-color) ion-ripple-effect {
|
||||||
color: globals.$ionic-color-neutral-200;
|
color: globals.$ion-primitives-neutral-200;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Button Sizes
|
// Button Sizes
|
||||||
@ -97,52 +97,52 @@
|
|||||||
:host(.button-xsmall),
|
:host(.button-xsmall),
|
||||||
:host(.button-small) {
|
:host(.button-small) {
|
||||||
::slotted(ion-icon[slot="start"]) {
|
::slotted(ion-icon[slot="start"]) {
|
||||||
@include globals.margin-horizontal(null, globals.$ionic-space-100);
|
@include globals.margin-horizontal(null, globals.$ion-space-100);
|
||||||
}
|
}
|
||||||
|
|
||||||
::slotted(ion-icon[slot="end"]) {
|
::slotted(ion-icon[slot="end"]) {
|
||||||
@include globals.margin-horizontal(globals.$ionic-space-100, null);
|
@include globals.margin-horizontal(globals.$ion-space-100, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Extra Small Button */
|
/* Extra Small Button */
|
||||||
:host(.button-xsmall) {
|
:host(.button-xsmall) {
|
||||||
--padding-top: #{globals.$ionic-space-100};
|
--padding-top: #{globals.$ion-space-100};
|
||||||
--padding-end: #{globals.$ionic-space-300};
|
--padding-end: #{globals.$ion-space-300};
|
||||||
|
|
||||||
min-height: globals.$ionic-space-600;
|
min-height: globals.$ion-space-600;
|
||||||
|
|
||||||
font-size: globals.$ionic-font-size-300;
|
font-size: globals.$ion-font-size-300;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Small Button */
|
/* Small Button */
|
||||||
:host(.button-small) {
|
:host(.button-small) {
|
||||||
--padding-top: #{globals.$ionic-space-200};
|
--padding-top: #{globals.$ion-space-200};
|
||||||
--padding-end: #{globals.$ionic-space-400};
|
--padding-end: #{globals.$ion-space-400};
|
||||||
|
|
||||||
min-height: #{globals.$ionic-scale-800};
|
min-height: #{globals.$ion-scale-800};
|
||||||
|
|
||||||
font-size: #{globals.$ionic-font-size-300};
|
font-size: #{globals.$ion-font-size-300};
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Large Button */
|
/* Large Button */
|
||||||
:host(.button-large) {
|
:host(.button-large) {
|
||||||
--padding-top: #{globals.$ionic-space-400};
|
--padding-top: #{globals.$ion-space-400};
|
||||||
--padding-end: #{globals.$ionic-space-600};
|
--padding-end: #{globals.$ion-space-600};
|
||||||
|
|
||||||
min-height: #{globals.$ionic-scale-1200};
|
min-height: #{globals.$ion-scale-1200};
|
||||||
|
|
||||||
font-size: #{globals.$ionic-font-size-400};
|
font-size: #{globals.$ion-font-size-400};
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Extra Large Button */
|
/* Extra Large Button */
|
||||||
:host(.button-xlarge) {
|
:host(.button-xlarge) {
|
||||||
--padding-top: #{globals.$ionic-space-400};
|
--padding-top: #{globals.$ion-space-400};
|
||||||
--padding-end: #{globals.$ionic-space-800};
|
--padding-end: #{globals.$ion-space-800};
|
||||||
|
|
||||||
min-height: #{globals.$ionic-scale-1400};
|
min-height: #{globals.$ion-scale-1400};
|
||||||
|
|
||||||
font-size: #{globals.$ionic-font-size-500};
|
font-size: #{globals.$ion-font-size-500};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Button with Icons
|
// Button with Icons
|
||||||
@ -152,7 +152,7 @@
|
|||||||
::slotted(ion-icon[slot="start"]),
|
::slotted(ion-icon[slot="start"]),
|
||||||
::slotted(ion-icon[slot="end"]),
|
::slotted(ion-icon[slot="end"]),
|
||||||
::slotted(ion-icon[slot="icon-only"]) {
|
::slotted(ion-icon[slot="icon-only"]) {
|
||||||
font-size: globals.$ionic-font-size-400;
|
font-size: globals.$ion-font-size-400;
|
||||||
}
|
}
|
||||||
|
|
||||||
:host(.button-xsmall),
|
:host(.button-xsmall),
|
||||||
@ -179,26 +179,26 @@
|
|||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
|
|
||||||
:host(.button-soft) {
|
:host(.button-soft) {
|
||||||
--border-radius: #{globals.$ionic-border-radius-200};
|
--border-radius: #{globals.$ion-border-radius-200};
|
||||||
}
|
}
|
||||||
|
|
||||||
:host(.button-soft.button-xsmall),
|
:host(.button-soft.button-xsmall),
|
||||||
:host(.button-soft.button-small) {
|
:host(.button-soft.button-small) {
|
||||||
--border-radius: #{globals.$ionic-border-radius-100};
|
--border-radius: #{globals.$ion-border-radius-100};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Round Button
|
// Round Button
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
|
|
||||||
:host(.button-round) {
|
:host(.button-round) {
|
||||||
--border-radius: #{globals.$ionic-border-radius-full};
|
--border-radius: #{globals.$ion-border-radius-full};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rectangular Button
|
// Rectangular Button
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
|
|
||||||
:host(.button-rectangular) {
|
:host(.button-rectangular) {
|
||||||
--border-radius: #{globals.$ionic-border-radius-0};
|
--border-radius: #{globals.$ion-border-radius-0};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Button: Focus
|
// Button: Focus
|
||||||
@ -206,8 +206,8 @@
|
|||||||
|
|
||||||
// Only show the focus ring when the button is focused
|
// Only show the focus ring when the button is focused
|
||||||
:host(.ion-focused) .button-native {
|
:host(.ion-focused) .button-native {
|
||||||
outline: var(--focus-ring-width) globals.$ionic-border-style-solid var(--focus-ring-color);
|
outline: var(--focus-ring-width) globals.$ion-border-style-solid var(--focus-ring-color);
|
||||||
outline-offset: globals.$ionic-border-size-050;
|
outline-offset: globals.$ion-border-size-050;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -243,29 +243,29 @@
|
|||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
|
|
||||||
::slotted(ion-icon) {
|
::slotted(ion-icon) {
|
||||||
font-size: globals.$ionic-font-size-500;
|
font-size: globals.$ion-font-size-500;
|
||||||
}
|
}
|
||||||
|
|
||||||
:host(.button-small) ::slotted(ion-icon[slot="start"]) {
|
:host(.button-small) ::slotted(ion-icon[slot="start"]) {
|
||||||
@include globals.margin-horizontal(null, globals.$ionic-space-200);
|
@include globals.margin-horizontal(null, globals.$ion-space-200);
|
||||||
}
|
}
|
||||||
|
|
||||||
::slotted(ion-icon[slot="start"]) {
|
::slotted(ion-icon[slot="start"]) {
|
||||||
@include globals.margin-horizontal(null, globals.$ionic-space-250);
|
@include globals.margin-horizontal(null, globals.$ion-space-250);
|
||||||
}
|
}
|
||||||
|
|
||||||
:host(.button-large) ::slotted(ion-icon[slot="start"]) {
|
:host(.button-large) ::slotted(ion-icon[slot="start"]) {
|
||||||
@include globals.margin-horizontal(null, globals.$ionic-space-300);
|
@include globals.margin-horizontal(null, globals.$ion-space-300);
|
||||||
}
|
}
|
||||||
|
|
||||||
:host(.button-small) ::slotted(ion-icon[slot="end"]) {
|
:host(.button-small) ::slotted(ion-icon[slot="end"]) {
|
||||||
@include globals.margin-horizontal(globals.$ionic-space-200, null);
|
@include globals.margin-horizontal(globals.$ion-space-200, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
::slotted(ion-icon[slot="end"]) {
|
::slotted(ion-icon[slot="end"]) {
|
||||||
@include globals.margin-horizontal(globals.$ionic-space-250, null);
|
@include globals.margin-horizontal(globals.$ion-space-250, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
:host(.button-large) ::slotted(ion-icon[slot="end"]) {
|
:host(.button-large) ::slotted(ion-icon[slot="end"]) {
|
||||||
@include globals.margin-horizontal(globals.$ionic-space-300, null);
|
@include globals.margin-horizontal(globals.$ion-space-300, null);
|
||||||
}
|
}
|
||||||
|
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 69 KiB |
Before Width: | Height: | Size: 89 KiB After Width: | Height: | Size: 88 KiB |
Before Width: | Height: | Size: 81 KiB After Width: | Height: | Size: 82 KiB |
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 69 KiB |
Before Width: | Height: | Size: 88 KiB After Width: | Height: | Size: 88 KiB |
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 82 KiB |
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 88 KiB After Width: | Height: | Size: 87 KiB |
Before Width: | Height: | Size: 80 KiB After Width: | Height: | Size: 80 KiB |
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 87 KiB After Width: | Height: | Size: 86 KiB |
Before Width: | Height: | Size: 80 KiB After Width: | Height: | Size: 81 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 107 KiB After Width: | Height: | Size: 107 KiB |