(colorStr: string)
| 60 | * Returns null if the color is invalid. |
| 61 | */ |
| 62 | export function parseCssColor(colorStr: string): ParsedColorResult | null { |
| 63 | if (typeof colorStr !== 'string') return null; |
| 64 | const clean = colorStr.trim().toLowerCase(); |
| 65 | if (!clean) return null; |
| 66 | |
| 67 | // 1. Hex Color Pattern |
| 68 | if (clean.startsWith('#')) { |
| 69 | if (!/^#([0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/.test(clean)) { |
| 70 | return null; |
| 71 | } |
| 72 | return parseHex(clean); |
| 73 | } |
| 74 | |
| 75 | // 2. Named Colors lookup |
| 76 | if (Object.prototype.hasOwnProperty.call(CSS_NAMED_COLORS, clean)) { |
| 77 | return parseHex(CSS_NAMED_COLORS[clean]!); |
| 78 | } |
| 79 | |
| 80 | // 3. Functional notations parse |
| 81 | const parsedFunc = tokenizeFunc(clean); |
| 82 | if (!parsedFunc) { |
| 83 | return null; |
| 84 | } |
| 85 | |
| 86 | const { name, args } = parsedFunc; |
| 87 | |
| 88 | switch (name) { |
| 89 | case 'rgb': |
| 90 | case 'rgba': { |
| 91 | // Supports rgb(255, 0, 0) and rgb(255 0 0 / 0.5) |
| 92 | // args could be: [r, g, b] or [r, g, b, a] |
| 93 | if (args.length !== 3 && args.length !== 4) return null; |
| 94 | const rRaw = parsePercentOrNumber(args[0]!, 255); |
| 95 | const gRaw = parsePercentOrNumber(args[1]!, 255); |
| 96 | const bRaw = parsePercentOrNumber(args[2]!, 255); |
| 97 | const aVal = args.length === 4 ? parseAlpha(args[3]) : 1; |
| 98 | |
| 99 | if (isNaN(rRaw) || isNaN(gRaw) || isNaN(bRaw) || isNaN(aVal)) return null; |
| 100 | |
| 101 | const r = Math.max(0, Math.min(255, Math.round(rRaw))); |
| 102 | const g = Math.max(0, Math.min(255, Math.round(gRaw))); |
| 103 | const b = Math.max(0, Math.min(255, Math.round(bRaw))); |
| 104 | const a = Math.max(0, Math.min(1, aVal)); |
| 105 | |
| 106 | return makeResult(r, g, b, a); |
| 107 | } |
| 108 | case 'hsl': |
| 109 | case 'hsla': { |
| 110 | // Supports hsl(120, 100%, 50%) and hsl(120deg 100% 50% / 0.5) |
| 111 | if (args.length !== 3 && args.length !== 4) return null; |
| 112 | const h = parseHue(args[0]!); |
| 113 | const s = parsePercentOrNumber(args[1]!, 1); |
| 114 | const l = parsePercentOrNumber(args[2]!, 1); |
| 115 | const a = args.length === 4 ? parseAlpha(args[3]) : 1; |
| 116 | |
| 117 | if (isNaN(h) || isNaN(s) || isNaN(l) || isNaN(a)) return null; |
| 118 | |
| 119 | const rgb = hslToRgb(h, s, l); |
no test coverage detected
searching dependent graphs…