UNPKG

@zag-js/color-utils

Version:

Color utilities for zag.js

168 lines (166 loc) • 6.32 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod2) => __copyProps(__defProp({}, "__esModule", { value: true }), mod2); var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); // src/hsl-color.ts var hsl_color_exports = {}; __export(hsl_color_exports, { HSLColor: () => HSLColor, HSL_REGEX: () => HSL_REGEX }); module.exports = __toCommonJS(hsl_color_exports); var import_utils = require("@zag-js/utils"); var import_color = require("./color.js"); var import_hsb_color = require("./hsb-color.js"); var import_rgb_color = require("./rgb-color.js"); var HSL_REGEX = /hsl\(([-+]?\d+(?:.\d+)?\s*,\s*[-+]?\d+(?:.\d+)?%\s*,\s*[-+]?\d+(?:.\d+)?%)\)|hsla\(([-+]?\d+(?:.\d+)?\s*,\s*[-+]?\d+(?:.\d+)?%\s*,\s*[-+]?\d+(?:.\d+)?%\s*,\s*[-+]?\d(.\d+)?)\)/; var _HSLColor = class _HSLColor extends import_color.Color { constructor(hue, saturation, lightness, alpha) { super(); __publicField(this, "hue", hue); __publicField(this, "saturation", saturation); __publicField(this, "lightness", lightness); __publicField(this, "alpha", alpha); } static parse(value) { let m; if (m = value.match(HSL_REGEX)) { const [h, s, l, a] = (m[1] ?? m[2]).split(",").map((n) => Number(n.trim().replace("%", ""))); return new _HSLColor((0, import_utils.mod)(h, 360), (0, import_utils.clampValue)(s, 0, 100), (0, import_utils.clampValue)(l, 0, 100), (0, import_utils.clampValue)(a ?? 1, 0, 1)); } } toString(format = "css") { switch (format) { case "hex": return this.toRGB().toString("hex"); case "hexa": return this.toRGB().toString("hexa"); case "hsl": return `hsl(${this.hue}, ${(0, import_utils.toFixedNumber)(this.saturation, 2)}%, ${(0, import_utils.toFixedNumber)(this.lightness, 2)}%)`; case "css": case "hsla": return `hsla(${this.hue}, ${(0, import_utils.toFixedNumber)(this.saturation, 2)}%, ${(0, import_utils.toFixedNumber)(this.lightness, 2)}%, ${this.alpha})`; case "hsb": return this.toHSB().toString("hsb"); case "rgb": return this.toRGB().toString("rgb"); default: return this.toFormat(format).toString(format); } } toFormat(format) { switch (format) { case "hsla": return this; case "hsba": return this.toHSB(); case "rgba": return this.toRGB(); default: throw new Error("Unsupported color conversion: hsl -> " + format); } } /** * Converts a HSL color to HSB. * Conversion formula adapted from https://en.wikipedia.org/wiki/HSL_and_HSV#HSL_to_HSV. * @returns An HSBColor object. */ toHSB() { let saturation = this.saturation / 100; let lightness = this.lightness / 100; let brightness = lightness + saturation * Math.min(lightness, 1 - lightness); saturation = brightness === 0 ? 0 : 2 * (1 - lightness / brightness); return new import_hsb_color.HSBColor( (0, import_utils.toFixedNumber)(this.hue, 2), (0, import_utils.toFixedNumber)(saturation * 100, 2), (0, import_utils.toFixedNumber)(brightness * 100, 2), (0, import_utils.toFixedNumber)(this.alpha, 2) ); } /** * Converts a HSL color to RGB. * Conversion formula adapted from https://en.wikipedia.org/wiki/HSL_and_HSV#HSL_to_RGB_alternative. * @returns An RGBColor object. */ toRGB() { let hue = this.hue; let saturation = this.saturation / 100; let lightness = this.lightness / 100; let a = saturation * Math.min(lightness, 1 - lightness); let fn = (n, k = (n + hue / 30) % 12) => lightness - a * Math.max(Math.min(k - 3, 9 - k, 1), -1); return new import_rgb_color.RGBColor( Math.round(fn(0) * 255), Math.round(fn(8) * 255), Math.round(fn(4) * 255), (0, import_utils.toFixedNumber)(this.alpha, 2) ); } clone() { return new _HSLColor(this.hue, this.saturation, this.lightness, this.alpha); } getChannelFormatOptions(channel) { switch (channel) { case "hue": return { style: "unit", unit: "degree", unitDisplay: "narrow" }; case "saturation": case "lightness": case "alpha": return { style: "percent" }; default: throw new Error("Unknown color channel: " + channel); } } formatChannelValue(channel, locale) { let options = this.getChannelFormatOptions(channel); let value = this.getChannelValue(channel); if (channel === "saturation" || channel === "lightness") { value /= 100; } return new Intl.NumberFormat(locale, options).format(value); } getChannelRange(channel) { switch (channel) { case "hue": return { minValue: 0, maxValue: 360, step: 1, pageSize: 15 }; case "saturation": case "lightness": return { minValue: 0, maxValue: 100, step: 1, pageSize: 10 }; case "alpha": return { minValue: 0, maxValue: 1, step: 0.01, pageSize: 0.1 }; default: throw new Error("Unknown color channel: " + channel); } } toJSON() { return { h: this.hue, s: this.saturation, l: this.lightness, a: this.alpha }; } getFormat() { return "hsla"; } getChannels() { return _HSLColor.colorChannels; } }; __publicField(_HSLColor, "colorChannels", ["hue", "saturation", "lightness"]); var HSLColor = _HSLColor; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { HSLColor, HSL_REGEX });