Skip to content

Commit f34c7b9

Browse files
committed
chore: add extra color helpers
1 parent 7e00355 commit f34c7b9

File tree

1 file changed

+53
-0
lines changed

1 file changed

+53
-0
lines changed

site/src/utils/colors.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,56 @@
1+
/**
2+
* Does not support shorthand hex string (e.g., #fff)
3+
*/
4+
const hexMatcher = /^#[0-9A-Fa-f]{6}$/;
5+
6+
export function isHexColor(input: string): boolean {
7+
return hexMatcher.test(input);
8+
}
9+
10+
/**
11+
* Regex written and tested via Regex101. This doesn't catch every invalid HSL
12+
* string and still requires some other checks, but it can do a lot by itself.
13+
*
14+
* Setup:
15+
* - Supports capture groups for all three numeric values. Regex tries to fail
16+
* the input as quickly as possible.
17+
* - Regex is all-or-nothing – there is some tolerance for extra spaces, but
18+
* this regex will fail any string that is missing any part of the format.
19+
* - String is case-insensitive
20+
* - String must start with HSL and have both parentheses
21+
* - All three numeric values must be comma-delimited
22+
* - Hue can be 1-3 digits. Rightmost digit (if it exists) can only be 1-3;
23+
* other digits have no constraints. The degree unit ("deg") is optional
24+
* - Both saturation and luminosity can be 1-3 digits. Rightmost digit (if it
25+
* exists) can only ever be 1. Other digits have no constraints.
26+
*/
27+
const hslMatcher =
28+
/^hsl\(((?:[1-3]?\d)?\d)(?:deg)?, *((?:1?\d)?\d)%, *((?:1?\d)?\d)%\)$/i;
29+
30+
export function isHslColor(input: string): boolean {
31+
const [, hue, sat, lum] = hslMatcher.exec(input) ?? [];
32+
if (hue === undefined || sat === undefined || lum === undefined) {
33+
return false;
34+
}
35+
36+
const hueN = Number(hue);
37+
if (!Number.isInteger(hueN) || hueN < 0 || hueN >= 360) {
38+
return false;
39+
}
40+
41+
const satN = Number(sat);
42+
if (!Number.isInteger(satN) || satN < 0 || satN > 100) {
43+
return false;
44+
}
45+
46+
const lumN = Number(sat);
47+
if (!Number.isInteger(lumN) || lumN < 0 || lumN > 100) {
48+
return false;
49+
}
50+
51+
return true;
52+
}
53+
154
// Used to convert our theme colors to Hex since monaco theme only support hex colors
255
// From https://www.jameslmilner.com/posts/converting-rgb-hex-hsl-colors/
356
export function hslToHex(hsl: string): string {

0 commit comments

Comments
 (0)