UNPKG

tiny-essentials

Version:

Collection of small, essential scripts designed to be used across various projects. These simple utilities are crafted for speed, ease of use, and versatility.

854 lines (853 loc) 31.5 kB
/** * Represents the allowed angle unit types for CSS color functions. * * - `deg` → Degrees (0–360). * - `grad` → Gradians (0–400). * - `rad` → Radians (0–2π). * - `turn` → Turns (0–1). * * @typedef {'deg' | 'grad' | 'rad' | 'turn'} AngleUnit */ /** * Represents the type of a CSS color. * * - `'hex'` → HEX color (`#RGB` / `#RRGGBB`) * - `'hexa'` → HEX with alpha (`#RRGGBBAA`) * - `'rgb'` → RGB color (`rgb(r, g, b)`) * - `'rgba'` → RGB with alpha (`rgba(r, g, b, a)`) * - `'hsl'` → HSL color (`hsl(h, s%, l%)`) * - `'hsla'` → HSL with alpha (`hsla(h, s%, l%, a)`) * - `'hwb'` → HWB color (`hwb(hue, whiteness%, blackness%)`) * - `'lab'` → CIELAB color (`lab(L a b)`) * - `'lch'` → LCH color (`lch(L C H)`) * - `'name'` → Standard HTML color name (e.g., `red`, `blue`) * - `'specialName'` → CSS special keywords (`transparent`, `currentColor`) * * @typedef {'hex'|'hexa'|'rgb'|'rgba'|'hsl'|'hsla'|'hwb'|'lab'|'lch'|'name'|'specialName'} ColorTypes */ /** * Utility class for validating and parsing CSS color values. * * Supports multiple CSS color syntaxes: * - **Hexadecimal**: `#RGB`, `#RRGGBB`, `#RRGGBBAA` * - **RGB/RGBA**: `rgb(r, g, b)`, `rgba(r, g, b, a)` * - **HSL/HSLA**: `hsl(h, s%, l%)`, `hsla(h, s%, l%, a)` * - **HWB**: `hwb(hue whiteness% blackness%)` * - **CIELAB**: `lab(L a b)` * - **LCH**: `lch(L C H)` * - **Named colors**: standard HTML color names (e.g., `red`, `blue`, `rebeccapurple`) * - **Special keywords**: `transparent`, `currentColor` * * Features: * - Provides validation (`isHex`, `isRgb`, `isHsl`, etc.) for each format. * - Provides parsing methods (`parseRgb`, `parseHsl`, etc.) returning numeric components. * - Allows extending and managing HTML color names and special keywords dynamically. * * Example: * ```js * const validator = new TinyColorValidator("rgb(255, 0, 0)"); * console.log(validator.isRgb()); // true * console.log(validator.parseRgb()); // [255, 0, 0] * ``` * * @class * @template {string} TinyColorValidatorT */ class TinyColorValidator { // Utility regex patterns static #HEX_REGEX = /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/; static #HEXA_REGEX = /^#([A-Fa-f0-9]{8})$/; // Alpha 0-1 static #ALPHA = `(0|1|0?\\.\\d+)`; // Matches integers from 0 to 255 static #NUM_0_255 = `(0|[1-9]\\d?|1\\d{2}|2[0-4]\\d|25[0-5])`; // Numbers 0-360 static #NUM_0_360 = `(0|[1-9]\\d?|[1-2]\\d{2}|3[0-5]\\d|360)`; // Numbers 0-100 static #NUM_0_100 = `(0|[1-9]?\\d|100)`; // RGB static #RGB_REGEX = new RegExp(`^rgb\\(\\s*${TinyColorValidator.#NUM_0_255}\\s*,\\s*${TinyColorValidator.#NUM_0_255}\\s*,\\s*${TinyColorValidator.#NUM_0_255}\\s*\\)$`); static #RGBA_REGEX = new RegExp(`^rgba\\(\\s*${TinyColorValidator.#NUM_0_255}\\s*,\\s*${TinyColorValidator.#NUM_0_255}\\s*,\\s*${TinyColorValidator.#NUM_0_255}\\s*,\\s*${TinyColorValidator.#ALPHA}\\s*\\)$`); // HSL static #HSL_REGEX = new RegExp(`^hsl\\(\\s*${TinyColorValidator.#NUM_0_360}\\s*,\\s*${TinyColorValidator.#NUM_0_100}%\\s*,\\s*${TinyColorValidator.#NUM_0_100}%\\s*\\)$`); static #HSLA_REGEX = new RegExp(`^hsla\\(\\s*${TinyColorValidator.#NUM_0_360}\\s*,\\s*${TinyColorValidator.#NUM_0_100}%\\s*,\\s*${TinyColorValidator.#NUM_0_100}%\\s*,\\s*${TinyColorValidator.#ALPHA}\\s*\\)$`); // HWB static #HWB_REGEX = new RegExp(`^hwb\\(\\s*${TinyColorValidator.#NUM_0_360}(deg|grad|rad|turn)?\\s*${TinyColorValidator.#NUM_0_100}%\\s*${TinyColorValidator.#NUM_0_100}%\\s*\\)$`); // LAB static #LAB_AB = `(-?\\d+)`; static #LAB_REGEX = new RegExp(`^lab\\(\\s*${TinyColorValidator.#NUM_0_100}%?\\s*${TinyColorValidator.#LAB_AB}%?\\s*${TinyColorValidator.#LAB_AB}%?\\s*\\)$`); // LCH static #LCH_REGEX = new RegExp(`^lch\\(\\s*${TinyColorValidator.#NUM_0_100}%?\\s*${TinyColorValidator.#NUM_0_100}%?\\s*${TinyColorValidator.#NUM_0_360}(deg|grad|rad|turn)?\\s*\\)$`); // CSS Level 4 color names static #HTML_COLOR_NAMES = new Set([ 'aliceblue', 'antiquewhite', 'aqua', 'aquamarine', 'azure', 'beige', 'bisque', 'black', 'blanchedalmond', 'blue', 'blueviolet', 'brown', 'burlywood', 'cadetblue', 'chartreuse', 'chocolate', 'coral', 'cornflowerblue', 'cornsilk', 'crimson', 'cyan', 'darkblue', 'darkcyan', 'darkgoldenrod', 'darkgray', 'darkgreen', 'darkgrey', 'darkkhaki', 'darkmagenta', 'darkolivegreen', 'darkorange', 'darkorchid', 'darkred', 'darksalmon', 'darkseagreen', 'darkslateblue', 'darkslategray', 'darkslategrey', 'darkturquoise', 'darkviolet', 'deeppink', 'deepskyblue', 'dimgray', 'dimgrey', 'dodgerblue', 'firebrick', 'floralwhite', 'forestgreen', 'fuchsia', 'gainsboro', 'ghostwhite', 'gold', 'goldenrod', 'gray', 'green', 'greenyellow', 'grey', 'honeydew', 'hotpink', 'indianred', 'indigo', 'ivory', 'khaki', 'lavender', 'lavenderblush', 'lawngreen', 'lemonchiffon', 'lightblue', 'lightcoral', 'lightcyan', 'lightgoldenrodyellow', 'lightgray', 'lightgreen', 'lightgrey', 'lightpink', 'lightsalmon', 'lightseagreen', 'lightskyblue', 'lightslategray', 'lightslategrey', 'lightsteelblue', 'lightyellow', 'lime', 'limegreen', 'linen', 'magenta', 'maroon', 'mediumaquamarine', 'mediumblue', 'mediumorchid', 'mediumpurple', 'mediumseagreen', 'mediumslateblue', 'mediumspringgreen', 'mediumturquoise', 'mediumvioletred', 'midnightblue', 'mintcream', 'mistyrose', 'moccasin', 'navajowhite', 'navy', 'oldlace', 'olive', 'olivedrab', 'orange', 'orangered', 'orchid', 'palegoldenrod', 'palegreen', 'paleturquoise', 'palevioletred', 'papayawhip', 'peachpuff', 'peru', 'pink', 'plum', 'powderblue', 'purple', 'rebeccapurple', 'red', 'rosybrown', 'royalblue', 'saddlebrown', 'salmon', 'sandybrown', 'seagreen', 'seashell', 'sienna', 'silver', 'skyblue', 'slateblue', 'slategray', 'slategrey', 'snow', 'springgreen', 'steelblue', 'tan', 'teal', 'thistle', 'tomato', 'turquoise', 'violet', 'wheat', 'white', 'whitesmoke', 'yellow', 'yellowgreen', ]); // CSS system special names static #SPECIAL_COLOR_NAMES = new Set(['transparent', 'currentColor']); // --- HTML Color Names --- /** * Returns all HTML color names as an array. * @returns {string[]} */ static getNames() { return Array.from(TinyColorValidator.#HTML_COLOR_NAMES); } /** * Adds a new HTML color name. * @param {string} name * @returns {boolean} True if added, false if it already existed. */ static addName(name) { const before = TinyColorValidator.#HTML_COLOR_NAMES.size; TinyColorValidator.#HTML_COLOR_NAMES.add(name.toLowerCase()); return TinyColorValidator.#HTML_COLOR_NAMES.size > before; } /** * Removes an HTML color name. * @param {string} name * @returns {boolean} True if removed, false if not found. */ static removeName(name) { return TinyColorValidator.#HTML_COLOR_NAMES.delete(name.toLowerCase()); } /** * Checks if an HTML color name exists. * @param {string} name * @returns {boolean} */ static hasName(name) { return TinyColorValidator.#HTML_COLOR_NAMES.has(name.toLowerCase()); } // --- Special Color Names --- /** * Returns all special color names as an array. * @returns {string[]} */ static getSpecialNames() { return Array.from(TinyColorValidator.#SPECIAL_COLOR_NAMES); } /** * Adds a new special color name. * @param {string} name * @returns {boolean} True if added, false if it already existed. */ static addSpecialName(name) { const before = TinyColorValidator.#SPECIAL_COLOR_NAMES.size; TinyColorValidator.#SPECIAL_COLOR_NAMES.add(name); return TinyColorValidator.#SPECIAL_COLOR_NAMES.size > before; } /** * Removes a special color name. * @param {string} name * @returns {boolean} True if removed, false if not found. */ static removeSpecialName(name) { return TinyColorValidator.#SPECIAL_COLOR_NAMES.delete(name); } /** * Checks if a special color name exists. * @param {string} name * @returns {boolean} */ static hasSpecialName(name) { return TinyColorValidator.#SPECIAL_COLOR_NAMES.has(name); } // Validators /** * Internal storage for the code value. * @type {string} */ #code; /** * Gets the current code. * @returns {string} The stored code. */ get code() { return this.#code; } /** * Internal storage for the code type. * @type {ColorTypes|null} */ #type; /** * Gets the current code. * @returns {ColorTypes|null} The stored code type. */ get type() { return this.#type; } /** * Creates a new instance of Example. * @param {TinyColorValidatorT} code - The code to be stored. */ constructor(code) { this.#code = code; this.#type = TinyColorValidator.isColor(this.#code); } /** * Validates if a string is a valid HEX color (#RGB, #RRGGBB). * @param {string} input - The input string to validate. * @returns {boolean} True if the input is a valid HEX color. * @throws {TypeError} If input is not a string. */ static isHex(input) { if (typeof input !== 'string') throw new TypeError('isHex: input must be a string.'); return TinyColorValidator.#HEX_REGEX.test(input.trim()); } /** * Validates if a string is a valid HEX color (#RGB, #RRGGBB). * @returns {boolean} True if the input is a valid HEX color. * @throws {TypeError} If input is not a string. */ isHex() { return TinyColorValidator.isHex(this.#code); } /** * Validates if a string is a valid HEX color (#RRGGBBAA). * @param {string} input - The input string to validate. * @returns {boolean} True if the input is a valid HEXA color. * @throws {TypeError} If input is not a string. */ static isHexa(input) { if (typeof input !== 'string') throw new TypeError('isHexa: input must be a string.'); return TinyColorValidator.#HEXA_REGEX.test(input.trim()); } /** * Validates if a string is a valid HEX color (#RRGGBBAA). * @returns {boolean} True if the input is a valid HEXA color. * @throws {TypeError} If input is not a string. */ isHexa() { return TinyColorValidator.isHexa(this.#code); } /** * Validates if a string is a valid RGB color. * @param {string} input - The input string to validate. * @returns {boolean} True if the input is a valid RGB color. * @throws {TypeError} If input is not a string. */ static isRgb(input) { if (typeof input !== 'string') throw new TypeError('isRgb: input must be a string.'); return TinyColorValidator.#RGB_REGEX.test(input.trim()); } /** * Validates if a string is a valid RGB color. * @returns {boolean} True if the input is a valid RGB color. * @throws {TypeError} If input is not a string. */ isRgb() { return TinyColorValidator.isRgb(this.#code); } /** * Validates if a string is a valid RGBA color. * @param {string} input - The input string to validate. * @returns {boolean} True if the input is a valid RGBA color. * @throws {TypeError} If input is not a string. */ static isRgba(input) { if (typeof input !== 'string') throw new TypeError('isRgba: input must be a string.'); return TinyColorValidator.#RGBA_REGEX.test(input.trim()); } /** * Validates if a string is a valid RGBA color. * @returns {boolean} True if the input is a valid RGBA color. * @throws {TypeError} If input is not a string. */ isRgba() { return TinyColorValidator.isRgba(this.#code); } /** * Validates if a string is a valid HSL color. * @param {string} input - The input string to validate. * @returns {boolean} True if the input is a valid HSL color. * @throws {TypeError} If input is not a string. */ static isHsl(input) { if (typeof input !== 'string') throw new TypeError('isHsl: input must be a string.'); return TinyColorValidator.#HSL_REGEX.test(input.trim()); } /** * Validates if a string is a valid HSL color. * @returns {boolean} True if the input is a valid HSL color. * @throws {TypeError} If input is not a string. */ isHsl() { return TinyColorValidator.isHsl(this.#code); } /** * Validates if a string is a valid HSLA color. * @param {string} input - The input string to validate. * @returns {boolean} True if the input is a valid HSLA color. * @throws {TypeError} If input is not a string. */ static isHsla(input) { if (typeof input !== 'string') throw new TypeError('isHsla: input must be a string.'); return TinyColorValidator.#HSLA_REGEX.test(input.trim()); } /** * Validates if a string is a valid HSLA color. * @returns {boolean} True if the input is a valid HSLA color. * @throws {TypeError} If input is not a string. */ isHsla() { return TinyColorValidator.isHsla(this.#code); } /** * Validates if a string is a valid HWB color. * @param {string} input - The input string to validate. * @returns {boolean} True if the input is a valid HWB color. * @throws {TypeError} If input is not a string. */ static isHwb(input) { if (typeof input !== 'string') throw new TypeError('isHwb: input must be a string.'); return TinyColorValidator.#HWB_REGEX.test(input.trim()); } /** * Validates if a string is a valid HWB color. * @returns {boolean} True if the input is a valid HWB color. * @throws {TypeError} If input is not a string. */ isHwb() { return TinyColorValidator.isHwb(this.#code); } /** * Validates if a string is a valid CIELAB color. * @param {string} input - The input string to validate. * @returns {boolean} True if the input is a valid Lab color. * @throws {TypeError} If input is not a string. */ static isLab(input) { if (typeof input !== 'string') throw new TypeError('isLab: input must be a string.'); return TinyColorValidator.#LAB_REGEX.test(input.trim()); } /** * Validates if a string is a valid CIELAB color. * @returns {boolean} True if the input is a valid Lab color. * @throws {TypeError} If input is not a string. */ isLab() { return TinyColorValidator.isLab(this.#code); } /** * Validates if a string is a valid LCH color. * @param {string} input - The input string to validate. * @returns {boolean} True if the input is a valid LCH color. * @throws {TypeError} If input is not a string. */ static isLch(input) { if (typeof input !== 'string') throw new TypeError('isLch: input must be a string.'); return TinyColorValidator.#LCH_REGEX.test(input.trim()); } /** * Validates if a string is a valid LCH color. * @returns {boolean} True if the input is a valid LCH color. * @throws {TypeError} If input is not a string. */ isLch() { return TinyColorValidator.isLch(this.#code); } /** * Validates if a string matches a standard HTML color name. * @param {string} input - The input string to validate. * @returns {boolean} True if the input is a valid HTML color name. * @throws {TypeError} If input is not a string. */ static isName(input) { if (typeof input !== 'string') throw new TypeError('isName: input must be a string.'); return TinyColorValidator.#HTML_COLOR_NAMES.has(input.trim().toLowerCase()); } /** * Validates if a string matches a standard HTML color name. * @returns {boolean} True if the input is a valid HTML color name. * @throws {TypeError} If input is not a string. */ isName() { return TinyColorValidator.isName(this.#code); } /** * Validates if a string matches a special CSS color keyword. * @param {string} input - The input string to validate. * @returns {boolean} True if the input is a special color keyword. * @throws {TypeError} If input is not a string. */ static isSpecialName(input) { if (typeof input !== 'string') throw new TypeError('isSpecialName: input must be a string.'); return TinyColorValidator.#SPECIAL_COLOR_NAMES.has(input.trim()); } /** * Validates if a string matches a special CSS color keyword. * @returns {boolean} True if the input is a special color keyword. * @throws {TypeError} If input is not a string. */ isSpecialName() { return TinyColorValidator.isSpecialName(this.#code); } /** * Validates if a string is any valid CSS color (HEX, RGB, HSL, HWB, Lab, LCH, name, or special name). * @param {string} input - The input string to validate. * @returns {ColorTypes|null} if the input is a valid CSS color. * @throws {TypeError} If input is not a string. */ static isColor(input) { if (typeof input !== 'string') throw new TypeError('isColor: input must be a string.'); if (TinyColorValidator.isHex(input)) return 'hex'; else if (TinyColorValidator.isHexa(input)) return 'hexa'; else if (TinyColorValidator.isRgb(input)) return 'rgb'; else if (TinyColorValidator.isRgba(input)) return 'rgba'; else if (TinyColorValidator.isHsl(input)) return 'hsl'; else if (TinyColorValidator.isHsla(input)) return 'hsla'; else if (TinyColorValidator.isHwb(input)) return 'hwb'; else if (TinyColorValidator.isLab(input)) return 'lab'; else if (TinyColorValidator.isLch(input)) return 'lch'; else if (TinyColorValidator.isName(input)) return 'name'; else if (TinyColorValidator.isSpecialName(input)) return 'specialName'; return null; } /** * Automatically parses the stored code based on its detected type. * @returns {any[]|string|null} Parsed color components according to type, or null if invalid. */ parse() { switch (this.#type) { case 'hex': return TinyColorValidator.parseHex(this.code); case 'hexa': return TinyColorValidator.parseHexa(this.code); case 'rgb': return TinyColorValidator.parseRgb(this.code); case 'rgba': return TinyColorValidator.parseRgba(this.code); case 'hsl': return TinyColorValidator.parseHsl(this.code); case 'hsla': return TinyColorValidator.parseHsla(this.code); case 'hwb': return TinyColorValidator.parseHwb(this.code); case 'lab': return TinyColorValidator.parseLab(this.code); case 'lch': return TinyColorValidator.parseLch(this.code); case 'name': case 'specialName': return this.#code.trim().toLowerCase(); default: return null; } } // --- HEX / HEXA --- /** * Parses a HEX color string (#RGB or #RRGGBB). * Returns the regex match array with captured groups or null if invalid. * @param {string} input - The input string to parse. * @returns {string|null} Regex match result with captured groups, or null if not valid. * @throws {TypeError} If input is not a string. */ static parseHex(input) { if (typeof input !== 'string') throw new TypeError('parseHex: input must be a string.'); const result = new RegExp(TinyColorValidator.#HEX_REGEX, 'gm').exec(input.trim()); if (!result) return null; return result[1]; } /** * Parses a HEX color string (#RGB or #RRGGBB). * Returns the regex match array with captured groups or null if invalid. * @returns {string|null} Regex match result with captured groups, or null if not valid. * @throws {TypeError} If input is not a string. */ parseHex() { return TinyColorValidator.parseHex(this.#code); } /** * Parses a HEXA color string (#RRGGBBAA). * Returns the regex match array with captured groups or null if invalid. * @param {string} input - The input string to parse. * @returns {string|null} Regex match result with captured groups, or null if not valid. * @throws {TypeError} If input is not a string. */ static parseHexa(input) { if (typeof input !== 'string') throw new TypeError('parseHexa: input must be a string.'); const result = new RegExp(TinyColorValidator.#HEXA_REGEX, 'gm').exec(input.trim()); if (!result) return null; return result[1]; } /** * Parses a HEXA color string (#RRGGBBAA). * Returns the regex match array with captured groups or null if invalid. * @returns {string|null} Regex match result with captured groups, or null if not valid. * @throws {TypeError} If input is not a string. */ parseHexa() { return TinyColorValidator.parseHexa(this.#code); } // --- RGB / RGBA --- /** * Parses an RGB color string (rgb(r, g, b)). * Returns the regex match array with captured groups for r, g, and b or null if invalid. * @param {string} input - The input string to parse. * @returns {[number, number, number]|null} Regex match result with groups [r, g, b], or null if not valid. * @throws {TypeError} If input is not a string. */ static parseRgb(input) { if (typeof input !== 'string') throw new TypeError('parseRgb: input must be a string.'); const result = new RegExp(TinyColorValidator.#RGB_REGEX, 'gm').exec(input.trim()); if (!result) return null; return [parseFloat(result[1]), parseFloat(result[2]), parseFloat(result[3])]; } /** * Parses an RGB color string (rgb(r, g, b)). * Returns the regex match array with captured groups for r, g, and b or null if invalid. * @returns {[number, number, number]|null} Regex match result with groups [r, g, b], or null if not valid. * @throws {TypeError} If input is not a string. */ parseRgb() { return TinyColorValidator.parseRgb(this.#code); } /** * Parses an RGBA color string (rgba(r, g, b, a)). * Returns the regex match array with captured groups for r, g, b, and a or null if invalid. * @param {string} input - The input string to parse. * @returns {[number, number, number, number]|null} Regex match result with groups [r, g, b, a], or null if not valid. * @throws {TypeError} If input is not a string. */ static parseRgba(input) { if (typeof input !== 'string') throw new TypeError('parseRgba: input must be a string.'); const result = new RegExp(TinyColorValidator.#RGBA_REGEX, 'gm').exec(input.trim()); if (!result) return null; return [ parseFloat(result[1]), parseFloat(result[2]), parseFloat(result[3]), parseFloat(result[4]), ]; } /** * Parses an RGBA color string (rgba(r, g, b, a)). * Returns the regex match array with captured groups for r, g, b, and a or null if invalid. * @returns {[number, number, number, number]|null} Regex match result with groups [r, g, b, a], or null if not valid. * @throws {TypeError} If input is not a string. */ parseRgba() { return TinyColorValidator.parseRgba(this.#code); } // --- HSL / HSLA --- /** * Parses an HSL color string (hsl(h, s%, l%)). * Returns the regex match array with captured groups for h, s, and l or null if invalid. * @param {string} input - The input string to parse. * @returns {[number, number, number]|null} Regex match result with groups [h, s, l], or null if not valid. * @throws {TypeError} If input is not a string. */ static parseHsl(input) { if (typeof input !== 'string') throw new TypeError('parseHsl: input must be a string.'); const result = new RegExp(TinyColorValidator.#HSL_REGEX, 'gm').exec(input.trim()); if (!result) return null; return [parseFloat(result[1]), parseFloat(result[2]), parseFloat(result[3])]; } /** * Parses an HSL color string (hsl(h, s%, l%)). * Returns the regex match array with captured groups for h, s, and l or null if invalid. * @returns {[number, number, number]|null} Regex match result with groups [h, s, l], or null if not valid. * @throws {TypeError} If input is not a string. */ parseHsl() { return TinyColorValidator.parseHsl(this.#code); } /** * Parses an HSLA color string (hsla(h, s%, l%, a)). * Returns the regex match array with captured groups for h, s, l, and a or null if invalid. * @param {string} input - The input string to parse. * @returns {[number, number, number, number]|null} Regex match result with groups [h, s, l, a], or null if not valid. * @throws {TypeError} If input is not a string. */ static parseHsla(input) { if (typeof input !== 'string') throw new TypeError('parseHsla: input must be a string.'); const result = new RegExp(TinyColorValidator.#HSLA_REGEX, 'gm').exec(input.trim()); if (!result) return null; return [ parseFloat(result[1]), parseFloat(result[2]), parseFloat(result[3]), parseFloat(result[4]), ]; } /** * Parses an HSLA color string (hsla(h, s%, l%, a)). * Returns the regex match array with captured groups for h, s, l, and a or null if invalid. * @returns {[number, number, number, number]|null} Regex match result with groups [h, s, l, a], or null if not valid. * @throws {TypeError} If input is not a string. */ parseHsla() { return TinyColorValidator.parseHsla(this.#code); } // --- HWB --- /** * Parses an HWB color string (hwb(hue, whiteness%, blackness%[, alpha])). * Returns the regex match array with captured groups or null if invalid. * @param {string} input - The input string to parse. * @returns {[number, AngleUnit|null, number, number]|null} Regex match result with captured groups, or null if not valid. * @throws {TypeError} If input is not a string. */ static parseHwb(input) { if (typeof input !== 'string') throw new TypeError('parseHwb: input must be a string.'); const result = new RegExp(TinyColorValidator.#HWB_REGEX, 'gm').exec(input.trim()); if (!result) return null; return [ parseFloat(result[1]), // @ts-ignore result[2] ?? null, parseFloat(result[3]), parseFloat(result[4]), ]; } /** * Parses an HWB color string (hwb(hue, whiteness%, blackness%[, alpha])). * Returns the regex match array with captured groups or null if invalid. * @returns {[number, AngleUnit|null, number, number]|null} Regex match result with captured groups, or null if not valid. * @throws {TypeError} If input is not a string. */ parseHwb() { return TinyColorValidator.parseHwb(this.#code); } // --- Lab --- /** * Parses a CIELAB color string (lab(L a b[/alpha])). * Returns the regex match array with captured groups or null if invalid. * @param {string} input - The input string to parse. * @returns {[number, number, number]|null} Regex match result with captured groups, or null if not valid. * @throws {TypeError} If input is not a string. */ static parseLab(input) { if (typeof input !== 'string') throw new TypeError('parseLab: input must be a string.'); const result = new RegExp(TinyColorValidator.#LAB_REGEX, 'gm').exec(input.trim()); if (!result) return null; return [parseFloat(result[1]), parseFloat(result[2]), parseFloat(result[3])]; } /** * Parses a CIELAB color string (lab(L a b[/alpha])). * Returns the regex match array with captured groups or null if invalid. * @returns {[number, number, number]|null} Regex match result with captured groups, or null if not valid. * @throws {TypeError} If input is not a string. */ parseLab() { return TinyColorValidator.parseLab(this.#code); } // --- LCH --- /** * Parses an LCH color string (lch(L C H[/alpha])). * Returns the regex match array with captured groups or null if invalid. * @param {string} input - The input string to parse. * @returns {[number, number, number, AngleUnit|null]|null} Regex match result with captured groups, or null if not valid. * @throws {TypeError} If input is not a string. */ static parseLch(input) { if (typeof input !== 'string') throw new TypeError('parseLch: input must be a string.'); const result = new RegExp(TinyColorValidator.#LCH_REGEX, 'gm').exec(input.trim()); if (!result) return null; return [ parseFloat(result[1]), parseFloat(result[2]), parseFloat(result[3]), // @ts-ignore result[4] ?? null, ]; } /** * Parses an LCH color string (lch(L C H[/alpha])). * Returns the regex match array with captured groups or null if invalid. * @returns {[number, number, number, AngleUnit|null]|null} Regex match result with captured groups, or null if not valid. * @throws {TypeError} If input is not a string. */ parseLch() { return TinyColorValidator.parseLch(this.#code); } } export default TinyColorValidator;