@sanity/ui
Version:
The Sanity UI components.
61 lines (44 loc) • 1.29 kB
text/typescript
import {hexToRgb, hslToRgb, rgbaToRGBA} from './convert'
import {HSL, RGB, RGBA} from './types'
const HEX_CHARS = '0123456789ABCDEFabcdef'
const HSL_RE = /hsl\(\s*(\d+)\s*,\s*((\d+(?:\.\d+)?)%)\s*,\s*((\d+(?:\.\d+)?)%)\s*\)/i
function isHexChars(str: string) {
for (const c of str) {
if (HEX_CHARS.indexOf(c) === -1) {
return false
}
}
return true
}
function isHex(str: string) {
if (str[0] !== '#') return false
// Accept both #000 and #000000
if (!(str.length === 4 || str.length === 7)) return false
return isHexChars(str.slice(1))
}
function parseHsl(str: string): HSL {
const res = HSL_RE.exec(str)
if (!res) {
throw new Error(`parseHsl: string is not a HSL color: "${str}"`)
}
return {h: parseInt(res[1]), s: parseFloat(res[3]), l: parseFloat(res[5])}
}
/**
* @internal
*/
export function parseColor(color: unknown): RGB | RGBA {
if (!color) return {r: 0, g: 0, b: 0}
if (typeof color !== 'string') {
throw new Error('parseColor: expected a string')
}
if (isHex(color)) {
return hexToRgb(color)
}
if (color.startsWith('hsl(')) {
return hslToRgb(parseHsl(color))
}
if (color.startsWith('rgba(')) {
return rgbaToRGBA(color)
}
throw new Error(`parseColor: unexpected color format: "${color}"`)
}