Skip to content

Commit cc69633

Browse files
authored
Improve type detection for arbitrary color values (#8201)
1 parent 89bf2ed commit cc69633

File tree

3 files changed

+31
-19
lines changed

3 files changed

+31
-19
lines changed

src/util/color.js

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@ let ALPHA_SEP = /\s*[,/]\s*/
88
let CUSTOM_PROPERTY = /var\(--(?:[^ )]*?)\)/
99

1010
let RGB = new RegExp(
11-
`^rgba?\\(\\s*(${VALUE.source}|${CUSTOM_PROPERTY.source})${SEP.source}(${VALUE.source}|${CUSTOM_PROPERTY.source})${SEP.source}(${VALUE.source}|${CUSTOM_PROPERTY.source})(?:${ALPHA_SEP.source}(${VALUE.source}|${CUSTOM_PROPERTY.source}))?\\s*\\)$`
11+
`^(rgb)a?\\(\\s*(${VALUE.source}|${CUSTOM_PROPERTY.source})(?:${SEP.source}(${VALUE.source}|${CUSTOM_PROPERTY.source}))?(?:${SEP.source}(${VALUE.source}|${CUSTOM_PROPERTY.source}))?(?:${ALPHA_SEP.source}(${VALUE.source}|${CUSTOM_PROPERTY.source}))?\\s*\\)$`
1212
)
1313
let HSL = new RegExp(
14-
`^hsla?\\(\\s*((?:${VALUE.source})(?:deg|rad|grad|turn)?|${CUSTOM_PROPERTY.source})${SEP.source}(${VALUE.source}|${CUSTOM_PROPERTY.source})${SEP.source}(${VALUE.source}|${CUSTOM_PROPERTY.source})(?:${ALPHA_SEP.source}(${VALUE.source}|${CUSTOM_PROPERTY.source}))?\\s*\\)$`
14+
`^(hsl)a?\\(\\s*((?:${VALUE.source})(?:deg|rad|grad|turn)?|${CUSTOM_PROPERTY.source})(?:${SEP.source}(${VALUE.source}|${CUSTOM_PROPERTY.source}))?(?:${SEP.source}(${VALUE.source}|${CUSTOM_PROPERTY.source}))?(?:${ALPHA_SEP.source}(${VALUE.source}|${CUSTOM_PROPERTY.source}))?\\s*\\)$`
1515
)
1616

17-
export function parseColor(value) {
17+
// In "loose" mode the color may contain fewer than 3 parts, as long as at least
18+
// one of the parts is variable.
19+
export function parseColor(value, { loose = false } = {}) {
1820
if (typeof value !== 'string') {
1921
return null
2022
}
@@ -42,27 +44,27 @@ export function parseColor(value) {
4244
}
4345
}
4446

45-
let rgbMatch = value.match(RGB)
47+
let match = value.match(RGB) ?? value.match(HSL)
4648

47-
if (rgbMatch !== null) {
48-
return {
49-
mode: 'rgb',
50-
color: [rgbMatch[1], rgbMatch[2], rgbMatch[3]].map((v) => v.toString()),
51-
alpha: rgbMatch[4]?.toString?.(),
52-
}
49+
if (match === null) {
50+
return null
5351
}
5452

55-
let hslMatch = value.match(HSL)
53+
let color = [match[2], match[3], match[4]].filter(Boolean).map((v) => v.toString())
5654

57-
if (hslMatch !== null) {
58-
return {
59-
mode: 'hsl',
60-
color: [hslMatch[1], hslMatch[2], hslMatch[3]].map((v) => v.toString()),
61-
alpha: hslMatch[4]?.toString?.(),
62-
}
55+
if (!loose && color.length !== 3) {
56+
return null
6357
}
6458

65-
return null
59+
if (color.length < 3 && !color.some((part) => /^var\(.*?\)$/.test(part))) {
60+
return null
61+
}
62+
63+
return {
64+
mode: match[1],
65+
color,
66+
alpha: match[5]?.toString?.(),
67+
}
6668
}
6769

6870
export function formatColor({ mode, color, alpha }) {

src/util/dataTypes.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ export function color(value) {
121121
part = normalize(part)
122122

123123
if (part.startsWith('var(')) return true
124-
if (parseColor(part) !== null) return colors++, true
124+
if (parseColor(part, { loose: true }) !== null) return colors++, true
125125

126126
return false
127127
})

tests/arbitrary-values.test.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ it('should support arbitrary values for various background utilities', () => {
6868
<!-- By implicit type -->
6969
<div class="bg-[url('/image-1-0.png')]"></div>
7070
<div class="bg-[#ff0000]"></div>
71+
<div class="bg-[rgb(var(--bg-color))]"></div>
72+
<div class="bg-[hsl(var(--bg-color))]"></div>
7173
7274
<!-- By explicit type -->
7375
<div class="bg-[url:var(--image-url)]"></div>
@@ -89,6 +91,14 @@ it('should support arbitrary values for various background utilities', () => {
8991
background-color: rgb(255 0 0 / var(--tw-bg-opacity));
9092
}
9193
94+
.bg-\[rgb\(var\(--bg-color\)\)\] {
95+
background-color: rgb(var(--bg-color));
96+
}
97+
98+
.bg-\[hsl\(var\(--bg-color\)\)\] {
99+
background-color: hsl(var(--bg-color));
100+
}
101+
92102
.bg-\[color\:var\(--bg-color\)\] {
93103
background-color: var(--bg-color);
94104
}

0 commit comments

Comments
 (0)