From c52cd713b0eeb4298e068532e8fe18cdbe3f06b3 Mon Sep 17 00:00:00 2001 From: Hunter Tunnicliff Date: Wed, 4 Aug 2021 20:31:04 -0700 Subject: [PATCH] Replace `color` with `culori` --- package-lock.json | 76 +++++------------------------------ package.json | 2 +- src/util/pluginUtils.js | 9 +---- src/util/withAlphaVariable.js | 72 ++++++++++++++++----------------- 4 files changed, 50 insertions(+), 109 deletions(-) diff --git a/package-lock.json b/package-lock.json index 30c8c7dcc..250eb6eae 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,8 +11,8 @@ "arg": "^5.0.1", "chalk": "^4.1.2", "chokidar": "^3.5.2", - "color": "^4.0.1", "cosmiconfig": "^7.0.1", + "culori": "^0.19.1", "detective": "^5.2.0", "didyoumean": "^1.2.2", "dlv": "^1.1.3", @@ -3434,15 +3434,6 @@ "node": ">=0.10.0" } }, - "node_modules/color": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/color/-/color-4.0.1.tgz", - "integrity": "sha512-rpZjOKN5O7naJxkH2Rx1sZzzBgaiWECc6BYXjeCE6kF0kcASJYbUq02u7JqIHwCb/j3NhV+QhRL2683aICeGZA==", - "dependencies": { - "color-convert": "^2.0.1", - "color-string": "^1.6.0" - } - }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -3459,15 +3450,6 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, - "node_modules/color-string": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.6.0.tgz", - "integrity": "sha512-c/hGS+kRWJutUBEngKKmk4iH3sD59MBkoxVapS/0wgpCz2u7XsNloxknyvBhzwEs1IbV36D9PwqLPJ2DTu3vMA==", - "dependencies": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } - }, "node_modules/colord": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/colord/-/colord-2.7.0.tgz", @@ -3828,6 +3810,11 @@ "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", "dev": true }, + "node_modules/culori": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/culori/-/culori-0.19.1.tgz", + "integrity": "sha512-K/NLpdtNnSQwH2Ru/Fk39wDL40v9PxTBFY6jHQegJDhmBqrE/d9mJB/AD4odSZJml10AlJjZdm6+I9JM3nE/EQ==" + }, "node_modules/data-urls": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", @@ -9121,19 +9108,6 @@ "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", "dev": true }, - "node_modules/simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", - "dependencies": { - "is-arrayish": "^0.3.1" - } - }, - "node_modules/simple-swizzle/node_modules/is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" - }, "node_modules/sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", @@ -12928,15 +12902,6 @@ "object-visit": "^1.0.0" } }, - "color": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/color/-/color-4.0.1.tgz", - "integrity": "sha512-rpZjOKN5O7naJxkH2Rx1sZzzBgaiWECc6BYXjeCE6kF0kcASJYbUq02u7JqIHwCb/j3NhV+QhRL2683aICeGZA==", - "requires": { - "color-convert": "^2.0.1", - "color-string": "^1.6.0" - } - }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -12950,15 +12915,6 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, - "color-string": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.6.0.tgz", - "integrity": "sha512-c/hGS+kRWJutUBEngKKmk4iH3sD59MBkoxVapS/0wgpCz2u7XsNloxknyvBhzwEs1IbV36D9PwqLPJ2DTu3vMA==", - "requires": { - "color-name": "^1.0.0", - "simple-swizzle": "^0.2.2" - } - }, "colord": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/colord/-/colord-2.7.0.tgz", @@ -13232,6 +13188,11 @@ } } }, + "culori": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/culori/-/culori-0.19.1.tgz", + "integrity": "sha512-K/NLpdtNnSQwH2Ru/Fk39wDL40v9PxTBFY6jHQegJDhmBqrE/d9mJB/AD4odSZJml10AlJjZdm6+I9JM3nE/EQ==" + }, "data-urls": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", @@ -17174,21 +17135,6 @@ "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", "dev": true }, - "simple-swizzle": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", - "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", - "requires": { - "is-arrayish": "^0.3.1" - }, - "dependencies": { - "is-arrayish": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", - "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" - } - } - }, "sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", diff --git a/package.json b/package.json index 18f75ee9d..d088ea811 100644 --- a/package.json +++ b/package.json @@ -70,8 +70,8 @@ "arg": "^5.0.1", "chalk": "^4.1.2", "chokidar": "^3.5.2", - "color": "^4.0.1", "cosmiconfig": "^7.0.1", + "culori": "^0.19.1", "detective": "^5.2.0", "didyoumean": "^1.2.2", "dlv": "^1.1.3", diff --git a/src/util/pluginUtils.js b/src/util/pluginUtils.js index 98cc2e082..056a455be 100644 --- a/src/util/pluginUtils.js +++ b/src/util/pluginUtils.js @@ -1,6 +1,6 @@ import selectorParser from 'postcss-selector-parser' import postcss from 'postcss' -import createColor from 'color' +import culori from 'culori' import escapeCommas from './escapeCommas' import { withAlphaValue } from './withAlphaVariable' import isKeyframeRule from './isKeyframeRule' @@ -222,12 +222,7 @@ function splitAlpha(modifier) { } function isColor(value) { - try { - createColor(value) - return true - } catch (e) { - return false - } + return culori.parse(value) !== undefined } export function asColor(modifier, lookup = {}, tailwindConfig = {}) { diff --git a/src/util/withAlphaVariable.js b/src/util/withAlphaVariable.js index 5080cf908..d27b6439f 100644 --- a/src/util/withAlphaVariable.js +++ b/src/util/withAlphaVariable.js @@ -1,25 +1,8 @@ -import createColor from 'color' +import culori from 'culori' import _ from 'lodash' -function hasAlpha(color) { - return ( - color.startsWith('rgba(') || - color.startsWith('hsla(') || - (color.startsWith('#') && color.length === 9) || - (color.startsWith('#') && color.length === 5) - ) -} - -export function toRgba(color) { - const [r, g, b, a] = createColor(color).rgb().array() - - 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] +function isValidColor(color) { + return culori.parse(color) !== undefined } export function withAlphaValue(color, alphaValue, defaultValue) { @@ -27,13 +10,22 @@ export function withAlphaValue(color, alphaValue, defaultValue) { return color({ opacityValue: alphaValue }) } - try { - const isHSL = color.startsWith('hsl') - const [i, j, k] = isHSL ? toHsla(color) : toRgba(color) - return `${isHSL ? 'hsla' : 'rgba'}(${i}, ${j}, ${k}, ${alphaValue})` - } catch { - return defaultValue + if (isValidColor(color)) { + // Parse color + const parsed = culori.parse(color) + + // Apply alpha value + parsed.alpha = alphaValue + + // Return formatted string + if (parsed.mode === 'hsl') { + return culori.formatHsl(parsed) + } else { + return culori.formatRgb(parsed) + } } + + return defaultValue } export default function withAlphaVariable({ color, property, variable }) { @@ -44,24 +36,32 @@ export default function withAlphaVariable({ color, property, variable }) { } } - try { - const isHSL = color.startsWith('hsl') + if (isValidColor(color)) { + const { alpha = 1, mode } = culori.parse(color) - const [i, j, k, a] = isHSL ? toHsla(color) : toRgba(color) - - if (a !== undefined) { + if (alpha !== 1) { + // Has an alpha value, return color as-is return { [property]: color, } } + let value + if (mode === 'hsl') { + const { h, s, l } = culori.hsl(color) + value = `hsla(${h}, ${s}, ${l}, var(${variable}))` + } else { + const { r, g, b } = culori.rgb(color) + value = `rgba(${r}, ${g}, ${b}, var(${variable}))` + } + return { [variable]: '1', - [property]: `${isHSL ? 'hsla' : 'rgba'}(${i}, ${j}, ${k}, var(${variable}))`, - } - } catch (error) { - return { - [property]: color, + [property]: value, } } + + return { + [property]: color, + } }