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

The default (iOS/MD) bundle is removed from the tests for the `ionic` theme because it adds global component styles that the `ionic` theme does not need. The missing utility files are imported, and padding/margin classes are generated from the design tokens, as many tests rely on `ion-padding` and `ion-text-center` being available. This change ensures the `ionic` theme includes the same classes offered in our documentation: https://ionicframework.com/docs/layout/css-utilities.
281 lines
11 KiB
JavaScript
281 lines
11 KiB
JavaScript
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 margin and padding utility classes to match the token-agnostic
|
|
// utilities provided by the Ionic Framework
|
|
function generateDefaultSpaceUtilityClasses() {
|
|
const zeroMarginPaddingToken = 'space-0';
|
|
const defaultMarginPaddingToken = 'space-400';
|
|
|
|
const marginPaddingTemplate = (type) => `
|
|
.${variablesPrefix}-no-${type} {
|
|
--${type}-top: #{$${variablesPrefix}-${zeroMarginPaddingToken}};
|
|
--${type}-end: #{$${variablesPrefix}-${zeroMarginPaddingToken}};
|
|
--${type}-bottom: #{$${variablesPrefix}-${zeroMarginPaddingToken}};
|
|
--${type}-start: #{$${variablesPrefix}-${zeroMarginPaddingToken}};
|
|
|
|
@include ${type}($${variablesPrefix}-${zeroMarginPaddingToken});
|
|
};
|
|
|
|
.${variablesPrefix}-${type} {
|
|
--${type}-top: #{$${variablesPrefix}-${defaultMarginPaddingToken}};
|
|
--${type}-end: #{$${variablesPrefix}-${defaultMarginPaddingToken}};
|
|
--${type}-bottom: #{$${variablesPrefix}-${defaultMarginPaddingToken}};
|
|
--${type}-start: #{$${variablesPrefix}-${defaultMarginPaddingToken}};
|
|
|
|
@include ${type}($${variablesPrefix}-${defaultMarginPaddingToken});
|
|
};
|
|
|
|
.${variablesPrefix}-${type}-top {
|
|
--${type}-top: #{$${variablesPrefix}-${defaultMarginPaddingToken}};
|
|
|
|
@include ${type}($${variablesPrefix}-${defaultMarginPaddingToken}, null, null, null);
|
|
};
|
|
|
|
.${variablesPrefix}-${type}-end {
|
|
--${type}-end: #{$${variablesPrefix}-${defaultMarginPaddingToken}};
|
|
|
|
@include ${type}(null, $${variablesPrefix}-${defaultMarginPaddingToken}, null, null);
|
|
};
|
|
|
|
.${variablesPrefix}-${type}-bottom {
|
|
--${type}-bottom: #{$${variablesPrefix}-${defaultMarginPaddingToken}};
|
|
|
|
@include ${type}(null, null, $${variablesPrefix}-${defaultMarginPaddingToken}, null);
|
|
};
|
|
|
|
.${variablesPrefix}-${type}-start {
|
|
--${type}-start: #{$${variablesPrefix}-${defaultMarginPaddingToken}};
|
|
|
|
@include ${type}(null, null, null, $${variablesPrefix}-${defaultMarginPaddingToken});
|
|
};
|
|
|
|
.${variablesPrefix}-${type}-vertical {
|
|
--${type}-top: #{$${variablesPrefix}-${defaultMarginPaddingToken}};
|
|
--${type}-bottom: #{$${variablesPrefix}-${defaultMarginPaddingToken}};
|
|
|
|
@include ${type}($${variablesPrefix}-${defaultMarginPaddingToken}, null, $${variablesPrefix}-${defaultMarginPaddingToken}, null);
|
|
};
|
|
|
|
.${variablesPrefix}-${type}-horizontal {
|
|
--${type}-start: #{$${variablesPrefix}-${defaultMarginPaddingToken}};
|
|
--${type}-end: #{$${variablesPrefix}-${defaultMarginPaddingToken}};
|
|
|
|
@include ${type}(null, $${variablesPrefix}-${defaultMarginPaddingToken}, null, $${variablesPrefix}-${defaultMarginPaddingToken});
|
|
};
|
|
`;
|
|
|
|
return `${marginPaddingTemplate('margin')}\n${marginPaddingTemplate('padding')}`;
|
|
}
|
|
|
|
// 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,
|
|
generateDefaultSpaceUtilityClasses,
|
|
generateSpaceUtilityClasses,
|
|
removeConsecutiveRepeatedWords,
|
|
generateBorderSizeUtilityClasses,
|
|
generateFontUtilityClasses,
|
|
generateShadowUtilityClasses,
|
|
generateUtilityClasses
|
|
};
|