Skip to content

Commit 14ffaf4

Browse files
author
Brad Cornes
committed
update color plucking logic (tailwindlabs#113)
1 parent 95b2494 commit 14ffaf4

File tree

3 files changed

+61
-179
lines changed

3 files changed

+61
-179
lines changed

packages/tailwindcss-language-server/package-lock.json

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/tailwindcss-language-server/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"node": "*"
1717
},
1818
"devDependencies": {
19+
"@ctrl/tinycolor": "^3.1.0",
1920
"@types/node": "^13.9.3",
2021
"@zeit/ncc": "^0.22.0",
2122
"css.escape": "^1.5.1",
Lines changed: 54 additions & 179 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
const dlv = require('dlv')
22
import { State } from './state'
33
import removeMeta from './removeMeta'
4+
import { TinyColor } from '@ctrl/tinycolor'
5+
import { ensureArray, dedupe, flatten } from './array'
46

57
const COLOR_PROPS = [
68
'caret-color',
@@ -19,202 +21,75 @@ const COLOR_PROPS = [
1921
'text-decoration-color',
2022
]
2123

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-
17524
export function getColor(
17625
state: State,
17726
keys: string[]
17827
): { documentation?: string } {
17928
const item = dlv(state.classNames.classNames, keys)
18029
if (!item.__rule) return null
18130
const props = Object.keys(removeMeta(item))
31+
if (props.length === 0) return null
18232
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
18633

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
19042
}
19143

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*rgba\(\s*(?<r>[0-9]{1,3})\s*,\s*(?<g>[0-9]{1,3})\s*,\s*(?<b>[0-9]{1,3})\s*,\s*var/
44+
const propsToCheck = areAllCustom ? props : nonCustomProps
45+
46+
const colors = flatten(
47+
propsToCheck.map((prop) => ensureArray(item[prop]).map(createColor))
19648
)
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
20153
}
20254

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+
}
20560

206-
export function isColor(str: any): boolean {
207-
return (
208-
typeof str === 'string' &&
209-
/^(?:#|0x)(?:[a-f0-9]{3,4}|[a-f0-9]{6}|[a-f0-9]{8})\b|(?:rgb|hsl)a?\([^\)]*\)$/.test(
210-
str.trim()
211-
)
212-
)
61+
return { documentation: colorStrings[0] }
21362
}
21463

21564
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()
21871
}
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*rgba\(\s*(?<r>[0-9]{1,3})\s*,\s*(?<g>[0-9]{1,3})\s*,\s*(?<b>[0-9]{1,3})\s*,\s*var/
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)
22095
}

0 commit comments

Comments
 (0)