// forked from https://github.com/sindresorhus/rgb-hex import {ColorRGB} from './common' type RGBColorValue = number | string export function rgbToHex(rgba: string): string export function rgbToHex(red: number, green: number, blue: number, alpha?: RGBColorValue): string export function rgbToHex(red: RGBColorValue, green?: RGBColorValue, blue?: RGBColorValue, alpha?: RGBColorValue) { const isPercent = ((red as string) + (alpha || '')).toString().includes('%') if (typeof red === 'string') { [red, green, blue, alpha] = red.match(/(0?\.?\d{1,3})%?\b/g)!.map(Number) } else if (alpha !== undefined && typeof alpha === 'string') { alpha = parseFloat(alpha) } if (typeof red !== 'number' || typeof green !== 'number' || typeof blue !== 'number' || red > 255 || green > 255 || blue > 255 ) { throw new TypeError('Expected three numbers below 256') } if (typeof alpha === 'number') { if (!isPercent && alpha >= 0 && alpha <= 1) { alpha = Math.round(255 * alpha) } else if (isPercent && alpha >= 0 && alpha <= 100) { alpha = Math.round(255 * alpha / 100) } else { throw new TypeError(`Expected alpha value (${alpha}) as a fraction or percentage`) } alpha = (alpha | 1 << 8).toString(16).slice(1) } else { alpha = '' } return ((blue | green << 8 | red << 16) | 1 << 24).toString(16).slice(1) + alpha } // forked from https://github.com/sindresorhus/hex-rgb const hexCharacters = 'a-f\\d' const match3or4Hex = `#?[${hexCharacters}]{3}[${hexCharacters}]?` const match6or8Hex = `#?[${hexCharacters}]{6}([${hexCharacters}]{2})?` const nonHexChars = new RegExp(`[^#${hexCharacters}]`, 'gi') const validHexSize = new RegExp(`^${match3or4Hex}$|^${match6or8Hex}$`, 'i') export function hexToRgb(hex: string): ColorRGB { if (typeof hex !== 'string' || nonHexChars.test(hex) || !validHexSize.test(hex)) { throw new TypeError('Expected a valid hex string') } hex = hex.replace(/^#/, '') let alpha = 1 if (hex.length === 8) { alpha = parseInt(hex.slice(6, 8), 16) / 255 hex = hex.slice(0, 6) } if (hex.length === 4) { alpha = parseInt(hex.slice(3, 4).repeat(2), 16) / 255 hex = hex.slice(0, 3) } if (hex.length === 3) { hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2] } const num = parseInt(hex, 16) const red = num >> 16 const green = (num >> 8) & 255 const blue = num & 255 return {r: red, g: green, b: blue, a: alpha} }