diff --git a/__tests__/plugins/gradientColorStops.test.js b/__tests__/plugins/gradientColorStops.test.js index 7017fc9e8077..2bc52204ba6d 100644 --- a/__tests__/plugins/gradientColorStops.test.js +++ b/__tests__/plugins/gradientColorStops.test.js @@ -17,6 +17,7 @@ test('opacity variables are given to colors defined as closures', () => { return `rgb(31,31,31)` }, + secondary: 'hsl(10, 50%, 50%)', }, opacity: { 50: '0.5', @@ -33,23 +34,47 @@ test('opacity variables are given to colors defined as closures', () => { .process('@tailwind utilities', { from: undefined }) .then((result) => { const expected = ` - .text-primary { - --tw-text-opacity: 1; - color: rgba(31,31,31,var(--tw-text-opacity)) - } - .text-opacity-50 { - --tw-text-opacity: 0.5 - } - .from-primary { - --tw-gradient-from: rgb(31,31,31); - --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to, rgba(31, 31, 31, 0)) - } - .via-primary { - --tw-gradient-stops: var(--tw-gradient-from), rgb(31,31,31), var(--tw-gradient-to, rgba(31, 31, 31, 0)) - } - .to-primary { - --tw-gradient-to: rgb(31,31,31) - } + .text-primary { + --tw-text-opacity: 1; + color: rgba(31, 31, 31, var(--tw-text-opacity)); + } + + .text-secondary { + --tw-text-opacity: 1; + color: hsla(10, 50%, 50%, var(--tw-text-opacity)); + } + + .text-opacity-50 { + --tw-text-opacity: 0.5; + } + + .from-primary { + --tw-gradient-from: rgb(31, 31, 31); + --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to, rgba(31, 31, 31, 0)); + } + + .from-secondary { + --tw-gradient-from: hsl(10, 50%, 50%); + --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to, hsla(10, 50%, 50%, 0)); + } + + .via-primary { + --tw-gradient-stops: var(--tw-gradient-from), rgb(31, 31, 31), + var(--tw-gradient-to, rgba(31, 31, 31, 0)); + } + + .via-secondary { + --tw-gradient-stops: var(--tw-gradient-from), hsl(10, 50%, 50%), + var(--tw-gradient-to, hsla(10, 50%, 50%, 0)); + } + + .to-primary { + --tw-gradient-to: rgb(31, 31, 31); + } + + .to-secondary { + --tw-gradient-to: hsl(10, 50%, 50%); + } ` expect(result.css).toMatchCss(expected) diff --git a/__tests__/plugins/ringWidth.test.js b/__tests__/plugins/ringWidth.test.js index 6f929229fbfb..2a167de3462e 100644 --- a/__tests__/plugins/ringWidth.test.js +++ b/__tests__/plugins/ringWidth.test.js @@ -61,6 +61,51 @@ test('ring widths', () => { ]) }) +test('ring widths with defaults and hsl value for ringColor', () => { + const config = { + theme: { + ringWidth: {}, + ringOffsetWidth: { + DEFAULT: '2px', + }, + ringOffsetColor: { + DEFAULT: 'pink', + }, + ringColor: { + DEFAULT: 'hsl(10, 50%, 50%)', + }, + }, + variants: { + ringColor: [], + }, + } + + const { utilities } = invokePlugin(plugin(), config) + expect(utilities).toEqual([ + [ + { + '*': { + '--tw-ring-color': 'hsla(10, 50%, 50%, 0.5)', + '--tw-ring-inset': 'var(--tw-empty,/*!*/ /*!*/)', + '--tw-ring-offset-color': 'pink', + '--tw-ring-offset-shadow': '0 0 #0000', + '--tw-ring-offset-width': '2px', + '--tw-ring-shadow': '0 0 #0000', + }, + }, + { respectImportant: false }, + ], + [ + { + '.ring-inset': { + '--tw-ring-inset': 'inset', + }, + }, + undefined, + ], + ]) +}) + test('ring widths with defaults', () => { const config = { theme: { diff --git a/__tests__/withAlphaVariable.test.js b/__tests__/withAlphaVariable.test.js index 6fdc939f181d..bf689ed6a7c5 100644 --- a/__tests__/withAlphaVariable.test.js +++ b/__tests__/withAlphaVariable.test.js @@ -118,3 +118,26 @@ test('it allows a closure to be passed', () => { 'background-color': 'rgba(0, 0, 0, var(--tw-bg-opacity))', }) }) + +test('it transforms rgb and hsl to rgba and hsla', () => { + expect( + withAlphaVariable({ + color: 'rgb(50, 50, 50)', + property: 'background-color', + variable: '--tw-bg-opacity', + }) + ).toEqual({ + '--tw-bg-opacity': '1', + 'background-color': 'rgba(50, 50, 50, var(--tw-bg-opacity))', + }) + expect( + withAlphaVariable({ + color: 'hsl(50, 50%, 50%)', + property: 'background-color', + variable: '--tw-bg-opacity', + }) + ).toEqual({ + '--tw-bg-opacity': '1', + 'background-color': 'hsla(50, 50%, 50%, var(--tw-bg-opacity))', + }) +}) diff --git a/src/plugins/gradientColorStops.js b/src/plugins/gradientColorStops.js index 800dcbe774f0..23a5f1709b4b 100644 --- a/src/plugins/gradientColorStops.js +++ b/src/plugins/gradientColorStops.js @@ -2,7 +2,7 @@ import _ from 'lodash' import flattenColorPalette from '../util/flattenColorPalette' import nameClass from '../util/nameClass' import toColorValue from '../util/toColorValue' -import { toRgba } from '../util/withAlphaVariable' +import { toRgba, toHsla } from '../util/withAlphaVariable' export default function () { return function ({ addUtilities, theme, variants }) { @@ -16,8 +16,9 @@ export default function () { } try { - const [r, g, b] = toRgba(value) - return `rgba(${r}, ${g}, ${b}, 0)` + const isHSL = value.startsWith('hsl') + const [i, j, k] = isHSL ? toHsla(value) : toRgba(value) + return `${isHSL ? 'hsla' : 'rgba'}(${i}, ${j}, ${k}, 0)` } catch (_error) { return `rgba(255, 255, 255, 0)` } diff --git a/src/plugins/ringWidth.js b/src/plugins/ringWidth.js index d2300620f0a8..bac8ed988be8 100644 --- a/src/plugins/ringWidth.js +++ b/src/plugins/ringWidth.js @@ -1,20 +1,21 @@ import _ from 'lodash' import nameClass from '../util/nameClass' -import { toRgba } from '../util/withAlphaVariable' +import { toHsla, toRgba } from '../util/withAlphaVariable' export default function () { return function ({ addUtilities, theme, variants }) { - function safeCall(callback, defaultValue) { + const ringColorDefault = (() => { + const isHSL = (theme('ringColor.DEFAULT') || '').startsWith('hsl') + const opacity = theme('ringOpacity.DEFAULT', '0.5') try { - return callback() + const [i, j, k] = isHSL + ? toHsla(theme('ringColor.DEFAULT')) + : toRgba(theme('ringColor.DEFAULT')) + return `${isHSL ? 'hsla' : 'rgba'}(${i}, ${j}, ${k}, ${opacity})` } catch (_error) { - return defaultValue + return `rgba(147, 197, 253, ${opacity})` } - } - - const ringColorDefault = (([r, g, b]) => { - return `rgba(${r}, ${g}, ${b}, ${theme('ringOpacity.DEFAULT', '0.5')})` - })(safeCall(() => toRgba(theme('ringColor.DEFAULT')), ['147', '197', '253'])) + })() addUtilities( { diff --git a/src/util/withAlphaVariable.js b/src/util/withAlphaVariable.js index d47dd275b0c0..73784bd41871 100644 --- a/src/util/withAlphaVariable.js +++ b/src/util/withAlphaVariable.js @@ -16,6 +16,12 @@ export function toRgba(color) { return [r, g, b, a === undefined && hasAlpha(color) ? 1 : a] } +export function toHsla(color) { + const [h, s, l, a] = createColor(color).hsl().array() + + return [h, `${s}%`, `${l}%`, a === undefined && hasAlpha(color) ? 1 : a] +} + export default function withAlphaVariable({ color, property, variable }) { if (_.isFunction(color)) { return { @@ -25,7 +31,9 @@ export default function withAlphaVariable({ color, property, variable }) { } try { - const [r, g, b, a] = toRgba(color) + const isHSL = color.startsWith('hsl') + + const [i, j, k, a] = isHSL ? toHsla(color) : toRgba(color) if (a !== undefined) { return { @@ -35,7 +43,7 @@ export default function withAlphaVariable({ color, property, variable }) { return { [variable]: '1', - [property]: `rgba(${r}, ${g}, ${b}, var(${variable}))`, + [property]: `${isHSL ? 'hsla' : 'rgba'}(${i}, ${j}, ${k}, var(${variable}))`, } } catch (error) { return {