@swapper-finance/sdk
Version:
JavaScript SDK form Swapper
122 lines (111 loc) • 2.93 kB
text/typescript
/**
* Validates if a color string is a valid CSS color
* Supports: hex (#fff, #ffffff), rgb(a), hsl(a), and named colors
*/
export function isValidColor(color: string): boolean {
if (!color || typeof color !== "string") {
return false;
}
// Trim whitespace
const trimmedColor = color.trim();
// Check hex colors
const hexPattern = /^#([0-9A-Fa-f]{3}){1,2}$/;
if (hexPattern.test(trimmedColor)) {
return true;
}
// Check rgb/rgba colors
const rgbPattern =
/^rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(0?\.\d+|1|0))?\s*\)$/;
if (rgbPattern.test(trimmedColor)) {
const matches = trimmedColor.match(rgbPattern);
if (matches && matches[1] && matches[2] && matches[3]) {
const red = parseInt(matches[1], 10);
const green = parseInt(matches[2], 10);
const blue = parseInt(matches[3], 10);
return (
red >= 0 &&
red <= 255 &&
green >= 0 &&
green <= 255 &&
blue >= 0 &&
blue <= 255
);
}
}
// Check hsl/hsla colors
const hslPattern =
/^hsla?\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*(?:,\s*(0?\.\d+|1|0))?\s*\)$/;
if (hslPattern.test(trimmedColor)) {
const matches = trimmedColor.match(hslPattern);
if (matches && matches[1] && matches[2] && matches[3]) {
const hue = parseInt(matches[1], 10);
const saturation = parseInt(matches[2], 10);
const lightness = parseInt(matches[3], 10);
return (
hue >= 0 &&
hue <= 360 &&
saturation >= 0 &&
saturation <= 100 &&
lightness >= 0 &&
lightness <= 100
);
}
}
// Check named colors by creating a temporary element
if (typeof document !== "undefined") {
const testElement = document.createElement("div");
testElement.style.color = trimmedColor;
return testElement.style.color !== "";
}
// Fallback for common named colors if document is not available
const namedColors = [
"black",
"white",
"red",
"green",
"blue",
"yellow",
"orange",
"purple",
"pink",
"brown",
"gray",
"grey",
"cyan",
"magenta",
"lime",
"maroon",
"navy",
"olive",
"teal",
"silver",
"transparent",
"currentColor",
"inherit",
"initial",
"unset",
];
return namedColors.includes(trimmedColor.toLowerCase());
}
/**
* Validates all colors in a styles object
* Returns an array of invalid color properties
*/
export function validateColors(
styles: Record<string, string | undefined>,
): string[] {
const invalidColors: string[] = [];
for (const [key, value] of Object.entries(styles)) {
if (
value &&
typeof value === "string" &&
(key.toLowerCase().includes("color") ||
key.toLowerCase().includes("background"))
) {
if (!isValidColor(value)) {
invalidColors.push(key);
}
}
}
return invalidColors;
}