1
1
const dlv = require ( 'dlv' )
2
2
import { State } from './state'
3
3
import removeMeta from './removeMeta'
4
+ import { TinyColor } from '@ctrl/tinycolor'
5
+ import { ensureArray , dedupe , flatten } from './array'
4
6
5
7
const COLOR_PROPS = [
6
8
'caret-color' ,
@@ -19,202 +21,75 @@ const COLOR_PROPS = [
19
21
'text-decoration-color' ,
20
22
]
21
23
22
- const COLOR_NAMES = {
23
- transparent : 'rgba(0, 0, 0, 0.01)' ,
24
- aliceblue : '#f0f8ff' ,
25
- antiquewhite : '#faebd7' ,
26
- aqua : '#0ff' ,
27
- aquamarine : '#7fffd4' ,
28
- azure : '#f0ffff' ,
29
- beige : '#f5f5dc' ,
30
- bisque : '#ffe4c4' ,
31
- black : '#000' ,
32
- blanchedalmond : '#ffebcd' ,
33
- blue : '#00f' ,
34
- blueviolet : '#8a2be2' ,
35
- brown : '#a52a2a' ,
36
- burlywood : '#deb887' ,
37
- burntsienna : '#ea7e5d' ,
38
- cadetblue : '#5f9ea0' ,
39
- chartreuse : '#7fff00' ,
40
- chocolate : '#d2691e' ,
41
- coral : '#ff7f50' ,
42
- cornflowerblue : '#6495ed' ,
43
- cornsilk : '#fff8dc' ,
44
- crimson : '#dc143c' ,
45
- cyan : '#0ff' ,
46
- darkblue : '#00008b' ,
47
- darkcyan : '#008b8b' ,
48
- darkgoldenrod : '#b8860b' ,
49
- darkgray : '#a9a9a9' ,
50
- darkgreen : '#006400' ,
51
- darkgrey : '#a9a9a9' ,
52
- darkkhaki : '#bdb76b' ,
53
- darkmagenta : '#8b008b' ,
54
- darkolivegreen : '#556b2f' ,
55
- darkorange : '#ff8c00' ,
56
- darkorchid : '#9932cc' ,
57
- darkred : '#8b0000' ,
58
- darksalmon : '#e9967a' ,
59
- darkseagreen : '#8fbc8f' ,
60
- darkslateblue : '#483d8b' ,
61
- darkslategray : '#2f4f4f' ,
62
- darkslategrey : '#2f4f4f' ,
63
- darkturquoise : '#00ced1' ,
64
- darkviolet : '#9400d3' ,
65
- deeppink : '#ff1493' ,
66
- deepskyblue : '#00bfff' ,
67
- dimgray : '#696969' ,
68
- dimgrey : '#696969' ,
69
- dodgerblue : '#1e90ff' ,
70
- firebrick : '#b22222' ,
71
- floralwhite : '#fffaf0' ,
72
- forestgreen : '#228b22' ,
73
- fuchsia : '#f0f' ,
74
- gainsboro : '#dcdcdc' ,
75
- ghostwhite : '#f8f8ff' ,
76
- gold : '#ffd700' ,
77
- goldenrod : '#daa520' ,
78
- gray : '#808080' ,
79
- green : '#008000' ,
80
- greenyellow : '#adff2f' ,
81
- grey : '#808080' ,
82
- honeydew : '#f0fff0' ,
83
- hotpink : '#ff69b4' ,
84
- indianred : '#cd5c5c' ,
85
- indigo : '#4b0082' ,
86
- ivory : '#fffff0' ,
87
- khaki : '#f0e68c' ,
88
- lavender : '#e6e6fa' ,
89
- lavenderblush : '#fff0f5' ,
90
- lawngreen : '#7cfc00' ,
91
- lemonchiffon : '#fffacd' ,
92
- lightblue : '#add8e6' ,
93
- lightcoral : '#f08080' ,
94
- lightcyan : '#e0ffff' ,
95
- lightgoldenrodyellow : '#fafad2' ,
96
- lightgray : '#d3d3d3' ,
97
- lightgreen : '#90ee90' ,
98
- lightgrey : '#d3d3d3' ,
99
- lightpink : '#ffb6c1' ,
100
- lightsalmon : '#ffa07a' ,
101
- lightseagreen : '#20b2aa' ,
102
- lightskyblue : '#87cefa' ,
103
- lightslategray : '#789' ,
104
- lightslategrey : '#789' ,
105
- lightsteelblue : '#b0c4de' ,
106
- lightyellow : '#ffffe0' ,
107
- lime : '#0f0' ,
108
- limegreen : '#32cd32' ,
109
- linen : '#faf0e6' ,
110
- magenta : '#f0f' ,
111
- maroon : '#800000' ,
112
- mediumaquamarine : '#66cdaa' ,
113
- mediumblue : '#0000cd' ,
114
- mediumorchid : '#ba55d3' ,
115
- mediumpurple : '#9370db' ,
116
- mediumseagreen : '#3cb371' ,
117
- mediumslateblue : '#7b68ee' ,
118
- mediumspringgreen : '#00fa9a' ,
119
- mediumturquoise : '#48d1cc' ,
120
- mediumvioletred : '#c71585' ,
121
- midnightblue : '#191970' ,
122
- mintcream : '#f5fffa' ,
123
- mistyrose : '#ffe4e1' ,
124
- moccasin : '#ffe4b5' ,
125
- navajowhite : '#ffdead' ,
126
- navy : '#000080' ,
127
- oldlace : '#fdf5e6' ,
128
- olive : '#808000' ,
129
- olivedrab : '#6b8e23' ,
130
- orange : '#ffa500' ,
131
- orangered : '#ff4500' ,
132
- orchid : '#da70d6' ,
133
- palegoldenrod : '#eee8aa' ,
134
- palegreen : '#98fb98' ,
135
- paleturquoise : '#afeeee' ,
136
- palevioletred : '#db7093' ,
137
- papayawhip : '#ffefd5' ,
138
- peachpuff : '#ffdab9' ,
139
- peru : '#cd853f' ,
140
- pink : '#ffc0cb' ,
141
- plum : '#dda0dd' ,
142
- powderblue : '#b0e0e6' ,
143
- purple : '#800080' ,
144
- rebeccapurple : '#663399' ,
145
- red : '#f00' ,
146
- rosybrown : '#bc8f8f' ,
147
- royalblue : '#4169e1' ,
148
- saddlebrown : '#8b4513' ,
149
- salmon : '#fa8072' ,
150
- sandybrown : '#f4a460' ,
151
- seagreen : '#2e8b57' ,
152
- seashell : '#fff5ee' ,
153
- sienna : '#a0522d' ,
154
- silver : '#c0c0c0' ,
155
- skyblue : '#87ceeb' ,
156
- slateblue : '#6a5acd' ,
157
- slategray : '#708090' ,
158
- slategrey : '#708090' ,
159
- snow : '#fffafa' ,
160
- springgreen : '#00ff7f' ,
161
- steelblue : '#4682b4' ,
162
- tan : '#d2b48c' ,
163
- teal : '#008080' ,
164
- thistle : '#d8bfd8' ,
165
- tomato : '#ff6347' ,
166
- turquoise : '#40e0d0' ,
167
- violet : '#ee82ee' ,
168
- wheat : '#f5deb3' ,
169
- white : '#fff' ,
170
- whitesmoke : '#f5f5f5' ,
171
- yellow : '#ff0' ,
172
- yellowgreen : '#9acd32' ,
173
- }
174
-
175
24
export function getColor (
176
25
state : State ,
177
26
keys : string [ ]
178
27
) : { documentation ?: string } {
179
28
const item = dlv ( state . classNames . classNames , keys )
180
29
if ( ! item . __rule ) return null
181
30
const props = Object . keys ( removeMeta ( item ) )
31
+ if ( props . length === 0 ) return null
182
32
const nonCustomProps = props . filter ( ( prop ) => ! prop . startsWith ( '--' ) )
183
- if ( nonCustomProps . length !== 1 ) return null
184
- const prop = nonCustomProps [ 0 ]
185
- if ( COLOR_PROPS . indexOf ( prop ) === - 1 ) return null
186
33
187
- const namedColor = COLOR_NAMES [ item [ prop ] . toLowerCase ( ) ]
188
- if ( namedColor ) {
189
- return { documentation : namedColor }
34
+ const areAllCustom = nonCustomProps . length === 0
35
+
36
+ if (
37
+ ! areAllCustom &&
38
+ nonCustomProps . some ( ( prop ) => ! COLOR_PROPS . includes ( prop ) )
39
+ ) {
40
+ // they should all be color-based props
41
+ return null
190
42
}
191
43
192
- // matches: rgba(<r>, <g>, <b>, var(--bg-opacity))
193
- // TODO: support other formats? e.g. hsla, css level 4
194
- const match = item [ prop ] . match (
195
- / ^ \s * r g b a \( \s * (?< r > [ 0 - 9 ] { 1 , 3 } ) \s * , \s * (?< g > [ 0 - 9 ] { 1 , 3 } ) \s * , \s * (?< b > [ 0 - 9 ] { 1 , 3 } ) \s * , \s * v a r /
44
+ const propsToCheck = areAllCustom ? props : nonCustomProps
45
+
46
+ const colors = flatten (
47
+ propsToCheck . map ( ( prop ) => ensureArray ( item [ prop ] ) . map ( createColor ) )
196
48
)
197
- if ( match ) {
198
- return {
199
- documentation : `rgb( ${ match . groups . r } , ${ match . groups . g } , ${ match . groups . b } )` ,
200
- }
49
+
50
+ // check that all of the values are valid colors
51
+ if ( colors . some ( ( color ) => ! color . isValid ) ) {
52
+ return null
201
53
}
202
54
203
- return { }
204
- }
55
+ // check that all of the values are the same color
56
+ const colorStrings = colors . map ( ( color ) => color . toRgbString ( ) )
57
+ if ( dedupe ( colorStrings ) . length !== 1 ) {
58
+ return null
59
+ }
205
60
206
- export function isColor ( str : any ) : boolean {
207
- return (
208
- typeof str === 'string' &&
209
- / ^ (?: # | 0 x ) (?: [ a - f 0 - 9 ] { 3 , 4 } | [ a - f 0 - 9 ] { 6 } | [ a - f 0 - 9 ] { 8 } ) \b | (?: r g b | h s l ) a ? \( [ ^ \) ] * \) $ / . test (
210
- str . trim ( )
211
- )
212
- )
61
+ return { documentation : colorStrings [ 0 ] }
213
62
}
214
63
215
64
export function getColorFromString ( str : string ) : string {
216
- if ( isColor ( str ) ) {
217
- return str
65
+ if ( str === 'transparent' ) {
66
+ return 'rgba(0, 0, 0, 0.01)'
67
+ }
68
+ const color = new TinyColor ( str )
69
+ if ( color . isValid ) {
70
+ return color . toRgbString ( )
218
71
}
219
- return COLOR_NAMES [ str ] || null
72
+ return null
73
+ }
74
+
75
+ function createColor ( str : string ) : TinyColor {
76
+ if ( str === 'transparent' ) {
77
+ return new TinyColor ( { r : 0 , g : 0 , b : 0 , a : 0.01 } )
78
+ }
79
+
80
+ // matches: rgba(<r>, <g>, <b>, var(--bg-opacity))
81
+ // TODO: support other formats? e.g. hsla, css level 4
82
+ const match = str . match (
83
+ / ^ \s * r g b a \( \s * (?< r > [ 0 - 9 ] { 1 , 3 } ) \s * , \s * (?< g > [ 0 - 9 ] { 1 , 3 } ) \s * , \s * (?< b > [ 0 - 9 ] { 1 , 3 } ) \s * , \s * v a r /
84
+ )
85
+
86
+ if ( match ) {
87
+ return new TinyColor ( {
88
+ r : match . groups . r ,
89
+ g : match . groups . g ,
90
+ b : match . groups . b ,
91
+ } )
92
+ }
93
+
94
+ return new TinyColor ( str )
220
95
}
0 commit comments