primeng
Version:
PrimeNG is a premium UI library for Angular featuring a rich set of 90+ components, a theme designer, various theme alternatives such as Material, Bootstrap, Tailwind, premium templates and professional support. In addition, it integrates with PrimeBlock,
1,286 lines (1,280 loc) • 102 kB
JavaScript
export * from 'primeng/types/inputcolor';
import * as i0 from '@angular/core';
import { InjectionToken, inject, computed, ViewEncapsulation, ChangeDetectionStrategy, Component, input, booleanAttribute, effect, Directive, Injectable, forwardRef, signal, output, NgModule } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { SharedModule } from 'primeng/api';
import { BaseComponent, PARENT_INSTANCE } from 'primeng/basecomponent';
import * as i1 from 'primeng/bind';
import { Bind } from 'primeng/bind';
import { isPlatformBrowser, NgTemplateOutlet } from '@angular/common';
import { ButtonDirective, ButtonIcon } from 'primeng/button';
import * as i1$1 from 'primeng/inputtext';
import { InputText } from 'primeng/inputtext';
import { style } from '@primeuix/styles/inputcolor';
import { BaseStyle } from 'primeng/base';
function clamp(value, min, max) {
return Math.min(Math.max(value, min), max);
}
function round(value, decimals = 0) {
const factor = Math.pow(10, decimals);
return Math.round(value * factor) / factor;
}
function multiplyMatrices(matrix, vector) {
return [matrix[0] * vector[0] + matrix[1] * vector[1] + matrix[2] * vector[2], matrix[3] * vector[0] + matrix[4] * vector[1] + matrix[5] * vector[2], matrix[6] * vector[0] + matrix[7] * vector[1] + matrix[8] * vector[2]];
}
function mod(n, m) {
return ((n % m) + m) % m;
}
/**
* Snaps a value to the nearest step increment within min/max bounds.
* @example snap(23.7, 0, 100, 5) => 25
* @example snap(0.234, 0, 1, 0.01) => 0.23
*/
function snapValue(value, min, max, step) {
const clamped = clamp(value, min, max);
const offset = clamped - min;
const steps = Math.round(offset / step);
const snapped = min + steps * step;
const precision = (step.toString().split('.')[1] || '').length;
return parseFloat(snapped.toFixed(precision));
}
class Color {
get alpha() {
return this.getChannelValue('alpha');
}
getSpaceAxes(xyChannels) {
const { xChannel, yChannel } = xyChannels;
if (xChannel === yChannel) {
throw new Error('xChannel and yChannel cannot be the same');
}
const zChannel = this.getChannels().find((channel) => channel !== xChannel && channel !== yChannel);
if (!zChannel) {
throw new Error('zChannel not found');
}
return { xChannel, yChannel, zChannel: zChannel };
}
incChannelValue(channel, step) {
const range = this.getChannelRange(channel);
const currentValue = this.getChannelValue(channel);
const newValue = snapValue(clamp(currentValue + step, range.minValue, range.maxValue), range.minValue, range.maxValue, range.step);
return this.setChannelValue(channel, newValue);
}
decChannelValue(channel, step) {
return this.incChannelValue(channel, -step);
}
toHex() {
const rgb = this.toRGB();
const r = Math.round(rgb.red).toString(16).padStart(2, '0');
const g = Math.round(rgb.green).toString(16).padStart(2, '0');
const b = Math.round(rgb.blue).toString(16).padStart(2, '0');
return `#${r}${g}${b}`;
}
toHexa() {
const hex = this.toHex();
if (this.alpha < 1) {
const a = Math.round(this.alpha * 255)
.toString(16)
.padStart(2, '0');
return `${hex}${a}`;
}
return hex;
}
toHexInt() {
const rgb = this.toRGB();
return (Math.round(rgb.red) << 16) | (Math.round(rgb.green) << 8) | Math.round(rgb.blue);
}
toRgbString() {
const rgb = this.toRGB();
const r = Math.round(rgb.red);
const g = Math.round(rgb.green);
const b = Math.round(rgb.blue);
if (this.alpha < 1) {
return `rgba(${r}, ${g}, ${b}, ${round(this.alpha, 2)})`;
}
return `rgb(${r}, ${g}, ${b})`;
}
toHslString() {
const hsl = this.toHSL();
const h = Math.round(hsl.hue) % 360;
const s = Math.round(hsl.saturation);
const l = Math.round(hsl.lightness);
if (this.alpha < 1) {
return `hsla(${h}, ${s}%, ${l}%, ${round(this.alpha, 2)})`;
}
return `hsl(${h}, ${s}%, ${l}%)`;
}
toHsbString() {
const hsb = this.toHSB();
const h = Math.round(hsb.hue) % 360;
const s = Math.round(hsb.saturation);
const b = Math.round(hsb.brightness);
if (this.alpha < 1) {
return `hsba(${h}, ${s}%, ${b}%, ${round(this.alpha, 2)})`;
}
return `hsb(${h}, ${s}%, ${b}%)`;
}
toString(format) {
const f = format || this.colorSpace;
switch (f) {
case 'hex':
return this.toHex();
case 'hexa':
return this.toHexa();
case 'rgb':
case 'rgba':
return this.toRgbString();
case 'hsl':
case 'hsla':
return this.toHslString();
case 'hsb':
case 'hsba':
return this.toHsbString();
case 'oklch':
return this.toOKLCH().toString('oklch');
case 'oklcha':
return this.toOKLCH().toString('oklcha');
case 'css':
return this.toHex();
default:
return this.toHex();
}
}
toFormat(format) {
switch (format) {
case 'hsba':
return this.toHSB();
case 'hsla':
return this.toHSL();
case 'rgba':
return this.toRGB();
case 'hexa':
return this.toRGB();
case 'oklch':
return this.toOKLCH();
default:
return this.toHSB();
}
}
}
class HSBColor extends Color {
hue;
saturation;
brightness;
_alpha;
colorSpace = 'hsba';
constructor(hue, saturation, brightness, _alpha = 1) {
super();
this.hue = hue;
this.saturation = saturation;
this.brightness = brightness;
this._alpha = _alpha;
this.hue = hue >= 0 && hue <= 360 ? hue : mod(hue, 360);
this.saturation = clamp(saturation, 0, 100);
this.brightness = clamp(brightness, 0, 100);
this._alpha = clamp(_alpha, 0, 1);
}
getChannelValue(channel) {
switch (channel) {
case 'hue':
return this.hue;
case 'saturation':
return this.saturation;
case 'brightness':
return this.brightness;
case 'alpha':
return this._alpha;
case 'lightness':
return this.toHSL().getChannelValue(channel);
case 'L':
case 'C':
case 'H':
case 'oklchLightness':
case 'oklchChroma':
case 'oklchHue':
return this.toOKLCH().getChannelValue(channel);
default:
return this.toRGB().getChannelValue(channel);
}
}
setChannelValue(channel, value) {
switch (channel) {
case 'hue':
return new HSBColor(value, this.saturation, this.brightness, this._alpha);
case 'saturation':
return new HSBColor(this.hue, value, this.brightness, this._alpha);
case 'brightness':
return new HSBColor(this.hue, this.saturation, value, this._alpha);
case 'alpha':
return new HSBColor(this.hue, this.saturation, this.brightness, value);
case 'lightness': {
const hsl = this.toHSL().setChannelValue(channel, value);
return hsl.toHSB();
}
case 'L':
case 'C':
case 'H':
case 'oklchLightness':
case 'oklchChroma':
case 'oklchHue': {
const oklch = this.toOKLCH().setChannelValue(channel, value);
return oklch.toHSB();
}
default: {
const rgb = this.toRGB().setChannelValue(channel, value);
return rgb.toHSB();
}
}
}
toHSB() {
return this.clone();
}
toHSL() {
const h = this.hue;
const s = this.saturation / 100;
const b = this.brightness / 100;
const l = b * (1 - s / 2);
const sl = l === 0 || l === 1 ? 0 : ((b - l) / Math.min(l, 1 - l)) * 100;
return new HSLColor(h, sl, l * 100, this._alpha);
}
toRGB() {
const h = this.hue / 360;
const s = this.saturation / 100;
const b = this.brightness / 100;
let r, g, bl;
const i = Math.floor(h * 6);
const f = h * 6 - i;
const p = b * (1 - s);
const q = b * (1 - f * s);
const t = b * (1 - (1 - f) * s);
switch (i % 6) {
case 0:
r = b;
g = t;
bl = p;
break;
case 1:
r = q;
g = b;
bl = p;
break;
case 2:
r = p;
g = b;
bl = t;
break;
case 3:
r = p;
g = q;
bl = b;
break;
case 4:
r = t;
g = p;
bl = b;
break;
case 5:
r = b;
g = p;
bl = q;
break;
default:
r = 0;
g = 0;
bl = 0;
}
return new RGBColor(r * 255, g * 255, bl * 255, this._alpha);
}
toOKLCH() {
return this.toRGB().toOKLCH();
}
clone() {
return new HSBColor(this.hue, this.saturation, this.brightness, this._alpha);
}
toJSON() {
return {
hue: this.hue,
saturation: this.saturation,
brightness: this.brightness,
alpha: this._alpha
};
}
getFormat() {
return 'hsba';
}
getChannels() {
return ['hue', 'saturation', 'brightness'];
}
getChannelRange(channel) {
switch (channel) {
case 'hue':
return { minValue: 0, maxValue: 360, step: 1, pageStep: 15 };
case 'saturation':
case 'brightness':
return { minValue: 0, maxValue: 100, step: 1, pageStep: 10 };
case 'alpha':
return { minValue: 0, maxValue: 1, step: 0.01, pageStep: 0.1 };
case 'lightness':
return this.toHSL().getChannelRange(channel);
case 'L':
case 'C':
case 'H':
case 'oklchLightness':
case 'oklchChroma':
case 'oklchHue':
return this.toOKLCH().getChannelRange(channel);
case 'red':
case 'green':
case 'blue':
return this.toRGB().getChannelRange(channel);
default:
throw new Error(`Unknown color channel: ${channel}`);
}
}
}
class HSLColor extends Color {
hue;
saturation;
lightness;
_alpha;
colorSpace = 'hsla';
constructor(hue, saturation, lightness, _alpha = 1) {
super();
this.hue = hue;
this.saturation = saturation;
this.lightness = lightness;
this._alpha = _alpha;
this.hue = hue >= 0 && hue <= 360 ? hue : mod(hue, 360);
this.saturation = clamp(saturation, 0, 100);
this.lightness = clamp(lightness, 0, 100);
this._alpha = clamp(_alpha, 0, 1);
}
getChannelValue(channel) {
switch (channel) {
case 'hue':
return this.hue;
case 'saturation':
return this.saturation;
case 'lightness':
return this.lightness;
case 'alpha':
return this._alpha;
case 'brightness':
return this.toHSB().getChannelValue(channel);
case 'L':
case 'C':
case 'H':
case 'oklchLightness':
case 'oklchChroma':
case 'oklchHue':
return this.toOKLCH().getChannelValue(channel);
default:
return this.toRGB().getChannelValue(channel);
}
}
setChannelValue(channel, value) {
switch (channel) {
case 'hue':
return new HSLColor(value, this.saturation, this.lightness, this._alpha);
case 'saturation':
return new HSLColor(this.hue, value, this.lightness, this._alpha);
case 'lightness':
return new HSLColor(this.hue, this.saturation, value, this._alpha);
case 'alpha':
return new HSLColor(this.hue, this.saturation, this.lightness, value);
case 'brightness': {
const hsb = this.toHSB().setChannelValue(channel, value);
return hsb.toHSL();
}
case 'L':
case 'C':
case 'H':
case 'oklchLightness':
case 'oklchChroma':
case 'oklchHue': {
const oklch = this.toOKLCH().setChannelValue(channel, value);
return oklch.toHSL();
}
default: {
const rgb = this.toRGB().setChannelValue(channel, value);
return rgb.toHSL();
}
}
}
toHSB() {
const h = this.hue;
const s = this.saturation / 100;
const l = this.lightness / 100;
const b = l + s * Math.min(l, 1 - l);
const sb = b === 0 ? 0 : 2 * (1 - l / b);
return new HSBColor(h, sb * 100, b * 100, this._alpha);
}
toHSL() {
return this.clone();
}
toRGB() {
const h = this.hue;
const s = this.saturation / 100;
const l = this.lightness / 100;
const a = s * Math.min(l, 1 - l);
const f = (n) => {
const k = (n + h / 30) % 12;
return l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
};
return new RGBColor(f(0) * 255, f(8) * 255, f(4) * 255, this._alpha);
}
toOKLCH() {
return this.toRGB().toOKLCH();
}
clone() {
return new HSLColor(this.hue, this.saturation, this.lightness, this._alpha);
}
toJSON() {
return {
hue: this.hue,
saturation: this.saturation,
lightness: this.lightness,
alpha: this._alpha
};
}
getFormat() {
return 'hsla';
}
getChannels() {
return ['hue', 'saturation', 'lightness'];
}
getChannelRange(channel) {
switch (channel) {
case 'hue':
return { minValue: 0, maxValue: 360, step: 1, pageStep: 15 };
case 'saturation':
case 'lightness':
return { minValue: 0, maxValue: 100, step: 1, pageStep: 10 };
case 'alpha':
return { minValue: 0, maxValue: 1, step: 0.01, pageStep: 0.1 };
case 'brightness':
return this.toHSB().getChannelRange(channel);
case 'L':
case 'C':
case 'H':
case 'oklchLightness':
case 'oklchChroma':
case 'oklchHue':
return this.toOKLCH().getChannelRange(channel);
case 'red':
case 'green':
case 'blue':
return this.toRGB().getChannelRange(channel);
default:
throw new Error(`Unknown color channel: ${channel}`);
}
}
}
class RGBColor extends Color {
red;
green;
blue;
_alpha;
colorSpace = 'rgba';
constructor(red, green, blue, _alpha = 1) {
super();
this.red = red;
this.green = green;
this.blue = blue;
this._alpha = _alpha;
this.red = clamp(red, 0, 255);
this.green = clamp(green, 0, 255);
this.blue = clamp(blue, 0, 255);
this._alpha = clamp(_alpha, 0, 1);
}
getChannelValue(channel) {
switch (channel) {
case 'red':
return this.red;
case 'green':
return this.green;
case 'blue':
return this.blue;
case 'alpha':
return this._alpha;
case 'hue':
case 'saturation':
case 'brightness':
return this.toHSB().getChannelValue(channel);
case 'lightness':
return this.toHSL().getChannelValue(channel);
case 'L':
case 'C':
case 'H':
case 'oklchLightness':
case 'oklchChroma':
case 'oklchHue':
return this.toOKLCH().getChannelValue(channel);
default:
return this.toHSB().getChannelValue(channel);
}
}
setChannelValue(channel, value) {
switch (channel) {
case 'red':
return new RGBColor(value, this.green, this.blue, this._alpha);
case 'green':
return new RGBColor(this.red, value, this.blue, this._alpha);
case 'blue':
return new RGBColor(this.red, this.green, value, this._alpha);
case 'alpha':
return new RGBColor(this.red, this.green, this.blue, value);
case 'hue':
case 'saturation':
case 'brightness': {
const hsb = this.toHSB().setChannelValue(channel, value);
return hsb.toRGB();
}
case 'lightness': {
const hsl = this.toHSL().setChannelValue(channel, value);
return hsl.toRGB();
}
case 'L':
case 'C':
case 'H':
case 'oklchLightness':
case 'oklchChroma':
case 'oklchHue': {
const oklch = this.toOKLCH().setChannelValue(channel, value);
return oklch.toRGB();
}
default: {
const hsb = this.toHSB().setChannelValue(channel, value);
return hsb.toRGB();
}
}
}
toHSB() {
const r = this.red / 255;
const g = this.green / 255;
const b = this.blue / 255;
const max = Math.max(r, g, b);
const min = Math.min(r, g, b);
const d = max - min;
let h = 0;
const s = max === 0 ? 0 : d / max;
const v = max;
if (d !== 0) {
switch (max) {
case r:
h = ((g - b) / d + (g < b ? 6 : 0)) / 6;
break;
case g:
h = ((b - r) / d + 2) / 6;
break;
case b:
h = ((r - g) / d + 4) / 6;
break;
}
}
return new HSBColor(h * 360, s * 100, v * 100, this._alpha);
}
toHSL() {
const r = this.red / 255;
const g = this.green / 255;
const b = this.blue / 255;
const max = Math.max(r, g, b);
const min = Math.min(r, g, b);
const d = max - min;
const l = (max + min) / 2;
let h = 0;
let s = 0;
if (d !== 0) {
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch (max) {
case r:
h = ((g - b) / d + (g < b ? 6 : 0)) / 6;
break;
case g:
h = ((b - r) / d + 2) / 6;
break;
case b:
h = ((r - g) / d + 4) / 6;
break;
}
}
return new HSLColor(h * 360, s * 100, l * 100, this._alpha);
}
toRGB() {
return this.clone();
}
toOKLCH() {
const rgb = [this.red / 255, this.green / 255, this.blue / 255];
const rgbLinear = rgb.map((c) => (Math.abs(c) <= 0.04045 ? c / 12.92 : (c < 0 ? -1 : 1) * ((Math.abs(c) + 0.055) / 1.055) ** 2.4));
const xyz = multiplyMatrices([0.41239079926595934, 0.357584339383878, 0.1804807884018343, 0.21263900587151027, 0.715168678767756, 0.07219231536073371, 0.01933081871559182, 0.11919477979462598, 0.9505321522496607], rgbLinear);
const LMS = multiplyMatrices([0.819022437996703, 0.3619062600528904, -0.1288737815209879, 0.0329836539323885, 0.9292868615863434, 0.0361446663506424, 0.0481771893596242, 0.2642395317527308, 0.6335478284694309], xyz);
const LMSg = LMS.map((val) => Math.cbrt(val));
const [L, a, b] = multiplyMatrices([0.210454268309314, 0.7936177747023054, -0.0040720430116193, 1.9779985324311684, -2.4285922420485799, 0.450593709617411, 0.0259040424655478, 0.7827717124575296, -0.8086757549230774], LMSg);
const C = Math.sqrt(a ** 2 + b ** 2);
const H = Math.abs(a) < 0.0002 && Math.abs(b) < 0.0002 ? NaN : ((((Math.atan2(b, a) * 180) / Math.PI) % 360) + 360) % 360;
const outL = Number(Math.min(1, Math.max(0, L)).toFixed(4));
const outC = Number(C.toFixed(4));
const outH = Number.isNaN(H) ? NaN : Number(H.toFixed(2));
return new OKLCHColor(outL, outC, outH, Number(this._alpha.toFixed(2)));
}
clone() {
return new RGBColor(this.red, this.green, this.blue, this._alpha);
}
toJSON() {
return {
red: this.red,
green: this.green,
blue: this.blue,
alpha: this._alpha
};
}
getFormat() {
return 'rgba';
}
getChannels() {
return ['red', 'green', 'blue'];
}
getChannelRange(channel) {
switch (channel) {
case 'red':
case 'green':
case 'blue':
return { minValue: 0, maxValue: 255, step: 1, pageStep: 17 };
case 'alpha':
return { minValue: 0, maxValue: 1, step: 0.01, pageStep: 0.1 };
case 'hue':
case 'saturation':
case 'brightness':
return this.toHSB().getChannelRange(channel);
case 'lightness':
return this.toHSL().getChannelRange(channel);
case 'L':
case 'C':
case 'H':
case 'oklchLightness':
case 'oklchChroma':
case 'oklchHue':
return this.toOKLCH().getChannelRange(channel);
default:
throw new Error(`Unknown color channel: ${channel}`);
}
}
}
class OKLCHColor extends Color {
L;
C;
H;
_alpha;
colorSpace = 'oklch';
constructor(L, C, H, _alpha = 1) {
super();
this.L = L;
this.C = C;
this.H = H;
this._alpha = _alpha;
this.L = clamp(L, 0, 1);
this.C = clamp(C, 0, 0.4);
this.H = Number.isNaN(H) ? NaN : H >= 0 && H <= 360 ? H : mod(H, 360);
this._alpha = clamp(_alpha, 0, 1);
}
getChannelValue(channel) {
switch (channel) {
case 'L':
case 'oklchLightness':
return this.L;
case 'C':
case 'oklchChroma':
return this.C;
case 'H':
case 'oklchHue':
return this.H;
case 'alpha':
return this._alpha;
default:
return this.toRGB().getChannelValue(channel);
}
}
setChannelValue(channel, value) {
switch (channel) {
case 'L':
case 'oklchLightness':
return new OKLCHColor(value, this.C, this.H, this._alpha);
case 'C':
case 'oklchChroma':
return new OKLCHColor(this.L, value, this.H, this._alpha);
case 'H':
case 'oklchHue':
return new OKLCHColor(this.L, this.C, value, this._alpha);
case 'alpha':
return new OKLCHColor(this.L, this.C, this.H, value);
default: {
const rgb = this.toRGB().setChannelValue(channel, value);
return rgb.toOKLCH();
}
}
}
toHSB() {
return this.toRGB().toHSB();
}
toHSL() {
return this.toRGB().toHSL();
}
toRGB() {
const hRad = (this.H * Math.PI) / 180;
const a = Number.isNaN(this.H) ? 0 : this.C * Math.cos(hRad);
const b = Number.isNaN(this.H) ? 0 : this.C * Math.sin(hRad);
const l_ = this.L + 0.3963377774 * a + 0.2158037573 * b;
const m_ = this.L - 0.1055613458 * a - 0.0638541728 * b;
const s_ = this.L - 0.0894841775 * a - 1.291485548 * b;
const l = l_ * l_ * l_;
const m = m_ * m_ * m_;
const s = s_ * s_ * s_;
const lr = 4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s;
const lg = -1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s;
const lb = -0.0041960863 * l - 0.7034186147 * m + 1.707614701 * s;
const toSrgb = (c) => {
if (c <= 0.0031308)
return c * 12.92;
return 1.055 * Math.pow(c, 1 / 2.4) - 0.055;
};
return new RGBColor(clamp(toSrgb(lr) * 255, 0, 255), clamp(toSrgb(lg) * 255, 0, 255), clamp(toSrgb(lb) * 255, 0, 255), this._alpha);
}
toOKLCH() {
return this.clone();
}
toString(format) {
const f = format || this.colorSpace;
switch (f) {
case 'oklch': {
const l = Number.isNaN(this.L) ? 0 : Number((this.L * 100).toFixed(2));
const c = Number.isNaN(this.C) ? 0 : Number(this.C.toFixed(4));
const h = Number.isNaN(this.H) ? 0 : Number(this.H.toFixed(2));
return `oklch(${l}% ${c} ${h})`;
}
case 'oklcha':
case 'css': {
const l = Number.isNaN(this.L) ? 0 : Number((this.L * 100).toFixed(2));
const c = Number.isNaN(this.C) ? 0 : Number(this.C.toFixed(4));
const h = Number.isNaN(this.H) ? 0 : Number(this.H.toFixed(2));
const a = Number.isNaN(this._alpha) ? 1 : Number(this._alpha.toFixed(2));
return `oklch(${l}% ${c} ${h} / ${a})`;
}
default:
return super.toString(f);
}
}
clone() {
return new OKLCHColor(this.L, this.C, this.H, this._alpha);
}
toJSON() {
return {
L: this.L,
C: this.C,
H: this.H,
alpha: this._alpha
};
}
getFormat() {
return 'oklch';
}
getChannels() {
return ['L', 'C', 'H'];
}
getChannelRange(channel) {
switch (channel) {
case 'L':
case 'oklchLightness':
return { minValue: 0, maxValue: 1, step: 0.01, pageStep: 0.1 };
case 'C':
case 'oklchChroma':
return { minValue: 0, maxValue: 0.4, step: 0.01, pageStep: 0.05 };
case 'H':
case 'oklchHue':
return { minValue: 0, maxValue: 360, step: 1, pageStep: 15 };
case 'alpha':
return { minValue: 0, maxValue: 1, step: 0.01, pageStep: 0.1 };
case 'hue':
case 'saturation':
case 'brightness':
return this.toHSB().getChannelRange(channel);
case 'lightness':
return this.toHSL().getChannelRange(channel);
case 'red':
case 'green':
case 'blue':
return this.toRGB().getChannelRange(channel);
default:
throw new Error(`Unknown color channel: ${channel}`);
}
}
}
function parseColor(value) {
if (!value)
return null;
if (value instanceof Color) {
return value;
}
if (typeof value !== 'string')
return null;
const str = value.trim();
const hexMatch = str.match(/^#?([0-9a-f]{3,8})$/i);
if (hexMatch) {
let hex = hexMatch[1];
if (hex.length === 3) {
hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
}
else if (hex.length === 4) {
hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2] + hex[3] + hex[3];
}
if (hex.length === 6) {
const r = parseInt(hex.substring(0, 2), 16);
const g = parseInt(hex.substring(2, 4), 16);
const b = parseInt(hex.substring(4, 6), 16);
return new RGBColor(r, g, b, 1);
}
if (hex.length === 8) {
const r = parseInt(hex.substring(0, 2), 16);
const g = parseInt(hex.substring(2, 4), 16);
const b = parseInt(hex.substring(4, 6), 16);
const a = parseInt(hex.substring(6, 8), 16) / 255;
return new RGBColor(r, g, b, a);
}
}
const rgbMatch = str.match(/^rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*([\d.]+))?\s*\)$/i);
if (rgbMatch) {
return new RGBColor(parseInt(rgbMatch[1]), parseInt(rgbMatch[2]), parseInt(rgbMatch[3]), rgbMatch[4] !== undefined ? parseFloat(rgbMatch[4]) : 1);
}
const hslMatch = str.match(/^hsla?\(\s*([\d.]+)\s*,\s*([\d.]+)%?\s*,\s*([\d.]+)%?\s*(?:,\s*([\d.]+))?\s*\)$/i);
if (hslMatch) {
return new HSLColor(parseFloat(hslMatch[1]), parseFloat(hslMatch[2]), parseFloat(hslMatch[3]), hslMatch[4] !== undefined ? parseFloat(hslMatch[4]) : 1);
}
const hsbMatch = str.match(/^hsba?\(\s*([\d.]+)\s*,\s*([\d.]+)%?\s*,\s*([\d.]+)%?\s*(?:,\s*([\d.]+))?\s*\)$/i);
if (hsbMatch) {
return new HSBColor(parseFloat(hsbMatch[1]), parseFloat(hsbMatch[2]), parseFloat(hsbMatch[3]), hsbMatch[4] !== undefined ? parseFloat(hsbMatch[4]) : 1);
}
const oklchMatch = str.match(/^oklch\(\s*([\d.]+)(%?)\s+([\d.]+)\s+([\d.]+)\s*(?:\/\s*([\d.]+))?\s*\)$/i);
if (oklchMatch) {
const lVal = parseFloat(oklchMatch[1]);
const l = oklchMatch[2] === '%' ? lVal / 100 : lVal;
return new OKLCHColor(l, parseFloat(oklchMatch[3]), parseFloat(oklchMatch[4]), oklchMatch[5] !== undefined ? parseFloat(oklchMatch[5]) : 1);
}
return null;
}
function getChannelRange(channel) {
switch (channel) {
case 'hue':
return { minValue: 0, maxValue: 360, step: 1, pageStep: 15 };
case 'H':
case 'oklchHue':
return { minValue: 0, maxValue: 360, step: 1, pageStep: 15 };
case 'saturation':
case 'brightness':
case 'lightness':
return { minValue: 0, maxValue: 100, step: 1, pageStep: 10 };
case 'red':
case 'green':
case 'blue':
return { minValue: 0, maxValue: 255, step: 1, pageStep: 17 };
case 'alpha':
return { minValue: 0, maxValue: 1, step: 0.01, pageStep: 0.1 };
case 'L':
case 'oklchLightness':
return { minValue: 0, maxValue: 1, step: 0.01, pageStep: 0.1 };
case 'C':
case 'oklchChroma':
return { minValue: 0, maxValue: 0.4, step: 0.01, pageStep: 0.05 };
default:
return { minValue: 0, maxValue: 100, step: 1, pageStep: 10 };
}
}
function getInputChannelRange(channel) {
if (channel === 'hex') {
return { minValue: 0, maxValue: 0xffffff, step: 1, pageStep: 1 };
}
return getChannelRange(channel);
}
function getChannelGradient(color, channel, orientation = 'horizontal') {
const range = getChannelRange(channel);
const direction = orientation === 'horizontal' ? 'right' : 'top';
switch (channel) {
case 'hue':
case 'H':
case 'oklchHue':
return `linear-gradient(to ${direction}, rgb(255, 0, 0) 0%, rgb(255, 255, 0) 17%, rgb(0, 255, 0) 33%, rgb(0, 255, 255) 50%, rgb(0, 0, 255) 67%, rgb(255, 0, 255) 83%, rgb(255, 0, 0) 100%)`;
case 'lightness':
case 'L':
case 'oklchLightness': {
const start = color.setChannelValue(channel, range.minValue).toRgbString();
const middle = color.setChannelValue(channel, (range.maxValue - range.minValue) / 2).toRgbString();
const end = color.setChannelValue(channel, range.maxValue).toRgbString();
return `linear-gradient(to ${direction}, ${start}, ${middle}, ${end})`;
}
case 'alpha': {
const start = color.setChannelValue('alpha', range.minValue).toRgbString();
const end = color.setChannelValue('alpha', range.maxValue).toRgbString();
return `linear-gradient(to ${direction}, ${start}, ${end})`;
}
default: {
const start = color.setChannelValue(channel, range.minValue).toRgbString();
const end = color.setChannelValue(channel, range.maxValue).toRgbString();
return `linear-gradient(to ${direction}, ${start}, ${end})`;
}
}
}
const channelGenerators = {
hue: (color) => [0, 60, 120, 180, 240, 300, 360].map((h) => color.setChannelValue('hue', h).toRgbString()).join(', '),
saturation: (color) => `${color.setChannelValue('saturation', 0).toRgbString()}, transparent`,
lightness: () => 'black, transparent, white',
brightness: () => 'black, transparent'
};
function getAreaGradient(color, xChannel, yChannel, format) {
const axes3d = getDefault3DAxes(format);
const zChannel = axes3d.zChannel;
const zValue = color.getChannelValue(zChannel);
const isHSL = format === 'hsla';
let base;
if (isHSL) {
base = parseColor('hsl(0, 100%, 50%)').setChannelValue(zChannel, zValue);
}
else {
base = parseColor('hsb(0, 100%, 100%)').setChannelValue(zChannel, zValue);
}
const channels = [xChannel, yChannel];
const direction = (c) => (c === xChannel ? 'right' : 'top');
const layers = channels
.map((c) => {
const gen = channelGenerators[c];
if (!gen)
return null;
return `linear-gradient(to ${direction(c)}, ${gen(base)})`;
})
.filter(Boolean)
.reverse();
const isHueZ = zChannel === 'hue' || zChannel === 'H' || zChannel === 'oklchHue';
if (isHueZ) {
layers.push(base.toRgbString());
}
return layers.join(', ');
}
function getChannelColor(color, channel) {
switch (channel) {
case 'hue':
return parseColor(`hsl(${color.getChannelValue('hue')}, 100%, 50%)`);
case 'red':
case 'green':
case 'blue':
case 'lightness':
case 'brightness':
case 'saturation':
return color.setChannelValue('alpha', 1);
case 'alpha':
return color;
default:
return color.setChannelValue('alpha', 1);
}
}
function toCssString(color, format) {
const a = round(color.alpha, 2);
switch (format) {
case 'rgba':
case 'hexa': {
const rgb = color.toRGB();
return `rgba(${Math.round(rgb.red)}, ${Math.round(rgb.green)}, ${Math.round(rgb.blue)}, ${a})`;
}
case 'hsla': {
const hsl = color.toHSL();
return `hsla(${Math.round(hsl.hue) % 360}, ${hsl.saturation.toFixed(2)}%, ${hsl.lightness.toFixed(2)}%, ${a})`;
}
case 'hsba': {
// CSS doesn't support hsb, convert to hsl
const hsl = color.toHSL();
return `hsla(${Math.round(hsl.hue) % 360}, ${hsl.saturation.toFixed(2)}%, ${hsl.lightness.toFixed(2)}%, ${a})`;
}
case 'oklch': {
return color.toOKLCH().toString('css');
}
default:
return color.toOKLCH().toString('css');
}
}
function getInputChannelValue(color, channel, format = 'hsba') {
if (channel === 'hex') {
const alphaRange = getChannelRange('alpha');
if (color.alpha < alphaRange.maxValue) {
return color.toHexa();
}
return color.toHex();
}
if (channel === 'css') {
return toCssString(color, format);
}
const value = color.getChannelValue(channel);
if (Number.isNaN(value))
return 'NaN';
const range = getChannelRange(channel);
if (channel === 'H' || channel === 'oklchHue') {
const rounded = round(value, 2);
return rounded.toString();
}
if (channel === 'hue') {
const rounded = Math.round(value);
return rounded.toString();
}
if (range.step >= 1) {
return Math.round(value).toString();
}
return round(value, 4).toString();
}
function getDefault2DAxes(format) {
switch (format) {
case 'hsla':
return { xChannel: 'saturation', yChannel: 'lightness' };
case 'hsba':
case 'rgba':
case 'oklch':
default:
return { xChannel: 'saturation', yChannel: 'brightness' };
}
}
function getDefault3DAxes(format) {
switch (format) {
case 'hsla':
return { xChannel: 'saturation', yChannel: 'lightness', zChannel: 'hue' };
case 'hsba':
case 'rgba':
case 'oklch':
default:
return { xChannel: 'saturation', yChannel: 'brightness', zChannel: 'hue' };
}
}
const INPUT_COLOR_INSTANCE = new InjectionToken('INPUT_COLOR_INSTANCE');
const INPUT_COLOR_SLIDER_INSTANCE = new InjectionToken('INPUT_COLOR_SLIDER_INSTANCE');
/**
* InputColorArea is a helper component for InputColor component.
* @group Components
*/
class InputColorArea extends BaseComponent {
componentName = 'InputColorArea';
bindDirectiveInstance = inject(Bind, { self: true });
$pc = inject(INPUT_COLOR_INSTANCE);
$xChannel = computed(() => this.$pc.$axes().xChannel, /* @ts-ignore */
...(ngDevMode ? [{ debugName: "$xChannel" }] : /* istanbul ignore next */ []));
$yChannel = computed(() => this.$pc.$axes().yChannel, /* @ts-ignore */
...(ngDevMode ? [{ debugName: "$yChannel" }] : /* istanbul ignore next */ []));
$areaGradient = computed(() => {
const color = this.$pc.$color();
const xCh = this.$xChannel();
const yCh = this.$yChannel();
const format = this.$pc.format();
return getAreaGradient(color, xCh, yCh, format);
}, /* @ts-ignore */
...(ngDevMode ? [{ debugName: "$areaGradient" }] : /* istanbul ignore next */ []));
$handleBackground = computed(() => this.$pc.$color().setChannelValue('alpha', 1).toRgbString(), /* @ts-ignore */
...(ngDevMode ? [{ debugName: "$handleBackground" }] : /* istanbul ignore next */ []));
$handleLeft = computed(() => {
const xCh = this.$xChannel();
const range = getChannelRange(xCh);
const value = this.$pc.$color().getChannelValue(xCh);
const pct = ((value - range.minValue) / (range.maxValue - range.minValue)) * 100;
return `${pct}%`;
}, /* @ts-ignore */
...(ngDevMode ? [{ debugName: "$handleLeft" }] : /* istanbul ignore next */ []));
$handleTop = computed(() => {
const yCh = this.$yChannel();
const range = getChannelRange(yCh);
const value = this.$pc.$color().getChannelValue(yCh);
const pct = (1 - (value - range.minValue) / (range.maxValue - range.minValue)) * 100;
return `${pct}%`;
}, /* @ts-ignore */
...(ngDevMode ? [{ debugName: "$handleTop" }] : /* istanbul ignore next */ []));
dragging = false;
dragOffset = { x: 0, y: 0 };
cleanupDrag = null;
onAfterViewChecked() {
this.bindDirectiveInstance.setAttrs(this.ptms(['host', 'root']));
}
onPointerDown(event) {
if (this.$pc.$disabled())
return;
event.preventDefault();
this.dragging = true;
const el = this.el.nativeElement;
el.setPointerCapture(event.pointerId);
const handle = event.target?.closest('[data-pc-section="areahandle"], .p-inputcolor-area-handle');
if (handle) {
const handleRect = handle.getBoundingClientRect();
this.dragOffset = {
x: event.clientX - (handleRect.left + handleRect.width / 2),
y: event.clientY - (handleRect.top + handleRect.height / 2)
};
}
else {
this.dragOffset = { x: 0, y: 0 };
}
this.updateFromPointer(event);
const onMove = (e) => {
if (!this.dragging)
return;
e.preventDefault();
this.updateFromPointer(e);
};
const cleanup = () => {
this.dragging = false;
this.cleanupDrag = null;
el.removeEventListener('pointermove', onMove);
el.removeEventListener('pointerup', onUp);
el.removeEventListener('pointercancel', onCancel);
el.removeEventListener('lostpointercapture', onLostCapture);
};
this.cleanupDrag = cleanup;
const onUp = (e) => {
if (!this.dragging)
return;
this.updateFromPointer(e, true);
this.dragOffset = { x: 0, y: 0 };
cleanup();
};
const onCancel = () => {
cleanup();
};
const onLostCapture = () => {
cleanup();
};
el.addEventListener('pointermove', onMove);
el.addEventListener('pointerup', onUp);
el.addEventListener('pointercancel', onCancel);
el.addEventListener('lostpointercapture', onLostCapture);
}
ngOnDestroy() {
this.cleanupDrag?.();
}
updateFromPointer(event, isEnd = false) {
const el = this.el.nativeElement;
const rect = el.getBoundingClientRect();
const xPercent = Math.max(0, Math.min(1, (event.clientX - this.dragOffset.x - rect.left) / rect.width));
const yPercent = Math.max(0, Math.min(1, (event.clientY - this.dragOffset.y - rect.top) / rect.height));
const xCh = this.$xChannel();
const yCh = this.$yChannel();
const xRange = getChannelRange(xCh);
const yRange = getChannelRange(yCh);
const xValue = snapValue(xRange.minValue + xPercent * (xRange.maxValue - xRange.minValue), xRange.minValue, xRange.maxValue, xRange.step);
const yValue = snapValue(yRange.maxValue - yPercent * (yRange.maxValue - yRange.minValue), yRange.minValue, yRange.maxValue, yRange.step);
const nativeColor = this.$pc.toChannelNativeFormat(this.$pc.$color(), xCh);
let color = nativeColor.setChannelValue(xCh, xValue);
color = color.setChannelValue(yCh, yValue);
this.$pc.updateColor(color, event, isEnd);
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: InputColorArea, deps: null, target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.6", type: InputColorArea, isStandalone: true, selector: "p-inputcolor-area", host: { listeners: { "pointerdown": "onPointerDown($event)" }, properties: { "class": "$pc.cx(\"area\")", "style.--px-area-gradient": "$areaGradient()", "style.--px-handle-background": "$handleBackground()", "style.--px-handle-position-left": "$handleLeft()", "style.--px-handle-position-top": "$handleTop()" } }, providers: [{ provide: PARENT_INSTANCE, useExisting: InputColorArea }], usesInheritance: true, hostDirectives: [{ directive: i1.Bind }], ngImport: i0, template: `<ng-content></ng-content>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: InputColorArea, decorators: [{
type: Component,
args: [{
selector: 'p-inputcolor-area',
standalone: true,
template: `<ng-content></ng-content>`,
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
host: {
'[class]': '$pc.cx("area")',
'[style.--px-area-gradient]': '$areaGradient()',
'[style.--px-handle-background]': '$handleBackground()',
'[style.--px-handle-position-left]': '$handleLeft()',
'[style.--px-handle-position-top]': '$handleTop()',
'(pointerdown)': 'onPointerDown($event)'
},
providers: [{ provide: PARENT_INSTANCE, useExisting: InputColorArea }],
hostDirectives: [Bind]
}]
}] });
/**
* InputColorAreaBackground is a helper component for InputColor component.
* @group Components
*/
class InputColorAreaBackground extends BaseComponent {
componentName = 'InputColorAreaBackground';
bindDirectiveInstance = inject(Bind, { self: true });
$pc = inject(INPUT_COLOR_INSTANCE);
onAfterViewChecked() {
this.bindDirectiveInstance.setAttrs(this.ptms(['host', 'root']));
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: InputColorAreaBackground, deps: null, target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.6", type: InputColorAreaBackground, isStandalone: true, selector: "p-inputcolor-area-background", host: { properties: { "class": "$pc.cx(\"areaBackground\")" } }, providers: [{ provide: PARENT_INSTANCE, useExisting: InputColorAreaBackground }], usesInheritance: true, hostDirectives: [{ directive: i1.Bind }], ngImport: i0, template: `<ng-content></ng-content>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: InputColorAreaBackground, decorators: [{
type: Component,
args: [{
selector: 'p-inputcolor-area-background',
standalone: true,
template: `<ng-content></ng-content>`,
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
host: {
'[class]': '$pc.cx("areaBackground")'
},
providers: [{ provide: PARENT_INSTANCE, useExisting: InputColorAreaBackground }],
hostDirectives: [Bind]
}]
}] });
/**
* InputColorAreaHandle is a helper component for InputColor component.
* @group Components
*/
class InputColorAreaHandle extends BaseComponent {
componentName = 'InputColorAreaHandle';
bindDirectiveInstance = inject(Bind, { self: true });
$pc = inject(INPUT_COLOR_INSTANCE);
$xChannel = computed(() => this.$pc.$axes().xChannel, /* @ts-ignore */
...(ngDevMode ? [{ debugName: "$xChannel" }] : /* istanbul ignore next */ []));
$yChannel = computed(() => this.$pc.$axes().yChannel, /* @ts-ignore */
...(ngDevMode ? [{ debugName: "$yChannel" }] : /* istanbul ignore next */ []));
$xRange = computed(() => getChannelRange(this.$xChannel()), /* @ts-ignore */
...(ngDevMode ? [{ debugName: "$xRange" }] : /* istanbul ignore next */ []));
$yRange = computed(() => getChannelRange(this.$yChannel()), /* @ts-ignore */
...(ngDevMode ? [{ debugName: "$yRange" }] : /* istanbul ignore next */ []));
$xValue = computed(() => this.$pc.$color().getChannelValue(this.$xChannel()), /* @ts-ignore */
...(ngDevMode ? [{ debugName: "$xValue" }] : /* istanbul ignore next */ []));
$yValue = computed(() => this.$pc.$color().getChannelValue(this.$yChannel()), /* @ts-ignore */
...(ngDevMode ? [{ debugName: "$yValue" }] : /* istanbul ignore next */ []));
$xMin = computed(() => this.$xRange().minValue, /* @ts-ignore */
...(ngDevMode ? [{ debugName: "$xMin" }] : /* istanbul ignore next */ []));
$xMax = computed(() => this.$xRange().maxValue, /* @ts-ignore */
...(ngDevMode ? [{ debugName: "$xMax" }] : /* istanbul ignore next */ []));
$tabindex = computed(() => (this.$pc.$disabled() ? -1 : 0), /* @ts-ignore */
...(ngDevMode ? [{ debugName: "$tabindex" }] : /* istanbul ignore next */ []));
$ariaDisabled = computed(() => this.$pc.$disabled() || undefined, /* @ts-ignore */
...(ngDevMode ? [{ debugName: "$ariaDisabled" }] : /* istanbul ignore next */ []));
$ariaValueText = computed(() => {
const xCh = this.$xChannel();
const yCh = this.$yChannel();
return `${xCh} ${this.$xValue()}, ${yCh} ${this.$yValue()}`;
}, /* @ts-ignore */
...(ngDevMode ? [{ debugName: "$ariaValueText" }] : /* istanbul ignore next */ []));
onAfterViewChecked() {
this.bindDirectiveInstance.setAttrs(this.ptms(['host', 'root']));
}
onKeyDown(event) {
if (this.$pc.$disabled())
return;
const xCh = this.$xChannel();
const yCh = this.$yChannel();
const xRange = this.$xRange();
const yRange = this.$yRange();
let xVal = this.$xValue();
let yVal = this.$yValue();
let handled = false;
switch (event.key) {
case 'ArrowRight':
xVal = Math.min(xVal + xRange.step, xRange.maxValue);
handled = true;
break;
case 'ArrowLeft':
xVal = Math.max(xVal - xRange.step, xRange.minValue);
handled = true;
break;
case 'ArrowUp':
yVal = Math.min(yVal + yRange.step, yRange.maxValue);
handled = true;
break;
case 'ArrowDown':
yVal = Math.max(yVal - yRange.step, yRange.minValue);
handled = true;