Skip to content

Commit f55bf8f

Browse files
committed
Convert OKLCH to HEX for React Native
1 parent 79c9244 commit f55bf8f

4 files changed

Lines changed: 341 additions & 290 deletions

File tree

formats/reactColorFormat.js

Lines changed: 63 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,81 @@
22

33
const _ = require('lodash');
44
const { fileHeader } = require('style-dictionary/lib/common/formatHelpers');
5-
const Color = require('tinycolor2')
5+
const Color = require('colorjs.io').default;
66

7-
const hexRegex = /#[0-9A-Fa-f]{6}\b/;
8-
const rgx = /rgb\((\d{1,3}), (\d{1,3}), (\d{1,3})\)/;
7+
/**
8+
* Convert OKLCH color values to hex/rgba for React Native compatibility.
9+
*/
10+
const oklchToHex = (oklchString) => {
11+
try {
12+
const color = new Color(oklchString);
13+
return color.to('srgb').toString({ format: 'hex' });
14+
} catch (e) {
15+
return oklchString; // Return original if conversion fails
16+
}
17+
};
18+
19+
const colorToRgba = (colorString, alpha) => {
20+
try {
21+
const color = new Color(colorString);
22+
const rgb = color.to('srgb');
23+
const r = Math.round(Math.max(0, Math.min(255, rgb.r * 255)));
24+
const g = Math.round(Math.max(0, Math.min(255, rgb.g * 255)));
25+
const b = Math.round(Math.max(0, Math.min(255, rgb.b * 255)));
26+
return `rgba(${r}, ${g}, ${b}, ${alpha})`;
27+
} catch (e) {
28+
return colorString;
29+
}
30+
};
31+
32+
/**
33+
* Convert any OKLCH value (including relative color syntax) to React Native compatible format
34+
*/
35+
const convertToReactNative = (value) => {
36+
if (typeof value !== 'string') return value;
37+
38+
// Handle linear-gradient - convert oklch colors inside but keep as CSS string
39+
if (value.includes('linear-gradient')) {
40+
let converted = value;
41+
// Convert oklch(from ... l c h / alpha) to rgba
42+
converted = converted.replace(/oklch\(from\s+(.+?)\s+l\s+c\s+h\s*\/\s*([\d.]+)\)/g, (match, baseColor, alpha) => {
43+
return colorToRgba(baseColor, parseFloat(alpha));
44+
});
45+
// Convert simple oklch() to hex
46+
converted = converted.replace(/oklch\([^)]+\)/g, (match) => oklchToHex(match));
47+
return converted;
48+
}
949

10-
const reactColorFormat= function ({
50+
// Handle relative color syntax: oklch(from <color> l c h / <alpha>)
51+
const relativeMatch = value.match(/oklch\(from\s+(.+?)\s+l\s+c\s+h\s*\/\s*([\d.]+)\)/);
52+
if (relativeMatch) {
53+
const baseColor = relativeMatch[1];
54+
const alpha = parseFloat(relativeMatch[2]);
55+
return colorToRgba(baseColor, alpha);
56+
}
57+
58+
// Handle simple oklch values
59+
if (value.startsWith('oklch(')) {
60+
return oklchToHex(value);
61+
}
62+
63+
return value;
64+
};
65+
66+
const reactColorFormat = function ({
1167
dictionary: { allTokens },
1268
options: { theme },
1369
file,
1470
}) {
1571
const colors = {};
16-
17-
const toReactColor = (value) => {
18-
while (value.match(/rgba\(\#/)) {
19-
let c = Color(value.match(hexRegex)[0]).toRgbString();
20-
value = value.replace(hexRegex, c).replace(rgx, '$1,$2,$3');
21-
}
22-
return value;
23-
};
24-
72+
2573
allTokens.forEach((token) => {
2674
const { path, value } = token;
2775

2876
_.setWith(
2977
colors,
30-
path.slice(1).map(a => _.camelCase(a)).join('.'),
31-
toReactColor(value),
78+
path.slice(1).map((a) => _.camelCase(a)).join('.'),
79+
convertToReactNative(value),
3280
Object
3381
);
3482
});

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
"build": "yarn build-transform && yarn build-styledictionary"
1515
},
1616
"devDependencies": {
17+
"colorjs.io": "^0.5.2",
1718
"lodash": "^4.17.21",
1819
"style-dictionary": "^3.7.0",
1920
"typescript": "^4.6.3"

style-dictionary.build.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,6 @@ const themeConfig = (theme) => {
150150
transforms: [
151151
'attribute/cti',
152152
'name/cti/kebab',
153-
'color/rgb',
154-
'css/duplicate-rgb',
155153
],
156154
buildPath: `src/output/`,
157155
files: [
@@ -176,7 +174,6 @@ const colorsSpectrumCssVarsConfig = {
176174
transforms: [
177175
'attribute/cti',
178176
'name/cti/kebab',
179-
'color/hex',
180177
],
181178
buildPath: `src/output/`,
182179
files: [

0 commit comments

Comments
 (0)