diff --git a/packages/plugin-figma-token-publisher/src/plugin/makeColorTokens.ts b/packages/plugin-figma-token-publisher/src/plugin/makeColorTokens.ts index 97959670c6b..6c2726656f5 100644 --- a/packages/plugin-figma-token-publisher/src/plugin/makeColorTokens.ts +++ b/packages/plugin-figma-token-publisher/src/plugin/makeColorTokens.ts @@ -7,7 +7,6 @@ import showNotification from './showNotification'; const THEME_TOKENS_COLLECTION = 'Blade Theme Tokens'; const GLOBAL_TOKENS_COLLECTION = '_global-tokens'; -// const COLOR_MODE_VALUE_ID = '68259:0'; const makeGlobalColorTokenName = (variableName: string): string => { return variableName.split('/').slice(1).join('.'); @@ -21,6 +20,60 @@ const makeThemeTokenName = (variableName: string): string => { .replace(/\.[0-9]+/, (matchedString: any) => `[${matchedString.replace('.', '')}]`); }; +const rgbaToHsla = ({ r, g, b, a }: RGBA): string => { + const opacity = { + '0.00': '${opacity[0]}', + '0.09': '${opacity[1]}', + '0.10': '${opacity[1]}', + '0.12': '${opacity[2]}', + '0.18': '${opacity[3]}', + '0.32': '${opacity[4]}', + '0.48': '${opacity[5]}', + '0.56': '${opacity[6]}', + '0.64': '${opacity[7]}', + '0.72': '${opacity[8]}', + '1.00': '${opacity[9]}', + }; + + // Find greatest and smallest channel values + const cmin = Math.min(r, g, b); + const cmax = Math.max(r, g, b); + const delta = cmax - cmin; + let h = 0; + let s = 0; + let l = 0; + + if (delta == 0) { + h = 0; + } else if (cmax == r) { + // Red is max + h = ((g - b) / delta) % 6; + } else if (cmax == g) { + // Green is max + h = (b - r) / delta + 2; + } else { + // Blue is max + h = (r - g) / delta + 4; + } + + h = Math.round(h * 60); + + // Make negative hues positive behind 360° + if (h < 0) { + h += 360; + } + + l = (cmax + cmin) / 2; + + // Calculate saturation + s = delta == 0 ? 0 : delta / (1 - Math.abs(2 * l - 1)); + + // Multiply l and s by 100 + s = +(s * 100).toFixed(1); + l = +(l * 100).toFixed(1); + + return `hsla(${h}, ${Math.round(s)}%, ${Math.round(l)}%, ${opacity[a.toFixed(2)]})`; +}; const makeThemeColorTokens = (): Record => { const themeColorTokens = { onLight: {}, @@ -44,7 +97,7 @@ const makeThemeColorTokens = (): Record => { // replace the "/" from token name with "." to store in json structure const tokenName = makeThemeTokenName(variable.name); - if (tokenName.includes('❌')) { + if (tokenName.includes('❌') || tokenName.includes('_')) { return; } @@ -59,6 +112,12 @@ const makeThemeColorTokens = (): Record => { tokenName, makeThemeTokenName(figma.variables.getVariableById(variableModeValue.id).name), ); + } else if ( + typeof variableModeValue === 'object' && + (tokenName.includes('transparent') || tokenName.includes('elevation')) + ) { + const tokenHSLAValue = rgbaToHsla(variableModeValue as RGBA); + setValue(themeColorTokens[modeName], tokenName, `\`${tokenHSLAValue}\``); } else { console.error( 'the theme variable token has hardcoded value', @@ -80,60 +139,6 @@ const makeThemeColorTokens = (): Record => { return themeColorTokens; }; -const rgbaToHsla = ({ r, g, b, a }: RGBA): string => { - const opacity = { - '0.00': '${opacity[0]}', - '0.09': '${opacity[1]}', - '0.12': '${opacity[2]}', - '0.18': '${opacity[3]}', - '0.32': '${opacity[4]}', - '0.48': '${opacity[5]}', - '0.56': '${opacity[6]}', - '0.64': '${opacity[7]}', - '0.72': '${opacity[8]}', - '1.00': '${opacity[9]}', - }; - - // Find greatest and smallest channel values - const cmin = Math.min(r, g, b); - const cmax = Math.max(r, g, b); - const delta = cmax - cmin; - let h = 0; - let s = 0; - let l = 0; - - if (delta == 0) { - h = 0; - } else if (cmax == r) { - // Red is max - h = ((g - b) / delta) % 6; - } else if (cmax == g) { - // Green is max - h = (b - r) / delta + 2; - } else { - // Blue is max - h = (r - g) / delta + 4; - } - - h = Math.round(h * 60); - - // Make negative hues positive behind 360° - if (h < 0) { - h += 360; - } - - l = (cmax + cmin) / 2; - - // Calculate saturation - s = delta == 0 ? 0 : delta / (1 - Math.abs(2 * l - 1)); - - // Multiply l and s by 100 - s = +(s * 100).toFixed(1); - l = +(l * 100).toFixed(1); - - return `hsla(${h}, ${Math.round(s)}%, ${Math.round(l)}%, ${opacity[a.toFixed(2)]})`; -}; - const makeGlobalColorTokens = (): Record => { const globalColorTokens = {}; try {