UNPKG

azure-devops-ui

Version:

React components for building web UI in Azure DevOps

115 lines (114 loc) 4.59 kB
export function darken(color, darkenFactor) { const darkenMultiplier = 1 - darkenFactor; return { red: color.red * darkenMultiplier, green: color.green * darkenMultiplier, blue: color.blue * darkenMultiplier }; } export function getColorString(color) { return `rgb(${color.red}, ${color.green}, ${color.blue})`; } export function isDark(color) { const luminance = color.red * 0.299 + color.green * 0.587 + color.blue * 0.114; return luminance <= 128; } export function rgbToHex(color) { return `#${rgbValueToString(color.red)}${rgbValueToString(color.green)}${rgbValueToString(color.blue)}`.toUpperCase(); } /** * Convert a hex color to numeric r g b value * @param color Color in format #aabbcc */ export function hexToRgb(color) { if (color.length !== 7 || color[0] !== "#") { throw new Error("Expected color in format #AABBCC"); } return { red: parseInt(color.substr(1, 2), 16), green: parseInt(color.substr(3, 2), 16), blue: parseInt(color.substr(5, 2), 16) }; } export function generateRandomColor() { const blue = Math.floor(Math.random() * 256); const green = Math.floor(Math.random() * 256); const red = Math.floor(Math.random() * 256); return { red, blue, green }; } export function generateRandomColorHex() { return rgbToHex(generateRandomColor()); } export function parseColor(hexString) { if (!hexString) { return undefined; } let color = undefined; if (hexString.length === 7) { try { color = hexToRgb(hexString); } catch (ex) { console.log(ex); // swallow the exception } } return color; } export function adjustHighlightedTextColors(elements, lightTextColor, darkTextColor) { var _a, _b; const corrections = []; // Check the contrast of lightTextColor and darkTextColor. If they are not good, fallback to white and black. const parsedLightTextColor = parseCssColor(lightTextColor !== null && lightTextColor !== void 0 ? lightTextColor : ""); const parsedDarkTextColor = parseCssColor(darkTextColor !== null && darkTextColor !== void 0 ? darkTextColor : ""); const lightColor = lightTextColor && parsedLightTextColor && !isDark(parsedLightTextColor) ? lightTextColor : "#ffffff"; const darkColor = darkTextColor && parsedDarkTextColor && isDark(parsedDarkTextColor) ? darkTextColor : "#000000"; for (const element of elements) { const backgroundColor = element.style.backgroundColor; if (!backgroundColor) { continue; } const parsedBackgroundColor = parseCssColor(backgroundColor); if (!parsedBackgroundColor) { continue; } const optimalTextColor = isDark(parsedBackgroundColor) ? lightColor : darkColor; const actualTextColor = (_b = (_a = element.ownerDocument) === null || _a === void 0 ? void 0 : _a.defaultView) === null || _b === void 0 ? void 0 : _b.getComputedStyle(element).color; if (actualTextColor) { const parsedTextColor = parseCssColor(actualTextColor); if (parsedTextColor && isDark(parsedBackgroundColor) !== isDark(parsedTextColor)) { // Check if contrast is good: dark text on light background or light text on dark background. // If not, adjust text color. If yes, keep the original one. continue; } } corrections.push({ element, color: optimalTextColor }); } for (const { element, color } of corrections) { element.style.color = color; } } const hexRegex = new RegExp("^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$"); const rgbRegex = new RegExp("^rgba?\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)(?:\\s*,\\s*[\\d.]+)?\\s*\\)"); export function testForHexString(hexString) { return hexString.match(hexRegex); } function rgbValueToString(colorCoord) { let hexColor = colorCoord.toString(16); if (hexColor.length === 1) { hexColor = "0" + hexColor; } return hexColor; } function parseCssColor(color) { const rgbMatch = color.trim().match(rgbRegex); if ((rgbMatch === null || rgbMatch === void 0 ? void 0 : rgbMatch.length) === 4) { return { red: parseInt(rgbMatch[1]), green: parseInt(rgbMatch[2]), blue: parseInt(rgbMatch[3]) }; } // Fallback to hex parsing. return parseColor(color); }