colvert
Version:
A comprehensive color conversion and manipulation package for JavaScript/TypeScript
856 lines (855 loc) • 26.8 kB
JavaScript
const isColorValid = (value, type) => {
switch (type) {
case "rgb": {
if (!Array.isArray(value) || value.length !== 3) return false;
return value.every((val) => typeof val === "number" && val >= 0 && val <= 255);
}
case "rgba": {
if (!Array.isArray(value) || value.length !== 4) return false;
return value.slice(0, 3).every((val) => typeof val === "number" && val >= 0 && val <= 255) && typeof value[3] === "number" && value[3] >= 0 && value[3] <= 1;
}
case "hsl": {
if (!Array.isArray(value) || value.length !== 3) return false;
return typeof value[0] === "number" && value[0] >= 0 && value[0] <= 360 && typeof value[1] === "number" && value[1] >= 0 && value[1] <= 100 && typeof value[2] === "number" && value[2] >= 0 && value[2] <= 100;
}
case "hsv": {
if (!Array.isArray(value) || value.length !== 3) return false;
return typeof value[0] === "number" && value[0] >= 0 && value[0] <= 360 && typeof value[1] === "number" && value[1] >= 0 && value[1] <= 100 && typeof value[2] === "number" && value[2] >= 0 && value[2] <= 100;
}
case "cmyk": {
if (!Array.isArray(value) || value.length !== 4) return false;
return value.every((val) => typeof val === "number" && val >= 0 && val <= 100);
}
case "hex": {
if (typeof value !== "string") return false;
return /^#([0-9A-F]{3}|[0-9A-F]{4}|[0-9A-F]{6}|[0-9A-F]{8})$/i.test(value);
}
default: {
return false;
}
}
};
let ColorConversionError$1 = class ColorConversionError extends Error {
constructor(message) {
super(message);
this.name = "ColorConversionError";
}
};
const validateOrThrow = (value, type, errorMsg) => {
if (!isColorValid(value, type)) {
throw new ColorConversionError$1(errorMsg);
}
return value;
};
const clamp = (num, min, max) => {
return Math.min(Math.max(num, min), max);
};
const getRandomValue = (option, min, max) => {
if (option === void 0) {
return Math.floor(Math.random() * (max - min + 1)) + min;
} else if (Array.isArray(option)) {
const rangeMin = clamp(option[0], min, max);
const rangeMax = clamp(option[1], min, max);
return Math.floor(Math.random() * (rangeMax - rangeMin + 1)) + rangeMin;
} else {
return clamp(option, min, max);
}
};
const rgbToHexConversion = (num) => {
let hexv = Math.round(clamp(num, 0, 255)).toString(16);
if (hexv.length < 2) {
hexv = "0" + hexv;
}
return hexv;
};
const rgbTohex = (rgb) => {
try {
const validRgb = validateOrThrow(
rgb,
"rgb",
"Invalid RGB value. Expected an array of 3 numbers between 0-255."
);
const r = rgbToHexConversion(validRgb[0]);
const g = rgbToHexConversion(validRgb[1]);
const b = rgbToHexConversion(validRgb[2]);
return `#${r}${g}${b}`;
} catch (e) {
if (e instanceof ColorConversionError$1) throw e;
throw new ColorConversionError$1(`Failed to convert RGB to Hex: ${e.message}`);
}
};
const rgbTohsl = (rgb) => {
try {
const validRgb = validateOrThrow(
rgb,
"rgb",
"Invalid RGB value. Expected an array of 3 numbers between 0-255."
);
const r = validRgb[0] / 255;
const g = validRgb[1] / 255;
const b = validRgb[2] / 255;
const min = Math.min(r, g, b);
const max = Math.max(r, g, b);
const delta = max - min;
let h = 0;
let s = 0;
let l = (min + max) / 2;
if (max !== min) {
s = l <= 0.5 ? delta / (max + min) : delta / (2 - max - min);
if (r === max) {
h = (g - b) / delta + (g < b ? 6 : 0);
} else if (g === max) {
h = (b - r) / delta + 2;
} else if (b === max) {
h = (r - g) / delta + 4;
}
h *= 60;
}
return [Math.round(h), Math.round(s * 100), Math.round(l * 100)];
} catch (e) {
if (e instanceof ColorConversionError$1) throw e;
throw new ColorConversionError$1(`Failed to convert RGB to HSL: ${e.message}`);
}
};
const rgbTohsv = (rgb) => {
try {
const validRgb = validateOrThrow(
rgb,
"rgb",
"Invalid RGB value. Expected an array of 3 numbers between 0-255."
);
const r = validRgb[0] / 255;
const g = validRgb[1] / 255;
const b = validRgb[2] / 255;
const max = Math.max(r, g, b);
const min = Math.min(r, g, b);
const delta = max - min;
let h = 0;
let s = max === 0 ? 0 : delta / max;
let v = max;
if (delta !== 0) {
if (max === r) {
h = (g - b) / delta % 6;
} else if (max === g) {
h = (b - r) / delta + 2;
} else {
h = (r - g) / delta + 4;
}
h *= 60;
if (h < 0) h += 360;
}
return [Math.round(h), Math.round(s * 100), Math.round(v * 100)];
} catch (e) {
if (e instanceof ColorConversionError$1) throw e;
throw new ColorConversionError$1(`Failed to convert RGB to HSV: ${e.message}`);
}
};
const rgbTocmyk = (rgb) => {
try {
const validRgb = validateOrThrow(
rgb,
"rgb",
"Invalid RGB value. Expected an array of 3 numbers between 0-255."
);
const r = validRgb[0] / 255;
const g = validRgb[1] / 255;
const b = validRgb[2] / 255;
if (r === 0 && g === 0 && b === 0) {
return [0, 0, 0, 100];
}
const k = 1 - Math.max(r, g, b);
const c = (1 - r - k) / (1 - k);
const m = (1 - g - k) / (1 - k);
const y = (1 - b - k) / (1 - k);
return [
Math.round(c * 100),
Math.round(m * 100),
Math.round(y * 100),
Math.round(k * 100)
];
} catch (e) {
if (e instanceof ColorConversionError$1) throw e;
throw new ColorConversionError$1(`Failed to convert RGB to CMYK: ${e.message}`);
}
};
const rgbaToHex = (rgba) => {
try {
const validRgba = validateOrThrow(
rgba,
"rgba",
"Invalid RGBA value. Expected an array of 4 numbers, RGB between 0-255 and alpha between 0-1."
);
const r = rgbToHexConversion(validRgba[0]);
const g = rgbToHexConversion(validRgba[1]);
const b = rgbToHexConversion(validRgba[2]);
const a = rgbToHexConversion(Math.round(validRgba[3] * 255));
return `#${r}${g}${b}${a}`;
} catch (e) {
if (e instanceof ColorConversionError$1) throw e;
throw new ColorConversionError$1(`Failed to convert RGBA to Hex: ${e.message}`);
}
};
const rgbToLab = (rgb) => {
try {
const validRgb = validateOrThrow(
rgb,
"rgb",
"Invalid RGB value. Expected an array of 3 numbers between 0-255."
);
const xyz = rgbToXyz(validRgb);
const xRef = 95.047;
const yRef = 100;
const zRef = 108.883;
let x = xyz[0] / xRef;
let y = xyz[1] / yRef;
let z = xyz[2] / zRef;
x = x > 8856e-6 ? Math.pow(x, 1 / 3) : 7.787 * x + 16 / 116;
y = y > 8856e-6 ? Math.pow(y, 1 / 3) : 7.787 * y + 16 / 116;
z = z > 8856e-6 ? Math.pow(z, 1 / 3) : 7.787 * z + 16 / 116;
const l = 116 * y - 16;
const a = 500 * (x - y);
const b = 200 * (y - z);
return [Math.round(l), Math.round(a), Math.round(b)];
} catch (e) {
if (e instanceof ColorConversionError$1) throw e;
throw new ColorConversionError$1(`Failed to convert RGB to LAB: ${e.message}`);
}
};
const rgbToXyz = (rgb) => {
try {
const validRgb = validateOrThrow(
rgb,
"rgb",
"Invalid RGB value. Expected an array of 3 numbers between 0-255."
);
let r = validRgb[0] / 255;
let g = validRgb[1] / 255;
let b = validRgb[2] / 255;
r = r > 0.04045 ? Math.pow((r + 0.055) / 1.055, 2.4) : r / 12.92;
g = g > 0.04045 ? Math.pow((g + 0.055) / 1.055, 2.4) : g / 12.92;
b = b > 0.04045 ? Math.pow((b + 0.055) / 1.055, 2.4) : b / 12.92;
r *= 100;
g *= 100;
b *= 100;
const x = r * 0.4124 + g * 0.3576 + b * 0.1805;
const y = r * 0.2126 + g * 0.7152 + b * 0.0722;
const z = r * 0.0193 + g * 0.1192 + b * 0.9505;
return [x, y, z];
} catch (e) {
if (e instanceof ColorConversionError$1) throw e;
throw new ColorConversionError$1(`Failed to convert RGB to XYZ: ${e.message}`);
}
};
const rgbToLch = (rgb) => {
try {
const validRgb = validateOrThrow(
rgb,
"rgb",
"Invalid RGB value. Expected an array of 3 numbers between 0-255."
);
const lab = rgbToLab(validRgb);
const l = lab[0];
const c = Math.sqrt(Math.pow(lab[1], 2) + Math.pow(lab[2], 2));
let h = Math.atan2(lab[2], lab[1]) * (180 / Math.PI);
if (h < 0) {
h += 360;
}
return [l, Math.round(c), Math.round(h)];
} catch (e) {
if (e instanceof ColorConversionError$1) throw e;
throw new ColorConversionError$1(`Failed to convert RGB to LCH: ${e.message}`);
}
};
const hexTorgb = (hex) => {
try {
const validHex = validateOrThrow(
hex,
"hex",
"Invalid HEX value. Expected a string in format #RGB, #RGBA, #RRGGBB, or #RRGGBBAA."
);
let cleanHex = validHex.replace(/^#/, "");
if (cleanHex.length === 3) {
cleanHex = cleanHex.split("").map((char) => char + char).join("");
}
if (cleanHex.length === 8) {
cleanHex = cleanHex.substring(0, 6);
} else if (cleanHex.length === 4) {
cleanHex = cleanHex.substring(0, 3);
cleanHex = cleanHex.split("").map((char) => char + char).join("");
}
const bigint = parseInt(cleanHex, 16);
const r = bigint >> 16 & 255;
const g = bigint >> 8 & 255;
const b = bigint & 255;
return [r, g, b];
} catch (e) {
if (e instanceof ColorConversionError$1) throw e;
throw new ColorConversionError$1(`Failed to convert HEX to RGB: ${e.message}`);
}
};
const hexTohsl = (hex) => {
try {
const validHex = validateOrThrow(
hex,
"hex",
"Invalid HEX value. Expected a string in format #RGB, #RGBA, #RRGGBB, or #RRGGBBAA."
);
const rgb = hexTorgb(validHex);
return rgbTohsl(rgb);
} catch (e) {
if (e instanceof ColorConversionError$1) throw e;
throw new ColorConversionError$1(`Failed to convert HEX to HSL: ${e.message}`);
}
};
const hexTohsv = (hex) => {
try {
const validHex = validateOrThrow(
hex,
"hex",
"Invalid HEX value. Expected a string in format #RGB, #RGBA, #RRGGBB, or #RRGGBBAA."
);
const rgb = hexTorgb(validHex);
return rgbTohsv(rgb);
} catch (e) {
if (e instanceof ColorConversionError$1) throw e;
throw new ColorConversionError$1(`Failed to convert HEX to HSV: ${e.message}`);
}
};
const hexTocmyk = (hex) => {
try {
const validHex = validateOrThrow(
hex,
"hex",
"Invalid HEX value. Expected a string in format #RGB, #RGBA, #RRGGBB, or #RRGGBBAA."
);
const rgb = hexTorgb(validHex);
return rgbTocmyk(rgb);
} catch (e) {
if (e instanceof ColorConversionError$1) throw e;
throw new ColorConversionError$1(`Failed to convert HEX to CMYK: ${e.message}`);
}
};
const hexToRgba = (hex) => {
try {
const validHex = validateOrThrow(
hex,
"hex",
"Invalid HEX value. Expected a string in format #RGB, #RGBA, #RRGGBB, or #RRGGBBAA."
);
let cleanHex = validHex.replace(/^#/, "");
if (cleanHex.length === 3) {
cleanHex = cleanHex.split("").map((char) => char + char).join("");
cleanHex += "FF";
} else if (cleanHex.length === 4) {
cleanHex = cleanHex.split("").map((char) => char + char).join("");
} else if (cleanHex.length === 6) {
cleanHex += "FF";
}
const bigint = parseInt(cleanHex, 16);
const r = bigint >> 24 & 255;
const g = bigint >> 16 & 255;
const b = bigint >> 8 & 255;
const a = (bigint & 255) / 255;
return [r, g, b, parseFloat(a.toFixed(2))];
} catch (e) {
if (e instanceof ColorConversionError$1) throw e;
throw new ColorConversionError$1(`Failed to convert HEX to RGBA: ${e.message}`);
}
};
const hslTorgb = (hsl) => {
try {
const validHsl = validateOrThrow(
hsl,
"hsl",
"Invalid HSL value. Expected an array with h(0-360), s(0-100), l(0-100)."
);
const h = validHsl[0] / 360;
const s = validHsl[1] / 100;
const l = validHsl[2] / 100;
let r, g, b;
if (s === 0) {
r = g = b = l;
} else {
const hue2rgb = (p2, q2, t) => {
if (t < 0) t += 1;
if (t > 1) t -= 1;
if (t < 1 / 6) return p2 + (q2 - p2) * 6 * t;
if (t < 1 / 2) return q2;
if (t < 2 / 3) return p2 + (q2 - p2) * (2 / 3 - t) * 6;
return p2;
};
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
const p = 2 * l - q;
r = hue2rgb(p, q, h + 1 / 3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1 / 3);
}
return [
Math.round(r * 255),
Math.round(g * 255),
Math.round(b * 255)
];
} catch (e) {
if (e instanceof ColorConversionError$1) throw e;
throw new ColorConversionError$1(`Failed to convert HSL to RGB: ${e.message}`);
}
};
const hslTohex = (hsl) => {
try {
const validHsl = validateOrThrow(
hsl,
"hsl",
"Invalid HSL value. Expected an array with h(0-360), s(0-100), l(0-100)."
);
const rgb = hslTorgb(validHsl);
return rgbTohex(rgb);
} catch (e) {
if (e instanceof ColorConversionError$1) throw e;
throw new ColorConversionError$1(`Failed to convert HSL to HEX: ${e.message}`);
}
};
const hslTohsv = (hsl) => {
try {
const validHsl = validateOrThrow(
hsl,
"hsl",
"Invalid HSL value. Expected an array with h(0-360), s(0-100), l(0-100)."
);
const h = validHsl[0];
const s = validHsl[1] / 100;
const l = validHsl[2] / 100;
let v = l + s * Math.min(l, 1 - l);
let sv = v === 0 ? 0 : 2 * (1 - l / v);
return [h, Math.round(sv * 100), Math.round(v * 100)];
} catch (e) {
if (e instanceof ColorConversionError$1) throw e;
throw new ColorConversionError$1(`Failed to convert HSL to HSV: ${e.message}`);
}
};
const cmykTorgb = (cmyk) => {
try {
const validCmyk = validateOrThrow(
cmyk,
"cymk",
"Invalid CMYK value. Expected an array with c,m,y,k values between 0-100."
);
const c = validCmyk[0] / 100;
const m = validCmyk[1] / 100;
const y = validCmyk[2] / 100;
const k = validCmyk[3] / 100;
const r = Math.round(255 * (1 - c) * (1 - k));
const g = Math.round(255 * (1 - m) * (1 - k));
const b = Math.round(255 * (1 - y) * (1 - k));
return [r, g, b];
} catch (e) {
if (e instanceof ColorConversionError$1) throw e;
throw new ColorConversionError$1(`Failed to convert CMYK to RGB: ${e.message}`);
}
};
const cmykTohex = (cmyk) => {
try {
const validCmyk = validateOrThrow(
cmyk,
"cymk",
"Invalid CMYK value. Expected an array with c,m,y,k values between 0-100."
);
const rgb = cmykTorgb(validCmyk);
return rgbTohex(rgb);
} catch (e) {
if (e instanceof ColorConversionError$1) throw e;
throw new ColorConversionError$1(`Failed to convert CMYK to HEX: ${e.message}`);
}
};
const cmykTohsl = (cmyk) => {
try {
const validCmyk = validateOrThrow(
cmyk,
"hsl",
"Invalid CMYK value. Expected an array with c,m,y,k values between 0-100."
);
const rgb = cmykTorgb(validCmyk);
return rgbTohsl(rgb);
} catch (e) {
if (e instanceof ColorConversionError$1) throw e;
throw new ColorConversionError$1(`Failed to convert CMYK to HSL: ${e.message}`);
}
};
const colorConversion = /* @__PURE__ */ Object.freeze({
__proto__: null,
cmykToHex: cmykTohex,
cmykToHsl: cmykTohsl,
cmykToRgb: cmykTorgb,
cmykTohex,
cmykTohsl,
cmykTorgb,
hexToCmyk: hexTocmyk,
hexToHsl: hexTohsl,
hexToHsv: hexTohsv,
hexToRgb: hexTorgb,
hexToRgba,
hexTocmyk,
hexTohsl,
hexTohsv,
hexTorgb,
hslToHex: hslTohex,
hslToHsv: hslTohsv,
hslToRgb: hslTorgb,
hslTohex,
hslTohsv,
hslTorgb,
rgbToCmyk: rgbTocmyk,
rgbToHex: rgbTohex,
rgbToHsl: rgbTohsl,
rgbToHsv: rgbTohsv,
rgbToLab,
rgbToLch,
rgbToXyz,
rgbTocmyk,
rgbTohex,
rgbTohsl,
rgbTohsv,
rgbaToHex
});
const randomcolor = (options) => {
try {
const format = (options == null ? void 0 : options.format) || "hex";
const h = getRandomValue(options == null ? void 0 : options.hue, 0, 359);
const s = getRandomValue(options == null ? void 0 : options.saturation, 0, 100);
const l = getRandomValue(options == null ? void 0 : options.lightness, 0, 100);
const hsl = [h, s, l];
switch (format) {
case "hex":
return hslTohex(hsl);
case "rgb":
return hslTorgb(hsl);
case "hsl":
default:
return hsl;
}
} catch (e) {
throw new ColorConversionError$1(`Failed to generate random color: ${e.message}`);
}
};
const generateColorScheme = (baseColor) => {
try {
let baseHsl;
if (typeof baseColor === "string") {
baseHsl = hexTohsl(baseColor);
} else {
baseHsl = rgbTohsl(baseColor);
}
const h = baseHsl[0];
const s = baseHsl[1];
const l = baseHsl[2];
const schemeHex = typeof baseColor === "string" ? baseColor : rgbTohex(baseColor);
const analogous = [
hslTohex([(h + 30) % 360, s, l]),
hslTohex([(h + 330) % 360, s, l])
];
const complementary = [hslTohex([(h + 180) % 360, s, l])];
const triadic = [
hslTohex([(h + 120) % 360, s, l]),
hslTohex([(h + 240) % 360, s, l])
];
const tetradic = [
hslTohex([(h + 90) % 360, s, l]),
hslTohex([(h + 180) % 360, s, l]),
hslTohex([(h + 270) % 360, s, l])
];
const monochromatic = [
hslTohex([h, Math.max(0, s - 20), l]),
hslTohex([h, Math.min(100, s + 20), l]),
hslTohex([h, s, Math.max(0, l - 20)]),
hslTohex([h, s, Math.min(100, l + 20)])
];
const splitComplementary = [
hslTohex([(h + 150) % 360, s, l]),
hslTohex([(h + 210) % 360, s, l])
];
return {
base: schemeHex,
analogous,
complementary,
triadic,
tetradic,
monochromatic,
splitComplementary
};
} catch (e) {
if (e instanceof ColorConversionError$1) throw e;
throw new ColorConversionError$1(`Failed to generate color scheme: ${e.message}`);
}
};
const getLuminance = (color) => {
try {
const rgb = typeof color === "string" ? hexTorgb(color) : color;
const sRGB = rgb.map((val) => {
val = val / 255;
return val <= 0.03928 ? val / 12.92 : Math.pow((val + 0.055) / 1.055, 2.4);
});
return 0.2126 * sRGB[0] + 0.7152 * sRGB[1] + 0.0722 * sRGB[2];
} catch (e) {
if (e instanceof ColorConversionError$1) throw e;
throw new ColorConversionError$1(`Failed to calculate luminance: ${e.message}`);
}
};
const getContrastRatio = (color1, color2) => {
try {
const l1 = getLuminance(color1);
const l2 = getLuminance(color2);
return (Math.max(l1, l2) + 0.05) / (Math.min(l1, l2) + 0.05);
} catch (e) {
if (e instanceof ColorConversionError$1) throw e;
throw new ColorConversionError$1(`Failed to calculate contrast ratio: ${e.message}`);
}
};
const isWcagAA = (foreground, background, isLargeText = false) => {
try {
const ratio = getContrastRatio(foreground, background);
return isLargeText ? ratio >= 3 : ratio >= 4.5;
} catch (e) {
if (e instanceof ColorConversionError$1) throw e;
throw new ColorConversionError$1(`Failed to check WCAG AA compliance: ${e.message}`);
}
};
const isWcagAAA = (foreground, background, isLargeText = false) => {
try {
const ratio = getContrastRatio(foreground, background);
return isLargeText ? ratio >= 4.5 : ratio >= 7;
} catch (e) {
if (e instanceof ColorConversionError$1) throw e;
throw new ColorConversionError$1(`Failed to check WCAG AAA compliance: ${e.message}`);
}
};
const lighten = (color, amount) => {
try {
const normalizedAmount = clamp(amount, 0, 100) / 100;
if (typeof color === "string") {
const hsl = hexTohsl(color);
const newL = Math.min(100, hsl[2] + Math.round(normalizedAmount * 100));
return hslTohex([hsl[0], hsl[1], newL]);
} else if (color.length === 3) {
if (Boolean(validateOrThrow(
color,
"rgb",
"Invalid RGB value. Expected an array of 3 numbers between 0-255."
))) {
const hsl = rgbTohsl(color);
const newL = Math.min(100, hsl[2] + Math.round(normalizedAmount * 100));
if (Boolean(validateOrThrow(
[hsl[0], hsl[1], newL],
"hsl",
"Invalid HSL value. Expected an array with h(0-360), s(0-100), l(0-100)."
))) {
return hslTorgb([hsl[0], hsl[1], newL]);
}
} else if (Boolean(validateOrThrow(
color,
"hsl",
"Invalid HSL value. Expected an array with h(0-360), s(0-100), l(0-100)."
))) {
const hsl = color;
const newL = Math.min(100, hsl[2] + Math.round(normalizedAmount * 100));
return [hsl[0], hsl[1], newL];
}
}
throw new ColorConversionError$1("Unsupported color format for lighten function");
} catch (e) {
if (e instanceof ColorConversionError$1) throw e;
throw new ColorConversionError$1(`Failed to lighten color: ${e.message}`);
}
};
const darken = (color, amount) => {
try {
const normalizedAmount = clamp(amount, 0, 100) / 100;
if (typeof color === "string") {
const hsl = hexTohsl(color);
const newL = Math.max(0, hsl[2] - Math.round(normalizedAmount * 100));
return hslTohex([hsl[0], hsl[1], newL]);
} else if (color.length === 3) {
if (Boolean(validateOrThrow(
color,
"rgb",
"Invalid RGB value. Expected an array of 3 numbers between 0-255."
))) {
const hsl = rgbTohsl(color);
const newL = Math.max(0, hsl[2] - Math.round(normalizedAmount * 100));
return hslTorgb([hsl[0], hsl[1], newL]);
} else if (Boolean(validateOrThrow(
color,
"hsl",
"Invalid HSL value. Expected an array with h(0-360), s(0-100), l(0-100)."
))) {
const hsl = color;
const newL = Math.max(0, hsl[2] - Math.round(normalizedAmount * 100));
return [hsl[0], hsl[1], newL];
}
}
throw new ColorConversionError$1("Unsupported color format for darken function");
} catch (e) {
if (e instanceof ColorConversionError$1) throw e;
throw new ColorConversionError$1(`Failed to darken color: ${e.message}`);
}
};
const saturate = (color, amount) => {
try {
const normalizedAmount = clamp(amount, 0, 100) / 100;
if (typeof color === "string") {
const hsl = hexTohsl(color);
const newS = Math.min(100, hsl[1] + Math.round(normalizedAmount * 100));
return hslTohex([hsl[0], newS, hsl[2]]);
} else if (color.length === 3) {
if (Boolean(validateOrThrow(
color,
"rgb",
"Invalid RGB value. Expected an array of 3 numbers between 0-255."
))) {
const hsl = rgbTohsl(color);
const newS = Math.min(100, hsl[1] + Math.round(normalizedAmount * 100));
return hslTorgb([hsl[0], newS, hsl[2]]);
} else if (Boolean(validateOrThrow(
color,
"hsl",
"Invalid HSL value. Expected an array with h(0-360), s(0-100), l(0-100)."
))) {
const hsl = color;
const newS = Math.min(100, hsl[1] + Math.round(normalizedAmount * 100));
return [hsl[0], newS, hsl[2]];
}
}
throw new ColorConversionError$1("Unsupported color format for saturate function");
} catch (e) {
if (e instanceof ColorConversionError$1) throw e;
throw new ColorConversionError$1(`Failed to saturate color: ${e.message}`);
}
};
const desaturate = (color, amount) => {
try {
const normalizedAmount = clamp(amount, 0, 100) / 100;
if (typeof color === "string") {
const hsl = hexTohsl(color);
const newS = Math.max(0, hsl[1] - Math.round(normalizedAmount * 100));
return hslTohex([hsl[0], newS, hsl[2]]);
} else if (color.length === 3) {
if (Boolean(validateOrThrow(
color,
"rgb",
"Invalid RGB value. Expected an array of 3 numbers between 0-255."
))) {
const hsl = rgbTohsl(color);
const newS = Math.max(0, hsl[1] - Math.round(normalizedAmount * 100));
return hslTorgb([hsl[0], newS, hsl[2]]);
} else if (Boolean(validateOrThrow(
color,
"hsl",
"Invalid HSL value. Expected an array with h(0-360), s(0-100), l(0-100)."
))) {
const hsl = color;
const newS = Math.max(0, hsl[1] - Math.round(normalizedAmount * 100));
return [hsl[0], newS, hsl[2]];
}
}
throw new ColorConversionError$1("Unsupported color format for desaturate function");
} catch (e) {
if (e instanceof ColorConversionError$1) throw e;
throw new ColorConversionError$1(`Failed to desaturate color: ${e.message}`);
}
};
const grayscale = (color) => {
try {
return desaturate(color, 100);
} catch (e) {
if (e instanceof ColorConversionError$1) throw e;
throw new ColorConversionError$1(`Failed to convert color to grayscale: ${e.message}`);
}
};
const getSuggestedTextColor = (background) => {
try {
const bgLuminance = getLuminance(background);
return bgLuminance > 0.5 ? "#000000" : "#ffffff";
} catch (e) {
if (e instanceof ColorConversionError$1) throw e;
throw new ColorConversionError$1(`Failed to suggest text color: ${e.message}`);
}
};
const utils = /* @__PURE__ */ Object.freeze({
__proto__: null,
darken,
darkenColor: darken,
desaturate,
desaturateColor: desaturate,
generateColorScheme,
getContrastRatio,
getLuminance,
getSuggestedTextColor,
grayscale,
grayscaleColor: grayscale,
isWcagAA,
isWcagAAA,
lighten,
lightenColor: lighten,
randomColor: randomcolor,
randomcolor,
saturate,
saturateColor: saturate
});
class ColorConversionError2 extends Error {
constructor(message) {
super(message);
this.name = "ColorConversionError";
}
}
const index = {
...colorConversion,
...utils
};
export {
ColorConversionError2 as ColorConversionError,
cmykTohex as cmykToHex,
cmykTohsl as cmykToHsl,
cmykTorgb as cmykToRgb,
cmykTohex,
cmykTohsl,
cmykTorgb,
darken,
index as default,
desaturate,
generateColorScheme,
getContrastRatio,
getLuminance,
getSuggestedTextColor,
grayscale,
hexTocmyk as hexToCmyk,
hexTohsl as hexToHsl,
hexTohsv as hexToHsv,
hexTorgb as hexToRgb,
hexToRgba,
hexTocmyk,
hexTohsl,
hexTohsv,
hexTorgb,
hslTohex as hslToHex,
hslTohsv as hslToHsv,
hslTorgb as hslToRgb,
hslTohex,
hslTohsv,
hslTorgb,
isWcagAA,
isWcagAAA,
lighten,
randomcolor as randomColor,
randomcolor,
rgbTocmyk as rgbToCmyk,
rgbTohex as rgbToHex,
rgbTohsl as rgbToHsl,
rgbTohsv as rgbToHsv,
rgbToLab,
rgbToLch,
rgbToXyz,
rgbTocmyk,
rgbTohex,
rgbTohsl,
rgbTohsv,
rgbaToHex,
saturate
};