UNPKG

@zag-js/color-utils

Version:

Color utilities for zag.js

214 lines (212 loc) • 7.48 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 = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); // src/rgb-color.ts var rgb_color_exports = {}; __export(rgb_color_exports, { RGBColor: () => RGBColor }); module.exports = __toCommonJS(rgb_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_hsl_color = require("./hsl-color.js"); var HEX_COLOR_REGEX = /^#[\da-f]+$/i; var RGB_COLOR_REGEX = /^rgba?\((.*)\)$/; var HEX_STARTING_REGEX = /[^#]/gi; var _RGBColor = class _RGBColor extends import_color.Color { constructor(red, green, blue, alpha) { super(); __publicField(this, "red", red); __publicField(this, "green", green); __publicField(this, "blue", blue); __publicField(this, "alpha", alpha); } static parse(value) { let colors = []; if (HEX_COLOR_REGEX.test(value) && [4, 5, 7, 9].includes(value.length)) { const values = (value.length < 6 ? value.replace(HEX_STARTING_REGEX, "$&$&") : value).slice(1).split(""); while (values.length > 0) { colors.push(parseInt(values.splice(0, 2).join(""), 16)); } colors[3] = colors[3] !== void 0 ? colors[3] / 255 : void 0; } const match = value.match(RGB_COLOR_REGEX); if (match?.[1]) { colors = match[1].split(",").map((value2) => Number(value2.trim())).map((num, i) => (0, import_utils.clampValue)(num, 0, i < 3 ? 255 : 1)); } return colors.length < 3 ? void 0 : new _RGBColor(colors[0], colors[1], colors[2], colors[3] ?? 1); } toString(format = "css") { switch (format) { case "hex": return "#" + (this.red.toString(16).padStart(2, "0") + this.green.toString(16).padStart(2, "0") + this.blue.toString(16).padStart(2, "0")).toUpperCase(); case "hexa": return "#" + (this.red.toString(16).padStart(2, "0") + this.green.toString(16).padStart(2, "0") + this.blue.toString(16).padStart(2, "0") + Math.round(this.alpha * 255).toString(16).padStart(2, "0")).toUpperCase(); case "rgb": return `rgb(${this.red}, ${this.green}, ${this.blue})`; case "css": case "rgba": return `rgba(${this.red}, ${this.green}, ${this.blue}, ${this.alpha})`; case "hsl": return this.toHSL().toString("hsl"); case "hsb": return this.toHSB().toString("hsb"); default: return this.toFormat(format).toString(format); } } toFormat(format) { switch (format) { case "rgba": return this; case "hsba": return this.toHSB(); case "hsla": return this.toHSL(); default: throw new Error("Unsupported color conversion: rgb -> " + format); } } toHexInt() { return this.red << 16 | this.green << 8 | this.blue; } /** * Converts an RGB color value to HSB. * Conversion formula adapted from https://en.wikipedia.org/wiki/HSL_and_HSV#From_RGB. * @returns An HSBColor object. */ toHSB() { const red = this.red / 255; const green = this.green / 255; const blue = this.blue / 255; const min = Math.min(red, green, blue); const brightness = Math.max(red, green, blue); const chroma = brightness - min; const saturation = brightness === 0 ? 0 : chroma / brightness; let hue = 0; if (chroma !== 0) { switch (brightness) { case red: hue = (green - blue) / chroma + (green < blue ? 6 : 0); break; case green: hue = (blue - red) / chroma + 2; break; case blue: hue = (red - green) / chroma + 4; break; } hue /= 6; } return new import_hsb_color.HSBColor( (0, import_utils.toFixedNumber)(hue * 360, 2), (0, import_utils.toFixedNumber)(saturation * 100, 2), (0, import_utils.toFixedNumber)(brightness * 100, 2), (0, import_utils.toFixedNumber)(this.alpha, 2) ); } /** * Converts an RGB color value to HSL. * Conversion formula adapted from https://en.wikipedia.org/wiki/HSL_and_HSV#From_RGB. * @returns An HSLColor object. */ toHSL() { const red = this.red / 255; const green = this.green / 255; const blue = this.blue / 255; const min = Math.min(red, green, blue); const max = Math.max(red, green, blue); const lightness = (max + min) / 2; const chroma = max - min; let hue = -1; let saturation = -1; if (chroma === 0) { hue = saturation = 0; } else { saturation = chroma / (lightness < 0.5 ? max + min : 2 - max - min); switch (max) { case red: hue = (green - blue) / chroma + (green < blue ? 6 : 0); break; case green: hue = (blue - red) / chroma + 2; break; case blue: hue = (red - green) / chroma + 4; break; } hue /= 6; } return new import_hsl_color.HSLColor( (0, import_utils.toFixedNumber)(hue * 360, 2), (0, import_utils.toFixedNumber)(saturation * 100, 2), (0, import_utils.toFixedNumber)(lightness * 100, 2), (0, import_utils.toFixedNumber)(this.alpha, 2) ); } clone() { return new _RGBColor(this.red, this.green, this.blue, this.alpha); } getChannelFormatOptions(channel) { switch (channel) { case "red": case "green": case "blue": return { style: "decimal" }; 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); return new Intl.NumberFormat(locale, options).format(value); } getChannelRange(channel) { switch (channel) { case "red": case "green": case "blue": return { minValue: 0, maxValue: 255, step: 1, pageSize: 17 }; case "alpha": return { minValue: 0, maxValue: 1, step: 0.01, pageSize: 0.1 }; default: throw new Error("Unknown color channel: " + channel); } } toJSON() { return { r: this.red, g: this.green, b: this.blue, a: this.alpha }; } getFormat() { return "rgba"; } getChannels() { return _RGBColor.colorChannels; } }; __publicField(_RGBColor, "colorChannels", ["red", "green", "blue"]); var RGBColor = _RGBColor; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { RGBColor });