Skip to content

Commit

Permalink
feat: transform hsl to hsla (#3850)
Browse files Browse the repository at this point in the history
* feat: transform `hsl` to `hsla`

* feat: update plugins using `toRgba`

* Test `gradientColorStops`

* Add test for `ringWidth`

* Add percentage symbol after Saturation and Lightness
  • Loading branch information
fedeci authored and adamwathan committed May 7, 2021
1 parent 7c0e4bc commit 4daf57e
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 31 deletions.
59 changes: 42 additions & 17 deletions __tests__/plugins/gradientColorStops.test.js
Expand Up @@ -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',
Expand All @@ -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)
Expand Down
45 changes: 45 additions & 0 deletions __tests__/plugins/ringWidth.test.js
Expand Up @@ -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: {
Expand Down
23 changes: 23 additions & 0 deletions __tests__/withAlphaVariable.test.js
Expand Up @@ -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))',
})
})
7 changes: 4 additions & 3 deletions src/plugins/gradientColorStops.js
Expand Up @@ -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 }) {
Expand All @@ -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)`
}
Expand Down
19 changes: 10 additions & 9 deletions 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(
{
Expand Down
12 changes: 10 additions & 2 deletions src/util/withAlphaVariable.js
Expand Up @@ -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 {
Expand All @@ -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 {
Expand All @@ -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 {
Expand Down

0 comments on commit 4daf57e

Please sign in to comment.