fix: Use culori for oklch native support

fixes #1
This commit is contained in:
Sahaj Jain
2025-03-18 03:32:41 +05:30
parent a0ba992970
commit b164c86db5
5 changed files with 123 additions and 2145 deletions
+97 -2113
View File
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -43,7 +43,7 @@
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"cmdk": "^1.0.0",
"color": "^5.0.0",
"culori": "^4.0.1",
"date-fns": "^3.6.0",
"embla-carousel-react": "^8.3.0",
"input-otp": "^1.2.4",
@@ -68,6 +68,7 @@
"@eslint/js": "^9.9.0",
"@tailwindcss/container-queries": "^0.1.1",
"@tailwindcss/typography": "^0.5.15",
"@types/culori": "^2.1.1",
"@types/node": "^22.5.5",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
-1
View File
@@ -67,7 +67,6 @@ const CodePanel: React.FC<CodePanelProps> = ({ config, styles }) => {
<SelectItem value="oklch">OKLCH</SelectItem>
<SelectItem value="rgb">RGB</SelectItem>
<SelectItem value="hex">HEX</SelectItem>
<SelectItem value="cmyk">CMYK</SelectItem>
</SelectContent>
</Select>
)}
+1 -1
View File
@@ -119,4 +119,4 @@ export type ReadOnlyColorDisplayProps = {
linkTo: string;
};
export type ColorFormat = "hex" | "rgb" | "hsl" | "oklch" | "cmyk";
export type ColorFormat = "hex" | "rgb" | "hsl" | "oklch";
+23 -29
View File
@@ -1,43 +1,37 @@
import Color from "color"; // You'll need to install this package: npm install color
import * as culori from "culori";
import { ColorFormat } from "../types";
const formatNumber = (num) => (num % 1 === 0 ? num : num.toFixed(2));
export const colorFormatter = (
colorValue: string,
format: ColorFormat = "hsl",
): string => {
try {
// Use the color library to parse any color format
const color = Color(colorValue);
const color = culori.parse(colorValue);
if (!color) throw new Error("Invalid color input");
if (format === "hsl") {
const hsl = color.hsl().round().array();
return `${hsl[0]} ${hsl[1]}% ${hsl[2]}%`;
}
if (format === "rgb") {
const rgb = color.rgb().round().array();
return `rgb(${rgb[0]} ${rgb[1]} ${rgb[2]})`;
}
if (format === "cmyk") {
const cmyk = color.cmyk().round().array();
return `cmyk(${cmyk[0]} ${cmyk[1]} ${cmyk[2]} ${cmyk[3]})`;
}
if (format === "oklch") {
const oklch = color.lch().round().array();
return `oklch(${oklch[0]} ${oklch[1]} ${oklch[2]})`;
}
if (format === "hex") {
return color.hex();
switch (format) {
case "hsl": {
const hsl = culori.converter("hsl")(color);
return `${hsl.h} ${formatNumber(hsl.s * 100)}% ${formatNumber(hsl.l * 100)}%`;
}
case "rgb":
return culori.formatRgb(color); // e.g., "rgb(64, 128, 192)"
case "oklch": {
const oklch = culori.converter("oklch")(color);
return `oklch(${formatNumber(oklch.l)} ${formatNumber(oklch.c)} ${formatNumber(oklch.h ?? 0)})`;
}
case "hex":
return culori.formatHex(color); // e.g., "#4080c0"
default:
return colorValue;
}
} catch (error) {
console.error(`Failed to convert color: ${colorValue}`, error);
return colorValue; // Return original if conversion fails
return colorValue;
}
};
export const convertToHSL = (colorValue: string): string => {
return colorFormatter(colorValue, "hsl");
};
export const convertToHSL = (colorValue: string): string =>
colorFormatter(colorValue, "hsl");