feat(tokens): add rgba for color tokens with 8 chars (#29542)

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. -->


- Added new method to detect colors with eight characters
- Added logic to generate an rgba when the above is true. This is to
ensure better compatibility with older devices that don't support colors
with more than six characters.

## Does this introduce a breaking change?

- [ ] Yes
- [x] No

<!--
  If this introduces a breaking change:
1. Describe the impact and migration path for existing applications
below.
  2. Update the BREAKING.md file with the breaking change.
3. Add "BREAKING CHANGE: [...]" to the commit description when merging.
See
https://github.com/ionic-team/ionic-framework/blob/main/docs/CONTRIBUTING.md#footer
for more information.
-->
This commit is contained in:
Bernardo Cardoso
2024-05-23 15:19:02 +01:00
committed by GitHub
parent 1c035af1a2
commit b21f95cced
4 changed files with 94 additions and 29 deletions

View File

@@ -11,6 +11,7 @@ const targetPath = './src/foundations/';
const {
variablesPrefix,
getRgbaValue,
hexToRgb,
generateShadowValue,
generateFontFamilyValue,
@@ -41,8 +42,8 @@ StyleDictionary.registerFormat({
} else if (prop.attributes.category.match('font-family')) {
return generateFontFamilyValue(prop);
} else {
// TODO(ROU-4870): prevent colors with 8 characters to be created without a rgb transformation
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};` : ``
}`;

View File

@@ -1,6 +1,18 @@
const variablesPrefix = 'ionic'; // Variable that holds the prefix used on all css and scss variables generated
// Generates translate an hex color value to rgb
// 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
@@ -12,9 +24,24 @@ function hexToRgb(hex) {
: 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) {
return `${shadow.offsetX} ${shadow.offsetY} ${shadow.blur} ${shadow.spread} ${shadow.color}`;
const color = getRgbaValue(shadow.color);
return `${shadow.offsetX} ${shadow.offsetY} ${shadow.blur} ${shadow.spread} ${color}`;
}
// Generates a valid font-family value from a font-family Design Token structure
@@ -55,16 +82,19 @@ function getTypeMap(dictionary, type) {
);
}
// Generates a rgb color value, based on a color Design Token
function generateRgbValue(prop) {
// 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 the token is color, also add a rgb variable using the same color
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}`;
}
@@ -135,11 +165,13 @@ function generateSpaceUtilityClasses(prop, className) {
// Export all methods to be used on the tokens.js script
module.exports = {
variablesPrefix,
getRgbaValue,
hexToRgb,
hexToRgba,
generateShadowValue,
generateFontFamilyValue,
generateTypographyValue,
generateRgbValue,
generateRgbValue: generateValue,
generateColorUtilityClasses,
generateFontUtilityClass,
generateSpaceUtilityClasses,

View File

@@ -4,14 +4,14 @@
*/
:root {
--ionic-elevation-100: 0px 3px 9px 0px #00000012, 0px 0px 4px 0px #0000000a;
--ionic-elevation-200: 0px 8px 25px 0px #00000014, 0px 1px 5px 0px #0000000d;
--ionic-elevation-300: 0px 6px 32px 0px #00000029, 0px 2px 7px 0px #0000000d;
--ionic-elevation-400: 0px 15px 48px 0px #0000002e, 0px 3px 12px 0px #0000001f;
--ionic-elevation-500: 0px 3px 9px 0px #062b6312, 0px 0px 4px 0px #062b630a;
--ionic-elevation-600: 0px 8px 25px 0px #062b6314, 0px 1px 5px 0px #062b630d;
--ionic-elevation-700: 0px 15px 32px 0px #062b6317, 0px 2px 7px 0px #062b630d;
--ionic-elevation-800: 0px 20px 48px 0px #062b631f, 0px 3px 14px 0px #062b631f;
--ionic-elevation-100: 0px 3px 9px 0px rgba(0, 0, 0, 0.07), 0px 0px 4px 0px rgba(0, 0, 0, 0.04);
--ionic-elevation-200: 0px 8px 25px 0px rgba(0, 0, 0, 0.08), 0px 1px 5px 0px rgba(0, 0, 0, 0.05);
--ionic-elevation-300: 0px 6px 32px 0px rgba(0, 0, 0, 0.16), 0px 2px 7px 0px rgba(0, 0, 0, 0.05);
--ionic-elevation-400: 0px 15px 48px 0px rgba(0, 0, 0, 0.18), 0px 3px 12px 0px rgba(0, 0, 0, 0.12);
--ionic-elevation-500: 0px 3px 9px 0px rgba(6, 43, 99, 0.07), 0px 0px 4px 0px rgba(6, 43, 99, 0.04);
--ionic-elevation-600: 0px 8px 25px 0px rgba(6, 43, 99, 0.08), 0px 1px 5px 0px rgba(6, 43, 99, 0.05);
--ionic-elevation-700: 0px 15px 32px 0px rgba(6, 43, 99, 0.09), 0px 2px 7px 0px rgba(6, 43, 99, 0.05);
--ionic-elevation-800: 0px 20px 48px 0px rgba(6, 43, 99, 0.12), 0px 3px 14px 0px rgba(6, 43, 99, 0.12);
--ionic-font-size-275: 11px;
--ionic-font-size-300: 12px;
--ionic-font-size-350: 14px;
@@ -615,7 +615,7 @@
--ionic-state-focus-1-rgb: 158, 196, 253;
--ionic-state-focus-2: #ffafaf;
--ionic-state-focus-2-rgb: 255, 175, 175;
--ionic-state-disabled: #ffffff99;
--ionic-state-hover: #2424240a;
--ionic-state-pressed: #24242414;
--ionic-state-disabled: rgba(255, 255, 255, 0.6);
--ionic-state-hover: rgba(36, 36, 36, 0.04);
--ionic-state-pressed: rgba(36, 36, 36, 0.08);
}

View File

@@ -3,14 +3,46 @@
* Ionic Design System
*/
$ionic-elevation-100: var(--ionic-elevation-100, 0px 3px 9px 0px #00000012, 0px 0px 4px 0px #0000000a);
$ionic-elevation-200: var(--ionic-elevation-200, 0px 8px 25px 0px #00000014, 0px 1px 5px 0px #0000000d);
$ionic-elevation-300: var(--ionic-elevation-300, 0px 6px 32px 0px #00000029, 0px 2px 7px 0px #0000000d);
$ionic-elevation-400: var(--ionic-elevation-400, 0px 15px 48px 0px #0000002e, 0px 3px 12px 0px #0000001f);
$ionic-elevation-500: var(--ionic-elevation-500, 0px 3px 9px 0px #062b6312, 0px 0px 4px 0px #062b630a);
$ionic-elevation-600: var(--ionic-elevation-600, 0px 8px 25px 0px #062b6314, 0px 1px 5px 0px #062b630d);
$ionic-elevation-700: var(--ionic-elevation-700, 0px 15px 32px 0px #062b6317, 0px 2px 7px 0px #062b630d);
$ionic-elevation-800: var(--ionic-elevation-800, 0px 20px 48px 0px #062b631f, 0px 3px 14px 0px #062b631f);
$ionic-elevation-100: var(
--ionic-elevation-100,
0px 3px 9px 0px rgba(0, 0, 0, 0.07),
0px 0px 4px 0px rgba(0, 0, 0, 0.04)
);
$ionic-elevation-200: var(
--ionic-elevation-200,
0px 8px 25px 0px rgba(0, 0, 0, 0.08),
0px 1px 5px 0px rgba(0, 0, 0, 0.05)
);
$ionic-elevation-300: var(
--ionic-elevation-300,
0px 6px 32px 0px rgba(0, 0, 0, 0.16),
0px 2px 7px 0px rgba(0, 0, 0, 0.05)
);
$ionic-elevation-400: var(
--ionic-elevation-400,
0px 15px 48px 0px rgba(0, 0, 0, 0.18),
0px 3px 12px 0px rgba(0, 0, 0, 0.12)
);
$ionic-elevation-500: var(
--ionic-elevation-500,
0px 3px 9px 0px rgba(6, 43, 99, 0.07),
0px 0px 4px 0px rgba(6, 43, 99, 0.04)
);
$ionic-elevation-600: var(
--ionic-elevation-600,
0px 8px 25px 0px rgba(6, 43, 99, 0.08),
0px 1px 5px 0px rgba(6, 43, 99, 0.05)
);
$ionic-elevation-700: var(
--ionic-elevation-700,
0px 15px 32px 0px rgba(6, 43, 99, 0.09),
0px 2px 7px 0px rgba(6, 43, 99, 0.05)
);
$ionic-elevation-800: var(
--ionic-elevation-800,
0px 20px 48px 0px rgba(6, 43, 99, 0.12),
0px 3px 14px 0px rgba(6, 43, 99, 0.12)
);
$ionic-font-size-275: var(--ionic-font-size-275, 11px);
$ionic-font-size-300: var(--ionic-font-size-300, 12px);
$ionic-font-size-350: var(--ionic-font-size-350, 14px);
@@ -614,9 +646,9 @@ $ionic-state-focus-1: var(--ionic-state-focus-1, #9ec4fd);
$ionic-state-focus-1-rgb: var(--ionic-state-focus-1-rgb, 158, 196, 253);
$ionic-state-focus-2: var(--ionic-state-focus-2, #ffafaf);
$ionic-state-focus-2-rgb: var(--ionic-state-focus-2-rgb, 255, 175, 175);
$ionic-state-disabled: var(--ionic-state-disabled, #ffffff99);
$ionic-state-hover: var(--ionic-state-hover, #2424240a);
$ionic-state-pressed: var(--ionic-state-pressed, #24242414);
$ionic-state-disabled: var(--ionic-state-disabled, rgba(255, 255, 255, 0.6));
$ionic-state-hover: var(--ionic-state-hover, rgba(36, 36, 36, 0.04));
$ionic-state-pressed: var(--ionic-state-pressed, rgba(36, 36, 36, 0.08));
$ionic-display-sm-regular: (
font-family: $ionic-font-family,