41 lines
1.0 KiB
JavaScript
41 lines
1.0 KiB
JavaScript
const HEX_COLOR_PATTERN = /^#?([0-9a-fA-F]{6})$/;
|
|
|
|
export const hexToRgb = (input) => {
|
|
if (!input) return null;
|
|
const match = HEX_COLOR_PATTERN.exec(input.trim());
|
|
if (!match) return null;
|
|
const value = parseInt(match[1], 16);
|
|
return {
|
|
r: (value >> 16) & 0xff,
|
|
g: (value >> 8) & 0xff,
|
|
b: value & 0xff,
|
|
hex: `#${match[1].toLowerCase()}`,
|
|
};
|
|
};
|
|
|
|
const relativeLuminance = ({ r, g, b }) => {
|
|
const transform = (channel) => {
|
|
const normalized = channel / 255;
|
|
return normalized <= 0.03928
|
|
? normalized / 12.92
|
|
: ((normalized + 0.055) / 1.055) ** 2.4;
|
|
};
|
|
|
|
const [red, green, blue] = [transform(r), transform(g), transform(b)];
|
|
return 0.2126 * red + 0.7152 * green + 0.0722 * blue;
|
|
};
|
|
|
|
export const getTagColorStyle = (hex) => {
|
|
const rgb = hexToRgb(hex);
|
|
if (!rgb) return null;
|
|
const luminance = relativeLuminance(rgb);
|
|
const textColor = luminance > 0.6 ? '#1f1f1f' : '#ffffff';
|
|
return {
|
|
backgroundColor: rgb.hex,
|
|
borderColor: rgb.hex,
|
|
color: textColor,
|
|
};
|
|
};
|
|
|
|
export { HEX_COLOR_PATTERN };
|