@eagami/ui 0.4.1 → 0.5.0

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.
@@ -1,8 +1,380 @@
1
1
  import { NgClass } from '@angular/common';
2
2
  import * as i0 from '@angular/core';
3
- import { viewChild, input, output, signal, computed, effect, ViewEncapsulation, ChangeDetectionStrategy, Component, model, forwardRef, HostListener, inject, Injectable, ElementRef, Renderer2, Directive } from '@angular/core';
3
+ import { ChangeDetectionStrategy, Component, inject, ElementRef, Renderer2, input, Directive, viewChild, output, signal, computed, Injector, effect, afterNextRender, ViewEncapsulation, model, forwardRef, HostListener, Injectable } from '@angular/core';
4
4
  import { NG_VALUE_ACCESSOR } from '@angular/forms';
5
5
 
6
+ class CameraIconComponent {
7
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CameraIconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
8
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.5", type: CameraIconComponent, isStandalone: true, selector: "ea-icon-camera", host: { styleAttribute: "display: inline-flex;" }, ngImport: i0, template: `
9
+ <svg
10
+ viewBox="0 0 24 24"
11
+ fill="none"
12
+ stroke="currentColor"
13
+ stroke-width="1.5"
14
+ stroke-linecap="round"
15
+ stroke-linejoin="round"
16
+ aria-hidden="true"
17
+ width="100%"
18
+ height="100%">
19
+ <path
20
+ d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z" />
21
+ <circle
22
+ cx="12"
23
+ cy="13"
24
+ r="4" />
25
+ </svg>
26
+ `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
27
+ }
28
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CameraIconComponent, decorators: [{
29
+ type: Component,
30
+ args: [{
31
+ selector: 'ea-icon-camera',
32
+ changeDetection: ChangeDetectionStrategy.OnPush,
33
+ host: { style: 'display: inline-flex;' },
34
+ template: `
35
+ <svg
36
+ viewBox="0 0 24 24"
37
+ fill="none"
38
+ stroke="currentColor"
39
+ stroke-width="1.5"
40
+ stroke-linecap="round"
41
+ stroke-linejoin="round"
42
+ aria-hidden="true"
43
+ width="100%"
44
+ height="100%">
45
+ <path
46
+ d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z" />
47
+ <circle
48
+ cx="12"
49
+ cy="13"
50
+ r="4" />
51
+ </svg>
52
+ `,
53
+ }]
54
+ }] });
55
+
56
+ class MinusIconComponent {
57
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: MinusIconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
58
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.5", type: MinusIconComponent, isStandalone: true, selector: "ea-icon-minus", host: { styleAttribute: "display: inline-flex;" }, ngImport: i0, template: `
59
+ <svg
60
+ viewBox="0 0 24 24"
61
+ fill="none"
62
+ stroke="currentColor"
63
+ stroke-width="2"
64
+ stroke-linecap="round"
65
+ stroke-linejoin="round"
66
+ aria-hidden="true"
67
+ width="100%"
68
+ height="100%">
69
+ <line
70
+ x1="5"
71
+ y1="12"
72
+ x2="19"
73
+ y2="12" />
74
+ </svg>
75
+ `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
76
+ }
77
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: MinusIconComponent, decorators: [{
78
+ type: Component,
79
+ args: [{
80
+ selector: 'ea-icon-minus',
81
+ changeDetection: ChangeDetectionStrategy.OnPush,
82
+ host: { style: 'display: inline-flex;' },
83
+ template: `
84
+ <svg
85
+ viewBox="0 0 24 24"
86
+ fill="none"
87
+ stroke="currentColor"
88
+ stroke-width="2"
89
+ stroke-linecap="round"
90
+ stroke-linejoin="round"
91
+ aria-hidden="true"
92
+ width="100%"
93
+ height="100%">
94
+ <line
95
+ x1="5"
96
+ y1="12"
97
+ x2="19"
98
+ y2="12" />
99
+ </svg>
100
+ `,
101
+ }]
102
+ }] });
103
+
104
+ class PlusIconComponent {
105
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: PlusIconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
106
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.5", type: PlusIconComponent, isStandalone: true, selector: "ea-icon-plus", host: { styleAttribute: "display: inline-flex;" }, ngImport: i0, template: `
107
+ <svg
108
+ viewBox="0 0 24 24"
109
+ fill="none"
110
+ stroke="currentColor"
111
+ stroke-width="2"
112
+ stroke-linecap="round"
113
+ stroke-linejoin="round"
114
+ aria-hidden="true"
115
+ width="100%"
116
+ height="100%">
117
+ <line
118
+ x1="12"
119
+ y1="5"
120
+ x2="12"
121
+ y2="19" />
122
+ <line
123
+ x1="5"
124
+ y1="12"
125
+ x2="19"
126
+ y2="12" />
127
+ </svg>
128
+ `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
129
+ }
130
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: PlusIconComponent, decorators: [{
131
+ type: Component,
132
+ args: [{
133
+ selector: 'ea-icon-plus',
134
+ changeDetection: ChangeDetectionStrategy.OnPush,
135
+ host: { style: 'display: inline-flex;' },
136
+ template: `
137
+ <svg
138
+ viewBox="0 0 24 24"
139
+ fill="none"
140
+ stroke="currentColor"
141
+ stroke-width="2"
142
+ stroke-linecap="round"
143
+ stroke-linejoin="round"
144
+ aria-hidden="true"
145
+ width="100%"
146
+ height="100%">
147
+ <line
148
+ x1="12"
149
+ y1="5"
150
+ x2="12"
151
+ y2="19" />
152
+ <line
153
+ x1="5"
154
+ y1="12"
155
+ x2="19"
156
+ y2="12" />
157
+ </svg>
158
+ `,
159
+ }]
160
+ }] });
161
+
162
+ class RotateCcwIconComponent {
163
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: RotateCcwIconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
164
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.5", type: RotateCcwIconComponent, isStandalone: true, selector: "ea-icon-rotate-ccw", host: { styleAttribute: "display: inline-flex;" }, ngImport: i0, template: `
165
+ <svg
166
+ viewBox="0 0 24 24"
167
+ fill="none"
168
+ stroke="currentColor"
169
+ stroke-width="2"
170
+ stroke-linecap="round"
171
+ stroke-linejoin="round"
172
+ aria-hidden="true"
173
+ width="100%"
174
+ height="100%">
175
+ <polyline points="1 4 1 10 7 10" />
176
+ <path d="M3.51 15a9 9 0 1 0 2.13-9.36L1 10" />
177
+ </svg>
178
+ `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
179
+ }
180
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: RotateCcwIconComponent, decorators: [{
181
+ type: Component,
182
+ args: [{
183
+ selector: 'ea-icon-rotate-ccw',
184
+ changeDetection: ChangeDetectionStrategy.OnPush,
185
+ host: { style: 'display: inline-flex;' },
186
+ template: `
187
+ <svg
188
+ viewBox="0 0 24 24"
189
+ fill="none"
190
+ stroke="currentColor"
191
+ stroke-width="2"
192
+ stroke-linecap="round"
193
+ stroke-linejoin="round"
194
+ aria-hidden="true"
195
+ width="100%"
196
+ height="100%">
197
+ <polyline points="1 4 1 10 7 10" />
198
+ <path d="M3.51 15a9 9 0 1 0 2.13-9.36L1 10" />
199
+ </svg>
200
+ `,
201
+ }]
202
+ }] });
203
+
204
+ class TrashIconComponent {
205
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: TrashIconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
206
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.5", type: TrashIconComponent, isStandalone: true, selector: "ea-icon-trash", host: { styleAttribute: "display: inline-flex;" }, ngImport: i0, template: `
207
+ <svg
208
+ viewBox="0 0 24 24"
209
+ fill="none"
210
+ stroke="currentColor"
211
+ stroke-width="2"
212
+ stroke-linecap="round"
213
+ stroke-linejoin="round"
214
+ aria-hidden="true"
215
+ width="100%"
216
+ height="100%">
217
+ <polyline points="3 6 5 6 21 6" />
218
+ <path
219
+ d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" />
220
+ </svg>
221
+ `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
222
+ }
223
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: TrashIconComponent, decorators: [{
224
+ type: Component,
225
+ args: [{
226
+ selector: 'ea-icon-trash',
227
+ changeDetection: ChangeDetectionStrategy.OnPush,
228
+ host: { style: 'display: inline-flex;' },
229
+ template: `
230
+ <svg
231
+ viewBox="0 0 24 24"
232
+ fill="none"
233
+ stroke="currentColor"
234
+ stroke-width="2"
235
+ stroke-linecap="round"
236
+ stroke-linejoin="round"
237
+ aria-hidden="true"
238
+ width="100%"
239
+ height="100%">
240
+ <polyline points="3 6 5 6 21 6" />
241
+ <path
242
+ d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" />
243
+ </svg>
244
+ `,
245
+ }]
246
+ }] });
247
+
248
+ class UploadIconComponent {
249
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: UploadIconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
250
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.5", type: UploadIconComponent, isStandalone: true, selector: "ea-icon-upload", host: { styleAttribute: "display: inline-flex;" }, ngImport: i0, template: `
251
+ <svg
252
+ viewBox="0 0 24 24"
253
+ fill="none"
254
+ stroke="currentColor"
255
+ stroke-width="1.5"
256
+ stroke-linecap="round"
257
+ stroke-linejoin="round"
258
+ aria-hidden="true"
259
+ width="100%"
260
+ height="100%">
261
+ <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
262
+ <polyline points="17 8 12 3 7 8" />
263
+ <line
264
+ x1="12"
265
+ y1="3"
266
+ x2="12"
267
+ y2="15" />
268
+ </svg>
269
+ `, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
270
+ }
271
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: UploadIconComponent, decorators: [{
272
+ type: Component,
273
+ args: [{
274
+ selector: 'ea-icon-upload',
275
+ changeDetection: ChangeDetectionStrategy.OnPush,
276
+ host: { style: 'display: inline-flex;' },
277
+ template: `
278
+ <svg
279
+ viewBox="0 0 24 24"
280
+ fill="none"
281
+ stroke="currentColor"
282
+ stroke-width="1.5"
283
+ stroke-linecap="round"
284
+ stroke-linejoin="round"
285
+ aria-hidden="true"
286
+ width="100%"
287
+ height="100%">
288
+ <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" />
289
+ <polyline points="17 8 12 3 7 8" />
290
+ <line
291
+ x1="12"
292
+ y1="3"
293
+ x2="12"
294
+ y2="15" />
295
+ </svg>
296
+ `,
297
+ }]
298
+ }] });
299
+
300
+ class TooltipDirective {
301
+ el = inject(ElementRef);
302
+ renderer = inject(Renderer2);
303
+ eaTooltip = input.required(...(ngDevMode ? [{ debugName: "eaTooltip" }] : /* istanbul ignore next */ []));
304
+ tooltipPosition = input('top', ...(ngDevMode ? [{ debugName: "tooltipPosition" }] : /* istanbul ignore next */ []));
305
+ tooltipEl = null;
306
+ showHandler = () => this.show();
307
+ hideHandler = () => this.hide();
308
+ constructor() {
309
+ const native = this.el.nativeElement;
310
+ native.addEventListener('mouseenter', this.showHandler);
311
+ native.addEventListener('mouseleave', this.hideHandler);
312
+ native.addEventListener('focus', this.showHandler);
313
+ native.addEventListener('blur', this.hideHandler);
314
+ }
315
+ ngOnDestroy() {
316
+ const native = this.el.nativeElement;
317
+ native.removeEventListener('mouseenter', this.showHandler);
318
+ native.removeEventListener('mouseleave', this.hideHandler);
319
+ native.removeEventListener('focus', this.showHandler);
320
+ native.removeEventListener('blur', this.hideHandler);
321
+ this.hide();
322
+ }
323
+ show() {
324
+ if (this.tooltipEl || !this.eaTooltip())
325
+ return;
326
+ this.tooltipEl = this.renderer.createElement('div');
327
+ this.renderer.addClass(this.tooltipEl, 'ea-tooltip');
328
+ this.renderer.addClass(this.tooltipEl, `ea-tooltip--${this.tooltipPosition()}`);
329
+ this.tooltipEl.textContent = this.eaTooltip();
330
+ this.renderer.appendChild(document.body, this.tooltipEl);
331
+ this.positionTooltip();
332
+ }
333
+ hide() {
334
+ if (this.tooltipEl) {
335
+ this.tooltipEl.remove();
336
+ this.tooltipEl = null;
337
+ }
338
+ }
339
+ positionTooltip() {
340
+ if (!this.tooltipEl)
341
+ return;
342
+ const hostRect = this.el.nativeElement.getBoundingClientRect();
343
+ const tooltipRect = this.tooltipEl.getBoundingClientRect();
344
+ const gap = 8;
345
+ let top;
346
+ let left;
347
+ switch (this.tooltipPosition()) {
348
+ case 'top':
349
+ top = hostRect.top - tooltipRect.height - gap;
350
+ left = hostRect.left + (hostRect.width - tooltipRect.width) / 2;
351
+ break;
352
+ case 'bottom':
353
+ top = hostRect.bottom + gap;
354
+ left = hostRect.left + (hostRect.width - tooltipRect.width) / 2;
355
+ break;
356
+ case 'left':
357
+ top = hostRect.top + (hostRect.height - tooltipRect.height) / 2;
358
+ left = hostRect.left - tooltipRect.width - gap;
359
+ break;
360
+ case 'right':
361
+ top = hostRect.top + (hostRect.height - tooltipRect.height) / 2;
362
+ left = hostRect.right + gap;
363
+ break;
364
+ }
365
+ this.renderer.setStyle(this.tooltipEl, 'top', `${top + window.scrollY}px`);
366
+ this.renderer.setStyle(this.tooltipEl, 'left', `${left + window.scrollX}px`);
367
+ }
368
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: TooltipDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
369
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.5", type: TooltipDirective, isStandalone: true, selector: "[eaTooltip]", inputs: { eaTooltip: { classPropertyName: "eaTooltip", publicName: "eaTooltip", isSignal: true, isRequired: true, transformFunction: null }, tooltipPosition: { classPropertyName: "tooltipPosition", publicName: "tooltipPosition", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
370
+ }
371
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: TooltipDirective, decorators: [{
372
+ type: Directive,
373
+ args: [{
374
+ selector: '[eaTooltip]',
375
+ }]
376
+ }], ctorParameters: () => [], propDecorators: { eaTooltip: [{ type: i0.Input, args: [{ isSignal: true, alias: "eaTooltip", required: true }] }], tooltipPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "tooltipPosition", required: false }] }] } });
377
+
6
378
  class AvatarEditorComponent {
7
379
  canvasEl = viewChild('canvasEl', ...(ngDevMode ? [{ debugName: "canvasEl" }] : /* istanbul ignore next */ []));
8
380
  fileInputEl = viewChild('fileInputEl', ...(ngDevMode ? [{ debugName: "fileInputEl" }] : /* istanbul ignore next */ []));
@@ -16,16 +388,19 @@ class AvatarEditorComponent {
16
388
  exportQuality = input(0.92, ...(ngDevMode ? [{ debugName: "exportQuality" }] : /* istanbul ignore next */ []));
17
389
  exportType = input('image/png', ...(ngDevMode ? [{ debugName: "exportType" }] : /* istanbul ignore next */ []));
18
390
  cropped = output();
391
+ removed = output();
19
392
  fileError = output();
20
393
  hasImage = signal(false, ...(ngDevMode ? [{ debugName: "hasImage" }] : /* istanbul ignore next */ []));
21
394
  isDragOver = signal(false, ...(ngDevMode ? [{ debugName: "isDragOver" }] : /* istanbul ignore next */ []));
22
395
  zoom = signal(1, ...(ngDevMode ? [{ debugName: "zoom" }] : /* istanbul ignore next */ []));
396
+ canRevert = computed(() => this.hasImage() && !!this.currentSrc(), ...(ngDevMode ? [{ debugName: "canRevert" }] : /* istanbul ignore next */ []));
23
397
  image = null;
24
398
  offsetX = 0;
25
399
  offsetY = 0;
26
400
  dragStartX = 0;
27
401
  dragStartY = 0;
28
402
  isDragging = false;
403
+ hasDragged = false;
29
404
  initialOffsetX = 0;
30
405
  initialOffsetY = 0;
31
406
  hostClasses = computed(() => ({
@@ -33,6 +408,7 @@ class AvatarEditorComponent {
33
408
  'ea-avatar-editor--has-image': this.hasImage(),
34
409
  'ea-avatar-editor--drag-over': this.isDragOver(),
35
410
  }), ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
411
+ injector = inject(Injector);
36
412
  boundWheel = (e) => this.onWheel(e);
37
413
  constructor() {
38
414
  effect(() => {
@@ -79,6 +455,7 @@ class AvatarEditorComponent {
79
455
  return;
80
456
  event.preventDefault();
81
457
  this.isDragging = true;
458
+ this.hasDragged = false;
82
459
  this.dragStartX = event.clientX;
83
460
  this.dragStartY = event.clientY;
84
461
  this.initialOffsetX = this.offsetX;
@@ -91,6 +468,7 @@ class AvatarEditorComponent {
91
468
  return;
92
469
  const touch = event.touches[0];
93
470
  this.isDragging = true;
471
+ this.hasDragged = false;
94
472
  this.dragStartX = touch.clientX;
95
473
  this.dragStartY = touch.clientY;
96
474
  this.initialOffsetX = this.offsetX;
@@ -107,12 +485,16 @@ class AvatarEditorComponent {
107
485
  return;
108
486
  const dx = event.clientX - this.dragStartX;
109
487
  const dy = event.clientY - this.dragStartY;
488
+ if (Math.abs(dx) > 3 || Math.abs(dy) > 3)
489
+ this.hasDragged = true;
110
490
  this.offsetX = this.initialOffsetX + dx;
111
491
  this.offsetY = this.initialOffsetY + dy;
112
492
  this.clampOffset();
113
493
  this.draw();
114
494
  }
115
495
  onMouseUp() {
496
+ if (!this.hasDragged)
497
+ this.openFilePicker();
116
498
  this.isDragging = false;
117
499
  document.removeEventListener('mousemove', this.onMouseMoveBound);
118
500
  document.removeEventListener('mouseup', this.onMouseUpBound);
@@ -124,12 +506,16 @@ class AvatarEditorComponent {
124
506
  const touch = event.touches[0];
125
507
  const dx = touch.clientX - this.dragStartX;
126
508
  const dy = touch.clientY - this.dragStartY;
509
+ if (Math.abs(dx) > 3 || Math.abs(dy) > 3)
510
+ this.hasDragged = true;
127
511
  this.offsetX = this.initialOffsetX + dx;
128
512
  this.offsetY = this.initialOffsetY + dy;
129
513
  this.clampOffset();
130
514
  this.draw();
131
515
  }
132
516
  onTouchEnd() {
517
+ if (!this.hasDragged)
518
+ this.openFilePicker();
133
519
  this.isDragging = false;
134
520
  document.removeEventListener('touchmove', this.onTouchMoveBound);
135
521
  document.removeEventListener('touchend', this.onTouchEndBound);
@@ -158,6 +544,13 @@ class AvatarEditorComponent {
158
544
  this.offsetX = 0;
159
545
  this.offsetY = 0;
160
546
  this.clearCanvas();
547
+ this.removed.emit();
548
+ }
549
+ revertImage() {
550
+ const src = this.currentSrc();
551
+ if (!src)
552
+ return;
553
+ this.loadFromUrl(src);
161
554
  }
162
555
  exportCrop() {
163
556
  if (!this.image)
@@ -193,12 +586,7 @@ class AvatarEditorComponent {
193
586
  this.hasImage.set(true);
194
587
  this.zoom.set(1);
195
588
  this.centerImage();
196
- requestAnimationFrame(() => {
197
- this.draw();
198
- const canvas = this.canvasEl()?.nativeElement;
199
- canvas?.removeEventListener('wheel', this.boundWheel);
200
- canvas?.addEventListener('wheel', this.boundWheel, { passive: false });
201
- });
589
+ this.scheduleDrawAfterRender();
202
590
  };
203
591
  img.src = url;
204
592
  }
@@ -220,18 +608,20 @@ class AvatarEditorComponent {
220
608
  this.hasImage.set(true);
221
609
  this.zoom.set(1);
222
610
  this.centerImage();
223
- // Defer draw until Angular has rendered the canvas (@if block)
224
- requestAnimationFrame(() => {
225
- this.draw();
226
- const canvas = this.canvasEl()?.nativeElement;
227
- canvas?.removeEventListener('wheel', this.boundWheel);
228
- canvas?.addEventListener('wheel', this.boundWheel, { passive: false });
229
- });
611
+ this.scheduleDrawAfterRender();
230
612
  };
231
613
  img.src = e.target?.result;
232
614
  };
233
615
  reader.readAsDataURL(file);
234
616
  }
617
+ scheduleDrawAfterRender() {
618
+ afterNextRender(() => {
619
+ this.draw();
620
+ const canvas = this.canvasEl()?.nativeElement;
621
+ canvas?.removeEventListener('wheel', this.boundWheel);
622
+ canvas?.addEventListener('wheel', this.boundWheel, { passive: false });
623
+ }, { injector: this.injector });
624
+ }
235
625
  centerImage() {
236
626
  if (!this.image)
237
627
  return;
@@ -303,12 +693,21 @@ class AvatarEditorComponent {
303
693
  ctx.clearRect(0, 0, canvas.width, canvas.height);
304
694
  }
305
695
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: AvatarEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
306
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: AvatarEditorComponent, isStandalone: true, selector: "ea-avatar-editor", inputs: { shape: { classPropertyName: "shape", publicName: "shape", isSignal: true, isRequired: false, transformFunction: null }, canvasSize: { classPropertyName: "canvasSize", publicName: "canvasSize", isSignal: true, isRequired: false, transformFunction: null }, currentSrc: { classPropertyName: "currentSrc", publicName: "currentSrc", isSignal: true, isRequired: false, transformFunction: null }, accept: { classPropertyName: "accept", publicName: "accept", isSignal: true, isRequired: false, transformFunction: null }, maxFileSize: { classPropertyName: "maxFileSize", publicName: "maxFileSize", isSignal: true, isRequired: false, transformFunction: null }, minZoom: { classPropertyName: "minZoom", publicName: "minZoom", isSignal: true, isRequired: false, transformFunction: null }, maxZoom: { classPropertyName: "maxZoom", publicName: "maxZoom", isSignal: true, isRequired: false, transformFunction: null }, exportQuality: { classPropertyName: "exportQuality", publicName: "exportQuality", isSignal: true, isRequired: false, transformFunction: null }, exportType: { classPropertyName: "exportType", publicName: "exportType", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { cropped: "cropped", fileError: "fileError" }, viewQueries: [{ propertyName: "canvasEl", first: true, predicate: ["canvasEl"], descendants: true, isSignal: true }, { propertyName: "fileInputEl", first: true, predicate: ["fileInputEl"], descendants: true, isSignal: true }], ngImport: i0, template: "<div\n class=\"ea-avatar-editor\"\n [ngClass]=\"hostClasses()\">\n\n <input\n #fileInputEl\n type=\"file\"\n class=\"ea-avatar-editor__file-input\"\n [accept]=\"accept()\"\n (change)=\"onFileSelected($event)\" />\n\n @if (!hasImage()) {\n <button\n type=\"button\"\n class=\"ea-avatar-editor__dropzone\"\n [style.width.px]=\"canvasSize()\"\n [style.height.px]=\"canvasSize()\"\n (click)=\"openFilePicker()\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\">\n <svg\n class=\"ea-avatar-editor__upload-icon\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"32\"\n height=\"32\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\">\n <path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\" />\n <polyline points=\"17 8 12 3 7 8\" />\n <line x1=\"12\" y1=\"3\" x2=\"12\" y2=\"15\" />\n </svg>\n <span class=\"ea-avatar-editor__dropzone-text\">\n Drop image or click to upload\n </span>\n </button>\n }\n\n @if (hasImage()) {\n <div class=\"ea-avatar-editor__preview\">\n <canvas\n #canvasEl\n class=\"ea-avatar-editor__canvas\"\n [width]=\"canvasSize()\"\n [height]=\"canvasSize()\"\n (mousedown)=\"onMouseDown($event)\"\n (touchstart)=\"onTouchStart($event)\"></canvas>\n\n <div class=\"ea-avatar-editor__controls\">\n <button\n type=\"button\"\n class=\"ea-avatar-editor__zoom-btn\"\n aria-label=\"Zoom out\"\n [disabled]=\"zoom() <= minZoom()\"\n (click)=\"setZoom(zoom() - 0.1)\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\">\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n </svg>\n </button>\n\n <input\n type=\"range\"\n class=\"ea-avatar-editor__zoom-slider\"\n [min]=\"minZoom()\"\n [max]=\"maxZoom()\"\n step=\"0.01\"\n [value]=\"zoom()\"\n aria-label=\"Zoom\"\n (input)=\"onZoomInput($event)\" />\n\n <button\n type=\"button\"\n class=\"ea-avatar-editor__zoom-btn\"\n aria-label=\"Zoom in\"\n [disabled]=\"zoom() >= maxZoom()\"\n (click)=\"setZoom(zoom() + 0.1)\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\">\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\" />\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n </svg>\n </button>\n </div>\n\n <div class=\"ea-avatar-editor__actions\">\n <button\n type=\"button\"\n class=\"ea-avatar-editor__action-btn ea-avatar-editor__action-btn--secondary\"\n (click)=\"openFilePicker()\">\n Change\n </button>\n <button\n type=\"button\"\n class=\"ea-avatar-editor__action-btn ea-avatar-editor__action-btn--secondary\"\n (click)=\"removeImage()\">\n Remove\n </button>\n <button\n type=\"button\"\n class=\"ea-avatar-editor__action-btn ea-avatar-editor__action-btn--primary\"\n (click)=\"exportCrop()\">\n Apply\n </button>\n </div>\n </div>\n }\n</div>\n", styles: [".ea-avatar-editor{display:inline-flex;flex-direction:column;gap:var(--space-3);font-family:var(--font-family-sans)}.ea-avatar-editor__file-input{position:absolute;overflow:hidden;width:1px;height:1px;padding:0;margin:-1px;border:0;white-space:nowrap;clip:rect(0,0,0,0);clip-path:inset(50%)}.ea-avatar-editor__dropzone{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--space-2);padding:var(--space-4);font-family:inherit;font-size:var(--font-size-sm);line-height:var(--line-height-normal);border:2px dashed var(--color-border-default);border-radius:var(--radius-lg);background-color:var(--color-bg-subtle);color:var(--color-text-tertiary);cursor:pointer;transition:var(--transition-colors)}.ea-avatar-editor__dropzone:hover{border-color:var(--color-border-focus);background-color:var(--color-bg-muted);color:var(--color-text-secondary)}.ea-avatar-editor__dropzone:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-avatar-editor--drag-over .ea-avatar-editor__dropzone{border-color:var(--color-primary-500);background-color:var(--color-primary-50);color:var(--color-primary-600)}.ea-avatar-editor--circle .ea-avatar-editor__dropzone{border-radius:var(--radius-full)}.ea-avatar-editor__upload-icon{opacity:.6}.ea-avatar-editor__dropzone-text{text-align:center}.ea-avatar-editor__preview{display:flex;flex-direction:column;align-items:center;gap:var(--space-3)}.ea-avatar-editor__canvas{border-radius:var(--radius-lg);cursor:grab}.ea-avatar-editor__canvas:active{cursor:grabbing}.ea-avatar-editor--circle .ea-avatar-editor__canvas{border-radius:var(--radius-full)}.ea-avatar-editor__controls{display:flex;align-items:center;gap:var(--space-2)}.ea-avatar-editor__zoom-btn{display:flex;align-items:center;justify-content:center;width:1.75rem;height:1.75rem;padding:0;border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-md);background-color:var(--color-bg-base);color:var(--color-text-primary);cursor:pointer;transition:var(--transition-colors)}.ea-avatar-editor__zoom-btn:hover:not(:disabled){border-color:var(--color-border-focus)}.ea-avatar-editor__zoom-btn:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-avatar-editor__zoom-btn:disabled{opacity:.4;cursor:not-allowed}.ea-avatar-editor__zoom-slider{width:7rem;height:4px;border-radius:var(--radius-full);background:var(--color-neutral-200);appearance:none;cursor:pointer}.ea-avatar-editor__zoom-slider::-webkit-slider-thumb{width:1rem;height:1rem;border:2px solid var(--color-primary-500);border-radius:var(--radius-full);background:var(--color-bg-base);appearance:none;cursor:grab}.ea-avatar-editor__zoom-slider::-webkit-slider-thumb:active{cursor:grabbing}.ea-avatar-editor__zoom-slider::-moz-range-thumb{width:1rem;height:1rem;border:2px solid var(--color-primary-500);border-radius:var(--radius-full);background:var(--color-bg-base);cursor:grab}.ea-avatar-editor__zoom-slider::-moz-range-thumb:active{cursor:grabbing}.ea-avatar-editor__zoom-slider:focus-visible{outline:none}.ea-avatar-editor__zoom-slider:focus-visible::-webkit-slider-thumb{box-shadow:var(--shadow-focus-ring)}.ea-avatar-editor__actions{display:flex;gap:var(--space-2)}.ea-avatar-editor__action-btn{padding:var(--space-1-5) var(--space-3);font-family:inherit;font-size:var(--font-size-sm);font-weight:var(--font-weight-medium);line-height:var(--line-height-normal);border:var(--border-width-thin) solid transparent;border-radius:var(--radius-md);cursor:pointer;transition:var(--transition-colors)}.ea-avatar-editor__action-btn:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-avatar-editor__action-btn--primary{background-color:var(--color-primary-600);color:var(--color-neutral-0)}.ea-avatar-editor__action-btn--primary:hover{background-color:var(--color-primary-700)}.ea-avatar-editor__action-btn--secondary{border-color:var(--color-border-default);background-color:var(--color-bg-base);color:var(--color-text-secondary)}.ea-avatar-editor__action-btn--secondary:hover{border-color:var(--color-border-focus);background-color:var(--color-bg-muted);color:var(--color-text-primary)}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
696
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: AvatarEditorComponent, isStandalone: true, selector: "ea-avatar-editor", inputs: { shape: { classPropertyName: "shape", publicName: "shape", isSignal: true, isRequired: false, transformFunction: null }, canvasSize: { classPropertyName: "canvasSize", publicName: "canvasSize", isSignal: true, isRequired: false, transformFunction: null }, currentSrc: { classPropertyName: "currentSrc", publicName: "currentSrc", isSignal: true, isRequired: false, transformFunction: null }, accept: { classPropertyName: "accept", publicName: "accept", isSignal: true, isRequired: false, transformFunction: null }, maxFileSize: { classPropertyName: "maxFileSize", publicName: "maxFileSize", isSignal: true, isRequired: false, transformFunction: null }, minZoom: { classPropertyName: "minZoom", publicName: "minZoom", isSignal: true, isRequired: false, transformFunction: null }, maxZoom: { classPropertyName: "maxZoom", publicName: "maxZoom", isSignal: true, isRequired: false, transformFunction: null }, exportQuality: { classPropertyName: "exportQuality", publicName: "exportQuality", isSignal: true, isRequired: false, transformFunction: null }, exportType: { classPropertyName: "exportType", publicName: "exportType", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { cropped: "cropped", removed: "removed", fileError: "fileError" }, viewQueries: [{ propertyName: "canvasEl", first: true, predicate: ["canvasEl"], descendants: true, isSignal: true }, { propertyName: "fileInputEl", first: true, predicate: ["fileInputEl"], descendants: true, isSignal: true }], ngImport: i0, template: "<div\n class=\"ea-avatar-editor\"\n [ngClass]=\"hostClasses()\">\n\n <input\n #fileInputEl\n type=\"file\"\n class=\"ea-avatar-editor__file-input\"\n [accept]=\"accept()\"\n (change)=\"onFileSelected($event)\" />\n\n @if (!hasImage()) {\n <button\n type=\"button\"\n class=\"ea-avatar-editor__dropzone\"\n [style.width.px]=\"canvasSize()\"\n [style.height.px]=\"canvasSize()\"\n (click)=\"openFilePicker()\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\">\n <ea-icon-upload class=\"ea-avatar-editor__upload-icon\" />\n <span class=\"ea-avatar-editor__dropzone-text\">\n Drop image or click to upload\n </span>\n </button>\n }\n\n @if (hasImage()) {\n <div\n class=\"ea-avatar-editor__canvas-wrapper\"\n [style.width.px]=\"canvasSize()\"\n [style.height.px]=\"canvasSize()\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\">\n <canvas\n #canvasEl\n class=\"ea-avatar-editor__canvas\"\n [width]=\"canvasSize()\"\n [height]=\"canvasSize()\"\n (mousedown)=\"onMouseDown($event)\"\n (touchstart)=\"onTouchStart($event)\"></canvas>\n\n <div class=\"ea-avatar-editor__canvas-overlay\">\n <ea-icon-camera class=\"ea-avatar-editor__overlay-icon\" />\n <span>Change photo</span>\n </div>\n </div>\n }\n\n <div class=\"ea-avatar-editor__controls\">\n <button\n type=\"button\"\n class=\"ea-avatar-editor__icon-btn\"\n [eaTooltip]=\"'Revert to original'\"\n aria-label=\"Revert to original\"\n [disabled]=\"!canRevert()\"\n (click)=\"revertImage()\">\n <ea-icon-rotate-ccw />\n </button>\n\n <button\n type=\"button\"\n class=\"ea-avatar-editor__icon-btn\"\n [eaTooltip]=\"'Zoom out'\"\n aria-label=\"Zoom out\"\n [disabled]=\"!hasImage() || zoom() <= minZoom()\"\n (click)=\"setZoom(zoom() - 0.1)\">\n <ea-icon-minus />\n </button>\n\n <input\n type=\"range\"\n class=\"ea-avatar-editor__zoom-slider\"\n [min]=\"minZoom()\"\n [max]=\"maxZoom()\"\n step=\"0.01\"\n [value]=\"zoom()\"\n [disabled]=\"!hasImage()\"\n aria-label=\"Zoom\"\n (input)=\"onZoomInput($event)\" />\n\n <button\n type=\"button\"\n class=\"ea-avatar-editor__icon-btn\"\n [eaTooltip]=\"'Zoom in'\"\n aria-label=\"Zoom in\"\n [disabled]=\"!hasImage() || zoom() >= maxZoom()\"\n (click)=\"setZoom(zoom() + 0.1)\">\n <ea-icon-plus />\n </button>\n\n <button\n type=\"button\"\n class=\"ea-avatar-editor__icon-btn ea-avatar-editor__icon-btn--danger\"\n [eaTooltip]=\"'Remove image'\"\n aria-label=\"Remove image\"\n [disabled]=\"!hasImage()\"\n (click)=\"removeImage()\">\n <ea-icon-trash />\n </button>\n </div>\n</div>\n", styles: [".ea-avatar-editor{display:inline-flex;flex-direction:column;align-items:center;gap:var(--space-3);font-family:var(--font-family-sans)}.ea-avatar-editor__file-input{position:absolute;overflow:hidden;width:1px;height:1px;padding:0;margin:-1px;border:0;white-space:nowrap;clip:rect(0,0,0,0);clip-path:inset(50%)}.ea-avatar-editor__dropzone{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--space-2);padding:var(--space-4);font-family:inherit;font-size:var(--font-size-sm);line-height:var(--line-height-normal);border:2px dashed var(--color-border-default);border-radius:var(--radius-lg);background-color:var(--color-bg-subtle);color:var(--color-text-tertiary);cursor:pointer;transition:var(--transition-colors)}.ea-avatar-editor__dropzone:hover{border-color:var(--color-border-focus);background-color:var(--color-bg-muted);color:var(--color-text-secondary)}.ea-avatar-editor__dropzone:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-avatar-editor--drag-over .ea-avatar-editor__dropzone{border-color:var(--color-primary-500);background-color:var(--color-primary-50);color:var(--color-primary-600)}.ea-avatar-editor--circle .ea-avatar-editor__dropzone{border-radius:var(--radius-full)}.ea-avatar-editor__upload-icon{width:32px;height:32px;opacity:.6}.ea-avatar-editor__dropzone-text{text-align:center}.ea-avatar-editor__canvas-wrapper{position:relative;overflow:hidden;border-radius:var(--radius-lg)}.ea-avatar-editor--circle .ea-avatar-editor__canvas-wrapper{border-radius:var(--radius-full)}.ea-avatar-editor__canvas{display:block;cursor:grab}.ea-avatar-editor__canvas:active{cursor:grabbing}.ea-avatar-editor__canvas-overlay{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--space-1);font-size:var(--font-size-sm);font-weight:var(--font-weight-medium);background-color:var(--color-bg-overlay);color:var(--color-text-inverse);opacity:0;pointer-events:none;transition:opacity var(--duration-fast) var(--easing-default)}.ea-avatar-editor__overlay-icon{width:24px;height:24px}.ea-avatar-editor__canvas-wrapper:hover .ea-avatar-editor__canvas-overlay{opacity:1}.ea-avatar-editor__controls{display:flex;align-items:center;gap:var(--space-2)}.ea-avatar-editor__icon-btn{display:flex;align-items:center;justify-content:center;width:1.75rem;height:1.75rem;padding:0}.ea-avatar-editor__icon-btn ea-icon-rotate-ccw,.ea-avatar-editor__icon-btn ea-icon-minus,.ea-avatar-editor__icon-btn ea-icon-plus,.ea-avatar-editor__icon-btn ea-icon-trash{width:1rem;height:1rem}.ea-avatar-editor__icon-btn{border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-md);background-color:var(--color-bg-base);color:var(--color-text-primary);cursor:pointer;transition:var(--transition-colors)}.ea-avatar-editor__icon-btn:hover:not(:disabled){border-color:var(--color-border-focus)}.ea-avatar-editor__icon-btn:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-avatar-editor__icon-btn:disabled{opacity:.4;cursor:not-allowed}.ea-avatar-editor__icon-btn--danger{color:var(--color-error-default)}.ea-avatar-editor__icon-btn--danger:hover:not(:disabled){border-color:var(--color-error-default)}.ea-avatar-editor__zoom-slider{width:7rem;height:4px;border-radius:var(--radius-full);background:var(--color-neutral-200);appearance:none;cursor:pointer}.ea-avatar-editor__zoom-slider::-webkit-slider-thumb{width:1rem;height:1rem;border:2px solid var(--color-primary-500);border-radius:var(--radius-full);background:var(--color-bg-base);appearance:none;cursor:grab}.ea-avatar-editor__zoom-slider::-webkit-slider-thumb:active{cursor:grabbing}.ea-avatar-editor__zoom-slider::-moz-range-thumb{width:1rem;height:1rem;border:2px solid var(--color-primary-500);border-radius:var(--radius-full);background:var(--color-bg-base);cursor:grab}.ea-avatar-editor__zoom-slider::-moz-range-thumb:active{cursor:grabbing}.ea-avatar-editor__zoom-slider:focus-visible{outline:none}.ea-avatar-editor__zoom-slider:focus-visible::-webkit-slider-thumb{box-shadow:var(--shadow-focus-ring)}.ea-avatar-editor__zoom-slider:disabled{opacity:.4;cursor:not-allowed}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: CameraIconComponent, selector: "ea-icon-camera" }, { kind: "component", type: MinusIconComponent, selector: "ea-icon-minus" }, { kind: "component", type: PlusIconComponent, selector: "ea-icon-plus" }, { kind: "component", type: RotateCcwIconComponent, selector: "ea-icon-rotate-ccw" }, { kind: "component", type: TrashIconComponent, selector: "ea-icon-trash" }, { kind: "component", type: UploadIconComponent, selector: "ea-icon-upload" }, { kind: "directive", type: TooltipDirective, selector: "[eaTooltip]", inputs: ["eaTooltip", "tooltipPosition"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
307
697
  }
308
698
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: AvatarEditorComponent, decorators: [{
309
699
  type: Component,
310
- args: [{ selector: 'ea-avatar-editor', imports: [NgClass], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div\n class=\"ea-avatar-editor\"\n [ngClass]=\"hostClasses()\">\n\n <input\n #fileInputEl\n type=\"file\"\n class=\"ea-avatar-editor__file-input\"\n [accept]=\"accept()\"\n (change)=\"onFileSelected($event)\" />\n\n @if (!hasImage()) {\n <button\n type=\"button\"\n class=\"ea-avatar-editor__dropzone\"\n [style.width.px]=\"canvasSize()\"\n [style.height.px]=\"canvasSize()\"\n (click)=\"openFilePicker()\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\">\n <svg\n class=\"ea-avatar-editor__upload-icon\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"32\"\n height=\"32\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\">\n <path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\" />\n <polyline points=\"17 8 12 3 7 8\" />\n <line x1=\"12\" y1=\"3\" x2=\"12\" y2=\"15\" />\n </svg>\n <span class=\"ea-avatar-editor__dropzone-text\">\n Drop image or click to upload\n </span>\n </button>\n }\n\n @if (hasImage()) {\n <div class=\"ea-avatar-editor__preview\">\n <canvas\n #canvasEl\n class=\"ea-avatar-editor__canvas\"\n [width]=\"canvasSize()\"\n [height]=\"canvasSize()\"\n (mousedown)=\"onMouseDown($event)\"\n (touchstart)=\"onTouchStart($event)\"></canvas>\n\n <div class=\"ea-avatar-editor__controls\">\n <button\n type=\"button\"\n class=\"ea-avatar-editor__zoom-btn\"\n aria-label=\"Zoom out\"\n [disabled]=\"zoom() <= minZoom()\"\n (click)=\"setZoom(zoom() - 0.1)\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\">\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n </svg>\n </button>\n\n <input\n type=\"range\"\n class=\"ea-avatar-editor__zoom-slider\"\n [min]=\"minZoom()\"\n [max]=\"maxZoom()\"\n step=\"0.01\"\n [value]=\"zoom()\"\n aria-label=\"Zoom\"\n (input)=\"onZoomInput($event)\" />\n\n <button\n type=\"button\"\n class=\"ea-avatar-editor__zoom-btn\"\n aria-label=\"Zoom in\"\n [disabled]=\"zoom() >= maxZoom()\"\n (click)=\"setZoom(zoom() + 0.1)\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\">\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\" />\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n </svg>\n </button>\n </div>\n\n <div class=\"ea-avatar-editor__actions\">\n <button\n type=\"button\"\n class=\"ea-avatar-editor__action-btn ea-avatar-editor__action-btn--secondary\"\n (click)=\"openFilePicker()\">\n Change\n </button>\n <button\n type=\"button\"\n class=\"ea-avatar-editor__action-btn ea-avatar-editor__action-btn--secondary\"\n (click)=\"removeImage()\">\n Remove\n </button>\n <button\n type=\"button\"\n class=\"ea-avatar-editor__action-btn ea-avatar-editor__action-btn--primary\"\n (click)=\"exportCrop()\">\n Apply\n </button>\n </div>\n </div>\n }\n</div>\n", styles: [".ea-avatar-editor{display:inline-flex;flex-direction:column;gap:var(--space-3);font-family:var(--font-family-sans)}.ea-avatar-editor__file-input{position:absolute;overflow:hidden;width:1px;height:1px;padding:0;margin:-1px;border:0;white-space:nowrap;clip:rect(0,0,0,0);clip-path:inset(50%)}.ea-avatar-editor__dropzone{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--space-2);padding:var(--space-4);font-family:inherit;font-size:var(--font-size-sm);line-height:var(--line-height-normal);border:2px dashed var(--color-border-default);border-radius:var(--radius-lg);background-color:var(--color-bg-subtle);color:var(--color-text-tertiary);cursor:pointer;transition:var(--transition-colors)}.ea-avatar-editor__dropzone:hover{border-color:var(--color-border-focus);background-color:var(--color-bg-muted);color:var(--color-text-secondary)}.ea-avatar-editor__dropzone:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-avatar-editor--drag-over .ea-avatar-editor__dropzone{border-color:var(--color-primary-500);background-color:var(--color-primary-50);color:var(--color-primary-600)}.ea-avatar-editor--circle .ea-avatar-editor__dropzone{border-radius:var(--radius-full)}.ea-avatar-editor__upload-icon{opacity:.6}.ea-avatar-editor__dropzone-text{text-align:center}.ea-avatar-editor__preview{display:flex;flex-direction:column;align-items:center;gap:var(--space-3)}.ea-avatar-editor__canvas{border-radius:var(--radius-lg);cursor:grab}.ea-avatar-editor__canvas:active{cursor:grabbing}.ea-avatar-editor--circle .ea-avatar-editor__canvas{border-radius:var(--radius-full)}.ea-avatar-editor__controls{display:flex;align-items:center;gap:var(--space-2)}.ea-avatar-editor__zoom-btn{display:flex;align-items:center;justify-content:center;width:1.75rem;height:1.75rem;padding:0;border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-md);background-color:var(--color-bg-base);color:var(--color-text-primary);cursor:pointer;transition:var(--transition-colors)}.ea-avatar-editor__zoom-btn:hover:not(:disabled){border-color:var(--color-border-focus)}.ea-avatar-editor__zoom-btn:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-avatar-editor__zoom-btn:disabled{opacity:.4;cursor:not-allowed}.ea-avatar-editor__zoom-slider{width:7rem;height:4px;border-radius:var(--radius-full);background:var(--color-neutral-200);appearance:none;cursor:pointer}.ea-avatar-editor__zoom-slider::-webkit-slider-thumb{width:1rem;height:1rem;border:2px solid var(--color-primary-500);border-radius:var(--radius-full);background:var(--color-bg-base);appearance:none;cursor:grab}.ea-avatar-editor__zoom-slider::-webkit-slider-thumb:active{cursor:grabbing}.ea-avatar-editor__zoom-slider::-moz-range-thumb{width:1rem;height:1rem;border:2px solid var(--color-primary-500);border-radius:var(--radius-full);background:var(--color-bg-base);cursor:grab}.ea-avatar-editor__zoom-slider::-moz-range-thumb:active{cursor:grabbing}.ea-avatar-editor__zoom-slider:focus-visible{outline:none}.ea-avatar-editor__zoom-slider:focus-visible::-webkit-slider-thumb{box-shadow:var(--shadow-focus-ring)}.ea-avatar-editor__actions{display:flex;gap:var(--space-2)}.ea-avatar-editor__action-btn{padding:var(--space-1-5) var(--space-3);font-family:inherit;font-size:var(--font-size-sm);font-weight:var(--font-weight-medium);line-height:var(--line-height-normal);border:var(--border-width-thin) solid transparent;border-radius:var(--radius-md);cursor:pointer;transition:var(--transition-colors)}.ea-avatar-editor__action-btn:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-avatar-editor__action-btn--primary{background-color:var(--color-primary-600);color:var(--color-neutral-0)}.ea-avatar-editor__action-btn--primary:hover{background-color:var(--color-primary-700)}.ea-avatar-editor__action-btn--secondary{border-color:var(--color-border-default);background-color:var(--color-bg-base);color:var(--color-text-secondary)}.ea-avatar-editor__action-btn--secondary:hover{border-color:var(--color-border-focus);background-color:var(--color-bg-muted);color:var(--color-text-primary)}\n"] }]
311
- }], ctorParameters: () => [], propDecorators: { canvasEl: [{ type: i0.ViewChild, args: ['canvasEl', { isSignal: true }] }], fileInputEl: [{ type: i0.ViewChild, args: ['fileInputEl', { isSignal: true }] }], shape: [{ type: i0.Input, args: [{ isSignal: true, alias: "shape", required: false }] }], canvasSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "canvasSize", required: false }] }], currentSrc: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentSrc", required: false }] }], accept: [{ type: i0.Input, args: [{ isSignal: true, alias: "accept", required: false }] }], maxFileSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxFileSize", required: false }] }], minZoom: [{ type: i0.Input, args: [{ isSignal: true, alias: "minZoom", required: false }] }], maxZoom: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxZoom", required: false }] }], exportQuality: [{ type: i0.Input, args: [{ isSignal: true, alias: "exportQuality", required: false }] }], exportType: [{ type: i0.Input, args: [{ isSignal: true, alias: "exportType", required: false }] }], cropped: [{ type: i0.Output, args: ["cropped"] }], fileError: [{ type: i0.Output, args: ["fileError"] }] } });
700
+ args: [{ selector: 'ea-avatar-editor', imports: [
701
+ NgClass,
702
+ CameraIconComponent,
703
+ MinusIconComponent,
704
+ PlusIconComponent,
705
+ RotateCcwIconComponent,
706
+ TrashIconComponent,
707
+ UploadIconComponent,
708
+ TooltipDirective,
709
+ ], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div\n class=\"ea-avatar-editor\"\n [ngClass]=\"hostClasses()\">\n\n <input\n #fileInputEl\n type=\"file\"\n class=\"ea-avatar-editor__file-input\"\n [accept]=\"accept()\"\n (change)=\"onFileSelected($event)\" />\n\n @if (!hasImage()) {\n <button\n type=\"button\"\n class=\"ea-avatar-editor__dropzone\"\n [style.width.px]=\"canvasSize()\"\n [style.height.px]=\"canvasSize()\"\n (click)=\"openFilePicker()\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\">\n <ea-icon-upload class=\"ea-avatar-editor__upload-icon\" />\n <span class=\"ea-avatar-editor__dropzone-text\">\n Drop image or click to upload\n </span>\n </button>\n }\n\n @if (hasImage()) {\n <div\n class=\"ea-avatar-editor__canvas-wrapper\"\n [style.width.px]=\"canvasSize()\"\n [style.height.px]=\"canvasSize()\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\">\n <canvas\n #canvasEl\n class=\"ea-avatar-editor__canvas\"\n [width]=\"canvasSize()\"\n [height]=\"canvasSize()\"\n (mousedown)=\"onMouseDown($event)\"\n (touchstart)=\"onTouchStart($event)\"></canvas>\n\n <div class=\"ea-avatar-editor__canvas-overlay\">\n <ea-icon-camera class=\"ea-avatar-editor__overlay-icon\" />\n <span>Change photo</span>\n </div>\n </div>\n }\n\n <div class=\"ea-avatar-editor__controls\">\n <button\n type=\"button\"\n class=\"ea-avatar-editor__icon-btn\"\n [eaTooltip]=\"'Revert to original'\"\n aria-label=\"Revert to original\"\n [disabled]=\"!canRevert()\"\n (click)=\"revertImage()\">\n <ea-icon-rotate-ccw />\n </button>\n\n <button\n type=\"button\"\n class=\"ea-avatar-editor__icon-btn\"\n [eaTooltip]=\"'Zoom out'\"\n aria-label=\"Zoom out\"\n [disabled]=\"!hasImage() || zoom() <= minZoom()\"\n (click)=\"setZoom(zoom() - 0.1)\">\n <ea-icon-minus />\n </button>\n\n <input\n type=\"range\"\n class=\"ea-avatar-editor__zoom-slider\"\n [min]=\"minZoom()\"\n [max]=\"maxZoom()\"\n step=\"0.01\"\n [value]=\"zoom()\"\n [disabled]=\"!hasImage()\"\n aria-label=\"Zoom\"\n (input)=\"onZoomInput($event)\" />\n\n <button\n type=\"button\"\n class=\"ea-avatar-editor__icon-btn\"\n [eaTooltip]=\"'Zoom in'\"\n aria-label=\"Zoom in\"\n [disabled]=\"!hasImage() || zoom() >= maxZoom()\"\n (click)=\"setZoom(zoom() + 0.1)\">\n <ea-icon-plus />\n </button>\n\n <button\n type=\"button\"\n class=\"ea-avatar-editor__icon-btn ea-avatar-editor__icon-btn--danger\"\n [eaTooltip]=\"'Remove image'\"\n aria-label=\"Remove image\"\n [disabled]=\"!hasImage()\"\n (click)=\"removeImage()\">\n <ea-icon-trash />\n </button>\n </div>\n</div>\n", styles: [".ea-avatar-editor{display:inline-flex;flex-direction:column;align-items:center;gap:var(--space-3);font-family:var(--font-family-sans)}.ea-avatar-editor__file-input{position:absolute;overflow:hidden;width:1px;height:1px;padding:0;margin:-1px;border:0;white-space:nowrap;clip:rect(0,0,0,0);clip-path:inset(50%)}.ea-avatar-editor__dropzone{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--space-2);padding:var(--space-4);font-family:inherit;font-size:var(--font-size-sm);line-height:var(--line-height-normal);border:2px dashed var(--color-border-default);border-radius:var(--radius-lg);background-color:var(--color-bg-subtle);color:var(--color-text-tertiary);cursor:pointer;transition:var(--transition-colors)}.ea-avatar-editor__dropzone:hover{border-color:var(--color-border-focus);background-color:var(--color-bg-muted);color:var(--color-text-secondary)}.ea-avatar-editor__dropzone:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-avatar-editor--drag-over .ea-avatar-editor__dropzone{border-color:var(--color-primary-500);background-color:var(--color-primary-50);color:var(--color-primary-600)}.ea-avatar-editor--circle .ea-avatar-editor__dropzone{border-radius:var(--radius-full)}.ea-avatar-editor__upload-icon{width:32px;height:32px;opacity:.6}.ea-avatar-editor__dropzone-text{text-align:center}.ea-avatar-editor__canvas-wrapper{position:relative;overflow:hidden;border-radius:var(--radius-lg)}.ea-avatar-editor--circle .ea-avatar-editor__canvas-wrapper{border-radius:var(--radius-full)}.ea-avatar-editor__canvas{display:block;cursor:grab}.ea-avatar-editor__canvas:active{cursor:grabbing}.ea-avatar-editor__canvas-overlay{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--space-1);font-size:var(--font-size-sm);font-weight:var(--font-weight-medium);background-color:var(--color-bg-overlay);color:var(--color-text-inverse);opacity:0;pointer-events:none;transition:opacity var(--duration-fast) var(--easing-default)}.ea-avatar-editor__overlay-icon{width:24px;height:24px}.ea-avatar-editor__canvas-wrapper:hover .ea-avatar-editor__canvas-overlay{opacity:1}.ea-avatar-editor__controls{display:flex;align-items:center;gap:var(--space-2)}.ea-avatar-editor__icon-btn{display:flex;align-items:center;justify-content:center;width:1.75rem;height:1.75rem;padding:0}.ea-avatar-editor__icon-btn ea-icon-rotate-ccw,.ea-avatar-editor__icon-btn ea-icon-minus,.ea-avatar-editor__icon-btn ea-icon-plus,.ea-avatar-editor__icon-btn ea-icon-trash{width:1rem;height:1rem}.ea-avatar-editor__icon-btn{border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-md);background-color:var(--color-bg-base);color:var(--color-text-primary);cursor:pointer;transition:var(--transition-colors)}.ea-avatar-editor__icon-btn:hover:not(:disabled){border-color:var(--color-border-focus)}.ea-avatar-editor__icon-btn:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-avatar-editor__icon-btn:disabled{opacity:.4;cursor:not-allowed}.ea-avatar-editor__icon-btn--danger{color:var(--color-error-default)}.ea-avatar-editor__icon-btn--danger:hover:not(:disabled){border-color:var(--color-error-default)}.ea-avatar-editor__zoom-slider{width:7rem;height:4px;border-radius:var(--radius-full);background:var(--color-neutral-200);appearance:none;cursor:pointer}.ea-avatar-editor__zoom-slider::-webkit-slider-thumb{width:1rem;height:1rem;border:2px solid var(--color-primary-500);border-radius:var(--radius-full);background:var(--color-bg-base);appearance:none;cursor:grab}.ea-avatar-editor__zoom-slider::-webkit-slider-thumb:active{cursor:grabbing}.ea-avatar-editor__zoom-slider::-moz-range-thumb{width:1rem;height:1rem;border:2px solid var(--color-primary-500);border-radius:var(--radius-full);background:var(--color-bg-base);cursor:grab}.ea-avatar-editor__zoom-slider::-moz-range-thumb:active{cursor:grabbing}.ea-avatar-editor__zoom-slider:focus-visible{outline:none}.ea-avatar-editor__zoom-slider:focus-visible::-webkit-slider-thumb{box-shadow:var(--shadow-focus-ring)}.ea-avatar-editor__zoom-slider:disabled{opacity:.4;cursor:not-allowed}\n"] }]
710
+ }], ctorParameters: () => [], propDecorators: { canvasEl: [{ type: i0.ViewChild, args: ['canvasEl', { isSignal: true }] }], fileInputEl: [{ type: i0.ViewChild, args: ['fileInputEl', { isSignal: true }] }], shape: [{ type: i0.Input, args: [{ isSignal: true, alias: "shape", required: false }] }], canvasSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "canvasSize", required: false }] }], currentSrc: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentSrc", required: false }] }], accept: [{ type: i0.Input, args: [{ isSignal: true, alias: "accept", required: false }] }], maxFileSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxFileSize", required: false }] }], minZoom: [{ type: i0.Input, args: [{ isSignal: true, alias: "minZoom", required: false }] }], maxZoom: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxZoom", required: false }] }], exportQuality: [{ type: i0.Input, args: [{ isSignal: true, alias: "exportQuality", required: false }] }], exportType: [{ type: i0.Input, args: [{ isSignal: true, alias: "exportType", required: false }] }], cropped: [{ type: i0.Output, args: ["cropped"] }], removed: [{ type: i0.Output, args: ["removed"] }], fileError: [{ type: i0.Output, args: ["fileError"] }] } });
312
711
 
313
712
  class UserIconComponent {
314
713
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: UserIconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
@@ -447,11 +846,11 @@ class CardComponent {
447
846
  'ea-card--full-width': this.fullWidth(),
448
847
  }), ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
449
848
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
450
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.5", type: CardComponent, isStandalone: true, selector: "ea-card", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, padding: { classPropertyName: "padding", publicName: "padding", isSignal: true, isRequired: false, transformFunction: null }, fullWidth: { classPropertyName: "fullWidth", publicName: "fullWidth", isSignal: true, isRequired: false, transformFunction: null }, headerAlign: { classPropertyName: "headerAlign", publicName: "headerAlign", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div\n class=\"ea-card\"\n [ngClass]=\"hostClasses()\">\n <div\n class=\"ea-card__header\"\n [style.text-align]=\"headerAlign()\">\n <ng-content select=\"[eaCardHeader]\" />\n </div>\n\n <div class=\"ea-card__body\">\n <ng-content />\n </div>\n\n <div class=\"ea-card__footer\">\n <ng-content select=\"[eaCardFooter]\" />\n </div>\n</div>\n", styles: [".ea-card{display:flex;flex-direction:column;border-radius:var(--radius-lg);font-family:var(--font-family-sans);color:var(--color-text-primary);overflow:hidden}.ea-card--elevated{background-color:var(--color-bg-base);box-shadow:var(--ea-card-shadow, var(--shadow-md))}.ea-card--outlined{background-color:var(--color-bg-base);border:var(--border-width-thin) solid var(--color-border-default)}.ea-card--filled{background-color:var(--color-bg-subtle)}.ea-card--padding-none .ea-card__header,.ea-card--padding-none .ea-card__body,.ea-card--padding-none .ea-card__footer{padding:0}.ea-card--padding-sm .ea-card__header{padding:var(--space-3) var(--space-3) 0}.ea-card--padding-sm .ea-card__body{padding:var(--space-3)}.ea-card--padding-sm .ea-card__footer{padding:0 var(--space-3) var(--space-3)}.ea-card--padding-md .ea-card__header{padding:var(--space-4) var(--space-4) 0}.ea-card--padding-md .ea-card__body{padding:var(--space-4)}.ea-card--padding-md .ea-card__footer{padding:0 var(--space-4) var(--space-4)}.ea-card--padding-lg .ea-card__header{padding:var(--space-6) var(--space-6) 0}.ea-card--padding-lg .ea-card__body{padding:var(--space-6)}.ea-card--padding-lg .ea-card__footer{padding:0 var(--space-6) var(--space-6)}.ea-card--padding-xl .ea-card__header{padding:var(--space-8) var(--space-8) 0}.ea-card--padding-xl .ea-card__body{padding:var(--space-8)}.ea-card--padding-xl .ea-card__footer{padding:0 var(--space-8) var(--space-8)}.ea-card--full-width{width:100%}.ea-card__header:empty,.ea-card__footer:empty{display:none}.ea-card__header{font-size:var(--text-label-lg-size);font-weight:var(--text-label-lg-weight);line-height:var(--text-label-lg-lh)}.ea-card__body{flex:1;font-size:var(--font-size-sm);line-height:var(--line-height-normal);color:var(--color-text-secondary)}.ea-card__footer{display:flex;align-items:center;justify-content:center;gap:var(--space-3)}.ea-card__footer>*{display:flex;align-items:center;justify-content:center;gap:var(--space-3)}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
849
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.5", type: CardComponent, isStandalone: true, selector: "ea-card", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, padding: { classPropertyName: "padding", publicName: "padding", isSignal: true, isRequired: false, transformFunction: null }, fullWidth: { classPropertyName: "fullWidth", publicName: "fullWidth", isSignal: true, isRequired: false, transformFunction: null }, headerAlign: { classPropertyName: "headerAlign", publicName: "headerAlign", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div\n class=\"ea-card\"\n [ngClass]=\"hostClasses()\">\n <div\n class=\"ea-card__header\"\n [style.text-align]=\"headerAlign()\">\n <ng-content select=\"[eaCardHeader]\" />\n </div>\n\n <div class=\"ea-card__body\">\n <ng-content />\n </div>\n\n <div class=\"ea-card__footer\">\n <ng-content select=\"[eaCardFooter]\" />\n </div>\n</div>\n", styles: ["ea-card{display:block;min-height:0}.ea-card{display:flex;flex-direction:column;min-height:0;border-radius:var(--radius-lg);font-family:var(--font-family-sans);color:var(--color-text-primary);overflow:hidden}.ea-card--elevated{background-color:var(--color-bg-base);box-shadow:var(--ea-card-shadow, var(--shadow-md))}.ea-card--outlined{background-color:var(--color-bg-base);border:var(--border-width-thin) solid var(--color-border-default)}.ea-card--filled{background-color:var(--color-bg-subtle)}.ea-card--padding-none .ea-card__header,.ea-card--padding-none .ea-card__body,.ea-card--padding-none .ea-card__footer{padding:0}.ea-card--padding-sm .ea-card__header{padding:var(--space-3) var(--space-3) 0}.ea-card--padding-sm .ea-card__body{padding:var(--space-3)}.ea-card--padding-sm .ea-card__footer{padding:0 var(--space-3) var(--space-3)}.ea-card--padding-md .ea-card__header{padding:var(--space-4) var(--space-4) 0}.ea-card--padding-md .ea-card__body{padding:var(--space-4)}.ea-card--padding-md .ea-card__footer{padding:0 var(--space-4) var(--space-4)}.ea-card--padding-lg .ea-card__header{padding:var(--space-6) var(--space-6) 0}.ea-card--padding-lg .ea-card__body{padding:var(--space-6)}.ea-card--padding-lg .ea-card__footer{padding:0 var(--space-6) var(--space-6)}.ea-card--padding-xl .ea-card__header{padding:var(--space-8) var(--space-8) 0}.ea-card--padding-xl .ea-card__body{padding:var(--space-8)}.ea-card--padding-xl .ea-card__footer{padding:0 var(--space-8) var(--space-8)}.ea-card--full-width{width:100%}.ea-card__header:empty,.ea-card__footer:empty{display:none}.ea-card__header{font-size:var(--text-label-lg-size);font-weight:var(--text-label-lg-weight);line-height:var(--text-label-lg-lh)}.ea-card__body{flex:1;font-size:var(--font-size-sm);line-height:var(--line-height-normal);color:var(--color-text-secondary)}.ea-card__footer{display:flex;align-items:center;justify-content:center;gap:var(--space-3)}.ea-card__footer>*{display:flex;align-items:center;justify-content:center;gap:var(--space-3)}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
451
850
  }
452
851
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CardComponent, decorators: [{
453
852
  type: Component,
454
- args: [{ selector: 'ea-card', imports: [NgClass], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div\n class=\"ea-card\"\n [ngClass]=\"hostClasses()\">\n <div\n class=\"ea-card__header\"\n [style.text-align]=\"headerAlign()\">\n <ng-content select=\"[eaCardHeader]\" />\n </div>\n\n <div class=\"ea-card__body\">\n <ng-content />\n </div>\n\n <div class=\"ea-card__footer\">\n <ng-content select=\"[eaCardFooter]\" />\n </div>\n</div>\n", styles: [".ea-card{display:flex;flex-direction:column;border-radius:var(--radius-lg);font-family:var(--font-family-sans);color:var(--color-text-primary);overflow:hidden}.ea-card--elevated{background-color:var(--color-bg-base);box-shadow:var(--ea-card-shadow, var(--shadow-md))}.ea-card--outlined{background-color:var(--color-bg-base);border:var(--border-width-thin) solid var(--color-border-default)}.ea-card--filled{background-color:var(--color-bg-subtle)}.ea-card--padding-none .ea-card__header,.ea-card--padding-none .ea-card__body,.ea-card--padding-none .ea-card__footer{padding:0}.ea-card--padding-sm .ea-card__header{padding:var(--space-3) var(--space-3) 0}.ea-card--padding-sm .ea-card__body{padding:var(--space-3)}.ea-card--padding-sm .ea-card__footer{padding:0 var(--space-3) var(--space-3)}.ea-card--padding-md .ea-card__header{padding:var(--space-4) var(--space-4) 0}.ea-card--padding-md .ea-card__body{padding:var(--space-4)}.ea-card--padding-md .ea-card__footer{padding:0 var(--space-4) var(--space-4)}.ea-card--padding-lg .ea-card__header{padding:var(--space-6) var(--space-6) 0}.ea-card--padding-lg .ea-card__body{padding:var(--space-6)}.ea-card--padding-lg .ea-card__footer{padding:0 var(--space-6) var(--space-6)}.ea-card--padding-xl .ea-card__header{padding:var(--space-8) var(--space-8) 0}.ea-card--padding-xl .ea-card__body{padding:var(--space-8)}.ea-card--padding-xl .ea-card__footer{padding:0 var(--space-8) var(--space-8)}.ea-card--full-width{width:100%}.ea-card__header:empty,.ea-card__footer:empty{display:none}.ea-card__header{font-size:var(--text-label-lg-size);font-weight:var(--text-label-lg-weight);line-height:var(--text-label-lg-lh)}.ea-card__body{flex:1;font-size:var(--font-size-sm);line-height:var(--line-height-normal);color:var(--color-text-secondary)}.ea-card__footer{display:flex;align-items:center;justify-content:center;gap:var(--space-3)}.ea-card__footer>*{display:flex;align-items:center;justify-content:center;gap:var(--space-3)}\n"] }]
853
+ args: [{ selector: 'ea-card', imports: [NgClass], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div\n class=\"ea-card\"\n [ngClass]=\"hostClasses()\">\n <div\n class=\"ea-card__header\"\n [style.text-align]=\"headerAlign()\">\n <ng-content select=\"[eaCardHeader]\" />\n </div>\n\n <div class=\"ea-card__body\">\n <ng-content />\n </div>\n\n <div class=\"ea-card__footer\">\n <ng-content select=\"[eaCardFooter]\" />\n </div>\n</div>\n", styles: ["ea-card{display:block;min-height:0}.ea-card{display:flex;flex-direction:column;min-height:0;border-radius:var(--radius-lg);font-family:var(--font-family-sans);color:var(--color-text-primary);overflow:hidden}.ea-card--elevated{background-color:var(--color-bg-base);box-shadow:var(--ea-card-shadow, var(--shadow-md))}.ea-card--outlined{background-color:var(--color-bg-base);border:var(--border-width-thin) solid var(--color-border-default)}.ea-card--filled{background-color:var(--color-bg-subtle)}.ea-card--padding-none .ea-card__header,.ea-card--padding-none .ea-card__body,.ea-card--padding-none .ea-card__footer{padding:0}.ea-card--padding-sm .ea-card__header{padding:var(--space-3) var(--space-3) 0}.ea-card--padding-sm .ea-card__body{padding:var(--space-3)}.ea-card--padding-sm .ea-card__footer{padding:0 var(--space-3) var(--space-3)}.ea-card--padding-md .ea-card__header{padding:var(--space-4) var(--space-4) 0}.ea-card--padding-md .ea-card__body{padding:var(--space-4)}.ea-card--padding-md .ea-card__footer{padding:0 var(--space-4) var(--space-4)}.ea-card--padding-lg .ea-card__header{padding:var(--space-6) var(--space-6) 0}.ea-card--padding-lg .ea-card__body{padding:var(--space-6)}.ea-card--padding-lg .ea-card__footer{padding:0 var(--space-6) var(--space-6)}.ea-card--padding-xl .ea-card__header{padding:var(--space-8) var(--space-8) 0}.ea-card--padding-xl .ea-card__body{padding:var(--space-8)}.ea-card--padding-xl .ea-card__footer{padding:0 var(--space-8) var(--space-8)}.ea-card--full-width{width:100%}.ea-card__header:empty,.ea-card__footer:empty{display:none}.ea-card__header{font-size:var(--text-label-lg-size);font-weight:var(--text-label-lg-weight);line-height:var(--text-label-lg-lh)}.ea-card__body{flex:1;font-size:var(--font-size-sm);line-height:var(--line-height-normal);color:var(--color-text-secondary)}.ea-card__footer{display:flex;align-items:center;justify-content:center;gap:var(--space-3)}.ea-card__footer>*{display:flex;align-items:center;justify-content:center;gap:var(--space-3)}\n"] }]
455
854
  }], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], padding: [{ type: i0.Input, args: [{ isSignal: true, alias: "padding", required: false }] }], fullWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullWidth", required: false }] }], headerAlign: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerAlign", required: false }] }] } });
456
855
 
457
856
  class CheckboxComponent {
@@ -742,7 +1141,7 @@ class DropdownComponent {
742
1141
  useExisting: forwardRef(() => DropdownComponent),
743
1142
  multi: true,
744
1143
  },
745
- ], viewQueries: [{ propertyName: "elRef", first: true, predicate: ["triggerEl"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"ea-dropdown-field\">\n @if (label()) {\n <label\n class=\"ea-dropdown-field__label\"\n [for]=\"id()\"\n [class.ea-dropdown-field__label--required]=\"required()\">\n {{ label() }}\n </label>\n }\n\n <div class=\"ea-dropdown\">\n <button\n #triggerEl\n type=\"button\"\n class=\"ea-dropdown__trigger\"\n [ngClass]=\"triggerClasses()\"\n [id]=\"id()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-haspopup]=\"'listbox'\"\n [attr.aria-labelledby]=\"label() ? id() : null\"\n (click)=\"toggle()\"\n (keydown)=\"handleKeydown($event)\">\n <span\n class=\"ea-dropdown__value\"\n [class.ea-dropdown__value--placeholder]=\"!selectedLabel()\">\n {{ selectedLabel() || placeholder() }}\n </span>\n <svg\n class=\"ea-dropdown__chevron\"\n [class.ea-dropdown__chevron--open]=\"isOpen()\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n aria-hidden=\"true\">\n <path\n d=\"M4 6l4 4 4-4\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </button>\n\n @if (isOpen()) {\n <ul\n class=\"ea-dropdown__menu\"\n role=\"listbox\"\n [attr.aria-activedescendant]=\"\n focusedIndex() >= 0 ? id() + '-option-' + focusedIndex() : null\n \">\n @for (option of options(); track option.value; let i = $index) {\n <li\n class=\"ea-dropdown__option\"\n [class.ea-dropdown__option--selected]=\"option.value === value()\"\n [class.ea-dropdown__option--focused]=\"i === focusedIndex()\"\n [class.ea-dropdown__option--disabled]=\"option.disabled\"\n [id]=\"id() + '-option-' + i\"\n role=\"option\"\n [attr.aria-selected]=\"option.value === value()\"\n [attr.aria-disabled]=\"option.disabled || null\"\n (click)=\"select(option)\"\n (mouseenter)=\"focusedIndex.set(i)\">\n {{ option.label }}\n </li>\n }\n </ul>\n }\n </div>\n\n @if (showError()) {\n <p\n class=\"ea-dropdown-field__message ea-dropdown-field__message--error\"\n [id]=\"id() + '-error'\"\n role=\"alert\">\n {{ errorMsg() }}\n </p>\n }\n\n @if (showHint()) {\n <p\n class=\"ea-dropdown-field__message ea-dropdown-field__message--hint\"\n [id]=\"id() + '-hint'\">\n {{ hint() }}\n </p>\n }\n</div>\n", styles: [".ea-dropdown-field{display:flex;flex-direction:column;gap:var(--space-1-5)}.ea-dropdown-field__label{font-size:var(--text-label-md-size);font-weight:var(--text-label-md-weight);line-height:var(--text-label-md-lh);color:var(--color-text-primary)}.ea-dropdown-field__label--required:after{content:\" *\";color:var(--color-error-default)}.ea-dropdown-field__message{display:flex;align-items:center;gap:var(--space-1);font-size:var(--text-helper-size);font-weight:var(--text-helper-weight);line-height:var(--text-helper-lh)}.ea-dropdown-field__message--hint{color:var(--color-text-secondary)}.ea-dropdown-field__message--error{color:var(--color-error-default)}.ea-dropdown{position:relative}.ea-dropdown__trigger{display:flex;align-items:center;justify-content:space-between;gap:var(--space-2);width:100%;background-color:var(--color-bg-base);border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-md);font-family:var(--font-family-sans);color:var(--color-text-primary);cursor:pointer;transition:var(--transition-colors),var(--transition-shadow);text-align:left}.ea-dropdown__trigger:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-dropdown__trigger--sm{padding:var(--space-1-5) var(--space-2);font-size:var(--font-size-sm);min-height:2rem}.ea-dropdown__trigger--md{padding:var(--space-2) var(--space-3);font-size:var(--font-size-sm);min-height:2.5rem}.ea-dropdown__trigger--lg{padding:var(--space-2-5) var(--space-4);font-size:var(--font-size-md);min-height:3rem}.ea-dropdown__trigger--open{border-color:var(--color-border-focus);box-shadow:var(--shadow-focus-ring)}.ea-dropdown__trigger--error{border-color:var(--color-error-default)}.ea-dropdown__trigger--error.ea-dropdown__trigger--open{box-shadow:0 0 0 3px #ef444459}.ea-dropdown__trigger--disabled{background-color:var(--color-bg-muted);opacity:.6;cursor:not-allowed}.ea-dropdown__value{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ea-dropdown__value--placeholder{color:var(--color-text-tertiary)}.ea-dropdown__chevron{width:1em;height:1em;flex-shrink:0;color:var(--color-text-secondary);transition:var(--transition-transform)}.ea-dropdown__chevron--open{transform:rotate(180deg)}.ea-dropdown__menu{position:absolute;top:calc(100% + var(--space-1));left:0;right:0;z-index:var(--z-index-dropdown);max-height:15rem;overflow-y:auto;background-color:var(--color-bg-base);border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-md);box-shadow:var(--shadow-lg);padding:var(--space-1) 0;margin:0;list-style:none}.ea-dropdown__option{padding:var(--space-2) var(--space-3);font-size:var(--font-size-sm);font-family:var(--font-family-sans);color:var(--color-text-primary);cursor:pointer;transition:var(--transition-colors)}.ea-dropdown__option--focused{background-color:var(--color-bg-muted)}.ea-dropdown__option--selected{color:var(--color-brand-default);font-weight:var(--font-weight-medium)}.ea-dropdown__option--disabled{color:var(--color-text-disabled);cursor:not-allowed}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1144
+ ], viewQueries: [{ propertyName: "elRef", first: true, predicate: ["triggerEl"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"ea-dropdown-field\">\n @if (label()) {\n <label\n class=\"ea-dropdown-field__label\"\n [for]=\"id()\"\n [class.ea-dropdown-field__label--required]=\"required()\">\n {{ label() }}\n </label>\n }\n\n <div class=\"ea-dropdown\">\n <button\n #triggerEl\n type=\"button\"\n class=\"ea-dropdown__trigger\"\n [ngClass]=\"triggerClasses()\"\n [id]=\"id()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-haspopup]=\"'listbox'\"\n [attr.aria-labelledby]=\"label() ? id() : null\"\n (click)=\"toggle()\"\n (keydown)=\"handleKeydown($event)\">\n <span\n class=\"ea-dropdown__value\"\n [class.ea-dropdown__value--placeholder]=\"!selectedLabel()\">\n {{ selectedLabel() || placeholder() }}\n </span>\n <svg\n class=\"ea-dropdown__chevron\"\n [class.ea-dropdown__chevron--open]=\"isOpen()\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n aria-hidden=\"true\">\n <path\n d=\"M4 6l4 4 4-4\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </button>\n\n @if (isOpen()) {\n <ul\n class=\"ea-dropdown__menu\"\n role=\"listbox\"\n [attr.aria-activedescendant]=\"\n focusedIndex() >= 0 ? id() + '-option-' + focusedIndex() : null\n \">\n @for (option of options(); track option.value; let i = $index) {\n <li\n class=\"ea-dropdown__option\"\n [class.ea-dropdown__option--selected]=\"option.value === value()\"\n [class.ea-dropdown__option--focused]=\"i === focusedIndex()\"\n [class.ea-dropdown__option--disabled]=\"option.disabled\"\n [id]=\"id() + '-option-' + i\"\n role=\"option\"\n [attr.aria-selected]=\"option.value === value()\"\n [attr.aria-disabled]=\"option.disabled || null\"\n (click)=\"select(option)\"\n (mouseenter)=\"focusedIndex.set(i)\">\n {{ option.label }}\n </li>\n }\n </ul>\n }\n </div>\n\n @if (showError()) {\n <p\n class=\"ea-dropdown-field__message ea-dropdown-field__message--error\"\n [id]=\"id() + '-error'\"\n role=\"alert\">\n {{ errorMsg() }}\n </p>\n }\n\n @if (showHint()) {\n <p\n class=\"ea-dropdown-field__message ea-dropdown-field__message--hint\"\n [id]=\"id() + '-hint'\">\n {{ hint() }}\n </p>\n }\n</div>\n", styles: [".ea-dropdown-field{display:flex;flex-direction:column;gap:var(--space-1-5)}.ea-dropdown-field__label{font-size:var(--text-label-md-size);font-weight:var(--text-label-md-weight);line-height:var(--text-label-md-lh);color:var(--color-text-primary)}.ea-dropdown-field__label--required:after{content:\" *\";color:var(--color-error-default)}.ea-dropdown-field__message{display:flex;align-items:center;gap:var(--space-1);font-size:var(--text-helper-size);font-weight:var(--text-helper-weight);line-height:var(--text-helper-lh)}.ea-dropdown-field__message--hint{color:var(--color-text-secondary)}.ea-dropdown-field__message--error{color:var(--color-error-default)}.ea-dropdown{position:relative}.ea-dropdown__trigger{display:flex;align-items:center;justify-content:space-between;gap:var(--space-2);width:100%;background-color:var(--color-bg-base);border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-md);font-family:var(--font-family-sans);color:var(--color-text-primary);cursor:pointer;transition:var(--transition-colors),var(--transition-shadow);text-align:left}.ea-dropdown__trigger:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-dropdown__trigger--sm{padding:var(--space-1-5) var(--space-2);font-size:var(--font-size-sm);min-height:2rem}.ea-dropdown__trigger--md{padding:var(--space-2) var(--space-3);font-size:var(--font-size-sm);min-height:2.5rem}.ea-dropdown__trigger--lg{padding:var(--space-2-5) var(--space-4);font-size:var(--font-size-md);min-height:3rem}.ea-dropdown__trigger--open{border-color:var(--color-border-focus);box-shadow:var(--shadow-focus-ring)}.ea-dropdown__trigger--error{border-color:var(--color-error-default)}.ea-dropdown__trigger--error.ea-dropdown__trigger--open{box-shadow:var(--shadow-focus-ring-error)}.ea-dropdown__trigger--disabled{background-color:var(--color-bg-muted);opacity:.6;cursor:not-allowed}.ea-dropdown__value{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ea-dropdown__value--placeholder{color:var(--color-text-tertiary)}.ea-dropdown__chevron{width:1em;height:1em;flex-shrink:0;color:var(--color-text-secondary);transition:var(--transition-transform)}.ea-dropdown__chevron--open{transform:rotate(180deg)}.ea-dropdown__menu{position:absolute;top:calc(100% + var(--space-1));left:0;right:0;z-index:var(--z-index-dropdown);max-height:15rem;overflow-y:auto;background-color:var(--color-bg-base);border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-md);box-shadow:var(--shadow-lg);padding:var(--space-1) 0;margin:0;list-style:none}.ea-dropdown__option{padding:var(--space-2) var(--space-3);font-size:var(--font-size-sm);font-family:var(--font-family-sans);color:var(--color-text-primary);cursor:pointer;transition:var(--transition-colors)}.ea-dropdown__option--focused{background-color:var(--color-bg-muted)}.ea-dropdown__option--selected{color:var(--color-brand-default);font-weight:var(--font-weight-medium)}.ea-dropdown__option--disabled{color:var(--color-text-disabled);cursor:not-allowed}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
746
1145
  }
747
1146
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: DropdownComponent, decorators: [{
748
1147
  type: Component,
@@ -752,7 +1151,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImpor
752
1151
  useExisting: forwardRef(() => DropdownComponent),
753
1152
  multi: true,
754
1153
  },
755
- ], template: "<div class=\"ea-dropdown-field\">\n @if (label()) {\n <label\n class=\"ea-dropdown-field__label\"\n [for]=\"id()\"\n [class.ea-dropdown-field__label--required]=\"required()\">\n {{ label() }}\n </label>\n }\n\n <div class=\"ea-dropdown\">\n <button\n #triggerEl\n type=\"button\"\n class=\"ea-dropdown__trigger\"\n [ngClass]=\"triggerClasses()\"\n [id]=\"id()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-haspopup]=\"'listbox'\"\n [attr.aria-labelledby]=\"label() ? id() : null\"\n (click)=\"toggle()\"\n (keydown)=\"handleKeydown($event)\">\n <span\n class=\"ea-dropdown__value\"\n [class.ea-dropdown__value--placeholder]=\"!selectedLabel()\">\n {{ selectedLabel() || placeholder() }}\n </span>\n <svg\n class=\"ea-dropdown__chevron\"\n [class.ea-dropdown__chevron--open]=\"isOpen()\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n aria-hidden=\"true\">\n <path\n d=\"M4 6l4 4 4-4\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </button>\n\n @if (isOpen()) {\n <ul\n class=\"ea-dropdown__menu\"\n role=\"listbox\"\n [attr.aria-activedescendant]=\"\n focusedIndex() >= 0 ? id() + '-option-' + focusedIndex() : null\n \">\n @for (option of options(); track option.value; let i = $index) {\n <li\n class=\"ea-dropdown__option\"\n [class.ea-dropdown__option--selected]=\"option.value === value()\"\n [class.ea-dropdown__option--focused]=\"i === focusedIndex()\"\n [class.ea-dropdown__option--disabled]=\"option.disabled\"\n [id]=\"id() + '-option-' + i\"\n role=\"option\"\n [attr.aria-selected]=\"option.value === value()\"\n [attr.aria-disabled]=\"option.disabled || null\"\n (click)=\"select(option)\"\n (mouseenter)=\"focusedIndex.set(i)\">\n {{ option.label }}\n </li>\n }\n </ul>\n }\n </div>\n\n @if (showError()) {\n <p\n class=\"ea-dropdown-field__message ea-dropdown-field__message--error\"\n [id]=\"id() + '-error'\"\n role=\"alert\">\n {{ errorMsg() }}\n </p>\n }\n\n @if (showHint()) {\n <p\n class=\"ea-dropdown-field__message ea-dropdown-field__message--hint\"\n [id]=\"id() + '-hint'\">\n {{ hint() }}\n </p>\n }\n</div>\n", styles: [".ea-dropdown-field{display:flex;flex-direction:column;gap:var(--space-1-5)}.ea-dropdown-field__label{font-size:var(--text-label-md-size);font-weight:var(--text-label-md-weight);line-height:var(--text-label-md-lh);color:var(--color-text-primary)}.ea-dropdown-field__label--required:after{content:\" *\";color:var(--color-error-default)}.ea-dropdown-field__message{display:flex;align-items:center;gap:var(--space-1);font-size:var(--text-helper-size);font-weight:var(--text-helper-weight);line-height:var(--text-helper-lh)}.ea-dropdown-field__message--hint{color:var(--color-text-secondary)}.ea-dropdown-field__message--error{color:var(--color-error-default)}.ea-dropdown{position:relative}.ea-dropdown__trigger{display:flex;align-items:center;justify-content:space-between;gap:var(--space-2);width:100%;background-color:var(--color-bg-base);border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-md);font-family:var(--font-family-sans);color:var(--color-text-primary);cursor:pointer;transition:var(--transition-colors),var(--transition-shadow);text-align:left}.ea-dropdown__trigger:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-dropdown__trigger--sm{padding:var(--space-1-5) var(--space-2);font-size:var(--font-size-sm);min-height:2rem}.ea-dropdown__trigger--md{padding:var(--space-2) var(--space-3);font-size:var(--font-size-sm);min-height:2.5rem}.ea-dropdown__trigger--lg{padding:var(--space-2-5) var(--space-4);font-size:var(--font-size-md);min-height:3rem}.ea-dropdown__trigger--open{border-color:var(--color-border-focus);box-shadow:var(--shadow-focus-ring)}.ea-dropdown__trigger--error{border-color:var(--color-error-default)}.ea-dropdown__trigger--error.ea-dropdown__trigger--open{box-shadow:0 0 0 3px #ef444459}.ea-dropdown__trigger--disabled{background-color:var(--color-bg-muted);opacity:.6;cursor:not-allowed}.ea-dropdown__value{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ea-dropdown__value--placeholder{color:var(--color-text-tertiary)}.ea-dropdown__chevron{width:1em;height:1em;flex-shrink:0;color:var(--color-text-secondary);transition:var(--transition-transform)}.ea-dropdown__chevron--open{transform:rotate(180deg)}.ea-dropdown__menu{position:absolute;top:calc(100% + var(--space-1));left:0;right:0;z-index:var(--z-index-dropdown);max-height:15rem;overflow-y:auto;background-color:var(--color-bg-base);border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-md);box-shadow:var(--shadow-lg);padding:var(--space-1) 0;margin:0;list-style:none}.ea-dropdown__option{padding:var(--space-2) var(--space-3);font-size:var(--font-size-sm);font-family:var(--font-family-sans);color:var(--color-text-primary);cursor:pointer;transition:var(--transition-colors)}.ea-dropdown__option--focused{background-color:var(--color-bg-muted)}.ea-dropdown__option--selected{color:var(--color-brand-default);font-weight:var(--font-weight-medium)}.ea-dropdown__option--disabled{color:var(--color-text-disabled);cursor:not-allowed}\n"] }]
1154
+ ], template: "<div class=\"ea-dropdown-field\">\n @if (label()) {\n <label\n class=\"ea-dropdown-field__label\"\n [for]=\"id()\"\n [class.ea-dropdown-field__label--required]=\"required()\">\n {{ label() }}\n </label>\n }\n\n <div class=\"ea-dropdown\">\n <button\n #triggerEl\n type=\"button\"\n class=\"ea-dropdown__trigger\"\n [ngClass]=\"triggerClasses()\"\n [id]=\"id()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-haspopup]=\"'listbox'\"\n [attr.aria-labelledby]=\"label() ? id() : null\"\n (click)=\"toggle()\"\n (keydown)=\"handleKeydown($event)\">\n <span\n class=\"ea-dropdown__value\"\n [class.ea-dropdown__value--placeholder]=\"!selectedLabel()\">\n {{ selectedLabel() || placeholder() }}\n </span>\n <svg\n class=\"ea-dropdown__chevron\"\n [class.ea-dropdown__chevron--open]=\"isOpen()\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n aria-hidden=\"true\">\n <path\n d=\"M4 6l4 4 4-4\"\n stroke=\"currentColor\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </button>\n\n @if (isOpen()) {\n <ul\n class=\"ea-dropdown__menu\"\n role=\"listbox\"\n [attr.aria-activedescendant]=\"\n focusedIndex() >= 0 ? id() + '-option-' + focusedIndex() : null\n \">\n @for (option of options(); track option.value; let i = $index) {\n <li\n class=\"ea-dropdown__option\"\n [class.ea-dropdown__option--selected]=\"option.value === value()\"\n [class.ea-dropdown__option--focused]=\"i === focusedIndex()\"\n [class.ea-dropdown__option--disabled]=\"option.disabled\"\n [id]=\"id() + '-option-' + i\"\n role=\"option\"\n [attr.aria-selected]=\"option.value === value()\"\n [attr.aria-disabled]=\"option.disabled || null\"\n (click)=\"select(option)\"\n (mouseenter)=\"focusedIndex.set(i)\">\n {{ option.label }}\n </li>\n }\n </ul>\n }\n </div>\n\n @if (showError()) {\n <p\n class=\"ea-dropdown-field__message ea-dropdown-field__message--error\"\n [id]=\"id() + '-error'\"\n role=\"alert\">\n {{ errorMsg() }}\n </p>\n }\n\n @if (showHint()) {\n <p\n class=\"ea-dropdown-field__message ea-dropdown-field__message--hint\"\n [id]=\"id() + '-hint'\">\n {{ hint() }}\n </p>\n }\n</div>\n", styles: [".ea-dropdown-field{display:flex;flex-direction:column;gap:var(--space-1-5)}.ea-dropdown-field__label{font-size:var(--text-label-md-size);font-weight:var(--text-label-md-weight);line-height:var(--text-label-md-lh);color:var(--color-text-primary)}.ea-dropdown-field__label--required:after{content:\" *\";color:var(--color-error-default)}.ea-dropdown-field__message{display:flex;align-items:center;gap:var(--space-1);font-size:var(--text-helper-size);font-weight:var(--text-helper-weight);line-height:var(--text-helper-lh)}.ea-dropdown-field__message--hint{color:var(--color-text-secondary)}.ea-dropdown-field__message--error{color:var(--color-error-default)}.ea-dropdown{position:relative}.ea-dropdown__trigger{display:flex;align-items:center;justify-content:space-between;gap:var(--space-2);width:100%;background-color:var(--color-bg-base);border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-md);font-family:var(--font-family-sans);color:var(--color-text-primary);cursor:pointer;transition:var(--transition-colors),var(--transition-shadow);text-align:left}.ea-dropdown__trigger:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-dropdown__trigger--sm{padding:var(--space-1-5) var(--space-2);font-size:var(--font-size-sm);min-height:2rem}.ea-dropdown__trigger--md{padding:var(--space-2) var(--space-3);font-size:var(--font-size-sm);min-height:2.5rem}.ea-dropdown__trigger--lg{padding:var(--space-2-5) var(--space-4);font-size:var(--font-size-md);min-height:3rem}.ea-dropdown__trigger--open{border-color:var(--color-border-focus);box-shadow:var(--shadow-focus-ring)}.ea-dropdown__trigger--error{border-color:var(--color-error-default)}.ea-dropdown__trigger--error.ea-dropdown__trigger--open{box-shadow:var(--shadow-focus-ring-error)}.ea-dropdown__trigger--disabled{background-color:var(--color-bg-muted);opacity:.6;cursor:not-allowed}.ea-dropdown__value{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ea-dropdown__value--placeholder{color:var(--color-text-tertiary)}.ea-dropdown__chevron{width:1em;height:1em;flex-shrink:0;color:var(--color-text-secondary);transition:var(--transition-transform)}.ea-dropdown__chevron--open{transform:rotate(180deg)}.ea-dropdown__menu{position:absolute;top:calc(100% + var(--space-1));left:0;right:0;z-index:var(--z-index-dropdown);max-height:15rem;overflow-y:auto;background-color:var(--color-bg-base);border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-md);box-shadow:var(--shadow-lg);padding:var(--space-1) 0;margin:0;list-style:none}.ea-dropdown__option{padding:var(--space-2) var(--space-3);font-size:var(--font-size-sm);font-family:var(--font-family-sans);color:var(--color-text-primary);cursor:pointer;transition:var(--transition-colors)}.ea-dropdown__option--focused{background-color:var(--color-bg-muted)}.ea-dropdown__option--selected{color:var(--color-brand-default);font-weight:var(--font-weight-medium)}.ea-dropdown__option--disabled{color:var(--color-text-disabled);cursor:not-allowed}\n"] }]
756
1155
  }], propDecorators: { elRef: [{ type: i0.ViewChild, args: ['triggerEl', { isSignal: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], errorMsg: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], changed: [{ type: i0.Output, args: ["changed"] }], onDocumentClick: [{
757
1156
  type: HostListener,
758
1157
  args: ['document:click', ['$event']]
@@ -1313,7 +1712,7 @@ class InputComponent {
1313
1712
  useExisting: forwardRef(() => InputComponent),
1314
1713
  multi: true,
1315
1714
  },
1316
- ], viewQueries: [{ propertyName: "inputEl", first: true, predicate: ["inputEl"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"ea-input-field\">\n @if (label()) {\n <label\n class=\"ea-input-field__label\"\n [for]=\"id()\"\n [class.ea-input-field__label--required]=\"required()\">\n {{ label() }}\n </label>\n }\n\n <div\n class=\"ea-input-wrapper\"\n [ngClass]=\"wrapperClasses()\">\n <!-- Prefix slot (icon or text) -->\n <span class=\"ea-input-wrapper__prefix\">\n <ng-content select=\"[slot=prefix]\" />\n </span>\n\n <input\n #inputEl\n class=\"ea-input\"\n [id]=\"id()\"\n [type]=\"effectiveType()\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"isDisabled()\"\n [readOnly]=\"readonly()\"\n [required]=\"required()\"\n [value]=\"value()\"\n [attr.autocomplete]=\"autocomplete() ?? null\"\n [attr.aria-invalid]=\"resolvedStatus() === 'error' || null\"\n [attr.aria-describedby]=\"\n showError() ? id() + '-error' : showHint() ? id() + '-hint' : null\n \"\n (input)=\"handleInput($event)\"\n (focus)=\"handleFocus($event)\"\n (blur)=\"handleBlur($event)\" />\n\n <!-- Suffix slot (icon, clear button, etc.) -->\n <span class=\"ea-input-wrapper__suffix\">\n <ng-content select=\"[slot=suffix]\" />\n </span>\n\n <!-- Built-in password visibility toggle -->\n @if (type() === 'password' && showPasswordToggle()) {\n <button\n type=\"button\"\n class=\"ea-input-wrapper__password-toggle\"\n [attr.aria-label]=\"passwordVisible() ? 'Hide password' : 'Show password'\"\n [attr.aria-pressed]=\"passwordVisible()\"\n (click)=\"togglePasswordVisibility()\"\n tabindex=\"-1\">\n @if (passwordVisible()) {\n <ea-icon-eye-off />\n } @else {\n <ea-icon-eye />\n }\n </button>\n }\n </div>\n\n @if (showError()) {\n <p\n class=\"ea-input-field__message ea-input-field__message--error\"\n [id]=\"id() + '-error'\"\n role=\"alert\">\n <ea-icon-alert-circle class=\"ea-input-field__message-icon\" />\n {{ errorMsg() }}\n </p>\n }\n\n @if (showHint()) {\n <p\n class=\"ea-input-field__message ea-input-field__message--hint\"\n [id]=\"id() + '-hint'\">\n {{ hint() }}\n </p>\n }\n</div>\n", styles: [".ea-input-field{display:flex;flex-direction:column;gap:var(--space-1-5);color:var(--color-text-secondary)}.ea-input-field__label{font-size:var(--text-label-md-size);font-weight:var(--text-label-md-weight);line-height:var(--text-label-md-lh);color:var(--color-text-primary)}.ea-input-field__label--required:after{content:\" *\";color:var(--color-error-default)}.ea-input-field__message{display:flex;align-items:center;gap:var(--space-1);font-size:var(--text-helper-size);font-weight:var(--text-helper-weight);line-height:var(--text-helper-lh)}.ea-input-field__message--hint{color:inherit}.ea-input-field__message--error{color:var(--color-error-default)}.ea-input-field__message-icon{flex-shrink:0;width:.875em;height:.875em}.ea-input-wrapper{display:flex;align-items:center;gap:var(--space-2);background-color:var(--color-bg-base);border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-md);color:var(--color-text-secondary);transition:var(--transition-colors),var(--transition-shadow);overflow:hidden}.ea-input-wrapper--sm{padding:0 var(--space-2);min-height:2rem}.ea-input-wrapper--sm .ea-input{font-size:var(--font-size-sm);padding:var(--space-1-5) 0}.ea-input-wrapper--md{padding:0 var(--space-3);min-height:2.5rem}.ea-input-wrapper--md .ea-input{font-size:var(--font-size-md);padding:var(--space-2) 0}.ea-input-wrapper--lg{padding:0 var(--space-4);min-height:3rem}.ea-input-wrapper--lg .ea-input{font-size:var(--font-size-lg);padding:var(--space-2-5) 0}.ea-input-wrapper--focused{border-color:var(--color-border-focus);box-shadow:var(--shadow-focus-ring)}.ea-input-wrapper--error{border-color:var(--color-error-default)}.ea-input-wrapper--error.ea-input-wrapper--focused{box-shadow:0 0 0 3px #ef444459}.ea-input-wrapper--success{border-color:var(--color-success-default)}.ea-input-wrapper--success.ea-input-wrapper--focused{box-shadow:0 0 0 3px #22c55e59}.ea-input-wrapper--disabled{background-color:var(--color-bg-muted);border-color:var(--color-border-default);cursor:not-allowed;opacity:.6}.ea-input-wrapper--disabled .ea-input{cursor:not-allowed}.ea-input-wrapper--readonly{background-color:var(--color-bg-subtle)}.ea-input-wrapper__prefix,.ea-input-wrapper__suffix{display:flex;align-items:center;flex-shrink:0;color:inherit}.ea-input-wrapper__prefix:empty,.ea-input-wrapper__suffix:empty{display:none}.ea-input-wrapper__password-toggle{display:flex;align-items:center;justify-content:center;flex-shrink:0;padding:0;width:1.25rem;height:1.25rem;background:none;border:none;cursor:pointer;color:inherit;border-radius:var(--radius-sm);transition:var(--transition-colors)}.ea-input-wrapper__password-toggle:hover{color:var(--color-text-primary)}.ea-input-wrapper__password-toggle ea-icon-eye,.ea-input-wrapper__password-toggle ea-icon-eye-off{width:1rem;height:1rem;pointer-events:none}.ea-input{flex:1;width:100%;min-width:0;background:transparent;border:none;outline:none;color:var(--color-text-primary);font-family:var(--font-family-sans);line-height:var(--line-height-normal)}.ea-input::placeholder{color:var(--color-text-tertiary)}.ea-input:disabled{cursor:not-allowed}.ea-input[type=number]::-webkit-inner-spin-button,.ea-input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.ea-input[type=number]{-moz-appearance:textfield;appearance:textfield}.ea-input[type=search]::-webkit-search-decoration,.ea-input[type=search]::-webkit-search-cancel-button{-webkit-appearance:none}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: EyeIconComponent, selector: "ea-icon-eye" }, { kind: "component", type: EyeOffIconComponent, selector: "ea-icon-eye-off" }, { kind: "component", type: AlertCircleIconComponent, selector: "ea-icon-alert-circle" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1715
+ ], viewQueries: [{ propertyName: "inputEl", first: true, predicate: ["inputEl"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"ea-input-field\">\n @if (label()) {\n <label\n class=\"ea-input-field__label\"\n [for]=\"id()\"\n [class.ea-input-field__label--required]=\"required()\">\n {{ label() }}\n </label>\n }\n\n <div\n class=\"ea-input-wrapper\"\n [ngClass]=\"wrapperClasses()\">\n <!-- Prefix slot (icon or text) -->\n <span class=\"ea-input-wrapper__prefix\">\n <ng-content select=\"[slot=prefix]\" />\n </span>\n\n <input\n #inputEl\n class=\"ea-input\"\n [id]=\"id()\"\n [type]=\"effectiveType()\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"isDisabled()\"\n [readOnly]=\"readonly()\"\n [required]=\"required()\"\n [value]=\"value()\"\n [attr.autocomplete]=\"autocomplete() ?? null\"\n [attr.aria-invalid]=\"resolvedStatus() === 'error' || null\"\n [attr.aria-describedby]=\"\n showError() ? id() + '-error' : showHint() ? id() + '-hint' : null\n \"\n (input)=\"handleInput($event)\"\n (focus)=\"handleFocus($event)\"\n (blur)=\"handleBlur($event)\" />\n\n <!-- Suffix slot (icon, clear button, etc.) -->\n <span class=\"ea-input-wrapper__suffix\">\n <ng-content select=\"[slot=suffix]\" />\n </span>\n\n <!-- Built-in password visibility toggle -->\n @if (type() === 'password' && showPasswordToggle()) {\n <button\n type=\"button\"\n class=\"ea-input-wrapper__password-toggle\"\n [attr.aria-label]=\"passwordVisible() ? 'Hide password' : 'Show password'\"\n [attr.aria-pressed]=\"passwordVisible()\"\n (click)=\"togglePasswordVisibility()\"\n tabindex=\"-1\">\n @if (passwordVisible()) {\n <ea-icon-eye-off />\n } @else {\n <ea-icon-eye />\n }\n </button>\n }\n </div>\n\n @if (showError()) {\n <p\n class=\"ea-input-field__message ea-input-field__message--error\"\n [id]=\"id() + '-error'\"\n role=\"alert\">\n <ea-icon-alert-circle class=\"ea-input-field__message-icon\" />\n {{ errorMsg() }}\n </p>\n }\n\n @if (showHint()) {\n <p\n class=\"ea-input-field__message ea-input-field__message--hint\"\n [id]=\"id() + '-hint'\">\n {{ hint() }}\n </p>\n }\n</div>\n", styles: [".ea-input-field{display:flex;flex-direction:column;gap:var(--space-1-5);color:var(--color-text-secondary)}.ea-input-field__label{font-size:var(--text-label-md-size);font-weight:var(--text-label-md-weight);line-height:var(--text-label-md-lh);color:var(--color-text-primary)}.ea-input-field__label--required:after{content:\" *\";color:var(--color-error-default)}.ea-input-field__message{display:flex;align-items:center;gap:var(--space-1);font-size:var(--text-helper-size);font-weight:var(--text-helper-weight);line-height:var(--text-helper-lh)}.ea-input-field__message--hint{color:inherit}.ea-input-field__message--error{color:var(--color-error-default)}.ea-input-field__message-icon{flex-shrink:0;width:.875em;height:.875em}.ea-input-wrapper{display:flex;align-items:center;gap:var(--space-2);background-color:var(--color-bg-base);border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-md);color:var(--color-text-secondary);transition:var(--transition-colors),var(--transition-shadow);overflow:hidden}.ea-input-wrapper--sm{padding:0 var(--space-2);min-height:2rem}.ea-input-wrapper--sm .ea-input{font-size:var(--font-size-sm);padding:var(--space-1-5) 0}.ea-input-wrapper--md{padding:0 var(--space-3);min-height:2.5rem}.ea-input-wrapper--md .ea-input{font-size:var(--font-size-md);padding:var(--space-2) 0}.ea-input-wrapper--lg{padding:0 var(--space-4);min-height:3rem}.ea-input-wrapper--lg .ea-input{font-size:var(--font-size-lg);padding:var(--space-2-5) 0}.ea-input-wrapper--focused{border-color:var(--color-border-focus);box-shadow:var(--shadow-focus-ring)}.ea-input-wrapper--error{border-color:var(--color-error-default)}.ea-input-wrapper--error.ea-input-wrapper--focused{box-shadow:var(--shadow-focus-ring-error)}.ea-input-wrapper--success{border-color:var(--color-success-default)}.ea-input-wrapper--success.ea-input-wrapper--focused{box-shadow:var(--shadow-focus-ring-success)}.ea-input-wrapper--disabled{background-color:var(--color-bg-muted);border-color:var(--color-border-default);cursor:not-allowed;opacity:.6}.ea-input-wrapper--disabled .ea-input{cursor:not-allowed}.ea-input-wrapper--readonly{background-color:var(--color-bg-subtle)}.ea-input-wrapper__prefix,.ea-input-wrapper__suffix{display:flex;align-items:center;flex-shrink:0;color:inherit}.ea-input-wrapper__prefix:empty,.ea-input-wrapper__suffix:empty{display:none}.ea-input-wrapper__password-toggle{display:flex;align-items:center;justify-content:center;flex-shrink:0;padding:0;width:1.25rem;height:1.25rem;background:none;border:none;cursor:pointer;color:inherit;border-radius:var(--radius-sm);transition:var(--transition-colors)}.ea-input-wrapper__password-toggle:hover{color:var(--color-text-primary)}.ea-input-wrapper__password-toggle ea-icon-eye,.ea-input-wrapper__password-toggle ea-icon-eye-off{width:1rem;height:1rem;pointer-events:none}.ea-input{flex:1;width:100%;min-width:0;background:transparent;border:none;outline:none;color:var(--color-text-primary);font-family:var(--font-family-sans);line-height:var(--line-height-normal)}.ea-input::placeholder{color:var(--color-text-tertiary)}.ea-input:-webkit-autofill,.ea-input:autofill{-webkit-text-fill-color:var(--color-text-primary);-webkit-box-shadow:0 0 0 1000px var(--color-bg-base) inset;transition:background-color 5000s ease-in-out 0s}.ea-input:disabled{cursor:not-allowed}.ea-input[type=number]::-webkit-inner-spin-button,.ea-input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.ea-input[type=number]{-moz-appearance:textfield;appearance:textfield}.ea-input[type=search]::-webkit-search-decoration,.ea-input[type=search]::-webkit-search-cancel-button{-webkit-appearance:none}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: EyeIconComponent, selector: "ea-icon-eye" }, { kind: "component", type: EyeOffIconComponent, selector: "ea-icon-eye-off" }, { kind: "component", type: AlertCircleIconComponent, selector: "ea-icon-alert-circle" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1317
1716
  }
1318
1717
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: InputComponent, decorators: [{
1319
1718
  type: Component,
@@ -1323,7 +1722,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImpor
1323
1722
  useExisting: forwardRef(() => InputComponent),
1324
1723
  multi: true,
1325
1724
  },
1326
- ], template: "<div class=\"ea-input-field\">\n @if (label()) {\n <label\n class=\"ea-input-field__label\"\n [for]=\"id()\"\n [class.ea-input-field__label--required]=\"required()\">\n {{ label() }}\n </label>\n }\n\n <div\n class=\"ea-input-wrapper\"\n [ngClass]=\"wrapperClasses()\">\n <!-- Prefix slot (icon or text) -->\n <span class=\"ea-input-wrapper__prefix\">\n <ng-content select=\"[slot=prefix]\" />\n </span>\n\n <input\n #inputEl\n class=\"ea-input\"\n [id]=\"id()\"\n [type]=\"effectiveType()\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"isDisabled()\"\n [readOnly]=\"readonly()\"\n [required]=\"required()\"\n [value]=\"value()\"\n [attr.autocomplete]=\"autocomplete() ?? null\"\n [attr.aria-invalid]=\"resolvedStatus() === 'error' || null\"\n [attr.aria-describedby]=\"\n showError() ? id() + '-error' : showHint() ? id() + '-hint' : null\n \"\n (input)=\"handleInput($event)\"\n (focus)=\"handleFocus($event)\"\n (blur)=\"handleBlur($event)\" />\n\n <!-- Suffix slot (icon, clear button, etc.) -->\n <span class=\"ea-input-wrapper__suffix\">\n <ng-content select=\"[slot=suffix]\" />\n </span>\n\n <!-- Built-in password visibility toggle -->\n @if (type() === 'password' && showPasswordToggle()) {\n <button\n type=\"button\"\n class=\"ea-input-wrapper__password-toggle\"\n [attr.aria-label]=\"passwordVisible() ? 'Hide password' : 'Show password'\"\n [attr.aria-pressed]=\"passwordVisible()\"\n (click)=\"togglePasswordVisibility()\"\n tabindex=\"-1\">\n @if (passwordVisible()) {\n <ea-icon-eye-off />\n } @else {\n <ea-icon-eye />\n }\n </button>\n }\n </div>\n\n @if (showError()) {\n <p\n class=\"ea-input-field__message ea-input-field__message--error\"\n [id]=\"id() + '-error'\"\n role=\"alert\">\n <ea-icon-alert-circle class=\"ea-input-field__message-icon\" />\n {{ errorMsg() }}\n </p>\n }\n\n @if (showHint()) {\n <p\n class=\"ea-input-field__message ea-input-field__message--hint\"\n [id]=\"id() + '-hint'\">\n {{ hint() }}\n </p>\n }\n</div>\n", styles: [".ea-input-field{display:flex;flex-direction:column;gap:var(--space-1-5);color:var(--color-text-secondary)}.ea-input-field__label{font-size:var(--text-label-md-size);font-weight:var(--text-label-md-weight);line-height:var(--text-label-md-lh);color:var(--color-text-primary)}.ea-input-field__label--required:after{content:\" *\";color:var(--color-error-default)}.ea-input-field__message{display:flex;align-items:center;gap:var(--space-1);font-size:var(--text-helper-size);font-weight:var(--text-helper-weight);line-height:var(--text-helper-lh)}.ea-input-field__message--hint{color:inherit}.ea-input-field__message--error{color:var(--color-error-default)}.ea-input-field__message-icon{flex-shrink:0;width:.875em;height:.875em}.ea-input-wrapper{display:flex;align-items:center;gap:var(--space-2);background-color:var(--color-bg-base);border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-md);color:var(--color-text-secondary);transition:var(--transition-colors),var(--transition-shadow);overflow:hidden}.ea-input-wrapper--sm{padding:0 var(--space-2);min-height:2rem}.ea-input-wrapper--sm .ea-input{font-size:var(--font-size-sm);padding:var(--space-1-5) 0}.ea-input-wrapper--md{padding:0 var(--space-3);min-height:2.5rem}.ea-input-wrapper--md .ea-input{font-size:var(--font-size-md);padding:var(--space-2) 0}.ea-input-wrapper--lg{padding:0 var(--space-4);min-height:3rem}.ea-input-wrapper--lg .ea-input{font-size:var(--font-size-lg);padding:var(--space-2-5) 0}.ea-input-wrapper--focused{border-color:var(--color-border-focus);box-shadow:var(--shadow-focus-ring)}.ea-input-wrapper--error{border-color:var(--color-error-default)}.ea-input-wrapper--error.ea-input-wrapper--focused{box-shadow:0 0 0 3px #ef444459}.ea-input-wrapper--success{border-color:var(--color-success-default)}.ea-input-wrapper--success.ea-input-wrapper--focused{box-shadow:0 0 0 3px #22c55e59}.ea-input-wrapper--disabled{background-color:var(--color-bg-muted);border-color:var(--color-border-default);cursor:not-allowed;opacity:.6}.ea-input-wrapper--disabled .ea-input{cursor:not-allowed}.ea-input-wrapper--readonly{background-color:var(--color-bg-subtle)}.ea-input-wrapper__prefix,.ea-input-wrapper__suffix{display:flex;align-items:center;flex-shrink:0;color:inherit}.ea-input-wrapper__prefix:empty,.ea-input-wrapper__suffix:empty{display:none}.ea-input-wrapper__password-toggle{display:flex;align-items:center;justify-content:center;flex-shrink:0;padding:0;width:1.25rem;height:1.25rem;background:none;border:none;cursor:pointer;color:inherit;border-radius:var(--radius-sm);transition:var(--transition-colors)}.ea-input-wrapper__password-toggle:hover{color:var(--color-text-primary)}.ea-input-wrapper__password-toggle ea-icon-eye,.ea-input-wrapper__password-toggle ea-icon-eye-off{width:1rem;height:1rem;pointer-events:none}.ea-input{flex:1;width:100%;min-width:0;background:transparent;border:none;outline:none;color:var(--color-text-primary);font-family:var(--font-family-sans);line-height:var(--line-height-normal)}.ea-input::placeholder{color:var(--color-text-tertiary)}.ea-input:disabled{cursor:not-allowed}.ea-input[type=number]::-webkit-inner-spin-button,.ea-input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.ea-input[type=number]{-moz-appearance:textfield;appearance:textfield}.ea-input[type=search]::-webkit-search-decoration,.ea-input[type=search]::-webkit-search-cancel-button{-webkit-appearance:none}\n"] }]
1725
+ ], template: "<div class=\"ea-input-field\">\n @if (label()) {\n <label\n class=\"ea-input-field__label\"\n [for]=\"id()\"\n [class.ea-input-field__label--required]=\"required()\">\n {{ label() }}\n </label>\n }\n\n <div\n class=\"ea-input-wrapper\"\n [ngClass]=\"wrapperClasses()\">\n <!-- Prefix slot (icon or text) -->\n <span class=\"ea-input-wrapper__prefix\">\n <ng-content select=\"[slot=prefix]\" />\n </span>\n\n <input\n #inputEl\n class=\"ea-input\"\n [id]=\"id()\"\n [type]=\"effectiveType()\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"isDisabled()\"\n [readOnly]=\"readonly()\"\n [required]=\"required()\"\n [value]=\"value()\"\n [attr.autocomplete]=\"autocomplete() ?? null\"\n [attr.aria-invalid]=\"resolvedStatus() === 'error' || null\"\n [attr.aria-describedby]=\"\n showError() ? id() + '-error' : showHint() ? id() + '-hint' : null\n \"\n (input)=\"handleInput($event)\"\n (focus)=\"handleFocus($event)\"\n (blur)=\"handleBlur($event)\" />\n\n <!-- Suffix slot (icon, clear button, etc.) -->\n <span class=\"ea-input-wrapper__suffix\">\n <ng-content select=\"[slot=suffix]\" />\n </span>\n\n <!-- Built-in password visibility toggle -->\n @if (type() === 'password' && showPasswordToggle()) {\n <button\n type=\"button\"\n class=\"ea-input-wrapper__password-toggle\"\n [attr.aria-label]=\"passwordVisible() ? 'Hide password' : 'Show password'\"\n [attr.aria-pressed]=\"passwordVisible()\"\n (click)=\"togglePasswordVisibility()\"\n tabindex=\"-1\">\n @if (passwordVisible()) {\n <ea-icon-eye-off />\n } @else {\n <ea-icon-eye />\n }\n </button>\n }\n </div>\n\n @if (showError()) {\n <p\n class=\"ea-input-field__message ea-input-field__message--error\"\n [id]=\"id() + '-error'\"\n role=\"alert\">\n <ea-icon-alert-circle class=\"ea-input-field__message-icon\" />\n {{ errorMsg() }}\n </p>\n }\n\n @if (showHint()) {\n <p\n class=\"ea-input-field__message ea-input-field__message--hint\"\n [id]=\"id() + '-hint'\">\n {{ hint() }}\n </p>\n }\n</div>\n", styles: [".ea-input-field{display:flex;flex-direction:column;gap:var(--space-1-5);color:var(--color-text-secondary)}.ea-input-field__label{font-size:var(--text-label-md-size);font-weight:var(--text-label-md-weight);line-height:var(--text-label-md-lh);color:var(--color-text-primary)}.ea-input-field__label--required:after{content:\" *\";color:var(--color-error-default)}.ea-input-field__message{display:flex;align-items:center;gap:var(--space-1);font-size:var(--text-helper-size);font-weight:var(--text-helper-weight);line-height:var(--text-helper-lh)}.ea-input-field__message--hint{color:inherit}.ea-input-field__message--error{color:var(--color-error-default)}.ea-input-field__message-icon{flex-shrink:0;width:.875em;height:.875em}.ea-input-wrapper{display:flex;align-items:center;gap:var(--space-2);background-color:var(--color-bg-base);border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-md);color:var(--color-text-secondary);transition:var(--transition-colors),var(--transition-shadow);overflow:hidden}.ea-input-wrapper--sm{padding:0 var(--space-2);min-height:2rem}.ea-input-wrapper--sm .ea-input{font-size:var(--font-size-sm);padding:var(--space-1-5) 0}.ea-input-wrapper--md{padding:0 var(--space-3);min-height:2.5rem}.ea-input-wrapper--md .ea-input{font-size:var(--font-size-md);padding:var(--space-2) 0}.ea-input-wrapper--lg{padding:0 var(--space-4);min-height:3rem}.ea-input-wrapper--lg .ea-input{font-size:var(--font-size-lg);padding:var(--space-2-5) 0}.ea-input-wrapper--focused{border-color:var(--color-border-focus);box-shadow:var(--shadow-focus-ring)}.ea-input-wrapper--error{border-color:var(--color-error-default)}.ea-input-wrapper--error.ea-input-wrapper--focused{box-shadow:var(--shadow-focus-ring-error)}.ea-input-wrapper--success{border-color:var(--color-success-default)}.ea-input-wrapper--success.ea-input-wrapper--focused{box-shadow:var(--shadow-focus-ring-success)}.ea-input-wrapper--disabled{background-color:var(--color-bg-muted);border-color:var(--color-border-default);cursor:not-allowed;opacity:.6}.ea-input-wrapper--disabled .ea-input{cursor:not-allowed}.ea-input-wrapper--readonly{background-color:var(--color-bg-subtle)}.ea-input-wrapper__prefix,.ea-input-wrapper__suffix{display:flex;align-items:center;flex-shrink:0;color:inherit}.ea-input-wrapper__prefix:empty,.ea-input-wrapper__suffix:empty{display:none}.ea-input-wrapper__password-toggle{display:flex;align-items:center;justify-content:center;flex-shrink:0;padding:0;width:1.25rem;height:1.25rem;background:none;border:none;cursor:pointer;color:inherit;border-radius:var(--radius-sm);transition:var(--transition-colors)}.ea-input-wrapper__password-toggle:hover{color:var(--color-text-primary)}.ea-input-wrapper__password-toggle ea-icon-eye,.ea-input-wrapper__password-toggle ea-icon-eye-off{width:1rem;height:1rem;pointer-events:none}.ea-input{flex:1;width:100%;min-width:0;background:transparent;border:none;outline:none;color:var(--color-text-primary);font-family:var(--font-family-sans);line-height:var(--line-height-normal)}.ea-input::placeholder{color:var(--color-text-tertiary)}.ea-input:-webkit-autofill,.ea-input:autofill{-webkit-text-fill-color:var(--color-text-primary);-webkit-box-shadow:0 0 0 1000px var(--color-bg-base) inset;transition:background-color 5000s ease-in-out 0s}.ea-input:disabled{cursor:not-allowed}.ea-input[type=number]::-webkit-inner-spin-button,.ea-input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}.ea-input[type=number]{-moz-appearance:textfield;appearance:textfield}.ea-input[type=search]::-webkit-search-decoration,.ea-input[type=search]::-webkit-search-cancel-button{-webkit-appearance:none}\n"] }]
1327
1726
  }], propDecorators: { inputEl: [{ type: i0.ViewChild, args: ['inputEl', { isSignal: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], status: [{ type: i0.Input, args: [{ isSignal: true, alias: "status", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], errorMsg: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], autocomplete: [{ type: i0.Input, args: [{ isSignal: true, alias: "autocomplete", required: false }] }], autofocus: [{ type: i0.Input, args: [{ isSignal: true, alias: "autofocus", required: false }] }], showPasswordToggle: [{ type: i0.Input, args: [{ isSignal: true, alias: "showPasswordToggle", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], inputFocused: [{ type: i0.Output, args: ["inputFocused"] }], inputBlurred: [{ type: i0.Output, args: ["inputBlurred"] }] } });
1328
1727
 
1329
1728
  class RadioGroupComponent {
@@ -1555,7 +1954,7 @@ class TextareaComponent {
1555
1954
  useExisting: forwardRef(() => TextareaComponent),
1556
1955
  multi: true,
1557
1956
  },
1558
- ], viewQueries: [{ propertyName: "textareaEl", first: true, predicate: ["textareaEl"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"ea-textarea-field\">\n @if (label()) {\n <label\n class=\"ea-textarea-field__label\"\n [for]=\"id()\"\n [class.ea-textarea-field__label--required]=\"required()\">\n {{ label() }}\n </label>\n }\n\n <div\n class=\"ea-textarea-wrapper\"\n [ngClass]=\"wrapperClasses()\">\n <textarea\n #textareaEl\n class=\"ea-textarea\"\n [id]=\"id()\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"isDisabled()\"\n [readOnly]=\"readonly()\"\n [required]=\"required()\"\n [rows]=\"rows()\"\n [value]=\"value()\"\n [style.resize]=\"resize()\"\n [attr.maxlength]=\"maxlength() ?? null\"\n [attr.aria-invalid]=\"resolvedStatus() === 'error' || null\"\n [attr.aria-describedby]=\"\n showError() ? id() + '-error' : showHint() ? id() + '-hint' : null\n \"\n (input)=\"handleInput($event)\"\n (focus)=\"handleFocus($event)\"\n (blur)=\"handleBlur($event)\"></textarea>\n </div>\n\n @if (showError()) {\n <p\n class=\"ea-textarea-field__message ea-textarea-field__message--error\"\n [id]=\"id() + '-error'\"\n role=\"alert\">\n <ea-icon-alert-circle class=\"ea-textarea-field__message-icon\" />\n {{ errorMsg() }}\n </p>\n }\n\n @if (showHint()) {\n <p\n class=\"ea-textarea-field__message ea-textarea-field__message--hint\"\n [id]=\"id() + '-hint'\">\n {{ hint() }}\n </p>\n }\n</div>\n", styles: [".ea-textarea-field{display:flex;flex-direction:column;gap:var(--space-1-5);color:var(--color-text-secondary)}.ea-textarea-field__label{font-size:var(--text-label-md-size);font-weight:var(--text-label-md-weight);line-height:var(--text-label-md-lh);color:var(--color-text-primary)}.ea-textarea-field__label--required:after{content:\" *\";color:var(--color-error-default)}.ea-textarea-field__message{display:flex;align-items:center;gap:var(--space-1);font-size:var(--text-helper-size);font-weight:var(--text-helper-weight);line-height:var(--text-helper-lh)}.ea-textarea-field__message--hint{color:inherit}.ea-textarea-field__message--error{color:var(--color-error-default)}.ea-textarea-field__message-icon{flex-shrink:0;width:.875em;height:.875em}.ea-textarea-wrapper{display:flex;background-color:var(--color-bg-base);border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-md);transition:var(--transition-colors),var(--transition-shadow);overflow:hidden}.ea-textarea-wrapper--sm .ea-textarea{padding:var(--space-2);font-size:var(--font-size-sm)}.ea-textarea-wrapper--md .ea-textarea{padding:var(--space-3);font-size:var(--font-size-md)}.ea-textarea-wrapper--lg .ea-textarea{padding:var(--space-4);font-size:var(--font-size-lg)}.ea-textarea-wrapper--focused{border-color:var(--color-border-focus);box-shadow:var(--shadow-focus-ring)}.ea-textarea-wrapper--error{border-color:var(--color-error-default)}.ea-textarea-wrapper--error.ea-textarea-wrapper--focused{box-shadow:0 0 0 3px #ef444459}.ea-textarea-wrapper--success{border-color:var(--color-success-default)}.ea-textarea-wrapper--success.ea-textarea-wrapper--focused{box-shadow:0 0 0 3px #22c55e59}.ea-textarea-wrapper--disabled{background-color:var(--color-bg-muted);border-color:var(--color-border-default);cursor:not-allowed;opacity:.6}.ea-textarea-wrapper--disabled .ea-textarea{cursor:not-allowed}.ea-textarea-wrapper--readonly{background-color:var(--color-bg-subtle)}.ea-textarea{flex:1;width:100%;min-width:0;min-height:0;background:transparent;border:none;outline:none;color:var(--color-text-primary);font-family:var(--font-family-sans);line-height:var(--line-height-normal)}.ea-textarea::placeholder{color:var(--color-text-tertiary)}.ea-textarea:disabled{cursor:not-allowed}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: AlertCircleIconComponent, selector: "ea-icon-alert-circle" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1957
+ ], viewQueries: [{ propertyName: "textareaEl", first: true, predicate: ["textareaEl"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"ea-textarea-field\">\n @if (label()) {\n <label\n class=\"ea-textarea-field__label\"\n [for]=\"id()\"\n [class.ea-textarea-field__label--required]=\"required()\">\n {{ label() }}\n </label>\n }\n\n <div\n class=\"ea-textarea-wrapper\"\n [ngClass]=\"wrapperClasses()\">\n <textarea\n #textareaEl\n class=\"ea-textarea\"\n [id]=\"id()\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"isDisabled()\"\n [readOnly]=\"readonly()\"\n [required]=\"required()\"\n [rows]=\"rows()\"\n [value]=\"value()\"\n [style.resize]=\"resize()\"\n [attr.maxlength]=\"maxlength() ?? null\"\n [attr.aria-invalid]=\"resolvedStatus() === 'error' || null\"\n [attr.aria-describedby]=\"\n showError() ? id() + '-error' : showHint() ? id() + '-hint' : null\n \"\n (input)=\"handleInput($event)\"\n (focus)=\"handleFocus($event)\"\n (blur)=\"handleBlur($event)\"></textarea>\n </div>\n\n @if (showError()) {\n <p\n class=\"ea-textarea-field__message ea-textarea-field__message--error\"\n [id]=\"id() + '-error'\"\n role=\"alert\">\n <ea-icon-alert-circle class=\"ea-textarea-field__message-icon\" />\n {{ errorMsg() }}\n </p>\n }\n\n @if (showHint()) {\n <p\n class=\"ea-textarea-field__message ea-textarea-field__message--hint\"\n [id]=\"id() + '-hint'\">\n {{ hint() }}\n </p>\n }\n</div>\n", styles: [".ea-textarea-field{display:flex;flex-direction:column;gap:var(--space-1-5);color:var(--color-text-secondary)}.ea-textarea-field__label{font-size:var(--text-label-md-size);font-weight:var(--text-label-md-weight);line-height:var(--text-label-md-lh);color:var(--color-text-primary)}.ea-textarea-field__label--required:after{content:\" *\";color:var(--color-error-default)}.ea-textarea-field__message{display:flex;align-items:center;gap:var(--space-1);font-size:var(--text-helper-size);font-weight:var(--text-helper-weight);line-height:var(--text-helper-lh)}.ea-textarea-field__message--hint{color:inherit}.ea-textarea-field__message--error{color:var(--color-error-default)}.ea-textarea-field__message-icon{flex-shrink:0;width:.875em;height:.875em}.ea-textarea-wrapper{display:flex;background-color:var(--color-bg-base);border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-md);transition:var(--transition-colors),var(--transition-shadow);overflow:hidden}.ea-textarea-wrapper--sm .ea-textarea{padding:var(--space-2);font-size:var(--font-size-sm)}.ea-textarea-wrapper--md .ea-textarea{padding:var(--space-3);font-size:var(--font-size-md)}.ea-textarea-wrapper--lg .ea-textarea{padding:var(--space-4);font-size:var(--font-size-lg)}.ea-textarea-wrapper--focused{border-color:var(--color-border-focus);box-shadow:var(--shadow-focus-ring)}.ea-textarea-wrapper--error{border-color:var(--color-error-default)}.ea-textarea-wrapper--error.ea-textarea-wrapper--focused{box-shadow:var(--shadow-focus-ring-error)}.ea-textarea-wrapper--success{border-color:var(--color-success-default)}.ea-textarea-wrapper--success.ea-textarea-wrapper--focused{box-shadow:var(--shadow-focus-ring-success)}.ea-textarea-wrapper--disabled{background-color:var(--color-bg-muted);border-color:var(--color-border-default);cursor:not-allowed;opacity:.6}.ea-textarea-wrapper--disabled .ea-textarea{cursor:not-allowed}.ea-textarea-wrapper--readonly{background-color:var(--color-bg-subtle)}.ea-textarea{flex:1;width:100%;min-width:0;min-height:0;background:transparent;border:none;outline:none;color:var(--color-text-primary);font-family:var(--font-family-sans);line-height:var(--line-height-normal)}.ea-textarea::placeholder{color:var(--color-text-tertiary)}.ea-textarea:disabled{cursor:not-allowed}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: AlertCircleIconComponent, selector: "ea-icon-alert-circle" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1559
1958
  }
1560
1959
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: TextareaComponent, decorators: [{
1561
1960
  type: Component,
@@ -1565,7 +1964,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImpor
1565
1964
  useExisting: forwardRef(() => TextareaComponent),
1566
1965
  multi: true,
1567
1966
  },
1568
- ], template: "<div class=\"ea-textarea-field\">\n @if (label()) {\n <label\n class=\"ea-textarea-field__label\"\n [for]=\"id()\"\n [class.ea-textarea-field__label--required]=\"required()\">\n {{ label() }}\n </label>\n }\n\n <div\n class=\"ea-textarea-wrapper\"\n [ngClass]=\"wrapperClasses()\">\n <textarea\n #textareaEl\n class=\"ea-textarea\"\n [id]=\"id()\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"isDisabled()\"\n [readOnly]=\"readonly()\"\n [required]=\"required()\"\n [rows]=\"rows()\"\n [value]=\"value()\"\n [style.resize]=\"resize()\"\n [attr.maxlength]=\"maxlength() ?? null\"\n [attr.aria-invalid]=\"resolvedStatus() === 'error' || null\"\n [attr.aria-describedby]=\"\n showError() ? id() + '-error' : showHint() ? id() + '-hint' : null\n \"\n (input)=\"handleInput($event)\"\n (focus)=\"handleFocus($event)\"\n (blur)=\"handleBlur($event)\"></textarea>\n </div>\n\n @if (showError()) {\n <p\n class=\"ea-textarea-field__message ea-textarea-field__message--error\"\n [id]=\"id() + '-error'\"\n role=\"alert\">\n <ea-icon-alert-circle class=\"ea-textarea-field__message-icon\" />\n {{ errorMsg() }}\n </p>\n }\n\n @if (showHint()) {\n <p\n class=\"ea-textarea-field__message ea-textarea-field__message--hint\"\n [id]=\"id() + '-hint'\">\n {{ hint() }}\n </p>\n }\n</div>\n", styles: [".ea-textarea-field{display:flex;flex-direction:column;gap:var(--space-1-5);color:var(--color-text-secondary)}.ea-textarea-field__label{font-size:var(--text-label-md-size);font-weight:var(--text-label-md-weight);line-height:var(--text-label-md-lh);color:var(--color-text-primary)}.ea-textarea-field__label--required:after{content:\" *\";color:var(--color-error-default)}.ea-textarea-field__message{display:flex;align-items:center;gap:var(--space-1);font-size:var(--text-helper-size);font-weight:var(--text-helper-weight);line-height:var(--text-helper-lh)}.ea-textarea-field__message--hint{color:inherit}.ea-textarea-field__message--error{color:var(--color-error-default)}.ea-textarea-field__message-icon{flex-shrink:0;width:.875em;height:.875em}.ea-textarea-wrapper{display:flex;background-color:var(--color-bg-base);border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-md);transition:var(--transition-colors),var(--transition-shadow);overflow:hidden}.ea-textarea-wrapper--sm .ea-textarea{padding:var(--space-2);font-size:var(--font-size-sm)}.ea-textarea-wrapper--md .ea-textarea{padding:var(--space-3);font-size:var(--font-size-md)}.ea-textarea-wrapper--lg .ea-textarea{padding:var(--space-4);font-size:var(--font-size-lg)}.ea-textarea-wrapper--focused{border-color:var(--color-border-focus);box-shadow:var(--shadow-focus-ring)}.ea-textarea-wrapper--error{border-color:var(--color-error-default)}.ea-textarea-wrapper--error.ea-textarea-wrapper--focused{box-shadow:0 0 0 3px #ef444459}.ea-textarea-wrapper--success{border-color:var(--color-success-default)}.ea-textarea-wrapper--success.ea-textarea-wrapper--focused{box-shadow:0 0 0 3px #22c55e59}.ea-textarea-wrapper--disabled{background-color:var(--color-bg-muted);border-color:var(--color-border-default);cursor:not-allowed;opacity:.6}.ea-textarea-wrapper--disabled .ea-textarea{cursor:not-allowed}.ea-textarea-wrapper--readonly{background-color:var(--color-bg-subtle)}.ea-textarea{flex:1;width:100%;min-width:0;min-height:0;background:transparent;border:none;outline:none;color:var(--color-text-primary);font-family:var(--font-family-sans);line-height:var(--line-height-normal)}.ea-textarea::placeholder{color:var(--color-text-tertiary)}.ea-textarea:disabled{cursor:not-allowed}\n"] }]
1967
+ ], template: "<div class=\"ea-textarea-field\">\n @if (label()) {\n <label\n class=\"ea-textarea-field__label\"\n [for]=\"id()\"\n [class.ea-textarea-field__label--required]=\"required()\">\n {{ label() }}\n </label>\n }\n\n <div\n class=\"ea-textarea-wrapper\"\n [ngClass]=\"wrapperClasses()\">\n <textarea\n #textareaEl\n class=\"ea-textarea\"\n [id]=\"id()\"\n [placeholder]=\"placeholder()\"\n [disabled]=\"isDisabled()\"\n [readOnly]=\"readonly()\"\n [required]=\"required()\"\n [rows]=\"rows()\"\n [value]=\"value()\"\n [style.resize]=\"resize()\"\n [attr.maxlength]=\"maxlength() ?? null\"\n [attr.aria-invalid]=\"resolvedStatus() === 'error' || null\"\n [attr.aria-describedby]=\"\n showError() ? id() + '-error' : showHint() ? id() + '-hint' : null\n \"\n (input)=\"handleInput($event)\"\n (focus)=\"handleFocus($event)\"\n (blur)=\"handleBlur($event)\"></textarea>\n </div>\n\n @if (showError()) {\n <p\n class=\"ea-textarea-field__message ea-textarea-field__message--error\"\n [id]=\"id() + '-error'\"\n role=\"alert\">\n <ea-icon-alert-circle class=\"ea-textarea-field__message-icon\" />\n {{ errorMsg() }}\n </p>\n }\n\n @if (showHint()) {\n <p\n class=\"ea-textarea-field__message ea-textarea-field__message--hint\"\n [id]=\"id() + '-hint'\">\n {{ hint() }}\n </p>\n }\n</div>\n", styles: [".ea-textarea-field{display:flex;flex-direction:column;gap:var(--space-1-5);color:var(--color-text-secondary)}.ea-textarea-field__label{font-size:var(--text-label-md-size);font-weight:var(--text-label-md-weight);line-height:var(--text-label-md-lh);color:var(--color-text-primary)}.ea-textarea-field__label--required:after{content:\" *\";color:var(--color-error-default)}.ea-textarea-field__message{display:flex;align-items:center;gap:var(--space-1);font-size:var(--text-helper-size);font-weight:var(--text-helper-weight);line-height:var(--text-helper-lh)}.ea-textarea-field__message--hint{color:inherit}.ea-textarea-field__message--error{color:var(--color-error-default)}.ea-textarea-field__message-icon{flex-shrink:0;width:.875em;height:.875em}.ea-textarea-wrapper{display:flex;background-color:var(--color-bg-base);border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-md);transition:var(--transition-colors),var(--transition-shadow);overflow:hidden}.ea-textarea-wrapper--sm .ea-textarea{padding:var(--space-2);font-size:var(--font-size-sm)}.ea-textarea-wrapper--md .ea-textarea{padding:var(--space-3);font-size:var(--font-size-md)}.ea-textarea-wrapper--lg .ea-textarea{padding:var(--space-4);font-size:var(--font-size-lg)}.ea-textarea-wrapper--focused{border-color:var(--color-border-focus);box-shadow:var(--shadow-focus-ring)}.ea-textarea-wrapper--error{border-color:var(--color-error-default)}.ea-textarea-wrapper--error.ea-textarea-wrapper--focused{box-shadow:var(--shadow-focus-ring-error)}.ea-textarea-wrapper--success{border-color:var(--color-success-default)}.ea-textarea-wrapper--success.ea-textarea-wrapper--focused{box-shadow:var(--shadow-focus-ring-success)}.ea-textarea-wrapper--disabled{background-color:var(--color-bg-muted);border-color:var(--color-border-default);cursor:not-allowed;opacity:.6}.ea-textarea-wrapper--disabled .ea-textarea{cursor:not-allowed}.ea-textarea-wrapper--readonly{background-color:var(--color-bg-subtle)}.ea-textarea{flex:1;width:100%;min-width:0;min-height:0;background:transparent;border:none;outline:none;color:var(--color-text-primary);font-family:var(--font-family-sans);line-height:var(--line-height-normal)}.ea-textarea::placeholder{color:var(--color-text-tertiary)}.ea-textarea:disabled{cursor:not-allowed}\n"] }]
1569
1968
  }], propDecorators: { textareaEl: [{ type: i0.ViewChild, args: ['textareaEl', { isSignal: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], status: [{ type: i0.Input, args: [{ isSignal: true, alias: "status", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], errorMsg: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], rows: [{ type: i0.Input, args: [{ isSignal: true, alias: "rows", required: false }] }], resize: [{ type: i0.Input, args: [{ isSignal: true, alias: "resize", required: false }] }], maxlength: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxlength", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], textareaFocused: [{ type: i0.Output, args: ["textareaFocused"] }], textareaBlurred: [{ type: i0.Output, args: ["textareaBlurred"] }] } });
1570
1969
 
1571
1970
  class ToastService {
@@ -1621,84 +2020,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImpor
1621
2020
  args: [{ selector: 'ea-toast', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "@if (toastService.toasts().length) {\n <div class=\"ea-toast-container\" aria-live=\"polite\" aria-atomic=\"false\">\n @for (toast of toastService.toasts(); track toast.id) {\n <div\n class=\"ea-toast ea-toast--{{ toast.variant }}\"\n role=\"status\">\n <span class=\"ea-toast__message\">{{ toast.message }}</span>\n <button\n class=\"ea-toast__close\"\n type=\"button\"\n aria-label=\"Dismiss\"\n (click)=\"toastService.dismiss(toast.id)\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n </button>\n </div>\n }\n </div>\n}\n", styles: [".ea-toast-container{position:fixed;bottom:var(--space-6);right:var(--space-6);left:var(--space-6);z-index:var(--z-index-toast);display:flex;flex-direction:column;align-items:flex-end;gap:var(--space-2);pointer-events:none}@media(min-width:640px){.ea-toast-container{left:auto;max-width:24rem}}.ea-toast{display:flex;align-items:center;gap:var(--space-3);width:100%;padding:var(--space-3) var(--space-4);font-family:var(--font-family-sans);font-size:var(--font-size-sm);font-weight:var(--font-weight-medium);line-height:var(--line-height-normal);border-radius:var(--radius-lg);box-shadow:var(--shadow-lg);pointer-events:auto;animation:ea-toast-slide-in var(--duration-slow) var(--ease-out)}@media(min-width:640px){.ea-toast{width:auto}}.ea-toast--default{background-color:var(--color-neutral-800);color:var(--color-neutral-0)}.ea-toast--success{background-color:var(--color-success-subtle);color:var(--color-success-700)}.ea-toast--warning{background-color:var(--color-warning-subtle);color:var(--color-warning-700)}.ea-toast--error{background-color:var(--color-error-subtle);color:var(--color-error-700)}.ea-toast--info{background-color:var(--color-info-subtle);color:var(--color-info-700)}.ea-toast__message{flex:1;min-width:0}.ea-toast__close{flex-shrink:0;display:flex;align-items:center;justify-content:center;width:1.25rem;height:1.25rem;padding:0;background:none;border:none;color:inherit;opacity:.7;cursor:pointer;border-radius:var(--radius-sm);transition:var(--transition-colors)}.ea-toast__close:hover{opacity:1}.ea-toast__close:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}@keyframes ea-toast-slide-in{0%{opacity:0;transform:translate(100%)}to{opacity:1;transform:translate(0)}}\n"] }]
1622
2021
  }] });
1623
2022
 
1624
- class TooltipDirective {
1625
- el = inject(ElementRef);
1626
- renderer = inject(Renderer2);
1627
- eaTooltip = input.required(...(ngDevMode ? [{ debugName: "eaTooltip" }] : /* istanbul ignore next */ []));
1628
- tooltipPosition = input('top', ...(ngDevMode ? [{ debugName: "tooltipPosition" }] : /* istanbul ignore next */ []));
1629
- tooltipEl = null;
1630
- showHandler = () => this.show();
1631
- hideHandler = () => this.hide();
1632
- constructor() {
1633
- const native = this.el.nativeElement;
1634
- native.addEventListener('mouseenter', this.showHandler);
1635
- native.addEventListener('mouseleave', this.hideHandler);
1636
- native.addEventListener('focus', this.showHandler);
1637
- native.addEventListener('blur', this.hideHandler);
1638
- }
1639
- ngOnDestroy() {
1640
- const native = this.el.nativeElement;
1641
- native.removeEventListener('mouseenter', this.showHandler);
1642
- native.removeEventListener('mouseleave', this.hideHandler);
1643
- native.removeEventListener('focus', this.showHandler);
1644
- native.removeEventListener('blur', this.hideHandler);
1645
- this.hide();
1646
- }
1647
- show() {
1648
- if (this.tooltipEl || !this.eaTooltip())
1649
- return;
1650
- this.tooltipEl = this.renderer.createElement('div');
1651
- this.renderer.addClass(this.tooltipEl, 'ea-tooltip');
1652
- this.renderer.addClass(this.tooltipEl, `ea-tooltip--${this.tooltipPosition()}`);
1653
- this.tooltipEl.textContent = this.eaTooltip();
1654
- this.renderer.appendChild(document.body, this.tooltipEl);
1655
- this.positionTooltip();
1656
- }
1657
- hide() {
1658
- if (this.tooltipEl) {
1659
- this.tooltipEl.remove();
1660
- this.tooltipEl = null;
1661
- }
1662
- }
1663
- positionTooltip() {
1664
- if (!this.tooltipEl)
1665
- return;
1666
- const hostRect = this.el.nativeElement.getBoundingClientRect();
1667
- const tooltipRect = this.tooltipEl.getBoundingClientRect();
1668
- const gap = 8;
1669
- let top;
1670
- let left;
1671
- switch (this.tooltipPosition()) {
1672
- case 'top':
1673
- top = hostRect.top - tooltipRect.height - gap;
1674
- left = hostRect.left + (hostRect.width - tooltipRect.width) / 2;
1675
- break;
1676
- case 'bottom':
1677
- top = hostRect.bottom + gap;
1678
- left = hostRect.left + (hostRect.width - tooltipRect.width) / 2;
1679
- break;
1680
- case 'left':
1681
- top = hostRect.top + (hostRect.height - tooltipRect.height) / 2;
1682
- left = hostRect.left - tooltipRect.width - gap;
1683
- break;
1684
- case 'right':
1685
- top = hostRect.top + (hostRect.height - tooltipRect.height) / 2;
1686
- left = hostRect.right + gap;
1687
- break;
1688
- }
1689
- this.renderer.setStyle(this.tooltipEl, 'top', `${top + window.scrollY}px`);
1690
- this.renderer.setStyle(this.tooltipEl, 'left', `${left + window.scrollX}px`);
1691
- }
1692
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: TooltipDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1693
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.5", type: TooltipDirective, isStandalone: true, selector: "[eaTooltip]", inputs: { eaTooltip: { classPropertyName: "eaTooltip", publicName: "eaTooltip", isSignal: true, isRequired: true, transformFunction: null }, tooltipPosition: { classPropertyName: "tooltipPosition", publicName: "tooltipPosition", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
1694
- }
1695
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: TooltipDirective, decorators: [{
1696
- type: Directive,
1697
- args: [{
1698
- selector: '[eaTooltip]',
1699
- }]
1700
- }], ctorParameters: () => [], propDecorators: { eaTooltip: [{ type: i0.Input, args: [{ isSignal: true, alias: "eaTooltip", required: true }] }], tooltipPosition: [{ type: i0.Input, args: [{ isSignal: true, alias: "tooltipPosition", required: false }] }] } });
1701
-
1702
2023
  // =============================================================================
1703
2024
  // EAGAMI UI — Public API
1704
2025
  // =============================================================================
@@ -1708,5 +2029,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImpor
1708
2029
  * Generated bundle index. Do not edit.
1709
2030
  */
1710
2031
 
1711
- export { AlertCircleIconComponent, AvatarComponent, AvatarEditorComponent, BadgeComponent, ButtonComponent, CardComponent, CheckIconComponent, CheckboxComponent, DialogComponent, DividerComponent, DropdownComponent, EyeIconComponent, EyeOffIconComponent, GoogleIconComponent, InfoIconComponent, InputComponent, LoaderIconComponent, RadioComponent, RadioGroupComponent, SpinnerComponent, SwitchComponent, TextareaComponent, ToastComponent, ToastService, TooltipDirective, UserIconComponent, XIconComponent };
2032
+ export { AlertCircleIconComponent, AvatarComponent, AvatarEditorComponent, BadgeComponent, ButtonComponent, CameraIconComponent, CardComponent, CheckIconComponent, CheckboxComponent, DialogComponent, DividerComponent, DropdownComponent, EyeIconComponent, EyeOffIconComponent, GoogleIconComponent, InfoIconComponent, InputComponent, LoaderIconComponent, MinusIconComponent, PlusIconComponent, RadioComponent, RadioGroupComponent, RotateCcwIconComponent, SpinnerComponent, SwitchComponent, TextareaComponent, ToastComponent, ToastService, TooltipDirective, TrashIconComponent, UploadIconComponent, UserIconComponent, XIconComponent };
1712
2033
  //# sourceMappingURL=eagami-ui.mjs.map