@zag-js/color-utils
Version:
Color utilities for zag.js
214 lines (212 loc) • 7.48 kB
JavaScript
"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
});