@libs-ui/components-color-picker 0.2.10-6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,562 @@
1
+ import * as i0 from '@angular/core';
2
+ import { signal, inject, input, output, viewChild, effect, Component, ChangeDetectionStrategy } from '@angular/core';
3
+ import { LibsUiComponentsInputsInputComponent } from '@libs-ui/components-inputs-input';
4
+ import { LibsUiNotificationService } from '@libs-ui/services-notification';
5
+ import { get, isNil, set } from '@libs-ui/utils';
6
+
7
+ const ColorNames = { 'aliceblue': '#F0F8FF', 'antiquewhite': '#FAEBD7', 'aqua': '#00FFFF', 'aquamarine': '#7FFFD4', 'azure': '#F0FFFF', 'beige': '#F5F5DC', 'bisque': '#FFE4C4', 'black': '#000000', 'blanchedalmond': '#FFEBCD', 'blue': '#0000FF', 'blueviolet': '#8A2BE2', 'brown': '#A52A2A', 'burlywood': '#DEB887', 'cadetblue': '#5F9EA0', 'chartreuse': '#7FFF00', 'chocolate': '#D2691E', 'coral': '#FF7F50', 'cornflowerblue': '#6495ED', 'cornsilk': '#FFF8DC', 'crimson': '#DC143C', 'cyan': '#00FFFF', 'darkblue': '#00008B', 'darkcyan': '#008B8B', 'darkgoldenrod': '#B8860B', 'darkgray': '#A9A9A9', 'darkgrey': '#A9A9A9', 'darkgreen': '#006400', 'darkkhaki': '#BDB76B', 'darkmagenta': '#8B008B', 'darkolivegreen': '#556B2F', 'darkorange': '#FF8C00', 'darkorchid': '#9932CC', 'darkred': '#8B0000', 'darksalmon': '#E9967A', 'darkseagreen': '#8FBC8F', 'darkslateblue': '#483D8B', 'darkslategray': '#2F4F4F', 'darkslategrey': '#2F4F4F', 'darkturquoise': '#00CED1', 'darkviolet': '#9400D3', 'deeppink': '#FF1493', 'deepskyblue': '#00BFFF', 'dimgray': '#696969', 'dimgrey': '#696969', 'dodgerblue': '#1E90FF', 'firebrick': '#B22222', 'floralwhite': '#FFFAF0', 'forestgreen': '#228B22', 'fuchsia': '#FF00FF', 'gainsboro': '#DCDCDC', 'ghostwhite': '#F8F8FF', 'gold': '#FFD700', 'goldenrod': '#DAA520', 'gray': '#808080', 'grey': '#808080', 'green': '#008000', 'greenyellow': '#ADFF2F', 'honeydew': '#F0FFF0', 'hotpink': '#FF69B4', 'indianred ': '#CD5C5C', 'indigo ': '#4B0082', 'ivory': '#FFFFF0', 'khaki': '#F0E68C', 'lavender': '#E6E6FA', 'lavenderblush': '#FFF0F5', 'lawngreen': '#7CFC00', 'lemonchiffon': '#FFFACD', 'lightblue': '#ADD8E6', 'lightcoral': '#F08080', 'lightcyan': '#E0FFFF', 'lightgoldenrodyellow': '#FAFAD2', 'lightgray': '#D3D3D3', 'lightgrey': '#D3D3D3', 'lightgreen': '#90EE90', 'lightpink': '#FFB6C1', 'lightsalmon': '#FFA07A', 'lightseagreen': '#20B2AA', 'lightskyblue': '#87CEFA', 'lightslategray': '#778899', 'lightslategrey': '#778899', 'lightsteelblue': '#B0C4DE', 'lightyellow': '#FFFFE0', 'lime': '#00FF00', 'limegreen': '#32CD32', 'linen': '#FAF0E6', 'magenta': '#FF00FF', 'maroon': '#800000', 'mediumaquamarine': '#66CDAA', 'mediumblue': '#0000CD', 'mediumorchid': '#BA55D3', 'mediumpurple': '#9370DB', 'mediumseagreen': '#3CB371', 'mediumslateblue': '#7B68EE', 'mediumspringgreen': '#00FA9A', 'mediumturquoise': '#48D1CC', 'mediumvioletred': '#C71585', 'midnightblue': '#191970', 'mintcream': '#F5FFFA', 'mistyrose': '#FFE4E1', 'moccasin': '#FFE4B5', 'navajowhite': '#FFDEAD', 'navy': '#000080', 'oldlace': '#FDF5E6', 'olive': '#808000', 'olivedrab': '#6B8E23', 'orange': '#FFA500', 'orangered': '#FF4500', 'orchid': '#DA70D6', 'palegoldenrod': '#EEE8AA', 'palegreen': '#98FB98', 'paleturquoise': '#AFEEEE', 'palevioletred': '#DB7093', 'papayawhip': '#FFEFD5', 'peachpuff': '#FFDAB9', 'peru': '#CD853F', 'pink': '#FFC0CB', 'plum': '#DDA0DD', 'powderblue': '#B0E0E6', 'purple': '#800080', 'rebeccapurple': '#663399', 'red': '#FF0000', 'rosybrown': '#BC8F8F', 'royalblue': '#4169E1', 'saddlebrown': '#8B4513', 'salmon': '#FA8072', 'sandybrown': '#F4A460', 'seagreen': '#2E8B57', 'seashell': '#FFF5EE', 'sienna': '#A0522D', 'silver': '#C0C0C0', 'skyblue': '#87CEEB', 'slateblue': '#6A5ACD', 'slategray': '#708090', 'slategrey': '#708090', 'snow': '#FFFAFA', 'springgreen': '#00FF7F', 'steelblue': '#4682B4', 'tan': '#D2B48C', 'teal': '#008080', 'thistle': '#D8BFD8', 'tomato': '#FF6347', 'turquoise': '#40E0D0', 'violet': '#EE82EE', 'wheat': '#F5DEB3', 'white': '#FFFFFF', 'whitesmoke': '#F5F5F5', 'yellow': '#FFFF00', 'yellowgreen': '#9ACD32' };
8
+ const optionsDefault = () => {
9
+ return {
10
+ showHsl: false,
11
+ showRgb: true,
12
+ showHex: true,
13
+ showAlpha: false,
14
+ color: '#ff0000',
15
+ format: 'color',
16
+ slBarSize: [316, 200],
17
+ hueBarSize: [316, 20],
18
+ alphaBarSize: [316, 20]
19
+ };
20
+ };
21
+ const limit = (value, min, max) => {
22
+ value = +value;
23
+ return isNaN(value) ? min : (value < min ? min : (value > max ? max : value));
24
+ };
25
+ const hslToRgb = (h, s, l) => {
26
+ let r, g, b;
27
+ [h, s, l] = [limit(h, 0, 360) / 360, limit(s, 0, 100) / 100, limit(l, 0, 100) / 100];
28
+ if (s == 0) {
29
+ r = g = b = l; // achromatic
30
+ return [r * 255, g * 255, b * 255].map(Math.round);
31
+ }
32
+ const hueToRgb = (p, q, t) => {
33
+ if (t < 0)
34
+ t += 1;
35
+ if (t > 1)
36
+ t -= 1;
37
+ if (t < 1 / 6)
38
+ return p + (q - p) * 6 * t;
39
+ if (t < 1 / 2)
40
+ return q;
41
+ if (t < 2 / 3)
42
+ return p + (q - p) * (2 / 3 - t) * 6;
43
+ return p;
44
+ };
45
+ const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
46
+ const p = (2 * l) - q;
47
+ r = hueToRgb(p, q, h + (1 / 3));
48
+ g = hueToRgb(p, q, h);
49
+ b = hueToRgb(p, q, h - (1 / 3));
50
+ return [r * 255, g * 255, b * 255].map(Math.round);
51
+ };
52
+ const cssColorToRgba = (color) => {
53
+ if (color) {
54
+ const colorByName = get(ColorNames, color.toLowerCase());
55
+ const [, , , r, g, b, a, , rr, gg, bb, aa] = /^\s*#?((([0-9A-F])([0-9A-F])([0-9A-F])([0-9A-F])?)|(([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})?))\s*$/i.exec(colorByName || color) || [];
56
+ if (!isNil(r)) {
57
+ return [
58
+ parseInt(r + r, 16),
59
+ parseInt(g + g, 16),
60
+ parseInt(b + b, 16),
61
+ a ? +((parseInt(a + a, 16)) / 255).toFixed(2) : 1
62
+ ];
63
+ }
64
+ if (!isNil(rr)) {
65
+ return [
66
+ parseInt(rr, 16),
67
+ parseInt(gg, 16),
68
+ parseInt(bb, 16),
69
+ aa ? +((parseInt(aa, 16)) / 255).toFixed(2) : 1
70
+ ];
71
+ }
72
+ }
73
+ return undefined;
74
+ };
75
+ const parseColorToRgba = (color) => {
76
+ if (Array.isArray(color)) {
77
+ return [
78
+ limit(color[0], 0, 255),
79
+ limit(color[1], 0, 255),
80
+ limit(color[2], 0, 255),
81
+ limit(color[3] ?? 1, 0, 1)
82
+ ];
83
+ }
84
+ const parsed = cssColorToRgba(color) || cssRgbaToRgba(color);
85
+ if (parsed && parsed.length === 3) {
86
+ parsed.push(1);
87
+ }
88
+ return parsed;
89
+ };
90
+ const cssRgbaToRgba = (rgba) => {
91
+ if (rgba) {
92
+ const [m, r, g, b, , a] = /^rgba?\((\d+)\s*[\s,]\s*(\d+)\s*[\s,]\s*(\d+)(\s*[\s,]\s*(\d*(.\d+)?))?\)/i.exec(rgba) || [];
93
+ return m ? [limit(r, 0, 255), limit(g, 0, 255), limit(b, 0, 255), limit(a ?? 1, 0, 1)] : undefined;
94
+ }
95
+ return undefined;
96
+ };
97
+ const cssHslaToHsla = (hsla) => {
98
+ if (hsla) {
99
+ const [m, h, s, l, , a] = /^hsla?\((\d+)\s*[\s,]\s*(\d+)\s*[\s,]\s*(\d+)(\s*[\s,]\s*(\d*(.\d+)?))?\)/i.exec(hsla) || [];
100
+ return m ? [limit(h, 0, 255), limit(s, 0, 255), limit(l, 0, 255), limit(a ?? 1, 0, 1)] : undefined;
101
+ }
102
+ return undefined;
103
+ };
104
+ const parseColorToHsla = (color) => {
105
+ if (Array.isArray(color)) {
106
+ return [
107
+ limit(color[0], 0, 360),
108
+ limit(color[1], 0, 100),
109
+ limit(color[2], 0, 100),
110
+ limit(color[3] ?? 1, 0, 1)
111
+ ];
112
+ }
113
+ const parsed = cssHslaToHsla(color);
114
+ if (parsed && parsed.length === 3) {
115
+ parsed.push(1);
116
+ }
117
+ return parsed;
118
+ };
119
+ const rgbToHsl = (r, g, b) => {
120
+ [r, g, b] = [limit(r, 0, 255) / 255, limit(g, 0, 255) / 255, limit(b, 0, 255) / 255];
121
+ const max = Math.max(r, g, b);
122
+ const min = Math.min(r, g, b);
123
+ let h, s = (max + min) / 2;
124
+ const l = (max + min) / 2;
125
+ if (max == min) {
126
+ h = s = 0; // achromatic
127
+ return [h * 360, s * 100, l * 100].map(Math.round);
128
+ }
129
+ const d = max - min;
130
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
131
+ switch (max) {
132
+ case r:
133
+ h = ((g - b) / d) + (g < b ? 6 : 0);
134
+ break;
135
+ case g:
136
+ h = ((b - r) / d) + 2;
137
+ break;
138
+ case b:
139
+ h = ((r - g) / d) + 4;
140
+ break;
141
+ }
142
+ h = (h || 0) / 6;
143
+ return [h * 360, s * 100, l * 100].map(Math.round);
144
+ };
145
+ const rgbToHex = (r, g, b) => {
146
+ [r, g, b] = [limit(r, 0, 255), limit(g, 0, 255), limit(b, 0, 255)];
147
+ return "#" + ("000000" + ((r << 16) | (g << 8) | b).toString(16)).slice(-6);
148
+ };
149
+ const rgbToInt = (r, g, b) => {
150
+ return (r << 16) | (g << 8) | b;
151
+ };
152
+ const rgbToHsv = (r, g, b) => {
153
+ [r, g, b] = [limit(r, 0, 255) / 255, limit(g, 0, 255) / 255, limit(b, 0, 255) / 255];
154
+ const max = Math.max(r, g, b);
155
+ const min = Math.min(r, g, b);
156
+ let h, s = max;
157
+ const v = max;
158
+ const d = max - min;
159
+ s = max === 0 ? 0 : d / max;
160
+ if (max == min) {
161
+ h = 0;
162
+ return [h, s, v];
163
+ }
164
+ switch (max) {
165
+ case r:
166
+ h = (g - b) / d + (g < b ? 6 : 0);
167
+ break;
168
+ case g:
169
+ h = (b - r) / d + 2;
170
+ break;
171
+ case b:
172
+ h = (r - g) / d + 4;
173
+ break;
174
+ }
175
+ h = (h || 0) / 6;
176
+ return [h, s, v];
177
+ };
178
+ const formatColor = (data, format) => {
179
+ switch (format) {
180
+ case 'rgb':
181
+ default:
182
+ return data.slice(0, 3);
183
+ case 'rgbcss':
184
+ return `rgb(${data[0]}, ${data[1]}, ${data[2]})`;
185
+ case 'rgbcss4':
186
+ return `rgb(${data[0]}, ${data[1]}, ${data[2]}, ${data[3]})`;
187
+ case 'rgba':
188
+ return data;
189
+ case 'rgbacss':
190
+ return `rgba(${data[0]}, ${data[1]}, ${data[2]}, ${data[3]})`;
191
+ case 'hsl':
192
+ return rgbToHsl(data[0], data[1], data[2]);
193
+ case 'hslcss':
194
+ data = rgbToHsl(data[0], data[1], data[2]);
195
+ return `hsl(${data[0]}, ${data[1]}, ${data[2]})`;
196
+ case 'hslcss4': {
197
+ const hh = rgbToHsl(data[0], data[1], data[2]);
198
+ return `hsl(${hh[0]}, ${hh[1]}, ${hh[2]}, ${data[3]})`;
199
+ }
200
+ case 'hsla':
201
+ return [...rgbToHsl(data[0], data[1], data[2]), data[3]];
202
+ case 'hslacss': {
203
+ const ha = rgbToHsl(data[0], data[1], data[2]);
204
+ return `hsla(${ha[0]}, ${ha[1]}, ${ha[2]}, ${data[3]})`;
205
+ }
206
+ case 'hex':
207
+ return rgbToHex(data[0], data[1], data[2]);
208
+ case 'hexcss4':
209
+ return rgbToHex(data[0], data[1], data[2]) + ('00' + parseInt((data[3] * 255).toString()).toString(16)).slice(-2);
210
+ case 'int':
211
+ return rgbToInt(data[0], data[1], data[2]);
212
+ }
213
+ };
214
+ const parseColor = (color, format) => {
215
+ if (!isNil(color)) {
216
+ let data = [];
217
+ data = parseColorToRgba(color) || (parseColorToHsla(color) && [...hslToRgb(data[0], data[1], data[2]), data[3]]);
218
+ if (data) {
219
+ if (typeof format === 'object') {
220
+ return ['rgb', 'rgbcss', 'rgbcss4', 'rgba', 'rgbacss', 'hsl', 'hslcss', 'hslcss4', 'hsla', 'hslacss', 'hex', 'hexcss4', 'int'].reduce((m, f) => {
221
+ set(m, f, formatColor(data, f));
222
+ return m;
223
+ }, format);
224
+ }
225
+ return formatColor(data, format);
226
+ }
227
+ }
228
+ return undefined;
229
+ };
230
+ const defaultHelper = () => {
231
+ return {
232
+ setHue: () => { return; },
233
+ grabColor: () => [],
234
+ findColor: () => []
235
+ };
236
+ };
237
+
238
+ class LibsUiComponentsColorPickerComponent {
239
+ /* PROPERTY */
240
+ options = signal(optionsDefault());
241
+ focus = signal(undefined);
242
+ hex = signal('');
243
+ s = signal(0);
244
+ h = signal(0);
245
+ l = signal(0);
246
+ r = signal(0);
247
+ g = signal(0);
248
+ b = signal(0);
249
+ a = signal(1);
250
+ slBarHelper = signal(defaultHelper());
251
+ notificationService = inject(LibsUiNotificationService);
252
+ /* INPUT */
253
+ customOptions = input();
254
+ /* OUTPUT */
255
+ outColorChange = output();
256
+ /* VIEW CHILD */
257
+ hueEl = viewChild('hueEl');
258
+ huePointerEl = viewChild('huePointerEl');
259
+ slEl = viewChild('slEl');
260
+ slPointerEl = viewChild('slPointerEl');
261
+ alphaEl = viewChild('alphaEl');
262
+ alphaPointerEl = viewChild('alphaPointerEl');
263
+ previewEl = viewChild('previewEl');
264
+ constructor() {
265
+ effect(() => {
266
+ const ctx = this.alphaEl()?.nativeElement.getContext('2d');
267
+ if (!ctx) {
268
+ return;
269
+ }
270
+ ctx.clearRect(0, 0, this.options().alphaBarSize[0], this.options().alphaBarSize[1]);
271
+ const gradient = ctx.createLinearGradient(0, 0, this.alphaEl()?.nativeElement.width - 1, 0);
272
+ gradient.addColorStop(0, `hsla(${this.h()},${this.s()}%,${this.l()}%, 0)`);
273
+ gradient.addColorStop(1, `hsla(${this.h()},${this.s()}%,${this.l()}%, 1)`);
274
+ ctx.fillStyle = gradient;
275
+ ctx.fillRect(0, 0, this.options().alphaBarSize[0], this.options().alphaBarSize[1]);
276
+ });
277
+ }
278
+ /* FUNCTIONS */
279
+ ngOnInit() {
280
+ if (this.customOptions()) {
281
+ this.options.update(options => ({ ...options, ...this.customOptions() }));
282
+ }
283
+ }
284
+ ngAfterViewInit() {
285
+ this.setupHueCanvas();
286
+ this.setupSlCanvas();
287
+ this.setupSlBarHelper();
288
+ if (this.options().showAlpha) {
289
+ this.setupAlphaCanvas();
290
+ }
291
+ this.handlerColorChange(this.options().format, this.options().color, true);
292
+ }
293
+ setupHueCanvas() {
294
+ const canvas = this.hueEl()?.nativeElement;
295
+ canvas.width = this.options().hueBarSize[0];
296
+ canvas.height = this.options().hueBarSize[1];
297
+ const ctx = canvas.getContext('2d');
298
+ const gradient = ctx.createLinearGradient(0, 0, this.options().hueBarSize[0], 0);
299
+ const step = 1 / 360;
300
+ for (let ii = 0; ii <= 1; ii += step) {
301
+ gradient.addColorStop(ii, `hsl(${360 * ii}, 100%, 50%)`);
302
+ }
303
+ ctx.fillStyle = gradient;
304
+ ctx.fillRect(0, 0, this.options().hueBarSize[0], this.options().hueBarSize[1]);
305
+ const onMouseMove = (event) => {
306
+ const x = limit(event.clientX - canvas.getBoundingClientRect().left, 0, this.options().hueBarSize[0]);
307
+ const hue = Math.round(x * 360 / this.options().hueBarSize[0]);
308
+ set(this.huePointerEl()?.nativeElement.style, 'left', `${x - 7}px`);
309
+ this.h.set(hue);
310
+ this.handlerColorChange('h', hue);
311
+ };
312
+ const onMouseUp = () => {
313
+ document.removeEventListener('mousemove', onMouseMove);
314
+ document.removeEventListener('mouseup', onMouseUp);
315
+ };
316
+ canvas.addEventListener('mousedown', (event) => {
317
+ onMouseMove(event);
318
+ document.addEventListener('mousemove', onMouseMove);
319
+ document.addEventListener('mouseup', onMouseUp);
320
+ });
321
+ }
322
+ setupSlCanvas() {
323
+ const canvas = this.slEl()?.nativeElement;
324
+ canvas.width = this.options().slBarSize[0];
325
+ canvas.height = this.options().slBarSize[1];
326
+ const onMouseMove = (event) => {
327
+ const x = limit(event.clientX - canvas.getBoundingClientRect().left, 0, this.options().slBarSize[0] - 1);
328
+ const y = limit(event.clientY - canvas.getBoundingClientRect().top, 0, this.options().slBarSize[1] - 1);
329
+ const c = this.slBarHelper().grabColor(x, y);
330
+ set(this.slPointerEl()?.nativeElement.style, 'left', `${x - 7}px`);
331
+ set(this.slPointerEl()?.nativeElement.style, 'top', `${y - 7}px`);
332
+ this.handlerColorChange('rgb', c);
333
+ };
334
+ const onMouseUp = () => {
335
+ document.removeEventListener('mousemove', onMouseMove);
336
+ document.removeEventListener('mouseup', onMouseUp);
337
+ };
338
+ canvas.addEventListener('mousedown', (event) => {
339
+ onMouseMove(event);
340
+ document.addEventListener('mousemove', onMouseMove);
341
+ document.addEventListener('mouseup', onMouseUp);
342
+ });
343
+ }
344
+ setupSlBarHelper() {
345
+ const canvas = this.slEl()?.nativeElement;
346
+ const ctx = canvas.getContext('2d');
347
+ const width = +canvas.width;
348
+ const height = +canvas.height;
349
+ const whiteBlackGradient = ctx.createLinearGradient(1, 1, 1, height - 1);
350
+ whiteBlackGradient.addColorStop(0, 'white');
351
+ whiteBlackGradient.addColorStop(1, 'black');
352
+ this.slBarHelper.set({
353
+ setHue: (hue) => {
354
+ const colorGradient = ctx.createLinearGradient(1, 0, width - 1, 0);
355
+ colorGradient.addColorStop(0, `hsla(${hue}, 100%, 50%, 0)`);
356
+ colorGradient.addColorStop(1, `hsla(${hue}, 100%, 50%, 1)`);
357
+ ctx.fillStyle = whiteBlackGradient;
358
+ ctx.fillRect(0, 0, width, height);
359
+ ctx.fillStyle = colorGradient;
360
+ ctx.globalCompositeOperation = 'multiply';
361
+ ctx.fillRect(0, 0, width, height);
362
+ ctx.globalCompositeOperation = 'source-over';
363
+ },
364
+ grabColor: (x, y) => ctx.getImageData(x, y, 1, 1).data,
365
+ findColor: (r, g, b) => {
366
+ const [, s, v] = rgbToHsv(r, g, b);
367
+ const x = s * width;
368
+ const y = height - (v * height);
369
+ return [x, y];
370
+ }
371
+ });
372
+ }
373
+ setupAlphaCanvas() {
374
+ const canvas = this.alphaEl()?.nativeElement;
375
+ canvas.width = this.options().alphaBarSize[0];
376
+ canvas.height = this.options().alphaBarSize[1];
377
+ const ctx = canvas.getContext('2d');
378
+ const gradient = ctx.createLinearGradient(0, 0, canvas.width - 1, 0);
379
+ gradient.addColorStop(0, `hsla(${this.h()},${this.s()}%,${this.l()}%, 0)`);
380
+ gradient.addColorStop(1, `hsla(${this.h()},${this.s()}%,${this.l()}%, 1)`);
381
+ ctx.fillStyle = gradient;
382
+ ctx.fillRect(0, 0, this.options().alphaBarSize[0], this.options().alphaBarSize[1]);
383
+ const onMouseMove = (event) => {
384
+ const x = limit(event.clientX - canvas.getBoundingClientRect().left, 0, this.options().alphaBarSize[0]);
385
+ const alpha = +(x / this.options().alphaBarSize[0]).toFixed(2);
386
+ set(this.alphaPointerEl()?.nativeElement.style, 'left', `${x - 7}px`);
387
+ this.handlerColorChange('alpha', alpha);
388
+ };
389
+ const onMouseUp = () => {
390
+ document.removeEventListener('mousemove', onMouseMove);
391
+ document.removeEventListener('mouseup', onMouseUp);
392
+ };
393
+ canvas.addEventListener('mousedown', (event) => {
394
+ onMouseMove(event);
395
+ document.addEventListener('mousemove', onMouseMove);
396
+ document.addEventListener('mouseup', onMouseUp);
397
+ });
398
+ }
399
+ handlerCopyColor(event) {
400
+ event.stopPropagation();
401
+ window.navigator.clipboard.writeText(this.hex());
402
+ this.notificationService.showCompTypeTextSuccess('i18n_copy_successfully');
403
+ }
404
+ updatePointerH(h) {
405
+ const x = this.options().hueBarSize[0] * h / 360;
406
+ set(this.huePointerEl()?.nativeElement.style, 'left', `${x - 7}px`);
407
+ }
408
+ updatePointerSl(h, s, l) {
409
+ const [r, g, b] = hslToRgb(h, s, l);
410
+ const [x, y] = this.slBarHelper().findColor(r, g, b);
411
+ if (x >= 0) {
412
+ set(this.slPointerEl()?.nativeElement.style, 'left', `${x - 7}px`);
413
+ set(this.slPointerEl()?.nativeElement.style, 'top', `${y - 7}px`);
414
+ }
415
+ }
416
+ updatePointerA(a) {
417
+ if (!this.options().showAlpha) {
418
+ return;
419
+ }
420
+ const x = this.options().alphaBarSize[0] * a;
421
+ set(this.alphaPointerEl()?.nativeElement.style, 'left', `${x - 7}px`);
422
+ }
423
+ updateHex(r, g, b, a) {
424
+ if (this.options().showAlpha) {
425
+ this.hex.set(parseColor([r, g, b, a], 'hexcss4'));
426
+ return;
427
+ }
428
+ this.hex.set(rgbToHex(r, g, b));
429
+ }
430
+ updateRgb() {
431
+ const rgb = hslToRgb(this.h(), this.s(), this.l());
432
+ this.r.set(rgb[0]);
433
+ this.g.set(rgb[1]);
434
+ this.b.set(rgb[2]);
435
+ }
436
+ updateHsl() {
437
+ const hsl = rgbToHsl(this.r(), this.g(), this.b());
438
+ this.h.set(hsl[0]);
439
+ this.s.set(hsl[1]);
440
+ this.l.set(hsl[2]);
441
+ }
442
+ updateValuesAndPointer(config) {
443
+ if (config.rgb) {
444
+ this.updateRgb();
445
+ }
446
+ if (config.hsl) {
447
+ this.updateHsl();
448
+ }
449
+ if (config.hue) {
450
+ this.slBarHelper().setHue(this.h());
451
+ }
452
+ if (config.hPoint) {
453
+ this.updatePointerH(this.h());
454
+ }
455
+ if (config.slPoint) {
456
+ this.updatePointerSl(this.h(), this.s(), this.l());
457
+ }
458
+ if (config.hex) {
459
+ this.updateHex(this.r(), this.g(), this.b(), this.a());
460
+ }
461
+ if (config.aPoint) {
462
+ this.updatePointerA(this.a());
463
+ }
464
+ }
465
+ handlerColorChange(key, value, silent = false) {
466
+ let config = {};
467
+ switch (key) {
468
+ case 'h':
469
+ config = { hPoint: true, hex: true, rgb: true, hue: true };
470
+ break;
471
+ case 's':
472
+ config = { slPoint: true, hex: true, rgb: true };
473
+ break;
474
+ case 'l':
475
+ config = { slPoint: true, hex: true, rgb: true };
476
+ break;
477
+ case 'r':
478
+ config = { hPoint: true, slPoint: true, hex: true, hsl: true, hue: true };
479
+ break;
480
+ case 'g':
481
+ config = { hPoint: true, slPoint: true, hex: true, hsl: true, hue: true };
482
+ break;
483
+ case 'b':
484
+ config = { hPoint: true, slPoint: true, hex: true, hsl: true, hue: true };
485
+ break;
486
+ case 'rgb':
487
+ this.r.set(value[0]);
488
+ this.g.set(value[1]);
489
+ this.b.set(value[2]);
490
+ config = { hex: true, hsl: true };
491
+ break;
492
+ case 'rgba':
493
+ this.r.set(value[0]);
494
+ this.g.set(value[1]);
495
+ this.b.set(value[2]);
496
+ this.a.set(value[3]);
497
+ config = { hPoint: true, slPoint: true, hex: true, aPoint: true, hsl: true, hue: true };
498
+ break;
499
+ case 'hsl':
500
+ this.h.set(value[0]);
501
+ this.s.set(value[1]);
502
+ this.l.set(value[2]);
503
+ config = { hPoint: true, slPoint: true, hex: true, aPoint: true, rgb: true, hue: true };
504
+ break;
505
+ case 'hsla':
506
+ this.h.set(value[0]);
507
+ this.s.set(value[1]);
508
+ this.l.set(value[2]);
509
+ this.a.set(value[3]);
510
+ config = { hPoint: true, slPoint: true, hex: true, aPoint: true, rgb: true, hue: true };
511
+ break;
512
+ case 'hex': {
513
+ const rgba = cssColorToRgba(value) || [this.r(), this.g(), this.b(), this.a()];
514
+ this.r.set(rgba[0]);
515
+ this.g.set(rgba[1]);
516
+ this.b.set(rgba[2]);
517
+ this.a.set(rgba[3]);
518
+ config = { hPoint: true, slPoint: true, aPoint: true, hsl: true, hue: true };
519
+ break;
520
+ }
521
+ case 'color': {
522
+ const rgba = (parseColor(value, 'rgba') || [0, 0, 0, 1]);
523
+ this.r.set(rgba[0]);
524
+ this.g.set(rgba[1]);
525
+ this.b.set(rgba[2]);
526
+ this.a.set(rgba[3]);
527
+ config = { hPoint: true, slPoint: true, hex: true, aPoint: true, hsl: true, hue: true };
528
+ break;
529
+ }
530
+ case 'alpha':
531
+ this.a.set(value);
532
+ this.updateHex(this.r(), this.g(), this.b(), this.a());
533
+ break;
534
+ }
535
+ this.updateValuesAndPointer(config);
536
+ set(this.previewEl()?.nativeElement.style, 'backgroundColor', this.a() === 1 ? `rgb(${this.r()},${this.g()},${this.b()})` : `rgba(${this.r()},${this.g()},${this.b()},${this.a()})`);
537
+ if (!silent) {
538
+ this.outColorChange.emit(this.hex());
539
+ }
540
+ }
541
+ handlerFocusAndBlur(event, key) {
542
+ this.focus.set(event.name === 'blur' ? undefined : key);
543
+ }
544
+ handlerValueChange(event, key) {
545
+ this.handlerColorChange(key, event);
546
+ }
547
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LibsUiComponentsColorPickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
548
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: LibsUiComponentsColorPickerComponent, isStandalone: true, selector: "libs_ui-components-color_picker", inputs: { customOptions: { classPropertyName: "customOptions", publicName: "customOptions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { outColorChange: "outColorChange" }, viewQueries: [{ propertyName: "hueEl", first: true, predicate: ["hueEl"], descendants: true, isSignal: true }, { propertyName: "huePointerEl", first: true, predicate: ["huePointerEl"], descendants: true, isSignal: true }, { propertyName: "slEl", first: true, predicate: ["slEl"], descendants: true, isSignal: true }, { propertyName: "slPointerEl", first: true, predicate: ["slPointerEl"], descendants: true, isSignal: true }, { propertyName: "alphaEl", first: true, predicate: ["alphaEl"], descendants: true, isSignal: true }, { propertyName: "alphaPointerEl", first: true, predicate: ["alphaPointerEl"], descendants: true, isSignal: true }, { propertyName: "previewEl", first: true, predicate: ["previewEl"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"relative\"\n [style.width.px]=\"options().slBarSize[0]\">\n <div class=\"cursor-pointer\">\n <canvas #slEl\n class=\"rounded-tl-[4px] rounded-tr-[4px] libs-ui-color-picker-background-transparent\"></canvas>\n <div #slPointerEl\n class=\"libs-ui-color-picker-dot\"></div>\n </div>\n <div class=\"relative\">\n <canvas #hueEl\n class=\"libs-ui-color-picker-background-transparent\"\n [class.rounded-bl-[4px]]=\"!options().showAlpha\"\n [class.rounded-br-[4px]]=\"!options().showAlpha\"></canvas>\n <div #huePointerEl\n class=\"libs-ui-color-picker-dot\"></div>\n </div>\n @if (options().showAlpha) {\n <div class=\"relative\">\n <canvas #alphaEl\n class=\"rounded-bl-[4px] rounded-br-[4px] libs-ui-color-picker-background-transparent\">\n </canvas>\n <div #alphaPointerEl\n class=\"libs-ui-color-picker-dot\"></div>\n </div>\n }\n <div class=\"flex items-end\">\n <div class=\"text-center mr-[16px]\">\n <div class=\"libs-ui-color-picker-background-transparent rounded-[4px]\">\n <div #previewEl\n class=\"w-[32px] h-[32px] rounded-[4px] cursor-pointer\"\n (click)=\"handlerCopyColor($event)\"></div>\n </div>\n </div>\n @if (options().showHex) {\n <div class=\"text-center mr-[12px]\">\n <span class=\"libs-ui-font-h7r text-[#6a7383]\">HEX</span>\n <div class=\"w-[88px]\">\n <libs_ui-components-inputs-input [(value)]=\"hex\"\n [classInclude]=\"'text-center !p-0'\"\n (outChange)=\"handlerValueChange($event, 'hex')\" />\n </div>\n </div>\n }\n <div>\n @if (options().showHsl) {\n <div class=\"flex\">\n <div class=\"text-center\">\n <span class=\"libs-ui-font-h7r text-[#6a7383]\">H</span>\n <div class=\"w-[56px]\">\n <libs_ui-components-inputs-input [(value)]=\"h\"\n [dataType]=\"'int'\"\n [minValueNumber]=\"0\"\n [maxValueNumber]=\"360\"\n [classInclude]=\"'text-center !p-0 !rounded-tr-none !rounded-br-none ' + (focus() === 's' ? '!border-r-transparent' : '')\"\n (outFocusAndBlurEvent)=\"handlerFocusAndBlur($event, 'h')\"\n (outChange)=\"handlerValueChange($event, 'h')\" />\n </div>\n </div>\n <div class=\"text-center\">\n <span class=\"libs-ui-font-h7r text-[#6a7383]\">S</span>\n <div class=\"w-[56px]\">\n <libs_ui-components-inputs-input [(value)]=\"s\"\n [dataType]=\"'int'\"\n [minValueNumber]=\"0\"\n [maxValueNumber]=\"100\"\n [classInclude]=\"'text-center !p-0 !rounded-none ' + (focus() === 's' ? '' : '!border-x-transparent')\"\n (outFocusAndBlurEvent)=\"handlerFocusAndBlur($event, 's')\"\n (outChange)=\"handlerValueChange($event, 's')\" />\n </div>\n </div>\n <div class=\"text-center\">\n <span class=\"libs-ui-font-h7r text-[#6a7383]\">L</span>\n <div class=\"w-[56px]\">\n <libs_ui-components-inputs-input [(value)]=\"l\"\n [dataType]=\"'int'\"\n [minValueNumber]=\"0\"\n [maxValueNumber]=\"100\"\n [classInclude]=\"'text-center !p-0 !rounded-tl-none !rounded-bl-none ' + (focus() === 's' ? '!border-l-transparent' : '')\"\n (outFocusAndBlurEvent)=\"handlerFocusAndBlur($event, 'l')\"\n (outChange)=\"handlerValueChange($event, 'l')\" />\n </div>\n </div>\n </div>\n }\n @if (options().showRgb) {\n <div class=\"flex\">\n <div class=\"text-center\">\n <span class=\"libs-ui-font-h7r text-[#6a7383]\">R</span>\n <div class=\"w-[56px]\">\n <libs_ui-components-inputs-input [(value)]=\"r\"\n [dataType]=\"'int'\"\n [minValueNumber]=\"0\"\n [maxValueNumber]=\"255\"\n [classInclude]=\"'text-center !p-0 !rounded-tr-none !rounded-br-none ' + (focus() === 'g' ? '!border-r-transparent' : '')\"\n (outFocusAndBlurEvent)=\"handlerFocusAndBlur($event, 'r')\"\n (outChange)=\"handlerValueChange($event, 'r')\" />\n </div>\n </div>\n <div class=\"text-center\">\n <span class=\"libs-ui-font-h7r text-[#6a7383]\">G</span>\n <div class=\"w-[56px]\">\n <libs_ui-components-inputs-input [(value)]=\"g\"\n [dataType]=\"'int'\"\n [minValueNumber]=\"0\"\n [maxValueNumber]=\"255\"\n [classInclude]=\"'text-center !p-0 !rounded-none ' + (focus() === 'g' ? '' : '!border-x-transparent')\"\n (outFocusAndBlurEvent)=\"handlerFocusAndBlur($event, 'g')\"\n (outChange)=\"handlerValueChange($event, 'g')\" />\n </div>\n </div>\n <div class=\"text-center\">\n <span class=\"libs-ui-font-h7r text-[#6a7383]\">B</span>\n <div class=\"w-[56px]\">\n <libs_ui-components-inputs-input [(value)]=\"b\"\n [dataType]=\"'int'\"\n [minValueNumber]=\"0\"\n [maxValueNumber]=\"255\"\n [classInclude]=\"'text-center !p-0 !rounded-tl-none !rounded-bl-none ' + (focus() === 'g' ? '!border-l-transparent' : '')\"\n (outFocusAndBlurEvent)=\"handlerFocusAndBlur($event, 'b')\"\n (outChange)=\"handlerValueChange($event, 'b')\" />\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n</div>\n", styles: [".libs-ui-color-picker-background-transparent{background-image:conic-gradient(rgba(0,0,0,.06) 0 25%,transparent 0 50%,rgba(0,0,0,.06) 0 75%,transparent 0);background-size:11px 11px}.libs-ui-color-picker-dot{position:absolute;width:14px;height:14px;top:3px;left:0;background:transparent;border:1px solid #ffffff;pointer-events:none;border-radius:50px;z-index:1;box-shadow:0 1px 2px #000000bf}\n"], dependencies: [{ kind: "component", type: LibsUiComponentsInputsInputComponent, selector: "libs_ui-components-inputs-input", inputs: ["tagInput", "dataType", "tabInsertContentTagInput", "textAreaEnterNotNewLine", "emitEmptyInDataTypeNumber", "keepZeroInTypeInt", "autoAddZeroLessThan10InTypeInt", "ignoreBlockInputMaxValue", "hiddenContent", "maxValueNumber", "minValueNumber", "fixedFloat", "acceptNegativeValue", "valueUpDownNumber", "classInclude", "maxLength", "readonly", "disable", "noBorder", "backgroundNone", "borderError", "useColorModeExist", "placeholder", "keepPlaceholderOnly", "value", "autoRemoveEmoji", "defaultHeight", "minHeightTextArea", "maxHeightTextArea", "focusTimeOut", "blurTimeOut", "zIndexPopoverContent", "classContainerInput", "showCount", "ignoreStopPropagationEvent", "resize", "templateLeftBottomInput", "templateRightBottomInput", "classContainerBottomInput", "ignoreWidthInput100", "iconLeftClass", "popoverContentIconLeft", "iconRightClass", "popoverContentIconRight", "resetAutoCompletePassword", "acceptOnlyClickIcon", "setIconRightColorSameColorDisableReadOnly", "onlyAcceptNegativeValue", "maxLengthNumberCount", "focusInput"], outputs: ["maxValueNumberChange", "minValueNumberChange", "fixedFloatChange", "acceptNegativeValueChange", "maxLengthChange", "valueChange", "maxLengthNumberCountChange", "outHeightAreaChange", "outChange", "outFocusAndBlurEvent", "outEnterEvent", "outInputEvent", "outIconLeft", "outIconRight", "outFunctionsControl", "outFilesDrop", "outFileDrop", "outChangeValueByButtonUpDown"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
549
+ }
550
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: LibsUiComponentsColorPickerComponent, decorators: [{
551
+ type: Component,
552
+ args: [{ selector: 'libs_ui-components-color_picker', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
553
+ LibsUiComponentsInputsInputComponent
554
+ ], template: "<div class=\"relative\"\n [style.width.px]=\"options().slBarSize[0]\">\n <div class=\"cursor-pointer\">\n <canvas #slEl\n class=\"rounded-tl-[4px] rounded-tr-[4px] libs-ui-color-picker-background-transparent\"></canvas>\n <div #slPointerEl\n class=\"libs-ui-color-picker-dot\"></div>\n </div>\n <div class=\"relative\">\n <canvas #hueEl\n class=\"libs-ui-color-picker-background-transparent\"\n [class.rounded-bl-[4px]]=\"!options().showAlpha\"\n [class.rounded-br-[4px]]=\"!options().showAlpha\"></canvas>\n <div #huePointerEl\n class=\"libs-ui-color-picker-dot\"></div>\n </div>\n @if (options().showAlpha) {\n <div class=\"relative\">\n <canvas #alphaEl\n class=\"rounded-bl-[4px] rounded-br-[4px] libs-ui-color-picker-background-transparent\">\n </canvas>\n <div #alphaPointerEl\n class=\"libs-ui-color-picker-dot\"></div>\n </div>\n }\n <div class=\"flex items-end\">\n <div class=\"text-center mr-[16px]\">\n <div class=\"libs-ui-color-picker-background-transparent rounded-[4px]\">\n <div #previewEl\n class=\"w-[32px] h-[32px] rounded-[4px] cursor-pointer\"\n (click)=\"handlerCopyColor($event)\"></div>\n </div>\n </div>\n @if (options().showHex) {\n <div class=\"text-center mr-[12px]\">\n <span class=\"libs-ui-font-h7r text-[#6a7383]\">HEX</span>\n <div class=\"w-[88px]\">\n <libs_ui-components-inputs-input [(value)]=\"hex\"\n [classInclude]=\"'text-center !p-0'\"\n (outChange)=\"handlerValueChange($event, 'hex')\" />\n </div>\n </div>\n }\n <div>\n @if (options().showHsl) {\n <div class=\"flex\">\n <div class=\"text-center\">\n <span class=\"libs-ui-font-h7r text-[#6a7383]\">H</span>\n <div class=\"w-[56px]\">\n <libs_ui-components-inputs-input [(value)]=\"h\"\n [dataType]=\"'int'\"\n [minValueNumber]=\"0\"\n [maxValueNumber]=\"360\"\n [classInclude]=\"'text-center !p-0 !rounded-tr-none !rounded-br-none ' + (focus() === 's' ? '!border-r-transparent' : '')\"\n (outFocusAndBlurEvent)=\"handlerFocusAndBlur($event, 'h')\"\n (outChange)=\"handlerValueChange($event, 'h')\" />\n </div>\n </div>\n <div class=\"text-center\">\n <span class=\"libs-ui-font-h7r text-[#6a7383]\">S</span>\n <div class=\"w-[56px]\">\n <libs_ui-components-inputs-input [(value)]=\"s\"\n [dataType]=\"'int'\"\n [minValueNumber]=\"0\"\n [maxValueNumber]=\"100\"\n [classInclude]=\"'text-center !p-0 !rounded-none ' + (focus() === 's' ? '' : '!border-x-transparent')\"\n (outFocusAndBlurEvent)=\"handlerFocusAndBlur($event, 's')\"\n (outChange)=\"handlerValueChange($event, 's')\" />\n </div>\n </div>\n <div class=\"text-center\">\n <span class=\"libs-ui-font-h7r text-[#6a7383]\">L</span>\n <div class=\"w-[56px]\">\n <libs_ui-components-inputs-input [(value)]=\"l\"\n [dataType]=\"'int'\"\n [minValueNumber]=\"0\"\n [maxValueNumber]=\"100\"\n [classInclude]=\"'text-center !p-0 !rounded-tl-none !rounded-bl-none ' + (focus() === 's' ? '!border-l-transparent' : '')\"\n (outFocusAndBlurEvent)=\"handlerFocusAndBlur($event, 'l')\"\n (outChange)=\"handlerValueChange($event, 'l')\" />\n </div>\n </div>\n </div>\n }\n @if (options().showRgb) {\n <div class=\"flex\">\n <div class=\"text-center\">\n <span class=\"libs-ui-font-h7r text-[#6a7383]\">R</span>\n <div class=\"w-[56px]\">\n <libs_ui-components-inputs-input [(value)]=\"r\"\n [dataType]=\"'int'\"\n [minValueNumber]=\"0\"\n [maxValueNumber]=\"255\"\n [classInclude]=\"'text-center !p-0 !rounded-tr-none !rounded-br-none ' + (focus() === 'g' ? '!border-r-transparent' : '')\"\n (outFocusAndBlurEvent)=\"handlerFocusAndBlur($event, 'r')\"\n (outChange)=\"handlerValueChange($event, 'r')\" />\n </div>\n </div>\n <div class=\"text-center\">\n <span class=\"libs-ui-font-h7r text-[#6a7383]\">G</span>\n <div class=\"w-[56px]\">\n <libs_ui-components-inputs-input [(value)]=\"g\"\n [dataType]=\"'int'\"\n [minValueNumber]=\"0\"\n [maxValueNumber]=\"255\"\n [classInclude]=\"'text-center !p-0 !rounded-none ' + (focus() === 'g' ? '' : '!border-x-transparent')\"\n (outFocusAndBlurEvent)=\"handlerFocusAndBlur($event, 'g')\"\n (outChange)=\"handlerValueChange($event, 'g')\" />\n </div>\n </div>\n <div class=\"text-center\">\n <span class=\"libs-ui-font-h7r text-[#6a7383]\">B</span>\n <div class=\"w-[56px]\">\n <libs_ui-components-inputs-input [(value)]=\"b\"\n [dataType]=\"'int'\"\n [minValueNumber]=\"0\"\n [maxValueNumber]=\"255\"\n [classInclude]=\"'text-center !p-0 !rounded-tl-none !rounded-bl-none ' + (focus() === 'g' ? '!border-l-transparent' : '')\"\n (outFocusAndBlurEvent)=\"handlerFocusAndBlur($event, 'b')\"\n (outChange)=\"handlerValueChange($event, 'b')\" />\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n</div>\n", styles: [".libs-ui-color-picker-background-transparent{background-image:conic-gradient(rgba(0,0,0,.06) 0 25%,transparent 0 50%,rgba(0,0,0,.06) 0 75%,transparent 0);background-size:11px 11px}.libs-ui-color-picker-dot{position:absolute;width:14px;height:14px;top:3px;left:0;background:transparent;border:1px solid #ffffff;pointer-events:none;border-radius:50px;z-index:1;box-shadow:0 1px 2px #000000bf}\n"] }]
555
+ }], ctorParameters: () => [] });
556
+
557
+ /**
558
+ * Generated bundle index. Do not edit.
559
+ */
560
+
561
+ export { LibsUiComponentsColorPickerComponent };
562
+ //# sourceMappingURL=libs-ui-components-color-picker.mjs.map