UNPKG

@publidata/utils-colors

Version:
203 lines (175 loc) 5.91 kB
/** * Will check if the given element is a valid CSS variable * @param {String} str String to be parsed * @return {Boolean} Return a boolean representing if the given string is a valid CSS variable */ export const isCssVariable = str => { if (!str) return false; if (str.startsWith("var(") && str.endsWith(")")) return true; if (str.startsWith("--")) return true; return false; }; /** * Removes "var(" and ")" from a given string * @param {String} str String representing the CSS variable * @return {String} Return the string without "var(" and ")" */ export const getSearchableCssVariable = str => { if (!str) return ""; if (str.startsWith("var(") && str.endsWith(")")) return str.slice(4, -1); return str; }; /** * Will fetch the value of the given CSS variable * @param {String} variable String representing the CSS variable * @return {String} Return the value of the given CSS variable if it exists, else return null */ export const getCssVariableValue = variable => { if (typeof window === "undefined") return; if (!variable) return null; if (!isCssVariable(variable)) { return variable; } const hexaColor = window .getComputedStyle(document.documentElement) .getPropertyValue(getSearchableCssVariable(variable)) .trim(); return hexaColor.length ? hexaColor : null; }; /** Return an hexadecimal color as RGB valid color * @Param: String, an hexadecimal valid color * @Param: [String], the format with wich the color should be returned string by default * @Return: String or Array, as a valid CSS color */ export const hexaToRgb = (hexa, format = "string") => { if (!hexa) return null; const shades = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hexa); const asArray = shades ? shades.slice(1, 4).map(shade => parseInt(shade, 16)) : null; return asArray && format === "string" ? asArray.join(", ") : asArray; }; /** Return an hexadecimal color as RGBA valid color * @Param String, could be an hexa or an array of 3 RGB colors * @Param Number, between 0 and 1 * @Return String, of RGBA color */ export const hexaToRgba = (hexa, alpha = 1) => { if (!hexa) return null; const rgb = hexaToRgb(hexa); if (!rgb) return null; let parsedAlpha = alpha > 1 ? 1 : alpha < 0 ? 0 : alpha; return `${rgb}, ${parsedAlpha}`; }; /** Return an hexadecimal color * @Param String, could be an hexa or an array of 3 RGB colors * @Return String, value for css color properties */ export const hexify = color => { if (!color || typeof color !== "string") return null; const values = color .replace(/rgba?/, "") .replace(/[(|)]/, "") .replace(/[\s+]/g, "") .split(","); const a = parseFloat(values[3] || 1); const hexArray = values .slice(0, 3) .map(value => Math.floor(a * parseInt(value) + (1 - a) * 255)); hexArray.forEach( (hex, index) => (hexArray[index] = ("0" + hex.toString(16)).slice(-2)) ); return `#${hexArray.join("")}`; }; /** Return an hexadecimal color with a darker or lighter shade * @credits https://css-tricks.com/snippets/javascript/lighten-darken-color * @Param String, color as hexadecimal * @Param Number, negative for lighter color and positive for darker * @Return String, Hexa color with different shade */ export const getShade = (color, shade) => { if (!color || typeof color !== "string") return null; let usePound = false; let output = color; if (color[0] === "#") { output = color.slice(1); usePound = true; } const num = parseInt(output, 16); let r = (num >> 16) + shade; if (r > 255) r = 255; else if (r < 0) r = 0; let g = (num & 0x0000ff) + shade; if (g > 255) g = 255; else if (g < 0) g = 0; let b = ((num >> 8) & 0x00ff) + shade; if (b > 255) b = 255; else if (b < 0) b = 0; return `${usePound ? "#" : ""} ${(g | (b << 8) | (r << 16)).toString( 16 )}`.replaceAll(" ", ""); }; /** Return css valid value from a color and an opacity * @Param: String, could be an hexa or an array of 3 RGB colors * @Return: String, value for css color properties */ export const getCSSColor = (color, alpha = 1) => { if (!color) return color; const isArray = Array.isArray(color) && color.length === 3; const isHexa = typeof color === "string"; if (isHexa || isArray) { let r, g, b; if (isHexa) { const rgb = hexaToRgb(color, "array"); if (!rgb) return color; [r, g, b] = rgb; } else [r, g, b] = color; return alpha === 1 ? `rgba(${r}, ${g}, ${b})` : `rgba(${r}, ${g}, ${b}, ${alpha})`; } return color; }; /* Shade and Tint generators @credits: https://github.com/edelstone/tints-and-shades/blob/main/scripts/tints-and-shades.js */ const pad = (number, length) => { var str = "" + number; while (str.length < length) { str = "0" + str; } return str; }; const intToHex = rgbint => { return pad(Math.min(Math.max(Math.round(rgbint), 0), 255).toString(16), 2); }; const calculate = (colorValue, shadeOrTint) => { const color = { red: parseInt(colorValue.substr(0, 2), 16), green: parseInt(colorValue.substr(2, 2), 16), blue: parseInt(colorValue.substr(4, 2), 16) }; var shadeValues = []; function rgbObjToHex(rgb) { return intToHex(rgb.red) + intToHex(rgb.green) + intToHex(rgb.blue); } for (var i = 0; i < 10; i++) { shadeValues[i] = rgbObjToHex(shadeOrTint(color, i)); } return shadeValues; }; const rgbTint = (rgb, i) => ({ red: rgb.red + (255 - rgb.red) * i * 0.1, green: rgb.green + (255 - rgb.green) * i * 0.1, blue: rgb.blue + (255 - rgb.blue) * i * 0.1 }); export const getTints = colorValue => calculate(colorValue, rgbTint).concat("ffffff"); const rgbShade = (rgb, i) => ({ red: rgb.red * (1 - 0.1 * i), green: rgb.green * (1 - 0.1 * i), blue: rgb.blue * (1 - 0.1 * i) }); export const getShades = colorValue => calculate(colorValue, rgbShade).concat("000000");