diff --git a/README.md b/README.md
index c8d960d38..c5d18a663 100644
--- a/README.md
+++ b/README.md
@@ -110,6 +110,7 @@ Validator | Description
**isHash(str, algorithm)** | check if the string is a hash of type algorithm.
Algorithm is one of `['md4', 'md5', 'sha1', 'sha256', 'sha384', 'sha512', 'ripemd128', 'ripemd160', 'tiger128', 'tiger160', 'tiger192', 'crc32', 'crc32b']`
**isHexadecimal(str)** | check if the string is a hexadecimal number.
**isHexColor(str)** | check if the string is a hexadecimal color.
+**isHSL(str)** | check if the string is an HSL (hue, saturation, lightness, optional alpha) color based on [CSS Colors Level 4 specification](https://developer.mozilla.org/en-US/docs/Web/CSS/color_value).
Comma-separated format supported. Space-separated format supported with the exception of a few edge cases (ex: `hsl(200grad+.1%62%/1)`).
**isRgbColor(str, [, includePercentValues])** | check if the string is a rgb or rgba color.
`includePercentValues` defaults to `true`. If you don't want to allow to set `rgb` or `rgba` values with percents, like `rgb(5%,5%,5%)`, or `rgba(90%,90%,90%,.3)`, then set it to false.
**isIdentityCard(str [, locale])** | check if the string is a valid identity card code.
`locale` is one of `['ES', 'zh-TW', 'he-IL']` OR `'any'`. If 'any' is used, function will check if any of the locals match.
Defaults to 'any'.
**isIn(str, values)** | check if the string is in a array of allowed values.
@@ -187,8 +188,8 @@ In general, we follow the "fork-and-pull" Git workflow.
2. Clone the project to your own machine
3. Work on your fork
1. Make your changes and additions
- - Most of your changes should be focused on `src/` and `test/` folders and/or `README.md`.
- - Files such as `validator.js`, `validator.min.js` and files in `lib/` folder are autogenerated when running tests (`npm test`) and need not to be changed **manually**.
+ - Most of your changes should be focused on `src/` and `test/` folders and/or `README.md`.
+ - Files such as `validator.js`, `validator.min.js` and files in `lib/` folder are autogenerated when running tests (`npm test`) and need not to be changed **manually**.
2. Change or add tests if needed
3. Run tests and make sure they pass
4. Add changes to README.md if needed
diff --git a/src/index.js b/src/index.js
index 68645f78e..42549f1b4 100644
--- a/src/index.js
+++ b/src/index.js
@@ -41,6 +41,7 @@ import isDivisibleBy from './lib/isDivisibleBy';
import isHexColor from './lib/isHexColor';
import isRgbColor from './lib/isRgbColor';
+import isHSL from './lib/isHSL';
import isISRC from './lib/isISRC';
@@ -155,6 +156,7 @@ const validator = {
isDivisibleBy,
isHexColor,
isRgbColor,
+ isHSL,
isISRC,
isMD5,
isHash,
diff --git a/src/lib/isHSL.js b/src/lib/isHSL.js
new file mode 100644
index 000000000..b4f446334
--- /dev/null
+++ b/src/lib/isHSL.js
@@ -0,0 +1,10 @@
+import assertString from './util/assertString';
+
+
+const hslcomma = /^(hsl)a?\(\s*((\+|\-)?([0-9]+(\.[0-9]+)?(e(\+|\-)?[0-9]+)?|\.[0-9]+(e(\+|\-)?[0-9]+)?))(deg|grad|rad|turn|\s*)(\s*,\s*(\+|\-)?([0-9]+(\.[0-9]+)?(e(\+|\-)?[0-9]+)?|\.[0-9]+(e(\+|\-)?[0-9]+)?)%){2}\s*(,\s*((\+|\-)?([0-9]+(\.[0-9]+)?(e(\+|\-)?[0-9]+)?|\.[0-9]+(e(\+|\-)?[0-9]+)?)%?)\s*)?\)$/i;
+const hslspace = /^(hsl)a?\(\s*((\+|\-)?([0-9]+(\.[0-9]+)?(e(\+|\-)?[0-9]+)?|\.[0-9]+(e(\+|\-)?[0-9]+)?))(deg|grad|rad|turn|\s)(\s*(\+|\-)?([0-9]+(\.[0-9]+)?(e(\+|\-)?[0-9]+)?|\.[0-9]+(e(\+|\-)?[0-9]+)?)%){2}\s*(\/\s*((\+|\-)?([0-9]+(\.[0-9]+)?(e(\+|\-)?[0-9]+)?|\.[0-9]+(e(\+|\-)?[0-9]+)?)%?)\s*)?\)$/i;
+
+export default function isHSL(str) {
+ assertString(str);
+ return hslcomma.test(str) || hslspace.test(str);
+}
diff --git a/test/validators.js b/test/validators.js
index b5e413403..d87a1889e 100644
--- a/test/validators.js
+++ b/test/validators.js
@@ -3126,6 +3126,54 @@ describe('Validators', () => {
});
});
+ it('should validate HSL color strings', () => {
+ test({
+ validator: 'isHSL',
+ valid: [
+ 'hsl(360,0000000000100%,000000100%)',
+ 'hsl(000010, 00000000001%, 00000040%)',
+ 'HSL(00000,0000000000100%,000000100%)',
+ 'hsL(0, 0%, 0%)',
+ 'hSl( 360 , 100% , 100% )',
+ 'Hsl( 00150 , 000099% , 01% )',
+ 'hsl(01080, 03%, 4%)',
+ 'hsl(-540, 03%, 4%)',
+ 'hsla(+540, 03%, 4%)',
+ 'hsla(+540, 03%, 4%, 500)',
+ 'hsl(+540deg, 03%, 4%, 500)',
+ 'hsl(+540gRaD, 03%, 4%, 500)',
+ 'hsl(+540.01e-98rad, 03%, 4%, 500)',
+ 'hsl(-540.5turn, 03%, 4%, 500)',
+ 'hsl(+540, 03%, 4%, 500e-01)',
+ 'hsl(+540, 03%, 4%, 500e+80)',
+ 'hsl(4.71239rad, 60%, 70%)',
+ 'hsl(270deg, 60%, 70%)',
+ 'hsl(200, +.1%, 62%, 1)',
+ 'hsl(270 60% 70%)',
+ 'hsl(200, +.1e-9%, 62e10%, 1)',
+ 'hsl(.75turn, 60%, 70%)',
+ // 'hsl(200grad+.1%62%/1)', //supposed to pass, but need to handle delimiters
+ 'hsl(200grad +.1% 62% / 1)',
+ 'hsl(270, 60%, 50%, .15)',
+ 'hsl(270, 60%, 50%, 15%)',
+ 'hsl(270 60% 50% / .15)',
+ 'hsl(270 60% 50% / 15%)',
+ ],
+ invalid: [
+ 'hsl (360,0000000000100%,000000100%)',
+ 'hsl(0260, 100 %, 100%)',
+ 'hsl(0160, 100%, 100%, 100 %)',
+ 'hsl(-0160, 100%, 100a)',
+ 'hsl(-0160, 100%, 100)',
+ 'hsl(-0160 100%, 100%, )',
+ 'hsl(270 deg, 60%, 70%)',
+ 'hsl( deg, 60%, 70%)',
+ 'hsl(, 60%, 70%)',
+ 'hsl(3000deg, 70%)',
+ ],
+ });
+ });
+
it('should validate rgb color strings', () => {
test({
validator: 'isRgbColor',