UNPKG

@tokens-studio/sd-transforms

Version:

Custom transforms for Style-Dictionary, to work with Design Tokens that are exported from Tokens Studio

72 lines (71 loc) 3.14 kB
import Color from 'colorjs.io'; import { transparentize } from './transparentize.js'; import { mix } from './mix.js'; import { darken } from './darken.js'; import { lighten } from './lighten.js'; import { defaultColorPrecision, defaultFractionDigits } from '../utils/constants.js'; import { parseAndReduce } from '../checkAndEvaluateMath.js'; // Users using UIColor swift format are blocked from using such transform in // combination with this color modify transform when using references. // This is because reference value props are deferred so the UIColor // transform always applies first to non-reference tokens, and only after that // can the color modifier transitive transform apply to deferred tokens, at which point // it is already UIColor format. // We can remove this hotfix later once https://github.com/amzn/style-dictionary/issues/1063 // is resolved. Then users can use a post-transitive transform for more fine grained control function parseUIColor(value) { const reg = new RegExp(`UIColor\\(red: (?<red>[\\d\\.]+?), green: (?<green>[\\d\\.]+?), blue: (?<blue>[\\d\\.]+?), alpha: (?<alpha>[\\d\\.]+?)\\)`); const match = value.match(reg); if (match?.groups) { const { red, green, blue, alpha } = match.groups; return `rgba(${parseFloat(red) * 255}, ${parseFloat(green) * 255}, ${parseFloat(blue) * 255}, ${alpha})`; } return value; } export function modifyColor(baseColor, modifier) { if (baseColor === undefined) { return baseColor; } baseColor = parseUIColor(baseColor); const color = new Color(baseColor); let returnedColor = color; const modifyValueResolvedCalc = Number(parseAndReduce(modifier.value, defaultFractionDigits)); try { switch (modifier.type) { case 'lighten': returnedColor = lighten(color, modifier.space, modifyValueResolvedCalc); break; case 'darken': returnedColor = darken(color, modifier.space, modifyValueResolvedCalc); break; case 'mix': returnedColor = mix(color, modifier.space, modifyValueResolvedCalc, new Color(modifier.color)); break; case 'alpha': { returnedColor = transparentize(color, modifyValueResolvedCalc); break; } default: returnedColor = color; break; } returnedColor = returnedColor.to(modifier.space); if (modifier.format && ['lch', 'srgb', 'p3', 'hsl', 'hex'].includes(modifier.format)) { // Since hex is not a color space, convert to srgb, toString will then be able to format to hex if (modifier.format === 'hex') { returnedColor = returnedColor.to('srgb'); } else { returnedColor = returnedColor.to(modifier.format); } } return returnedColor.toString({ inGamut: true, precision: defaultColorPrecision, format: modifier.format, }); } catch (e) { return baseColor; } }