mirror of
https://github.com/tailwindlabs/tailwindcss.git
synced 2025-12-08 21:36:08 +00:00
feat: transform hsl to hsla (#3850)
* feat: transform `hsl` to `hsla` * feat: update plugins using `toRgba` * Test `gradientColorStops` * Add test for `ringWidth` * Add percentage symbol after Saturation and Lightness
This commit is contained in:
parent
7c0e4bce4d
commit
4daf57e543
@ -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)
|
||||
|
||||
@ -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: {
|
||||
|
||||
@ -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))',
|
||||
})
|
||||
})
|
||||
|
||||
@ -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)`
|
||||
}
|
||||
|
||||
@ -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(
|
||||
{
|
||||
|
||||
@ -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 {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user