Skip to content

Commit

Permalink
fix: add support for UIColor format in ts/color/modifiers
Browse files Browse the repository at this point in the history
  • Loading branch information
jorenbroekema committed Dec 7, 2023
1 parent e3d89fe commit 67b9171
Show file tree
Hide file tree
Showing 7 changed files with 166 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .changeset/green-forks-rhyme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@tokens-studio/sd-transforms': patch
---

Workaround fix in color modifiers transform to allow UIColor format. This workaround should be removed (in a breaking change) if https://github.com/amzn/style-dictionary/issues/1063 gets resolved and post-transitive transforms become a thing.
14 changes: 11 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
"@esm-bundle/chai": "^4.3.4-fix.0",
"@rollup/plugin-commonjs": "^24.1.0",
"@rollup/plugin-typescript": "^11.0.0",
"@types/tinycolor2": "^1.4.6",
"@typescript-eslint/eslint-plugin": "^5.54.0",
"@typescript-eslint/parser": "^5.54.0",
"@web/dev-server-esbuild": "^0.3.3",
Expand All @@ -70,6 +71,7 @@
"prettier-package-json": "^2.8.0",
"rimraf": "^4.1.3",
"rollup": "^3.18.0",
"tinycolor2": "^1.6.0",
"ts-mocha": "^10.0.0",
"ts-node": "^10.9.1",
"typescript": "^4.9.5"
Expand Down
25 changes: 25 additions & 0 deletions src/color-modifiers/modifyColor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,38 @@ import { darken } from './darken.js';
import { lighten } from './lighten.js';
import { ColorModifier } from '@tokens-studio/types';

// 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: string): string {
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: string | undefined,
modifier: ColorModifier,
): string | undefined {
if (baseColor === undefined) {
return baseColor;
}

baseColor = parseUIColor(baseColor);

const color = new Color(baseColor);
let returnedColor = color;
try {
Expand Down
70 changes: 70 additions & 0 deletions test/integration/swift-UI-color.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { expect } from '@esm-bundle/chai';
import StyleDictionary from 'style-dictionary';
import Color from 'tinycolor2';
import { promises } from 'fs';
import path from 'path';
import { cleanup, init } from './utils.js';

const outputDir = 'test/integration/tokens/';
const outputFileName = 'vars.css';
const outputFilePath = path.resolve(outputDir, outputFileName);

StyleDictionary.registerTransform({
name: 'transitive/color/UIColorSwift',
type: 'value',
transitive: true,
transformer: token => {
const { r, g, b, a } = Color(token.value).toRgb();
const rFixed = (r / 255.0).toFixed(3);
const gFixed = (g / 255.0).toFixed(3);
const bFixed = (b / 255.0).toFixed(3);
return `UIColor(red: ${rFixed}, green: ${gFixed}, blue: ${bFixed}, alpha: ${a})`;
},
});

const cfg = {
source: ['test/integration/tokens/swift-UI-colors.tokens.json'],
platforms: {
css: {
transforms: [
'ts/color/modifiers',
'attribute/cti',
'transitive/color/UIColorSwift',
'name/cti/camel',
],
buildPath: outputDir,
files: [
{
destination: outputFileName,
format: 'ios-swift/class.swift',
},
],
},
},
};

let dict: StyleDictionary.Core | undefined;

describe('outputReferences integration', () => {
beforeEach(() => {
if (dict) {
cleanup(dict);
}
dict = init(cfg, { 'ts/color/modifiers': { format: 'hex' } });
});

afterEach(() => {
if (dict) {
cleanup(dict);
}
});

it('supports UIColor with color modifiers', async () => {
const file = await promises.readFile(outputFilePath, 'utf-8');
console.log(file);
expect(file).to
.include(` public static let colorDanger = UIColor(red: 0.251, green: 0.000, blue: 0.000, alpha: 1)
public static let colorError = UIColor(red: 0.125, green: 0.000, blue: 0.000, alpha: 1)
public static let colorRed = UIColor(red: 1.000, green: 0.000, blue: 0.000, alpha: 1)`);
});
});
34 changes: 34 additions & 0 deletions test/integration/tokens/swift-UI-colors.tokens.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"color": {
"red": {
"value": "#f00",
"type": "color"
},
"danger": {
"value": "{color.red}",
"type": "color",
"$extensions": {
"studio.tokens": {
"modify": {
"type": "darken",
"value": "0.75",
"space": "hsl"
}
}
}
},
"error": {
"value": "{color.danger}",
"type": "color",
"$extensions": {
"studio.tokens": {
"modify": {
"type": "darken",
"value": "0.5",
"space": "hsl"
}
}
}
}
}
}
19 changes: 19 additions & 0 deletions test/spec/color-modifiers/transformColorModifiers.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -291,4 +291,23 @@ describe('transform color modifiers', () => {

expect(transformColorModifiers(token)).to.equal('#983735');
});

it('supports UIColor(r,g,b,a) format', () => {
const token = {
value: 'UIColor(red: 1, green: 0, blue: 0.5, alpha: 0.5)',
type: 'color',
$extensions: {
'studio.tokens': {
modify: {
type: 'darken',
value: '0.5',
space: 'srgb',
format: 'srgb',
},
},
},
};

expect(transformColorModifiers(token)).to.equal('rgb(50% 0% 25% / 0.5)');
});
});

0 comments on commit 67b9171

Please sign in to comment.