From aefb24d2b3a2dc77e4bf3bc4cb277bb186681778 Mon Sep 17 00:00:00 2001 From: Christian Varga Date: Wed, 6 Apr 2022 14:32:41 +1000 Subject: [PATCH 1/2] fix(parsetorgb): fix rgba/hsla alpha precision --- src/color/parseToRgb.js | 4 +- src/color/test/parseToHsl.test.js | 30 +++++++++++++++ src/color/test/parseToRgb.test.js | 62 +++++++++++++++++++++++++++++++ 3 files changed, 94 insertions(+), 2 deletions(-) diff --git a/src/color/parseToRgb.js b/src/color/parseToRgb.js index 802cac35..a7c91fa4 100644 --- a/src/color/parseToRgb.js +++ b/src/color/parseToRgb.js @@ -10,9 +10,9 @@ const hexRgbaRegex = /^#[a-fA-F0-9]{8}$/ const reducedHexRegex = /^#[a-fA-F0-9]{3}$/ const reducedRgbaHexRegex = /^#[a-fA-F0-9]{4}$/ const rgbRegex = /^rgb\(\s*(\d{1,3})\s*(?:,)?\s*(\d{1,3})\s*(?:,)?\s*(\d{1,3})\s*\)$/i -const rgbaRegex = /^rgb(?:a)?\(\s*(\d{1,3})\s*(?:,)?\s*(\d{1,3})\s*(?:,)?\s*(\d{1,3})\s*(?:,|\/)\s*([-+]?[0-9]*[.]?[0-9]?[0-9]?[%]?)\s*\)$/i +const rgbaRegex = /^rgb(?:a)?\(\s*(\d{1,3})\s*(?:,)?\s*(\d{1,3})\s*(?:,)?\s*(\d{1,3})\s*(?:,|\/)\s*([-+]?\d*[.]?\d+[%]?)\s*\)$/i const hslRegex = /^hsl\(\s*(\d{0,3}[.]?[0-9]+(?:deg)?)\s*(?:,)?\s*(\d{1,3}[.]?[0-9]?)%\s*(?:,)?\s*(\d{1,3}[.]?[0-9]?)%\s*\)$/i -const hslaRegex = /^hsl(?:a)?\(\s*(\d{0,3}[.]?[0-9]+(?:deg)?)\s*(?:,)?\s*(\d{1,3}[.]?[0-9]?)%\s*(?:,)?\s*(\d{1,3}[.]?[0-9]?)%\s*(?:,|\/)\s*([-+]?[0-9]*[.]?[0-9]?[0-9]?[%]?)\s*\)$/i +const hslaRegex = /^hsl(?:a)?\(\s*(\d{0,3}[.]?[0-9]+(?:deg)?)\s*(?:,)?\s*(\d{1,3}[.]?[0-9]?)%\s*(?:,)?\s*(\d{1,3}[.]?[0-9]?)%\s*(?:,|\/)\s*([-+]?\d*[.]?\d+[%]?)\s*\)$/i /** * Returns an RgbColor or RgbaColor object. This utility function is only useful diff --git a/src/color/test/parseToHsl.test.js b/src/color/test/parseToHsl.test.js index 4b51619a..c84c2c4a 100644 --- a/src/color/test/parseToHsl.test.js +++ b/src/color/test/parseToHsl.test.js @@ -56,6 +56,21 @@ describe('parseToHsl', () => { }) }) + it('should parse a rgba color representation with a precise alpha', () => { + expect(parseToHsl('rgba(174,67,255,.12345)')).toEqual({ + alpha: 0.12345, + hue: 274.1489361702128, + lightness: 0.6313725490196078, + saturation: 1, + }) + expect(parseToHsl('rgba(174,67,255,12.345%)')).toEqual({ + alpha: 0.12345, + hue: 274.1489361702128, + lightness: 0.6313725490196078, + saturation: 1, + }) + }) + it('should parse a rgb color representation', () => { expect(parseToHsl('rgb(174,67,255)')).toEqual({ hue: 274.1489361702128, @@ -163,6 +178,21 @@ describe('parseToHsl', () => { }) }) + it('should parse a hsla color representation with a precise alpha', () => { + expect(parseToHsl('hsla(210,10%,40%,.12345)')).toEqual({ + alpha: 0.12345, + hue: 209.99999999999997, + lightness: 0.4, + saturation: 0.09803921568627451, + }) + expect(parseToHsl('hsla(210,10%,40%,12.345%)')).toEqual({ + alpha: 0.12345, + hue: 209.99999999999997, + lightness: 0.4, + saturation: 0.09803921568627451, + }) + }) + it('should parse a hsla 4 space-separated color representation', () => { expect(parseToHsl('hsla(210 10% 40% / 0.75)')).toEqual({ alpha: 0.75, diff --git a/src/color/test/parseToRgb.test.js b/src/color/test/parseToRgb.test.js index 90a3723c..ac8421b4 100644 --- a/src/color/test/parseToRgb.test.js +++ b/src/color/test/parseToRgb.test.js @@ -56,6 +56,21 @@ describe('parseToRgb', () => { }) }) + it('should parse a rgba color representation with a precise alpha', () => { + expect(parseToRgb('rgba(174,67,255,.12345)')).toEqual({ + alpha: 0.12345, + blue: 255, + green: 67, + red: 174, + }) + expect(parseToRgb('rgba(174,67,255,12.345%)')).toEqual({ + alpha: 0.12345, + blue: 255, + green: 67, + red: 174, + }) + }) + it('should parse a rgb color representation', () => { expect(parseToRgb('rgb(174,67,255)')).toEqual({ blue: 255, @@ -137,6 +152,21 @@ describe('parseToRgb', () => { }) }) + it('should parse a hsla color representation with a precise alpha', () => { + expect(parseToRgb('hsla(210,10%,40%,.12345)')).toEqual({ + alpha: 0.12345, + blue: 112, + green: 102, + red: 92, + }) + expect(parseToRgb('hsla(210,10%,40%,12.345%)')).toEqual({ + alpha: 0.12345, + blue: 112, + green: 102, + red: 92, + }) + }) + it('should throw an error if an invalid color string is provided', () => { expect(() => { parseToRgb('(174,67,255)') @@ -153,6 +183,38 @@ describe('parseToRgb', () => { ) }) + it('should throw an error if an invalid rgba string is provided', () => { + const colors = [ + 'rgba(174,67,255,)', + 'rgba(174,67,255,%)', + 'rgba(174,67,255,.)', + 'rgba(174,67,255,1.)', + ] + colors.forEach(color => { + expect(() => { + parseToRgb(color) + }).toThrow( + "Couldn't parse the color string. Please provide the color as a string in hex, rgb, rgba, hsl or hsla notation.", + ) + }) + }) + + it('should throw an error if an invalid hsla string is provided', () => { + const colors = [ + 'hsla(210,10%,40%,)', + 'hsla(210,10%,40%,%)', + 'hsla(210,10%,40%,.)', + 'hsla(210,10%,40%,1.)', + ] + colors.forEach(color => { + expect(() => { + parseToRgb(color) + }).toThrow( + "Couldn't parse the color string. Please provide the color as a string in hex, rgb, rgba, hsl or hsla notation.", + ) + }) + }) + it('should throw an error if an invalid hsl string is provided', () => { expect(() => { parseToRgb('hsl(210,120%,4%)') From 880f5d230ebfb03a215c11bc03c16c27d1dfb6fb Mon Sep 17 00:00:00 2001 From: Christian Varga Date: Wed, 6 Apr 2022 14:40:49 +1000 Subject: [PATCH 2/2] docs(parsetorgb): update regexes --- docs/assets/polished.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/assets/polished.js b/docs/assets/polished.js index 7e740c54..a21b33ee 100644 --- a/docs/assets/polished.js +++ b/docs/assets/polished.js @@ -2296,10 +2296,10 @@ var hexRgbaRegex = /^#[a-fA-F0-9]{8}$/; var reducedHexRegex = /^#[a-fA-F0-9]{3}$/; var reducedRgbaHexRegex = /^#[a-fA-F0-9]{4}$/; - var rgbRegex = /^rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)$/i; - var rgbaRegex = /^rgba\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*([-+]?[0-9]*[.]?[0-9]+)\s*\)$/i; - var hslRegex = /^hsl\(\s*(\d{0,3}[.]?[0-9]+)\s*,\s*(\d{1,3}[.]?[0-9]?)%\s*,\s*(\d{1,3}[.]?[0-9]?)%\s*\)$/i; - var hslaRegex = /^hsla\(\s*(\d{0,3}[.]?[0-9]+)\s*,\s*(\d{1,3}[.]?[0-9]?)%\s*,\s*(\d{1,3}[.]?[0-9]?)%\s*,\s*([-+]?[0-9]*[.]?[0-9]+)\s*\)$/i; + var rgbRegex = /^rgb\(\s*(\d{1,3})\s*(?:,)?\s*(\d{1,3})\s*(?:,)?\s*(\d{1,3})\s*\)$/i; + var rgbaRegex = /^rgb(?:a)?\(\s*(\d{1,3})\s*(?:,)?\s*(\d{1,3})\s*(?:,)?\s*(\d{1,3})\s*(?:,|\/)\s*([-+]?\d*[.]?\d+[%]?)\s*\)$/i; + var hslRegex = /^hsl\(\s*(\d{0,3}[.]?[0-9]+(?:deg)?)\s*(?:,)?\s*(\d{1,3}[.]?[0-9]?)%\s*(?:,)?\s*(\d{1,3}[.]?[0-9]?)%\s*\)$/i; + var hslaRegex = /^hsl(?:a)?\(\s*(\d{0,3}[.]?[0-9]+(?:deg)?)\s*(?:,)?\s*(\d{1,3}[.]?[0-9]?)%\s*(?:,)?\s*(\d{1,3}[.]?[0-9]?)%\s*(?:,|\/)\s*([-+]?\d*[.]?\d+[%]?)\s*\)$/i; /** * Returns an RgbColor or RgbaColor object. This utility function is only useful * if want to extract a color component. With the color util `toColorString` you @@ -2373,7 +2373,7 @@ red: parseInt("" + rgbaMatched[1], 10), green: parseInt("" + rgbaMatched[2], 10), blue: parseInt("" + rgbaMatched[3], 10), - alpha: parseFloat("" + rgbaMatched[4]) + alpha: parseFloat("" + rgbaMatched[4]) > 1 ? parseFloat("" + rgbaMatched[4]) / 100 : parseFloat("" + rgbaMatched[4]) }; } @@ -2418,7 +2418,7 @@ red: parseInt("" + _hslRgbMatched[1], 10), green: parseInt("" + _hslRgbMatched[2], 10), blue: parseInt("" + _hslRgbMatched[3], 10), - alpha: parseFloat("" + hslaMatched[4]) + alpha: parseFloat("" + hslaMatched[4]) > 1 ? parseFloat("" + hslaMatched[4]) / 100 : parseFloat("" + hslaMatched[4]) }; }