|
| 1 | +const CSS_NAMED_COLORS: Record<string, string> = { |
| 2 | + aliceblue: '#F0F8FFFF', |
| 3 | + antiquewhite: '#FAEBD7FF', |
| 4 | + aqua: '#00FFFFFF', |
| 5 | + aquamarine: '#7FFFD4FF', |
| 6 | + azure: '#F0FFFFFF', |
| 7 | + beige: '#F5F5DCFF', |
| 8 | + bisque: '#FFE4C4FF', |
| 9 | + black: '#000000FF', |
| 10 | + blanchedalmond: '#FFEBCDFF', |
| 11 | + blue: '#0000FFFF', |
| 12 | + blueviolet: '#8A2BE2FF', |
| 13 | + brown: '#A52A2AFF', |
| 14 | + burlywood: '#DEB887FF', |
| 15 | + cadetblue: '#5F9EA0FF', |
| 16 | + chartreuse: '#7FFF00FF', |
| 17 | + chocolate: '#D2691EFF', |
| 18 | + coral: '#FF7F50FF', |
| 19 | + cornflowerblue: '#6495EDFF', |
| 20 | + cornsilk: '#FFF8DCFF', |
| 21 | + crimson: '#DC143CFF', |
| 22 | + cyan: '#00FFFFFF', |
| 23 | + darkblue: '#00008BFF', |
| 24 | + darkcyan: '#008B8BFF', |
| 25 | + darkgoldenrod: '#B8860BFF', |
| 26 | + darkgray: '#A9A9A9FF', |
| 27 | + darkgrey: '#A9A9A9FF', |
| 28 | + darkgreen: '#006400FF', |
| 29 | + darkkhaki: '#BDB76BFF', |
| 30 | + darkmagenta: '#8B008BFF', |
| 31 | + darkolivegreen: '#556B2FFF', |
| 32 | + darkorange: '#FF8C00FF', |
| 33 | + darkorchid: '#9932CCFF', |
| 34 | + darkred: '#8B0000FF', |
| 35 | + darksalmon: '#E9967AFF', |
| 36 | + darkseagreen: '#8FBC8FFF', |
| 37 | + darkslateblue: '#483D8BFF', |
| 38 | + darkslategray: '#2F4F4FFF', |
| 39 | + darkslategrey: '#2F4F4FFF', |
| 40 | + darkturquoise: '#00CED1FF', |
| 41 | + darkviolet: '#9400D3FF', |
| 42 | + deeppink: '#FF1493FF', |
| 43 | + deepskyblue: '#00BFFFFF', |
| 44 | + dimgray: '#696969FF', |
| 45 | + dimgrey: '#696969FF', |
| 46 | + dodgerblue: '#1E90FFFF', |
| 47 | + firebrick: '#B22222FF', |
| 48 | + floralwhite: '#FFFAF0FF', |
| 49 | + forestgreen: '#228B22FF', |
| 50 | + fuchsia: '#FF00FFFF', |
| 51 | + gainsboro: '#DCDCDCFF', |
| 52 | + ghostwhite: '#F8F8FFFF', |
| 53 | + gold: '#FFD700FF', |
| 54 | + goldenrod: '#DAA520FF', |
| 55 | + gray: '#808080FF', |
| 56 | + grey: '#808080FF', |
| 57 | + green: '#008000FF', |
| 58 | + greenyellow: '#ADFF2FFF', |
| 59 | + honeydew: '#F0FFF0FF', |
| 60 | + hotpink: '#FF69B4FF', |
| 61 | + indianred: '#CD5C5CFF', |
| 62 | + indigo: '#4B0082FF', |
| 63 | + ivory: '#FFFFF0FF', |
| 64 | + khaki: '#F0E68CFF', |
| 65 | + lavender: '#E6E6FAFF', |
| 66 | + lavenderblush: '#FFF0F5FF', |
| 67 | + lawngreen: '#7CFC00FF', |
| 68 | + lemonchiffon: '#FFFACDFF', |
| 69 | + lightblue: '#ADD8E6FF', |
| 70 | + lightcoral: '#F08080FF', |
| 71 | + lightcyan: '#E0FFFFFF', |
| 72 | + lightgoldenrodyellow: '#FAFAD2FF', |
| 73 | + lightgray: '#D3D3D3FF', |
| 74 | + lightgrey: '#D3D3D3FF', |
| 75 | + lightgreen: '#90EE90FF', |
| 76 | + lightpink: '#FFB6C1FF', |
| 77 | + lightsalmon: '#FFA07AFF', |
| 78 | + lightseagreen: '#20B2AAFF', |
| 79 | + lightskyblue: '#87CEFAFF', |
| 80 | + lightslategray: '#778899FF', |
| 81 | + lightslategrey: '#778899FF', |
| 82 | + lightsteelblue: '#B0C4DEFF', |
| 83 | + lightyellow: '#FFFFE0FF', |
| 84 | + lime: '#00FF00FF', |
| 85 | + limegreen: '#32CD32FF', |
| 86 | + linen: '#FAF0E6FF', |
| 87 | + magenta: '#FF00FFFF', |
| 88 | + maroon: '#800000FF', |
| 89 | + mediumaquamarine: '#66CDAAFF', |
| 90 | + mediumblue: '#0000CDFF', |
| 91 | + mediumorchid: '#BA55D3FF', |
| 92 | + mediumpurple: '#9370D8FF', |
| 93 | + mediumseagreen: '#3CB371FF', |
| 94 | + mediumslateblue: '#7B68EEFF', |
| 95 | + mediumspringgreen: '#00FA9AFF', |
| 96 | + mediumturquoise: '#48D1CCFF', |
| 97 | + mediumvioletred: '#C71585FF', |
| 98 | + midnightblue: '#191970FF', |
| 99 | + mintcream: '#F5FFFAFF', |
| 100 | + mistyrose: '#FFE4E1FF', |
| 101 | + moccasin: '#FFE4B5FF', |
| 102 | + navajowhite: '#FFDEADFF', |
| 103 | + navy: '#000080FF', |
| 104 | + oldlace: '#FDF5E6FF', |
| 105 | + olive: '#808000FF', |
| 106 | + olivedrab: '#6B8E23FF', |
| 107 | + orange: '#FFA500FF', |
| 108 | + orangered: '#FF4500FF', |
| 109 | + orchid: '#DA70D6FF', |
| 110 | + palegoldenrod: '#EEE8AAFF', |
| 111 | + palegreen: '#98FB98FF', |
| 112 | + paleturquoise: '#AFEEEEFF', |
| 113 | + palevioletred: '#D87093FF', |
| 114 | + papayawhip: '#FFEFD5FF', |
| 115 | + peachpuff: '#FFDAB9FF', |
| 116 | + peru: '#CD853FFF', |
| 117 | + pink: '#FFC0CBFF', |
| 118 | + plum: '#DDA0DDFF', |
| 119 | + powderblue: '#B0E0E6FF', |
| 120 | + purple: '#800080FF', |
| 121 | + rebeccapurple: '#663399FF', |
| 122 | + red: '#FF0000FF', |
| 123 | + rosybrown: '#BC8F8FFF', |
| 124 | + royalblue: '#4169E1FF', |
| 125 | + saddlebrown: '#8B4513FF', |
| 126 | + salmon: '#FA8072FF', |
| 127 | + sandybrown: '#F4A460FF', |
| 128 | + seagreen: '#2E8B57FF', |
| 129 | + seashell: '#FFF5EEFF', |
| 130 | + sienna: '#A0522DFF', |
| 131 | + silver: '#C0C0C0FF', |
| 132 | + skyblue: '#87CEEBFF', |
| 133 | + slateblue: '#6A5ACDFF', |
| 134 | + slategray: '#708090FF', |
| 135 | + slategrey: '#708090FF', |
| 136 | + snow: '#FFFAFAFF', |
| 137 | + springgreen: '#00FF7FFF', |
| 138 | + steelblue: '#4682B4FF', |
| 139 | + tan: '#D2B48CFF', |
| 140 | + teal: '#008080FF', |
| 141 | + thistle: '#D8BFD8FF', |
| 142 | + tomato: '#FF6347FF', |
| 143 | + turquoise: '#40E0D0FF', |
| 144 | + violet: '#EE82EEFF', |
| 145 | + wheat: '#F5DEB3FF', |
| 146 | + white: '#FFFFFFFF', |
| 147 | + whitesmoke: '#F5F5F5FF', |
| 148 | + yellow: '#FFFF00FF', |
| 149 | + yellowgreen: '#9ACD32FF', |
| 150 | +}; |
| 151 | + |
| 152 | +export function normalizeColorToHex( |
| 153 | + value: string | null | undefined |
| 154 | +): string | null { |
| 155 | + if (!value) return null; |
| 156 | + let str = value.trim().toLowerCase(); |
| 157 | + |
| 158 | + // Handle Named Colors |
| 159 | + if (CSS_NAMED_COLORS[str] !== undefined) { |
| 160 | + str = CSS_NAMED_COLORS[str]!.toLowerCase(); |
| 161 | + } |
| 162 | + |
| 163 | + // Handle Hex (#FFF, #RGBA, #RRGGBB, #RRGGBBAA) |
| 164 | + if (str.startsWith('#')) { |
| 165 | + const hex = str.substring(1); |
| 166 | + let r, |
| 167 | + g, |
| 168 | + b, |
| 169 | + a = 'ff'; |
| 170 | + |
| 171 | + if (hex.length === 3) { |
| 172 | + r = hex.charAt(0) + hex.charAt(0); |
| 173 | + g = hex.charAt(1) + hex.charAt(1); |
| 174 | + b = hex.charAt(2) + hex.charAt(2); |
| 175 | + } else if (hex.length === 4) { |
| 176 | + r = hex.charAt(0) + hex.charAt(0); |
| 177 | + g = hex.charAt(1) + hex.charAt(1); |
| 178 | + b = hex.charAt(2) + hex.charAt(2); |
| 179 | + a = hex.charAt(3) + hex.charAt(3); |
| 180 | + } else if (hex.length === 6) { |
| 181 | + r = hex.substring(0, 2); |
| 182 | + g = hex.substring(2, 4); |
| 183 | + b = hex.substring(4, 6); |
| 184 | + } else if (hex.length === 8) { |
| 185 | + r = hex.substring(0, 2); |
| 186 | + g = hex.substring(2, 4); |
| 187 | + b = hex.substring(4, 6); |
| 188 | + a = hex.substring(6, 8); |
| 189 | + } else { |
| 190 | + return null; |
| 191 | + } |
| 192 | + |
| 193 | + // drop alpha if it's 255 (FF) |
| 194 | + if (a === 'ff') { |
| 195 | + return `#${r}${g}${b}`.toUpperCase(); |
| 196 | + } |
| 197 | + return `#${r}${g}${b}${a}`.toUpperCase(); |
| 198 | + } |
| 199 | + |
| 200 | + // Handle rgb() and rgba() |
| 201 | + if (str.startsWith('rgb')) { |
| 202 | + const match = str.match( |
| 203 | + /rgba?\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)(?:\s*,\s*([\d.]+))?\s*\)/ |
| 204 | + ); |
| 205 | + if (match && match[1] && match[2] && match[3]) { |
| 206 | + const r = Math.round(parseFloat(match[1])).toString(16).padStart(2, '0'); |
| 207 | + const g = Math.round(parseFloat(match[2])).toString(16).padStart(2, '0'); |
| 208 | + const b = Math.round(parseFloat(match[3])).toString(16).padStart(2, '0'); |
| 209 | + |
| 210 | + let a = 'ff'; |
| 211 | + if (match[4] !== undefined) { |
| 212 | + a = Math.round(parseFloat(match[4]) * 255) |
| 213 | + .toString(16) |
| 214 | + .padStart(2, '0'); |
| 215 | + } |
| 216 | + |
| 217 | + if (a === 'ff') { |
| 218 | + return `#${r}${g}${b}`.toUpperCase(); |
| 219 | + } |
| 220 | + return `#${r}${g}${b}${a}`.toUpperCase(); |
| 221 | + } |
| 222 | + } |
| 223 | + |
| 224 | + return null; |
| 225 | +} |
0 commit comments