From 485d068b52ec6fa1c3e5b0d6db534a52330679ec Mon Sep 17 00:00:00 2001 From: Adam Wathan Date: Fri, 24 Dec 2021 13:11:40 -0500 Subject: [PATCH] Support HSL with hue units in arbitrary values --- src/util/color.js | 27 ++++++++++++++----- tests/arbitrary-values.test.css | 7 +++++ tests/arbitrary-values.test.html | 1 + tests/color.test.js | 46 +++++++++++++++++++++----------- 4 files changed, 59 insertions(+), 22 deletions(-) diff --git a/src/util/color.js b/src/util/color.js index b1d1a5565524..aa21d6685d7c 100644 --- a/src/util/color.js +++ b/src/util/color.js @@ -5,8 +5,11 @@ let SHORT_HEX = /^#([a-f\d])([a-f\d])([a-f\d])([a-f\d])?$/i let VALUE = `(?:\\d+|\\d*\\.\\d+)%?` let SEP = `(?:\\s*,\\s*|\\s+)` let ALPHA_SEP = `\\s*[,/]\\s*` -let RGB_HSL = new RegExp( - `^(rgb|hsl)a?\\(\\s*(${VALUE})${SEP}(${VALUE})${SEP}(${VALUE})(?:${ALPHA_SEP}(${VALUE}))?\\s*\\)$` +let RGB = new RegExp( + `^rgba?\\(\\s*(${VALUE})${SEP}(${VALUE})${SEP}(${VALUE})(?:${ALPHA_SEP}(${VALUE}))?\\s*\\)$` +) +let HSL = new RegExp( + `^hsla?\\(\\s*((?:${VALUE})(?:deg|rad|grad|turn)?)${SEP}(${VALUE})${SEP}(${VALUE})(?:${ALPHA_SEP}(${VALUE}))?\\s*\\)$` ) export function parseColor(value) { @@ -37,13 +40,23 @@ export function parseColor(value) { } } - let match = value.match(RGB_HSL) + let rgbMatch = value.match(RGB) + + if (rgbMatch !== null) { + return { + mode: 'rgb', + color: [rgbMatch[1], rgbMatch[2], rgbMatch[3]].map((v) => v.toString()), + alpha: rgbMatch[4]?.toString?.(), + } + } + + let hslMatch = value.match(HSL) - if (match !== null) { + if (hslMatch !== null) { return { - mode: match[1], - color: [match[2], match[3], match[4]].map((v) => v.toString()), - alpha: match[5]?.toString?.(), + mode: 'hsl', + color: [hslMatch[1], hslMatch[2], hslMatch[3]].map((v) => v.toString()), + alpha: hslMatch[4]?.toString?.(), } } diff --git a/tests/arbitrary-values.test.css b/tests/arbitrary-values.test.css index ffa4d3cf8a91..47a311ef86dd 100644 --- a/tests/arbitrary-values.test.css +++ b/tests/arbitrary-values.test.css @@ -603,6 +603,13 @@ .bg-\[hsla\(0\2c 100\%\2c 50\%\2c 0\.3\)\] { background-color: hsla(0, 100%, 50%, 0.3); } +.bg-\[hsl\(0rad\2c 100\%\2c 50\%\)\] { + --tw-bg-opacity: 1; + background-color: hsl(0rad 100% 50% / var(--tw-bg-opacity)); +} +.bg-\[hsla\(0turn\2c 100\%\2c 50\%\2c 0\.3\)\] { + background-color: hsla(0turn, 100%, 50%, 0.3); +} .bg-\[\#0f0_var\(--value\)\] { background-color: #0f0 var(--value); } diff --git a/tests/arbitrary-values.test.html b/tests/arbitrary-values.test.html index af75a3254c27..142240b14590 100644 --- a/tests/arbitrary-values.test.html +++ b/tests/arbitrary-values.test.html @@ -216,6 +216,7 @@
+
diff --git a/tests/color.test.js b/tests/color.test.js index be9edbac5e2e..a01b9d7e1d80 100644 --- a/tests/color.test.js +++ b/tests/color.test.js @@ -2,21 +2,37 @@ import { parseColor, formatColor } from '../src/util/color' describe('parseColor', () => { it.each` - color | output - ${'black'} | ${{ mode: 'rgb', color: ['0', '0', '0'], alpha: undefined }} - ${'#0088cc'} | ${{ mode: 'rgb', color: ['0', '136', '204'], alpha: undefined }} - ${'#08c'} | ${{ mode: 'rgb', color: ['0', '136', '204'], alpha: undefined }} - ${'#0088cc99'} | ${{ mode: 'rgb', color: ['0', '136', '204'], alpha: '0.6' }} - ${'#08c9'} | ${{ mode: 'rgb', color: ['0', '136', '204'], alpha: '0.6' }} - ${'rgb(0, 30, 60)'} | ${{ mode: 'rgb', color: ['0', '30', '60'], alpha: undefined }} - ${'rgba(0, 30, 60, 0.5)'} | ${{ mode: 'rgb', color: ['0', '30', '60'], alpha: '0.5' }} - ${'rgb(0 30 60)'} | ${{ mode: 'rgb', color: ['0', '30', '60'], alpha: undefined }} - ${'rgb(0 30 60 / 0.5)'} | ${{ mode: 'rgb', color: ['0', '30', '60'], alpha: '0.5' }} - ${'hsl(0, 30%, 60%)'} | ${{ mode: 'hsl', color: ['0', '30%', '60%'], alpha: undefined }} - ${'hsla(0, 30%, 60%, 0.5)'} | ${{ mode: 'hsl', color: ['0', '30%', '60%'], alpha: '0.5' }} - ${'hsl(0 30% 60%)'} | ${{ mode: 'hsl', color: ['0', '30%', '60%'], alpha: undefined }} - ${'hsl(0 30% 60% / 0.5)'} | ${{ mode: 'hsl', color: ['0', '30%', '60%'], alpha: '0.5' }} - ${'transparent'} | ${{ mode: 'rgb', color: ['0', '0', '0'], alpha: '0' }} + color | output + ${'black'} | ${{ mode: 'rgb', color: ['0', '0', '0'], alpha: undefined }} + ${'#0088cc'} | ${{ mode: 'rgb', color: ['0', '136', '204'], alpha: undefined }} + ${'#08c'} | ${{ mode: 'rgb', color: ['0', '136', '204'], alpha: undefined }} + ${'#0088cc99'} | ${{ mode: 'rgb', color: ['0', '136', '204'], alpha: '0.6' }} + ${'#08c9'} | ${{ mode: 'rgb', color: ['0', '136', '204'], alpha: '0.6' }} + ${'rgb(0, 30, 60)'} | ${{ mode: 'rgb', color: ['0', '30', '60'], alpha: undefined }} + ${'rgba(0, 30, 60, 0.5)'} | ${{ mode: 'rgb', color: ['0', '30', '60'], alpha: '0.5' }} + ${'rgb(0 30 60)'} | ${{ mode: 'rgb', color: ['0', '30', '60'], alpha: undefined }} + ${'rgb(0 30 60 / 0.5)'} | ${{ mode: 'rgb', color: ['0', '30', '60'], alpha: '0.5' }} + ${'hsl(0, 30%, 60%)'} | ${{ mode: 'hsl', color: ['0', '30%', '60%'], alpha: undefined }} + ${'hsl(0deg, 30%, 60%)'} | ${{ mode: 'hsl', color: ['0deg', '30%', '60%'], alpha: undefined }} + ${'hsl(0rad, 30%, 60%)'} | ${{ mode: 'hsl', color: ['0rad', '30%', '60%'], alpha: undefined }} + ${'hsl(0grad, 30%, 60%)'} | ${{ mode: 'hsl', color: ['0grad', '30%', '60%'], alpha: undefined }} + ${'hsl(0turn, 30%, 60%)'} | ${{ mode: 'hsl', color: ['0turn', '30%', '60%'], alpha: undefined }} + ${'hsla(0, 30%, 60%, 0.5)'} | ${{ mode: 'hsl', color: ['0', '30%', '60%'], alpha: '0.5' }} + ${'hsla(0deg, 30%, 60%, 0.5)'} | ${{ mode: 'hsl', color: ['0deg', '30%', '60%'], alpha: '0.5' }} + ${'hsla(0rad, 30%, 60%, 0.5)'} | ${{ mode: 'hsl', color: ['0rad', '30%', '60%'], alpha: '0.5' }} + ${'hsla(0grad, 30%, 60%, 0.5)'} | ${{ mode: 'hsl', color: ['0grad', '30%', '60%'], alpha: '0.5' }} + ${'hsla(0turn, 30%, 60%, 0.5)'} | ${{ mode: 'hsl', color: ['0turn', '30%', '60%'], alpha: '0.5' }} + ${'hsl(0 30% 60%)'} | ${{ mode: 'hsl', color: ['0', '30%', '60%'], alpha: undefined }} + ${'hsl(0deg 30% 60%)'} | ${{ mode: 'hsl', color: ['0deg', '30%', '60%'], alpha: undefined }} + ${'hsl(0rad 30% 60%)'} | ${{ mode: 'hsl', color: ['0rad', '30%', '60%'], alpha: undefined }} + ${'hsl(0grad 30% 60%)'} | ${{ mode: 'hsl', color: ['0grad', '30%', '60%'], alpha: undefined }} + ${'hsl(0turn 30% 60%)'} | ${{ mode: 'hsl', color: ['0turn', '30%', '60%'], alpha: undefined }} + ${'hsl(0 30% 60% / 0.5)'} | ${{ mode: 'hsl', color: ['0', '30%', '60%'], alpha: '0.5' }} + ${'hsl(0deg 30% 60% / 0.5)'} | ${{ mode: 'hsl', color: ['0deg', '30%', '60%'], alpha: '0.5' }} + ${'hsl(0rad 30% 60% / 0.5)'} | ${{ mode: 'hsl', color: ['0rad', '30%', '60%'], alpha: '0.5' }} + ${'hsl(0grad 30% 60% / 0.5)'} | ${{ mode: 'hsl', color: ['0grad', '30%', '60%'], alpha: '0.5' }} + ${'hsl(0turn 30% 60% / 0.5)'} | ${{ mode: 'hsl', color: ['0turn', '30%', '60%'], alpha: '0.5' }} + ${'transparent'} | ${{ mode: 'rgb', color: ['0', '0', '0'], alpha: '0' }} `('should parse "$color" to the correct value', ({ color, output }) => { expect(parseColor(color)).toEqual(output) })