tag colors
This commit is contained in:
@@ -85,6 +85,71 @@ const rgbToHsl = ({ r, g, b }: RgbColor) => {
|
||||
return { h: hue, s: clamp01(saturation), l: clamp01(lightness) };
|
||||
};
|
||||
|
||||
const srgbChannelToLinear = (value: number) => {
|
||||
const normalized = value / 255;
|
||||
if (normalized <= 0.04045) {
|
||||
return normalized / 12.92;
|
||||
}
|
||||
return ((normalized + 0.055) / 1.055) ** 2.4;
|
||||
};
|
||||
|
||||
const hexToOklch = (input?: string) => {
|
||||
const rgb = hexToRgb(input);
|
||||
if (!rgb) {
|
||||
return null;
|
||||
}
|
||||
const r = srgbChannelToLinear(rgb.r);
|
||||
const g = srgbChannelToLinear(rgb.g);
|
||||
const b = srgbChannelToLinear(rgb.b);
|
||||
|
||||
const l = 0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b;
|
||||
const m = 0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b;
|
||||
const s = 0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b;
|
||||
|
||||
const lRoot = Math.cbrt(l);
|
||||
const mRoot = Math.cbrt(m);
|
||||
const sRoot = Math.cbrt(s);
|
||||
|
||||
const L = 0.2104542553 * lRoot + 0.793617785 * mRoot - 0.0040720468 * sRoot;
|
||||
const a = 1.9779984951 * lRoot - 2.428592205 * mRoot + 0.4505937099 * sRoot;
|
||||
const bLab = 0.0259040371 * lRoot + 0.7827717662 * mRoot - 0.808675766 * sRoot;
|
||||
|
||||
const chroma = Math.sqrt(a * a + bLab * bLab);
|
||||
let hue = Math.atan2(bLab, a) * (180 / Math.PI);
|
||||
if (hue < 0) {
|
||||
hue += 360;
|
||||
}
|
||||
|
||||
return {
|
||||
l: clamp01(L),
|
||||
c: chroma,
|
||||
h: hue,
|
||||
};
|
||||
};
|
||||
|
||||
const formatCssNumber = (value: number) => {
|
||||
if (!Number.isFinite(value)) {
|
||||
return `${value}`;
|
||||
}
|
||||
const rounded = Number(value.toFixed(6));
|
||||
return `${rounded}`;
|
||||
};
|
||||
|
||||
const buildTagStyle = (backgroundHex: string) => {
|
||||
const oklch = hexToOklch(backgroundHex);
|
||||
if (!oklch) {
|
||||
return {
|
||||
'--tag-chip-base': backgroundHex,
|
||||
};
|
||||
}
|
||||
return {
|
||||
'--tag-chip-base': backgroundHex,
|
||||
'--tag-chip-base-l': formatCssNumber(oklch.l),
|
||||
'--tag-chip-base-c': formatCssNumber(oklch.c),
|
||||
'--tag-chip-base-h': formatCssNumber(oklch.h),
|
||||
};
|
||||
};
|
||||
|
||||
export const hexToRgb = (input?: string): (RgbColor & { hex: string }) | null => {
|
||||
if (!input) return null;
|
||||
const match = HEX_COLOR_PATTERN.exec(input.trim());
|
||||
@@ -234,11 +299,7 @@ export const getTagColorStyle = (hex) => {
|
||||
let bestRatio = baseRatio;
|
||||
|
||||
if (bestRatio >= TARGET_RATIO) {
|
||||
return {
|
||||
backgroundColor: bestBackground,
|
||||
borderColor: bestBackground,
|
||||
color: bestText,
|
||||
};
|
||||
return buildTagStyle(bestBackground);
|
||||
}
|
||||
|
||||
let compliantBackground = null;
|
||||
@@ -277,18 +338,10 @@ export const getTagColorStyle = (hex) => {
|
||||
});
|
||||
|
||||
if (compliantBackground) {
|
||||
return {
|
||||
backgroundColor: compliantBackground,
|
||||
borderColor: compliantBackground,
|
||||
color: compliantText,
|
||||
};
|
||||
return buildTagStyle(compliantBackground);
|
||||
}
|
||||
|
||||
return {
|
||||
backgroundColor: bestBackground,
|
||||
borderColor: bestBackground,
|
||||
color: bestText,
|
||||
};
|
||||
return buildTagStyle(bestBackground);
|
||||
};
|
||||
|
||||
export const generateRandomTagColor = () => {
|
||||
|
||||
Reference in New Issue
Block a user