UNPKG

2.7 kBJavaScriptView Raw
1const { colord, extend } = require('colord');
2const valueParser = require('postcss-value-parser');
3
4const namesPlugin = require('colord/plugins/names');
5const hwbPlugin = require('colord/plugins/hwb');
6const labPlugin = require('colord/plugins/lab');
7const lchPlugin = require('colord/plugins/lch');
8
9extend([
10 // Type definitions are not compatible with commonjs.
11 /** @type {any} */ (namesPlugin),
12 /** @type {any} */ (hwbPlugin),
13 /** @type {any} */ (labPlugin),
14 /** @type {any} */ (lchPlugin),
15
16 /* Syntaxes that is removed in Color Module Level 4 specification. */
17
18 // hwb() with comma
19 (_colordClass, parsers) => {
20 parsers.string.push([parseHwbWithCommaString, /** @type {any} */ ('hwb-with-comma')]);
21 },
22 // gray()
23 (_colordClass, parsers) => {
24 parsers.string.push([parseGrayString, /** @type {any} */ ('gray')]);
25 },
26]);
27
28module.exports = {
29 colord,
30};
31
32/**
33 * Parses a valid hwb with comma CSS color function
34 * https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/hwb()#syntax
35 * @type {import('colord/types').ParseFunction<string>}
36 */
37function parseHwbWithCommaString(input) {
38 input = input.toLowerCase();
39
40 if (!input.startsWith('hwb(') || !input.endsWith(')') || input.includes('/')) {
41 return null;
42 }
43
44 const [hue, whiteness = '', blackness = '', alpha, ...extraArgs] = input.slice(4, -1).split(',');
45
46 if (!hue.trim() || !whiteness.trim() || !blackness.trim() || extraArgs.length > 0) {
47 return null;
48 }
49
50 // Change the delimiter and parse with colord.
51 const colordInstance = colord(
52 `hwb(${hue} ${whiteness} ${blackness}${alpha ? ` / ${alpha}` : ''})`,
53 );
54
55 if (!colordInstance.isValid()) {
56 return null;
57 }
58
59 return colordInstance.rgba;
60}
61
62/**
63 * Parses a valid gray() CSS color function
64 * @type {import('colord/types').ParseFunction<string>}
65 */
66function parseGrayString(input) {
67 input = input.toLowerCase();
68
69 if (!input.startsWith('gray(') || !input.endsWith(')')) {
70 return null;
71 }
72
73 const [lightness, alpha, ...extraArgs] = input.slice(5, -1).split(',');
74
75 if (extraArgs.length > 0) {
76 return null;
77 }
78
79 const lightnessWithUnit = valueParser.unit(lightness.trim());
80
81 if (!lightnessWithUnit || !['', '%'].includes(lightnessWithUnit.unit)) {
82 return null;
83 }
84
85 /**
86 * @type {import('colord/types').LabColor | import('colord/types').LabaColor}
87 */
88 let colorObject = {
89 l: Number(lightnessWithUnit.number),
90 a: 0,
91 b: 0,
92 };
93
94 if (alpha) {
95 const alphaWithUnit = valueParser.unit(alpha.trim());
96
97 if (!alphaWithUnit || !['', '%'].includes(alphaWithUnit.unit)) {
98 return null;
99 }
100
101 colorObject = {
102 ...colorObject,
103 alpha: Number(alphaWithUnit.number) / (alphaWithUnit.unit ? 100 : 1),
104 };
105 }
106
107 return colord(colorObject).rgba;
108}