@eagami/ui 1.5.0 → 2.0.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.
- package/fesm2022/eagami-ui.mjs +2092 -506
- package/fesm2022/eagami-ui.mjs.map +1 -1
- package/package.json +3 -3
- package/src/styles/tokens/_spacing.scss +28 -0
- package/src/styles/tokens/_typography.scss +26 -3
- package/types/eagami-ui.d.ts +627 -72
package/fesm2022/eagami-ui.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, makeEnvironmentProviders, inject,
|
|
2
|
+
import { InjectionToken, makeEnvironmentProviders, signal, inject, effect, computed, Injectable, input, ChangeDetectionStrategy, Component, HostBinding, Directive, model, output, viewChild, forwardRef, HostListener, ElementRef, Renderer2, Injector, untracked, afterNextRender, ViewEncapsulation, DestroyRef, contentChild, viewChildren } from '@angular/core';
|
|
3
3
|
import { NgClass, NgTemplateOutlet } from '@angular/common';
|
|
4
4
|
import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
5
5
|
|
|
@@ -34,6 +34,18 @@ function provideEagamiUi(config = {}) {
|
|
|
34
34
|
return makeEnvironmentProviders([{ provide: EAGAMI_I18N_CONFIG, useValue: config }]);
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
/**
|
|
38
|
+
* Module-level signal that lets external tooling (notably the Storybook
|
|
39
|
+
* preview decorator) imperatively override the active locale on a running
|
|
40
|
+
* `EagamiI18nService` without re-bootstrapping the Angular application.
|
|
41
|
+
*
|
|
42
|
+
* `null` means "no override" — the service uses its constructor-time locale.
|
|
43
|
+
*
|
|
44
|
+
* @internal Not part of the public API. Library consumers should call
|
|
45
|
+
* `EagamiI18nService.setLocale()` instead.
|
|
46
|
+
*/
|
|
47
|
+
const _eagamiI18nLocaleOverride = signal(null, ...(ngDevMode ? [{ debugName: "_eagamiI18nLocaleOverride" }] : /* istanbul ignore next */ []));
|
|
48
|
+
|
|
37
49
|
/** Greek messages. */
|
|
38
50
|
const el = {
|
|
39
51
|
alert: {
|
|
@@ -98,6 +110,15 @@ const el = {
|
|
|
98
110
|
menu: {
|
|
99
111
|
label: 'Μενού',
|
|
100
112
|
},
|
|
113
|
+
multiSelect: {
|
|
114
|
+
placeholder: 'Επιλέξτε…',
|
|
115
|
+
searchPlaceholder: 'Αναζήτηση…',
|
|
116
|
+
searchEmpty: 'Δεν βρέθηκαν αποτελέσματα',
|
|
117
|
+
selectAll: 'Επιλογή όλων',
|
|
118
|
+
clearAll: 'Εκκαθάριση επιλογής',
|
|
119
|
+
removeOption: label => `Αφαίρεση ${label}`,
|
|
120
|
+
selectedCount: count => `${count} επιλεγμέν${count === 1 ? 'ο' : 'α'}`,
|
|
121
|
+
},
|
|
101
122
|
paginator: {
|
|
102
123
|
label: 'Σελιδοποίηση',
|
|
103
124
|
rowsPerPage: 'Γραμμές ανά σελίδα:',
|
|
@@ -111,9 +132,27 @@ const el = {
|
|
|
111
132
|
spinner: {
|
|
112
133
|
label: 'Φόρτωση',
|
|
113
134
|
},
|
|
135
|
+
stepper: {
|
|
136
|
+
optional: 'προαιρετικό',
|
|
137
|
+
},
|
|
114
138
|
tag: {
|
|
115
139
|
remove: 'Αφαίρεση',
|
|
116
140
|
},
|
|
141
|
+
timePicker: {
|
|
142
|
+
placeholder: 'Επιλογή ώρας…',
|
|
143
|
+
clear: 'Καθαρισμός ώρας',
|
|
144
|
+
hoursLabel: 'Ώρες',
|
|
145
|
+
minutesLabel: 'Λεπτά',
|
|
146
|
+
secondsLabel: 'Δευτερόλεπτα',
|
|
147
|
+
incrementHours: 'Αύξηση ωρών',
|
|
148
|
+
decrementHours: 'Μείωση ωρών',
|
|
149
|
+
incrementMinutes: 'Αύξηση λεπτών',
|
|
150
|
+
decrementMinutes: 'Μείωση λεπτών',
|
|
151
|
+
incrementSeconds: 'Αύξηση δευτερολέπτων',
|
|
152
|
+
decrementSeconds: 'Μείωση δευτερολέπτων',
|
|
153
|
+
amLabel: 'πμ',
|
|
154
|
+
pmLabel: 'μμ',
|
|
155
|
+
},
|
|
117
156
|
toast: {
|
|
118
157
|
dismiss: 'Απόρριψη',
|
|
119
158
|
},
|
|
@@ -187,6 +226,15 @@ const en = {
|
|
|
187
226
|
menu: {
|
|
188
227
|
label: 'Menu',
|
|
189
228
|
},
|
|
229
|
+
multiSelect: {
|
|
230
|
+
placeholder: 'Select…',
|
|
231
|
+
searchPlaceholder: 'Search…',
|
|
232
|
+
searchEmpty: 'No matches',
|
|
233
|
+
selectAll: 'Select all',
|
|
234
|
+
clearAll: 'Clear selection',
|
|
235
|
+
removeOption: label => `Remove ${label}`,
|
|
236
|
+
selectedCount: count => `${count} selected`,
|
|
237
|
+
},
|
|
190
238
|
paginator: {
|
|
191
239
|
label: 'Pagination',
|
|
192
240
|
rowsPerPage: 'Rows per page:',
|
|
@@ -200,9 +248,27 @@ const en = {
|
|
|
200
248
|
spinner: {
|
|
201
249
|
label: 'Loading',
|
|
202
250
|
},
|
|
251
|
+
stepper: {
|
|
252
|
+
optional: 'optional',
|
|
253
|
+
},
|
|
203
254
|
tag: {
|
|
204
255
|
remove: 'Remove',
|
|
205
256
|
},
|
|
257
|
+
timePicker: {
|
|
258
|
+
placeholder: 'Select time…',
|
|
259
|
+
clear: 'Clear time',
|
|
260
|
+
hoursLabel: 'Hours',
|
|
261
|
+
minutesLabel: 'Minutes',
|
|
262
|
+
secondsLabel: 'Seconds',
|
|
263
|
+
incrementHours: 'Increment hours',
|
|
264
|
+
decrementHours: 'Decrement hours',
|
|
265
|
+
incrementMinutes: 'Increment minutes',
|
|
266
|
+
decrementMinutes: 'Decrement minutes',
|
|
267
|
+
incrementSeconds: 'Increment seconds',
|
|
268
|
+
decrementSeconds: 'Decrement seconds',
|
|
269
|
+
amLabel: 'AM',
|
|
270
|
+
pmLabel: 'PM',
|
|
271
|
+
},
|
|
206
272
|
toast: {
|
|
207
273
|
dismiss: 'Dismiss',
|
|
208
274
|
},
|
|
@@ -276,6 +342,15 @@ const esES = {
|
|
|
276
342
|
menu: {
|
|
277
343
|
label: 'Menú',
|
|
278
344
|
},
|
|
345
|
+
multiSelect: {
|
|
346
|
+
placeholder: 'Seleccionar…',
|
|
347
|
+
searchPlaceholder: 'Buscar…',
|
|
348
|
+
searchEmpty: 'Sin coincidencias',
|
|
349
|
+
selectAll: 'Seleccionar todo',
|
|
350
|
+
clearAll: 'Borrar selección',
|
|
351
|
+
removeOption: label => `Eliminar ${label}`,
|
|
352
|
+
selectedCount: count => `${count} seleccionado${count === 1 ? '' : 's'}`,
|
|
353
|
+
},
|
|
279
354
|
paginator: {
|
|
280
355
|
label: 'Paginación',
|
|
281
356
|
rowsPerPage: 'Filas por página:',
|
|
@@ -289,9 +364,27 @@ const esES = {
|
|
|
289
364
|
spinner: {
|
|
290
365
|
label: 'Cargando',
|
|
291
366
|
},
|
|
367
|
+
stepper: {
|
|
368
|
+
optional: 'opcional',
|
|
369
|
+
},
|
|
292
370
|
tag: {
|
|
293
371
|
remove: 'Eliminar',
|
|
294
372
|
},
|
|
373
|
+
timePicker: {
|
|
374
|
+
placeholder: 'Seleccionar hora…',
|
|
375
|
+
clear: 'Borrar hora',
|
|
376
|
+
hoursLabel: 'Horas',
|
|
377
|
+
minutesLabel: 'Minutos',
|
|
378
|
+
secondsLabel: 'Segundos',
|
|
379
|
+
incrementHours: 'Aumentar horas',
|
|
380
|
+
decrementHours: 'Disminuir horas',
|
|
381
|
+
incrementMinutes: 'Aumentar minutos',
|
|
382
|
+
decrementMinutes: 'Disminuir minutos',
|
|
383
|
+
incrementSeconds: 'Aumentar segundos',
|
|
384
|
+
decrementSeconds: 'Disminuir segundos',
|
|
385
|
+
amLabel: 'AM',
|
|
386
|
+
pmLabel: 'PM',
|
|
387
|
+
},
|
|
295
388
|
toast: {
|
|
296
389
|
dismiss: 'Descartar',
|
|
297
390
|
},
|
|
@@ -365,6 +458,15 @@ const frFR = {
|
|
|
365
458
|
menu: {
|
|
366
459
|
label: 'Menu',
|
|
367
460
|
},
|
|
461
|
+
multiSelect: {
|
|
462
|
+
placeholder: 'Sélectionner…',
|
|
463
|
+
searchPlaceholder: 'Rechercher…',
|
|
464
|
+
searchEmpty: 'Aucun résultat',
|
|
465
|
+
selectAll: 'Tout sélectionner',
|
|
466
|
+
clearAll: 'Effacer la sélection',
|
|
467
|
+
removeOption: label => `Supprimer ${label}`,
|
|
468
|
+
selectedCount: count => `${count} sélectionné${count > 1 ? 's' : ''}`,
|
|
469
|
+
},
|
|
368
470
|
paginator: {
|
|
369
471
|
label: 'Pagination',
|
|
370
472
|
rowsPerPage: 'Lignes par page :',
|
|
@@ -378,9 +480,27 @@ const frFR = {
|
|
|
378
480
|
spinner: {
|
|
379
481
|
label: 'Chargement',
|
|
380
482
|
},
|
|
483
|
+
stepper: {
|
|
484
|
+
optional: 'facultatif',
|
|
485
|
+
},
|
|
381
486
|
tag: {
|
|
382
487
|
remove: 'Supprimer',
|
|
383
488
|
},
|
|
489
|
+
timePicker: {
|
|
490
|
+
placeholder: 'Sélectionner une heure…',
|
|
491
|
+
clear: "Effacer l'heure",
|
|
492
|
+
hoursLabel: 'Heures',
|
|
493
|
+
minutesLabel: 'Minutes',
|
|
494
|
+
secondsLabel: 'Secondes',
|
|
495
|
+
incrementHours: 'Augmenter les heures',
|
|
496
|
+
decrementHours: 'Diminuer les heures',
|
|
497
|
+
incrementMinutes: 'Augmenter les minutes',
|
|
498
|
+
decrementMinutes: 'Diminuer les minutes',
|
|
499
|
+
incrementSeconds: 'Augmenter les secondes',
|
|
500
|
+
decrementSeconds: 'Diminuer les secondes',
|
|
501
|
+
amLabel: 'AM',
|
|
502
|
+
pmLabel: 'PM',
|
|
503
|
+
},
|
|
384
504
|
toast: {
|
|
385
505
|
dismiss: 'Fermer',
|
|
386
506
|
},
|
|
@@ -454,6 +574,15 @@ const pl = {
|
|
|
454
574
|
menu: {
|
|
455
575
|
label: 'Menu',
|
|
456
576
|
},
|
|
577
|
+
multiSelect: {
|
|
578
|
+
placeholder: 'Wybierz…',
|
|
579
|
+
searchPlaceholder: 'Szukaj…',
|
|
580
|
+
searchEmpty: 'Brak wyników',
|
|
581
|
+
selectAll: 'Zaznacz wszystko',
|
|
582
|
+
clearAll: 'Wyczyść wybór',
|
|
583
|
+
removeOption: label => `Usuń ${label}`,
|
|
584
|
+
selectedCount: count => `Wybrano: ${count}`,
|
|
585
|
+
},
|
|
457
586
|
paginator: {
|
|
458
587
|
label: 'Paginacja',
|
|
459
588
|
rowsPerPage: 'Wierszy na stronę:',
|
|
@@ -467,9 +596,27 @@ const pl = {
|
|
|
467
596
|
spinner: {
|
|
468
597
|
label: 'Ładowanie',
|
|
469
598
|
},
|
|
599
|
+
stepper: {
|
|
600
|
+
optional: 'opcjonalny',
|
|
601
|
+
},
|
|
470
602
|
tag: {
|
|
471
603
|
remove: 'Usuń',
|
|
472
604
|
},
|
|
605
|
+
timePicker: {
|
|
606
|
+
placeholder: 'Wybierz godzinę…',
|
|
607
|
+
clear: 'Wyczyść godzinę',
|
|
608
|
+
hoursLabel: 'Godziny',
|
|
609
|
+
minutesLabel: 'Minuty',
|
|
610
|
+
secondsLabel: 'Sekundy',
|
|
611
|
+
incrementHours: 'Zwiększ godziny',
|
|
612
|
+
decrementHours: 'Zmniejsz godziny',
|
|
613
|
+
incrementMinutes: 'Zwiększ minuty',
|
|
614
|
+
decrementMinutes: 'Zmniejsz minuty',
|
|
615
|
+
incrementSeconds: 'Zwiększ sekundy',
|
|
616
|
+
decrementSeconds: 'Zmniejsz sekundy',
|
|
617
|
+
amLabel: 'AM',
|
|
618
|
+
pmLabel: 'PM',
|
|
619
|
+
},
|
|
473
620
|
toast: {
|
|
474
621
|
dismiss: 'Zamknij',
|
|
475
622
|
},
|
|
@@ -504,9 +651,20 @@ function applyOverrides(base, overrides) {
|
|
|
504
651
|
*/
|
|
505
652
|
class EagamiI18nService {
|
|
506
653
|
config = inject(EAGAMI_I18N_CONFIG, { optional: true });
|
|
507
|
-
_locale = signal(this.config?.locale ?? 'en', ...(ngDevMode ? [{ debugName: "_locale" }] : /* istanbul ignore next */ []));
|
|
654
|
+
_locale = signal(_eagamiI18nLocaleOverride() ?? this.config?.locale ?? 'en', ...(ngDevMode ? [{ debugName: "_locale" }] : /* istanbul ignore next */ []));
|
|
508
655
|
/** The currently active locale. Read it reactively or call `setLocale()`. */
|
|
509
656
|
locale = this._locale.asReadonly();
|
|
657
|
+
constructor() {
|
|
658
|
+
// Pick up tooling-driven locale changes (Storybook globals dropdown). The
|
|
659
|
+
// override signal is `null` in production — this effect is a no-op for
|
|
660
|
+
// real applications.
|
|
661
|
+
effect(() => {
|
|
662
|
+
const override = _eagamiI18nLocaleOverride();
|
|
663
|
+
if (override !== null && EAGAMI_MESSAGES[override]) {
|
|
664
|
+
this._locale.set(override);
|
|
665
|
+
}
|
|
666
|
+
});
|
|
667
|
+
}
|
|
510
668
|
/** The resolved message dictionary for the active locale. */
|
|
511
669
|
messages = computed(() => {
|
|
512
670
|
const base = EAGAMI_MESSAGES[this._locale()] ?? en;
|
|
@@ -523,7 +681,7 @@ class EagamiI18nService {
|
|
|
523
681
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: EagamiI18nService, decorators: [{
|
|
524
682
|
type: Injectable,
|
|
525
683
|
args: [{ providedIn: 'root' }]
|
|
526
|
-
}] });
|
|
684
|
+
}], ctorParameters: () => [] });
|
|
527
685
|
|
|
528
686
|
// =============================================================================
|
|
529
687
|
// EAGAMI UI — French spacing helper
|
|
@@ -1630,6 +1788,149 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImpo
|
|
|
1630
1788
|
args: [{ selector: 'ea-skeleton', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"ea-skeleton\"\n [class.ea-skeleton--text]=\"variant() === 'text'\"\n [class.ea-skeleton--circle]=\"variant() === 'circle'\"\n [class.ea-skeleton--rect]=\"variant() === 'rect'\"\n [class.ea-skeleton--animated]=\"animated()\"\n [style]=\"hostStyles()\"\n aria-hidden=\"true\">\n</div>\n", styles: [".ea-skeleton{display:block;background-color:var(--color-bg-muted);border-radius:var(--radius-md)}.ea-skeleton--text{width:100%;height:1rem;border-radius:var(--radius-sm)}.ea-skeleton--circle{width:2.5rem;height:2.5rem;border-radius:var(--radius-full)}.ea-skeleton--rect{width:100%;height:6rem}.ea-skeleton--animated{animation:ea-skeleton-pulse 1.5s ease-in-out infinite}@keyframes ea-skeleton-pulse{0%,to{opacity:1}50%{opacity:.4}}@media(prefers-reduced-motion:reduce){.ea-skeleton--animated{animation:none}}\n"] }]
|
|
1631
1789
|
}], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }], height: [{ type: i0.Input, args: [{ isSignal: true, alias: "height", required: false }] }], animated: [{ type: i0.Input, args: [{ isSignal: true, alias: "animated", required: false }] }] } });
|
|
1632
1790
|
|
|
1791
|
+
/** True for cardinal placements that centre the popover on the perpendicular axis. */
|
|
1792
|
+
function isCardinal(placement) {
|
|
1793
|
+
return (placement === 'top' ||
|
|
1794
|
+
placement === 'bottom' ||
|
|
1795
|
+
placement === 'left' ||
|
|
1796
|
+
placement === 'right');
|
|
1797
|
+
}
|
|
1798
|
+
/** The dominant side of a placement (`top-start` → `top`, `bottom` → `bottom`, etc.). */
|
|
1799
|
+
function side(placement) {
|
|
1800
|
+
if (placement.startsWith('top'))
|
|
1801
|
+
return 'top';
|
|
1802
|
+
if (placement.startsWith('bottom'))
|
|
1803
|
+
return 'bottom';
|
|
1804
|
+
if (placement === 'left')
|
|
1805
|
+
return 'left';
|
|
1806
|
+
return 'right';
|
|
1807
|
+
}
|
|
1808
|
+
/** Maps `top → bottom`, `bottom-start → top-start`, etc. for flip logic. */
|
|
1809
|
+
function flipPlacement(placement) {
|
|
1810
|
+
if (placement === 'top')
|
|
1811
|
+
return 'bottom';
|
|
1812
|
+
if (placement === 'bottom')
|
|
1813
|
+
return 'top';
|
|
1814
|
+
if (placement === 'left')
|
|
1815
|
+
return 'right';
|
|
1816
|
+
if (placement === 'right')
|
|
1817
|
+
return 'left';
|
|
1818
|
+
if (placement === 'top-start')
|
|
1819
|
+
return 'bottom-start';
|
|
1820
|
+
if (placement === 'top-end')
|
|
1821
|
+
return 'bottom-end';
|
|
1822
|
+
if (placement === 'bottom-start')
|
|
1823
|
+
return 'top-start';
|
|
1824
|
+
return 'top-end';
|
|
1825
|
+
}
|
|
1826
|
+
/** Computes the top/left for a given placement without any flip or clamp logic. */
|
|
1827
|
+
function placeRaw(anchor, popover, placement, offset) {
|
|
1828
|
+
const s = side(placement);
|
|
1829
|
+
let top = 0;
|
|
1830
|
+
let left = 0;
|
|
1831
|
+
if (s === 'top') {
|
|
1832
|
+
top = anchor.top - popover.height - offset;
|
|
1833
|
+
}
|
|
1834
|
+
else if (s === 'bottom') {
|
|
1835
|
+
top = anchor.bottom + offset;
|
|
1836
|
+
}
|
|
1837
|
+
else if (s === 'left') {
|
|
1838
|
+
left = anchor.left - popover.width - offset;
|
|
1839
|
+
}
|
|
1840
|
+
else {
|
|
1841
|
+
left = anchor.right + offset;
|
|
1842
|
+
}
|
|
1843
|
+
if (s === 'top' || s === 'bottom') {
|
|
1844
|
+
if (isCardinal(placement)) {
|
|
1845
|
+
left = anchor.left + (anchor.width - popover.width) / 2;
|
|
1846
|
+
}
|
|
1847
|
+
else if (placement === 'top-start' || placement === 'bottom-start') {
|
|
1848
|
+
left = anchor.left;
|
|
1849
|
+
}
|
|
1850
|
+
else {
|
|
1851
|
+
left = anchor.right - popover.width;
|
|
1852
|
+
}
|
|
1853
|
+
}
|
|
1854
|
+
else {
|
|
1855
|
+
top = anchor.top + (anchor.height - popover.height) / 2;
|
|
1856
|
+
}
|
|
1857
|
+
return { top, left };
|
|
1858
|
+
}
|
|
1859
|
+
/**
|
|
1860
|
+
* Computes the viewport-space top/left for a popover anchored to `anchorRect`,
|
|
1861
|
+
* applying optional flip-on-overflow and edge-clamp logic. Pure function — no
|
|
1862
|
+
* DOM access. Both `<ea-popover>` and `[eaTooltip]` consume this.
|
|
1863
|
+
*
|
|
1864
|
+
* @param anchorRect The anchor element's `getBoundingClientRect()`.
|
|
1865
|
+
* @param popoverRect Width and height of the popover (post-render measurement).
|
|
1866
|
+
* @param viewport Viewport dimensions (`window.innerWidth/Height`).
|
|
1867
|
+
* @param options Placement and behavior flags.
|
|
1868
|
+
*/
|
|
1869
|
+
function computePopoverPosition(anchorRect, popoverRect, viewport, options) {
|
|
1870
|
+
const offset = options.offset ?? 4;
|
|
1871
|
+
const margin = options.margin ?? 8;
|
|
1872
|
+
const flip = options.flip ?? true;
|
|
1873
|
+
const clamp = options.clamp ?? true;
|
|
1874
|
+
let placement = options.placement;
|
|
1875
|
+
let pos = placeRaw(anchorRect, popoverRect, placement, offset);
|
|
1876
|
+
if (flip) {
|
|
1877
|
+
const overflowsTop = pos.top < margin;
|
|
1878
|
+
const overflowsBottom = pos.top + popoverRect.height > viewport.height - margin;
|
|
1879
|
+
const overflowsLeft = pos.left < margin;
|
|
1880
|
+
const overflowsRight = pos.left + popoverRect.width > viewport.width - margin;
|
|
1881
|
+
const s = side(placement);
|
|
1882
|
+
const shouldFlip = (s === 'top' && overflowsTop) ||
|
|
1883
|
+
(s === 'bottom' && overflowsBottom) ||
|
|
1884
|
+
(s === 'left' && overflowsLeft) ||
|
|
1885
|
+
(s === 'right' && overflowsRight);
|
|
1886
|
+
if (shouldFlip) {
|
|
1887
|
+
const flipped = flipPlacement(placement);
|
|
1888
|
+
const flippedPos = placeRaw(anchorRect, popoverRect, flipped, offset);
|
|
1889
|
+
const flippedFitsBetter = (s === 'top' &&
|
|
1890
|
+
flippedPos.top + popoverRect.height <= viewport.height - margin) ||
|
|
1891
|
+
(s === 'bottom' && flippedPos.top >= margin) ||
|
|
1892
|
+
(s === 'left' &&
|
|
1893
|
+
flippedPos.left + popoverRect.width <= viewport.width - margin) ||
|
|
1894
|
+
(s === 'right' && flippedPos.left >= margin);
|
|
1895
|
+
if (flippedFitsBetter) {
|
|
1896
|
+
placement = flipped;
|
|
1897
|
+
pos = flippedPos;
|
|
1898
|
+
}
|
|
1899
|
+
}
|
|
1900
|
+
}
|
|
1901
|
+
if (clamp) {
|
|
1902
|
+
// Only clamp the cross-axis (perpendicular to the placement). For
|
|
1903
|
+
// bottom-side placements we clamp `left` so the popover doesn't slip off
|
|
1904
|
+
// the left/right of the viewport, but we leave `top` alone — clamping it
|
|
1905
|
+
// when the popover is taller than the available space below the anchor
|
|
1906
|
+
// would yank it up over the anchor itself (the common Storybook-docs-
|
|
1907
|
+
// iframe failure mode where viewports are short). Better to let it
|
|
1908
|
+
// overflow and scroll than to overlap its own trigger.
|
|
1909
|
+
const s = side(placement);
|
|
1910
|
+
const isVertical = s === 'top' || s === 'bottom';
|
|
1911
|
+
if (isVertical) {
|
|
1912
|
+
const maxLeft = viewport.width - popoverRect.width - margin;
|
|
1913
|
+
pos = {
|
|
1914
|
+
top: pos.top,
|
|
1915
|
+
left: Math.max(margin, Math.min(pos.left, Math.max(margin, maxLeft))),
|
|
1916
|
+
};
|
|
1917
|
+
}
|
|
1918
|
+
else {
|
|
1919
|
+
const maxTop = viewport.height - popoverRect.height - margin;
|
|
1920
|
+
pos = {
|
|
1921
|
+
top: Math.max(margin, Math.min(pos.top, Math.max(margin, maxTop))),
|
|
1922
|
+
left: pos.left,
|
|
1923
|
+
};
|
|
1924
|
+
}
|
|
1925
|
+
}
|
|
1926
|
+
return {
|
|
1927
|
+
top: pos.top,
|
|
1928
|
+
left: pos.left,
|
|
1929
|
+
placement,
|
|
1930
|
+
...(options.matchAnchorWidth ? { width: anchorRect.width } : {}),
|
|
1931
|
+
};
|
|
1932
|
+
}
|
|
1933
|
+
|
|
1633
1934
|
/**
|
|
1634
1935
|
* Attaches a positioned tooltip to its host element. Shows on hover and
|
|
1635
1936
|
* focus, hides on leave/blur or Escape, and wires up `aria-describedby` so
|
|
@@ -1822,39 +2123,17 @@ class TooltipDirective {
|
|
|
1822
2123
|
}
|
|
1823
2124
|
}
|
|
1824
2125
|
const tooltipRect = this.tooltipEl.getBoundingClientRect();
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
case 'bottom':
|
|
1837
|
-
top = hostRect.bottom + gap;
|
|
1838
|
-
left = hostRect.left + (hostRect.width - tooltipRect.width) / 2;
|
|
1839
|
-
break;
|
|
1840
|
-
case 'left':
|
|
1841
|
-
top = hostRect.top + (hostRect.height - tooltipRect.height) / 2;
|
|
1842
|
-
left = hostRect.left - tooltipRect.width - gap;
|
|
1843
|
-
break;
|
|
1844
|
-
case 'right':
|
|
1845
|
-
top = hostRect.top + (hostRect.height - tooltipRect.height) / 2;
|
|
1846
|
-
left = hostRect.right + gap;
|
|
1847
|
-
break;
|
|
1848
|
-
}
|
|
1849
|
-
/* Clamp to the viewport so tooltips on near-edge triggers shift inward
|
|
1850
|
-
rather than getting clipped by the chrome. The position arrow (the small
|
|
1851
|
-
caret) stays centered on the host because the clamp only moves the
|
|
1852
|
-
bubble; we don't try to flip placement here, just nudge along the
|
|
1853
|
-
cross-axis. */
|
|
1854
|
-
const viewportWidth = document.documentElement.clientWidth;
|
|
1855
|
-
const viewportHeight = document.documentElement.clientHeight;
|
|
1856
|
-
left = Math.max(edgePadding, Math.min(left, viewportWidth - tooltipRect.width - edgePadding));
|
|
1857
|
-
top = Math.max(edgePadding, Math.min(top, viewportHeight - tooltipRect.height - edgePadding));
|
|
2126
|
+
/* Defer placement math to the shared popover positioning helper. `flip:
|
|
2127
|
+
false` preserves the tooltip's long-standing "stay on the requested
|
|
2128
|
+
side, just nudge inward at the edges" behavior — the caret is centered
|
|
2129
|
+
on the host and would point at empty space if we flipped. `margin: 8`
|
|
2130
|
+
keeps the same breathing room between the bubble and the viewport edge
|
|
2131
|
+
as before. */
|
|
2132
|
+
const placed = computePopoverPosition(hostRect, { width: tooltipRect.width, height: tooltipRect.height }, {
|
|
2133
|
+
width: document.documentElement.clientWidth,
|
|
2134
|
+
height: document.documentElement.clientHeight,
|
|
2135
|
+
}, { placement: this.tooltipPosition(), offset: 8, flip: false, margin: 8 });
|
|
2136
|
+
const { top, left } = placed;
|
|
1858
2137
|
/* Hide if the calculated bubble would render on top of a sticky/fixed
|
|
1859
2138
|
overlay (typically the app header). Catches the case where the trigger
|
|
1860
2139
|
is visible just below the header but a `position: top` tooltip would
|
|
@@ -1947,6 +2226,8 @@ class AvatarEditorComponent {
|
|
|
1947
2226
|
[`ea-avatar-editor--${this.shape()}`]: true,
|
|
1948
2227
|
'ea-avatar-editor--has-image': this.hasImage(),
|
|
1949
2228
|
'ea-avatar-editor--drag-over': this.isDragOver(),
|
|
2229
|
+
'ea-avatar-editor--compact': this.canvasSize() <= 150,
|
|
2230
|
+
'ea-avatar-editor--ultra-compact': this.canvasSize() <= 100,
|
|
1950
2231
|
}), ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
|
|
1951
2232
|
injector = inject(Injector);
|
|
1952
2233
|
boundWheel = (e) => this.onWheel(e);
|
|
@@ -1968,6 +2249,11 @@ class AvatarEditorComponent {
|
|
|
1968
2249
|
this.originalCropState = null;
|
|
1969
2250
|
this.loadFromUrl(src, untracked(() => this.cropState()) ?? null, true);
|
|
1970
2251
|
});
|
|
2252
|
+
effect(() => {
|
|
2253
|
+
this.canvasSize();
|
|
2254
|
+
if (this.image)
|
|
2255
|
+
this.draw();
|
|
2256
|
+
});
|
|
1971
2257
|
}
|
|
1972
2258
|
ngOnDestroy() {
|
|
1973
2259
|
const canvas = this.canvasEl()?.nativeElement;
|
|
@@ -2423,7 +2709,7 @@ class AvatarEditorComponent {
|
|
|
2423
2709
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
2424
2710
|
}
|
|
2425
2711
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: AvatarEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2426
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.13", 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 }, loading: { classPropertyName: "loading", publicName: "loading", 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 }, cropState: { classPropertyName: "cropState", publicName: "cropState", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { cropped: "cropped", fileSelected: "fileSelected", removed: "removed", errored: "errored", cropStateChanged: "cropStateChanged" }, 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 <input\n #fileInputEl\n type=\"file\"\n class=\"ea-avatar-editor__file-input\"\n [attr.aria-label]=\"i18n.messages().avatarEditor.upload\"\n [accept]=\"accept()\"\n (change)=\"onFileSelected($event)\" />\n\n @if (!hasImage() && !isLoading()) {\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 {{ i18n.messages().avatarEditor.dropzone }}\n </span>\n </button>\n }\n\n @if (hasImage() || isLoading()) {\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 @if (isLoading()) {\n <ea-skeleton\n [variant]=\"shape() === 'circle' ? 'circle' : 'rect'\"\n [width]=\"canvasSize() + 'px'\"\n [height]=\"canvasSize() + 'px'\" />\n }\n\n @if (hasImage()) {\n <canvas\n #canvasEl\n class=\"ea-avatar-editor__canvas\"\n role=\"img\"\n tabindex=\"0\"\n [attr.aria-label]=\"i18n.messages().avatarEditor.canvas\"\n [style.display]=\"isLoading() ? 'none' : 'block'\"\n [width]=\"canvasSize()\"\n [height]=\"canvasSize()\"\n (mousedown)=\"onMouseDown($event)\"\n (touchstart)=\"onTouchStart($event)\"\n (keydown)=\"onCanvasKeydown($event)\"></canvas>\n\n @if (!isLoading()) {\n <div\n class=\"ea-avatar-editor__canvas-overlay\"\n [class.ea-avatar-editor__canvas-overlay--on-light]=\"!isImageDark()\">\n <ea-icon-camera class=\"ea-avatar-editor__overlay-icon\" />\n <span>{{ i18n.messages().avatarEditor.change }}</span>\n </div>\n }\n }\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]=\"i18n.messages().avatarEditor.revert\"\n [attr.aria-label]=\"i18n.messages().avatarEditor.revert\"\n [disabled]=\"!canRevert() || isLoading()\"\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]=\"i18n.messages().avatarEditor.zoomOut\"\n [attr.aria-label]=\"i18n.messages().avatarEditor.zoomOut\"\n [disabled]=\"!hasImage() || isLoading() || 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() || isLoading()\"\n [attr.aria-label]=\"i18n.messages().avatarEditor.zoom\"\n (input)=\"onZoomInput($event)\" />\n\n <button\n type=\"button\"\n class=\"ea-avatar-editor__icon-btn\"\n [eaTooltip]=\"i18n.messages().avatarEditor.zoomIn\"\n [attr.aria-label]=\"i18n.messages().avatarEditor.zoomIn\"\n [disabled]=\"!hasImage() || isLoading() || 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]=\"i18n.messages().avatarEditor.remove\"\n [attr.aria-label]=\"i18n.messages().avatarEditor.remove\"\n [disabled]=\"!hasImage() || isLoading()\"\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);color:var(--color-neutral-0);opacity:0;pointer-events:none;transition:opacity var(--duration-fast) var(--easing-default),color var(--duration-fast) var(--easing-default)}.ea-avatar-editor__canvas-overlay--on-light{color:var(--color-neutral-950)}.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: "component", type: CameraIconComponent, selector: "ea-icon-camera" }, { kind: "component", type: MinusIconComponent, selector: "ea-icon-minus" }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: PlusIconComponent, selector: "ea-icon-plus" }, { kind: "component", type: RotateCcwIconComponent, selector: "ea-icon-rotate-ccw" }, { kind: "component", type: SkeletonComponent, selector: "ea-skeleton", inputs: ["variant", "width", "height", "animated"] }, { kind: "directive", type: TooltipDirective, selector: "[eaTooltip]", inputs: ["eaTooltip", "tooltipPosition"] }, { kind: "component", type: TrashIconComponent, selector: "ea-icon-trash" }, { kind: "component", type: UploadIconComponent, selector: "ea-icon-upload" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
2712
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.13", 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 }, loading: { classPropertyName: "loading", publicName: "loading", 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 }, cropState: { classPropertyName: "cropState", publicName: "cropState", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { cropped: "cropped", fileSelected: "fileSelected", removed: "removed", errored: "errored", cropStateChanged: "cropStateChanged" }, 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 <input\n #fileInputEl\n type=\"file\"\n class=\"ea-avatar-editor__file-input\"\n [attr.aria-label]=\"i18n.messages().avatarEditor.upload\"\n [accept]=\"accept()\"\n (change)=\"onFileSelected($event)\" />\n\n @if (!hasImage() && !isLoading()) {\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 {{ i18n.messages().avatarEditor.dropzone }}\n </span>\n </button>\n }\n\n @if (hasImage() || isLoading()) {\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 @if (isLoading()) {\n <ea-skeleton\n [variant]=\"shape() === 'circle' ? 'circle' : 'rect'\"\n [width]=\"canvasSize() + 'px'\"\n [height]=\"canvasSize() + 'px'\" />\n }\n\n @if (hasImage()) {\n <canvas\n #canvasEl\n class=\"ea-avatar-editor__canvas\"\n role=\"img\"\n tabindex=\"0\"\n [attr.aria-label]=\"i18n.messages().avatarEditor.canvas\"\n [style.display]=\"isLoading() ? 'none' : 'block'\"\n [width]=\"canvasSize()\"\n [height]=\"canvasSize()\"\n (mousedown)=\"onMouseDown($event)\"\n (touchstart)=\"onTouchStart($event)\"\n (keydown)=\"onCanvasKeydown($event)\"></canvas>\n\n @if (!isLoading()) {\n <div\n class=\"ea-avatar-editor__canvas-overlay\"\n [class.ea-avatar-editor__canvas-overlay--on-light]=\"!isImageDark()\">\n <ea-icon-camera class=\"ea-avatar-editor__overlay-icon\" />\n <span>{{ i18n.messages().avatarEditor.change }}</span>\n </div>\n }\n }\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]=\"i18n.messages().avatarEditor.revert\"\n [attr.aria-label]=\"i18n.messages().avatarEditor.revert\"\n [disabled]=\"!canRevert() || isLoading()\"\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]=\"i18n.messages().avatarEditor.zoomOut\"\n [attr.aria-label]=\"i18n.messages().avatarEditor.zoomOut\"\n [disabled]=\"!hasImage() || isLoading() || 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() || isLoading()\"\n [attr.aria-label]=\"i18n.messages().avatarEditor.zoom\"\n (input)=\"onZoomInput($event)\" />\n\n <button\n type=\"button\"\n class=\"ea-avatar-editor__icon-btn\"\n [eaTooltip]=\"i18n.messages().avatarEditor.zoomIn\"\n [attr.aria-label]=\"i18n.messages().avatarEditor.zoomIn\"\n [disabled]=\"!hasImage() || isLoading() || 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]=\"i18n.messages().avatarEditor.remove\"\n [attr.aria-label]=\"i18n.messages().avatarEditor.remove\"\n [disabled]=\"!hasImage() || isLoading()\"\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--compact .ea-avatar-editor__dropzone{gap:var(--space-1-5);padding:var(--space-3);font-size:.75rem;line-height:1.35}.ea-avatar-editor--compact .ea-avatar-editor__upload-icon{width:24px;height:24px}.ea-avatar-editor--ultra-compact .ea-avatar-editor__dropzone{gap:var(--space-1);padding:var(--space-2);font-size:.625rem;line-height:1.2}.ea-avatar-editor--ultra-compact .ea-avatar-editor__upload-icon{width:16px;height:16px}.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);color:var(--color-neutral-0);opacity:0;pointer-events:none;transition:opacity var(--duration-fast) var(--easing-default),color var(--duration-fast) var(--easing-default)}.ea-avatar-editor__canvas-overlay--on-light{color:var(--color-neutral-950)}.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: "component", type: CameraIconComponent, selector: "ea-icon-camera" }, { kind: "component", type: MinusIconComponent, selector: "ea-icon-minus" }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: PlusIconComponent, selector: "ea-icon-plus" }, { kind: "component", type: RotateCcwIconComponent, selector: "ea-icon-rotate-ccw" }, { kind: "component", type: SkeletonComponent, selector: "ea-skeleton", inputs: ["variant", "width", "height", "animated"] }, { kind: "directive", type: TooltipDirective, selector: "[eaTooltip]", inputs: ["eaTooltip", "tooltipPosition"] }, { kind: "component", type: TrashIconComponent, selector: "ea-icon-trash" }, { kind: "component", type: UploadIconComponent, selector: "ea-icon-upload" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
2427
2713
|
}
|
|
2428
2714
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: AvatarEditorComponent, decorators: [{
|
|
2429
2715
|
type: Component,
|
|
@@ -2437,7 +2723,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImpo
|
|
|
2437
2723
|
TooltipDirective,
|
|
2438
2724
|
TrashIconComponent,
|
|
2439
2725
|
UploadIconComponent,
|
|
2440
|
-
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div\n class=\"ea-avatar-editor\"\n [ngClass]=\"hostClasses()\">\n <input\n #fileInputEl\n type=\"file\"\n class=\"ea-avatar-editor__file-input\"\n [attr.aria-label]=\"i18n.messages().avatarEditor.upload\"\n [accept]=\"accept()\"\n (change)=\"onFileSelected($event)\" />\n\n @if (!hasImage() && !isLoading()) {\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 {{ i18n.messages().avatarEditor.dropzone }}\n </span>\n </button>\n }\n\n @if (hasImage() || isLoading()) {\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 @if (isLoading()) {\n <ea-skeleton\n [variant]=\"shape() === 'circle' ? 'circle' : 'rect'\"\n [width]=\"canvasSize() + 'px'\"\n [height]=\"canvasSize() + 'px'\" />\n }\n\n @if (hasImage()) {\n <canvas\n #canvasEl\n class=\"ea-avatar-editor__canvas\"\n role=\"img\"\n tabindex=\"0\"\n [attr.aria-label]=\"i18n.messages().avatarEditor.canvas\"\n [style.display]=\"isLoading() ? 'none' : 'block'\"\n [width]=\"canvasSize()\"\n [height]=\"canvasSize()\"\n (mousedown)=\"onMouseDown($event)\"\n (touchstart)=\"onTouchStart($event)\"\n (keydown)=\"onCanvasKeydown($event)\"></canvas>\n\n @if (!isLoading()) {\n <div\n class=\"ea-avatar-editor__canvas-overlay\"\n [class.ea-avatar-editor__canvas-overlay--on-light]=\"!isImageDark()\">\n <ea-icon-camera class=\"ea-avatar-editor__overlay-icon\" />\n <span>{{ i18n.messages().avatarEditor.change }}</span>\n </div>\n }\n }\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]=\"i18n.messages().avatarEditor.revert\"\n [attr.aria-label]=\"i18n.messages().avatarEditor.revert\"\n [disabled]=\"!canRevert() || isLoading()\"\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]=\"i18n.messages().avatarEditor.zoomOut\"\n [attr.aria-label]=\"i18n.messages().avatarEditor.zoomOut\"\n [disabled]=\"!hasImage() || isLoading() || 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() || isLoading()\"\n [attr.aria-label]=\"i18n.messages().avatarEditor.zoom\"\n (input)=\"onZoomInput($event)\" />\n\n <button\n type=\"button\"\n class=\"ea-avatar-editor__icon-btn\"\n [eaTooltip]=\"i18n.messages().avatarEditor.zoomIn\"\n [attr.aria-label]=\"i18n.messages().avatarEditor.zoomIn\"\n [disabled]=\"!hasImage() || isLoading() || 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]=\"i18n.messages().avatarEditor.remove\"\n [attr.aria-label]=\"i18n.messages().avatarEditor.remove\"\n [disabled]=\"!hasImage() || isLoading()\"\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);color:var(--color-neutral-0);opacity:0;pointer-events:none;transition:opacity var(--duration-fast) var(--easing-default),color var(--duration-fast) var(--easing-default)}.ea-avatar-editor__canvas-overlay--on-light{color:var(--color-neutral-950)}.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"] }]
|
|
2726
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div\n class=\"ea-avatar-editor\"\n [ngClass]=\"hostClasses()\">\n <input\n #fileInputEl\n type=\"file\"\n class=\"ea-avatar-editor__file-input\"\n [attr.aria-label]=\"i18n.messages().avatarEditor.upload\"\n [accept]=\"accept()\"\n (change)=\"onFileSelected($event)\" />\n\n @if (!hasImage() && !isLoading()) {\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 {{ i18n.messages().avatarEditor.dropzone }}\n </span>\n </button>\n }\n\n @if (hasImage() || isLoading()) {\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 @if (isLoading()) {\n <ea-skeleton\n [variant]=\"shape() === 'circle' ? 'circle' : 'rect'\"\n [width]=\"canvasSize() + 'px'\"\n [height]=\"canvasSize() + 'px'\" />\n }\n\n @if (hasImage()) {\n <canvas\n #canvasEl\n class=\"ea-avatar-editor__canvas\"\n role=\"img\"\n tabindex=\"0\"\n [attr.aria-label]=\"i18n.messages().avatarEditor.canvas\"\n [style.display]=\"isLoading() ? 'none' : 'block'\"\n [width]=\"canvasSize()\"\n [height]=\"canvasSize()\"\n (mousedown)=\"onMouseDown($event)\"\n (touchstart)=\"onTouchStart($event)\"\n (keydown)=\"onCanvasKeydown($event)\"></canvas>\n\n @if (!isLoading()) {\n <div\n class=\"ea-avatar-editor__canvas-overlay\"\n [class.ea-avatar-editor__canvas-overlay--on-light]=\"!isImageDark()\">\n <ea-icon-camera class=\"ea-avatar-editor__overlay-icon\" />\n <span>{{ i18n.messages().avatarEditor.change }}</span>\n </div>\n }\n }\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]=\"i18n.messages().avatarEditor.revert\"\n [attr.aria-label]=\"i18n.messages().avatarEditor.revert\"\n [disabled]=\"!canRevert() || isLoading()\"\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]=\"i18n.messages().avatarEditor.zoomOut\"\n [attr.aria-label]=\"i18n.messages().avatarEditor.zoomOut\"\n [disabled]=\"!hasImage() || isLoading() || 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() || isLoading()\"\n [attr.aria-label]=\"i18n.messages().avatarEditor.zoom\"\n (input)=\"onZoomInput($event)\" />\n\n <button\n type=\"button\"\n class=\"ea-avatar-editor__icon-btn\"\n [eaTooltip]=\"i18n.messages().avatarEditor.zoomIn\"\n [attr.aria-label]=\"i18n.messages().avatarEditor.zoomIn\"\n [disabled]=\"!hasImage() || isLoading() || 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]=\"i18n.messages().avatarEditor.remove\"\n [attr.aria-label]=\"i18n.messages().avatarEditor.remove\"\n [disabled]=\"!hasImage() || isLoading()\"\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--compact .ea-avatar-editor__dropzone{gap:var(--space-1-5);padding:var(--space-3);font-size:.75rem;line-height:1.35}.ea-avatar-editor--compact .ea-avatar-editor__upload-icon{width:24px;height:24px}.ea-avatar-editor--ultra-compact .ea-avatar-editor__dropzone{gap:var(--space-1);padding:var(--space-2);font-size:.625rem;line-height:1.2}.ea-avatar-editor--ultra-compact .ea-avatar-editor__upload-icon{width:16px;height:16px}.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);color:var(--color-neutral-0);opacity:0;pointer-events:none;transition:opacity var(--duration-fast) var(--easing-default),color var(--duration-fast) var(--easing-default)}.ea-avatar-editor__canvas-overlay--on-light{color:var(--color-neutral-950)}.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"] }]
|
|
2441
2727
|
}], 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 }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", 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 }] }], cropState: [{ type: i0.Input, args: [{ isSignal: true, alias: "cropState", required: false }] }], cropped: [{ type: i0.Output, args: ["cropped"] }], fileSelected: [{ type: i0.Output, args: ["fileSelected"] }], removed: [{ type: i0.Output, args: ["removed"] }], errored: [{ type: i0.Output, args: ["errored"] }], cropStateChanged: [{ type: i0.Output, args: ["cropStateChanged"] }] } });
|
|
2442
2728
|
|
|
2443
2729
|
class UserIconComponent extends IconComponentBase {
|
|
@@ -2534,23 +2820,25 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImpo
|
|
|
2534
2820
|
}], propDecorators: { src: [{ type: i0.Input, args: [{ isSignal: true, alias: "src", required: false }] }], alt: [{ type: i0.Input, args: [{ isSignal: true, alias: "alt", required: false }] }], initials: [{ type: i0.Input, args: [{ isSignal: true, alias: "initials", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], shape: [{ type: i0.Input, args: [{ isSignal: true, alias: "shape", required: false }] }] } });
|
|
2535
2821
|
|
|
2536
2822
|
/**
|
|
2537
|
-
* Compact
|
|
2538
|
-
*
|
|
2823
|
+
* Compact indicator used to communicate status, counts, or labels inline with
|
|
2824
|
+
* surrounding content.
|
|
2539
2825
|
*/
|
|
2540
2826
|
class BadgeComponent {
|
|
2541
2827
|
variant = input('default', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
2542
2828
|
size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
2829
|
+
shape = input('pill', ...(ngDevMode ? [{ debugName: "shape" }] : /* istanbul ignore next */ []));
|
|
2543
2830
|
hostClasses = computed(() => ({
|
|
2544
2831
|
[`ea-badge--${this.variant()}`]: true,
|
|
2545
2832
|
[`ea-badge--${this.size()}`]: true,
|
|
2833
|
+
[`ea-badge--${this.shape()}`]: true,
|
|
2546
2834
|
}), ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
|
|
2547
2835
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: BadgeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2548
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.13", type: BadgeComponent, isStandalone: true, selector: "ea-badge", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<span\n class=\"ea-badge\"\n [ngClass]=\"hostClasses()\">\n <ng-content />\n</span>\n", styles: [".ea-badge{display:inline-flex;align-items:center;gap:var(--space-1);font-family:var(--font-family-sans);font-weight:var(--font-weight-medium);line-height:var(--line-height-none);white-space:nowrap;border-radius:var(--radius-full)}.ea-badge--sm{padding:var(--space-0-5) var(--space-2);font-size:var(--font-size-xs)}.ea-badge--md{padding:var(--space-1) var(--space-2-5);font-size:var(--font-size-xs)}.ea-badge--lg{padding:var(--space-1) var(--space-3);font-size:var(--font-size-sm)}.ea-badge--default{background-color:var(--color-bg-muted);color:var(--color-text-secondary)}.ea-badge--success{background-color:var(--color-success-subtle);color:var(--color-success-700)}.ea-badge--warning{background-color:var(--color-warning-subtle);color:var(--color-warning-700)}.ea-badge--error{background-color:var(--color-error-subtle);color:var(--color-error-700)}.ea-badge--info{background-color:var(--color-info-subtle);color:var(--color-info-700)}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
2836
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.13", type: BadgeComponent, isStandalone: true, selector: "ea-badge", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, shape: { classPropertyName: "shape", publicName: "shape", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<span\n class=\"ea-badge\"\n [ngClass]=\"hostClasses()\">\n <ng-content />\n</span>\n", styles: [".ea-badge{display:inline-flex;align-items:center;gap:var(--space-1);font-family:var(--font-family-sans);font-weight:var(--font-weight-medium);line-height:var(--line-height-none);white-space:nowrap;border-style:solid;border-width:var(--ea-badge-border-width, 0);border-color:var(--ea-badge-border-color, transparent);border-radius:var(--radius-full)}.ea-badge--sm{padding:var(--space-0-5) var(--space-2);font-size:var(--ea-badge-font-size, var(--font-size-xs))}.ea-badge--md{padding:var(--space-1) var(--space-2-5);font-size:var(--ea-badge-font-size, var(--font-size-xs))}.ea-badge--lg{padding:var(--space-1) var(--space-3);font-size:var(--ea-badge-font-size, var(--font-size-sm))}.ea-badge--default{background-color:var(--ea-badge-background-color, var(--color-bg-muted));color:var(--ea-badge-color, var(--color-text-secondary))}.ea-badge--success{background-color:var(--ea-badge-background-color, var(--color-success-subtle));color:var(--ea-badge-color, var(--color-success-700))}.ea-badge--warning{background-color:var(--ea-badge-background-color, var(--color-warning-subtle));color:var(--ea-badge-color, var(--color-warning-700))}.ea-badge--error{background-color:var(--ea-badge-background-color, var(--color-error-subtle));color:var(--ea-badge-color, var(--color-error-700))}.ea-badge--info{background-color:var(--ea-badge-background-color, var(--color-info-subtle));color:var(--ea-badge-color, var(--color-info-700))}.ea-badge--pin{justify-content:center;box-sizing:border-box;padding:0 var(--space-1);font-variant-numeric:tabular-nums}.ea-badge--pin.ea-badge--sm{min-width:var(--ea-badge-size, 16px);height:var(--ea-badge-size, 16px);font-size:var(--ea-badge-font-size, 9px)}.ea-badge--pin.ea-badge--md{min-width:var(--ea-badge-size, 18px);height:var(--ea-badge-size, 18px);font-size:var(--ea-badge-font-size, 10px)}.ea-badge--pin.ea-badge--lg{min-width:var(--ea-badge-size, 22px);height:var(--ea-badge-size, 22px);font-size:var(--ea-badge-font-size, 12px)}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
2549
2837
|
}
|
|
2550
2838
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: BadgeComponent, decorators: [{
|
|
2551
2839
|
type: Component,
|
|
2552
|
-
args: [{ selector: 'ea-badge', imports: [NgClass], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<span\n class=\"ea-badge\"\n [ngClass]=\"hostClasses()\">\n <ng-content />\n</span>\n", styles: [".ea-badge{display:inline-flex;align-items:center;gap:var(--space-1);font-family:var(--font-family-sans);font-weight:var(--font-weight-medium);line-height:var(--line-height-none);white-space:nowrap;border-radius:var(--radius-full)}.ea-badge--sm{padding:var(--space-0-5) var(--space-2);font-size:var(--font-size-xs)}.ea-badge--md{padding:var(--space-1) var(--space-2-5);font-size:var(--font-size-xs)}.ea-badge--lg{padding:var(--space-1) var(--space-3);font-size:var(--font-size-sm)}.ea-badge--default{background-color:var(--color-bg-muted);color:var(--color-text-secondary)}.ea-badge--success{background-color:var(--color-success-subtle);color:var(--color-success-700)}.ea-badge--warning{background-color:var(--color-warning-subtle);color:var(--color-warning-700)}.ea-badge--error{background-color:var(--color-error-subtle);color:var(--color-error-700)}.ea-badge--info{background-color:var(--color-info-subtle);color:var(--color-info-700)}\n"] }]
|
|
2553
|
-
}], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }] } });
|
|
2840
|
+
args: [{ selector: 'ea-badge', imports: [NgClass], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<span\n class=\"ea-badge\"\n [ngClass]=\"hostClasses()\">\n <ng-content />\n</span>\n", styles: [".ea-badge{display:inline-flex;align-items:center;gap:var(--space-1);font-family:var(--font-family-sans);font-weight:var(--font-weight-medium);line-height:var(--line-height-none);white-space:nowrap;border-style:solid;border-width:var(--ea-badge-border-width, 0);border-color:var(--ea-badge-border-color, transparent);border-radius:var(--radius-full)}.ea-badge--sm{padding:var(--space-0-5) var(--space-2);font-size:var(--ea-badge-font-size, var(--font-size-xs))}.ea-badge--md{padding:var(--space-1) var(--space-2-5);font-size:var(--ea-badge-font-size, var(--font-size-xs))}.ea-badge--lg{padding:var(--space-1) var(--space-3);font-size:var(--ea-badge-font-size, var(--font-size-sm))}.ea-badge--default{background-color:var(--ea-badge-background-color, var(--color-bg-muted));color:var(--ea-badge-color, var(--color-text-secondary))}.ea-badge--success{background-color:var(--ea-badge-background-color, var(--color-success-subtle));color:var(--ea-badge-color, var(--color-success-700))}.ea-badge--warning{background-color:var(--ea-badge-background-color, var(--color-warning-subtle));color:var(--ea-badge-color, var(--color-warning-700))}.ea-badge--error{background-color:var(--ea-badge-background-color, var(--color-error-subtle));color:var(--ea-badge-color, var(--color-error-700))}.ea-badge--info{background-color:var(--ea-badge-background-color, var(--color-info-subtle));color:var(--ea-badge-color, var(--color-info-700))}.ea-badge--pin{justify-content:center;box-sizing:border-box;padding:0 var(--space-1);font-variant-numeric:tabular-nums}.ea-badge--pin.ea-badge--sm{min-width:var(--ea-badge-size, 16px);height:var(--ea-badge-size, 16px);font-size:var(--ea-badge-font-size, 9px)}.ea-badge--pin.ea-badge--md{min-width:var(--ea-badge-size, 18px);height:var(--ea-badge-size, 18px);font-size:var(--ea-badge-font-size, 10px)}.ea-badge--pin.ea-badge--lg{min-width:var(--ea-badge-size, 22px);height:var(--ea-badge-size, 22px);font-size:var(--ea-badge-font-size, 12px)}\n"] }]
|
|
2841
|
+
}], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], shape: [{ type: i0.Input, args: [{ isSignal: true, alias: "shape", required: false }] }] } });
|
|
2554
2842
|
|
|
2555
2843
|
class ChevronRightIconComponent extends IconComponentBase {
|
|
2556
2844
|
static slug = 'chevron-right';
|
|
@@ -2672,13 +2960,13 @@ class ButtonComponent {
|
|
|
2672
2960
|
this.clicked.emit(event);
|
|
2673
2961
|
}
|
|
2674
2962
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: ButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2675
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.13", type: ButtonComponent, isStandalone: true, selector: "ea-button", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, fullWidth: { classPropertyName: "fullWidth", publicName: "fullWidth", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null }, ariaCurrent: { classPropertyName: "ariaCurrent", publicName: "aria-current", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { clicked: "clicked" }, host: { properties: { "class.ea-button--full-width": "fullWidth()" } }, ngImport: i0, template: "<button\n class=\"ea-button\"\n [ngClass]=\"hostClasses()\"\n [type]=\"type()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-current]=\"ariaCurrent() || null\"\n [attr.aria-busy]=\"loading() || null\"\n (click)=\"handleClick($event)\">\n @if (loading()) {\n <span\n class=\"ea-button__spinner\"\n aria-hidden=\"true\">\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\">\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n stroke-dasharray=\"31.4\"\n stroke-dashoffset=\"10\" />\n </svg>\n </span>\n }\n\n <span\n class=\"ea-button__content\"\n [class.ea-button__content--hidden]=\"loading()\">\n <ng-content select=\"[slot=prefix]\" />\n <span class=\"ea-button__label\">\n <ng-content />\n </span>\n <ng-content select=\"[slot=suffix]\" />\n </span>\n</button>\n", styles: [".ea-button{display:inline-flex;align-items:center;justify-content:center;gap:var(--inline-xs);position:relative;white-space:nowrap;-webkit-user-select:none;user-select:none;font-family:var(--font-family-sans);font-weight:var(--ea-button-font-weight, var(--font-weight-medium));letter-spacing:var(--letter-spacing-wide);text-decoration:none;line-height:var(--line-height-none);border-width:var(--border-width-thin);border-style:solid;border-radius:var(--radius-md);transition:var(--transition-colors),var(--transition-shadow);cursor:pointer}.ea-button:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-button--sm{padding:var(--space-1-5) var(--space-3);font-size:var(--ea-button-font-size, var(--font-size-sm));min-height:2rem}.ea-button--md{padding:var(--space-2) var(--space-4);font-size:var(--ea-button-font-size, var(--font-size-sm));min-height:2.5rem}.ea-button--lg{padding:var(--space-2-5) var(--space-6);font-size:var(--ea-button-font-size, var(--font-size-md));min-height:3rem}.ea-button--primary{background-color:var(--color-brand-default);border-color:var(--color-brand-default);color:var(--color-text-inverse)}.ea-button--primary:hover:not(.ea-button--disabled){background-color:var(--color-brand-hover);border-color:var(--color-brand-hover)}.ea-button--primary:active:not(.ea-button--disabled){background-color:var(--color-brand-active);border-color:var(--color-brand-active)}.ea-button--secondary{background-color:transparent;border-color:var(--color-border-strong);color:var(--color-text-primary)}.ea-button--secondary:hover:not(.ea-button--disabled){background-color:var(--color-bg-muted);border-color:var(--color-neutral-500)}.ea-button--secondary:active:not(.ea-button--disabled){background-color:var(--color-neutral-200)}.ea-button--ghost{background-color:transparent;border-color:transparent;color:var(--color-text-primary)}.ea-button--ghost:hover:not(.ea-button--disabled){background-color:var(--color-bg-muted)}.ea-button--ghost:active:not(.ea-button--disabled){background-color:var(--color-neutral-200)}.ea-button--danger{background-color:var(--color-error-default);border-color:var(--color-error-default);color:var(--color-text-inverse)}.ea-button--danger:hover:not(.ea-button--disabled){background-color:var(--color-error-700);border-color:var(--color-error-700)}.ea-button--danger:active:not(.ea-button--disabled){background-color:var(--color-error-700);border-color:var(--color-error-700);filter:brightness(.9)}.ea-button--full-width{width:100%}.ea-button--disabled,.ea-button:disabled{opacity:.45;cursor:not-allowed;pointer-events:none}.ea-button--loading{cursor:wait;pointer-events:none}.ea-button__content{display:inline-flex;align-items:center;gap:var(--inline-xs)}.ea-button__content--hidden{visibility:hidden}.ea-button__label{display:inline-flex;align-items:center}.ea-button__spinner{position:absolute;inset:0;display:flex;align-items:center;justify-content:center}.ea-button__spinner svg{width:1.1em;height:1.1em;animation:ea-spin .75s linear infinite}:host(.ea-button--full-width){display:block;width:100%}@keyframes ea-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2963
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.13", type: ButtonComponent, isStandalone: true, selector: "ea-button", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, fullWidth: { classPropertyName: "fullWidth", publicName: "fullWidth", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null }, ariaCurrent: { classPropertyName: "ariaCurrent", publicName: "aria-current", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { clicked: "clicked" }, host: { properties: { "class.ea-button--full-width": "fullWidth()" } }, ngImport: i0, template: "<button\n class=\"ea-button\"\n [ngClass]=\"hostClasses()\"\n [type]=\"type()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-current]=\"ariaCurrent() || null\"\n [attr.aria-busy]=\"loading() || null\"\n (click)=\"handleClick($event)\">\n @if (loading()) {\n <span\n class=\"ea-button__spinner\"\n aria-hidden=\"true\">\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\">\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n stroke-dasharray=\"31.4\"\n stroke-dashoffset=\"10\" />\n </svg>\n </span>\n }\n\n <span\n class=\"ea-button__content\"\n [class.ea-button__content--hidden]=\"loading()\">\n <ng-content select=\"[slot=prefix]\" />\n <span class=\"ea-button__label\">\n <ng-content />\n </span>\n <ng-content select=\"[slot=suffix]\" />\n </span>\n</button>\n", styles: [":host{display:inline-flex}.ea-button{display:inline-flex;align-items:center;justify-content:center;gap:var(--inline-xs);position:relative;white-space:nowrap;-webkit-user-select:none;user-select:none;font-family:var(--font-family-sans);font-weight:var(--ea-button-font-weight, var(--font-weight-medium));letter-spacing:var(--letter-spacing-wide);text-decoration:none;line-height:var(--line-height-none);border-width:var(--border-width-thin);border-style:solid;border-radius:var(--radius-md);transition:var(--transition-colors),var(--transition-shadow);cursor:pointer}.ea-button:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-button--sm{padding:var(--space-1-5) var(--space-3);font-size:var(--ea-button-font-size, var(--font-size-sm));min-height:2rem}.ea-button--md{padding:var(--space-2) var(--space-4);font-size:var(--ea-button-font-size, var(--font-size-sm));min-height:2.5rem}.ea-button--lg{padding:var(--space-2-5) var(--space-6);font-size:var(--ea-button-font-size, var(--font-size-md));min-height:3rem}.ea-button--primary{background-color:var(--color-brand-default);border-color:var(--color-brand-default);color:var(--color-text-inverse)}.ea-button--primary:hover:not(.ea-button--disabled){background-color:var(--color-brand-hover);border-color:var(--color-brand-hover)}.ea-button--primary:active:not(.ea-button--disabled){background-color:var(--color-brand-active);border-color:var(--color-brand-active)}.ea-button--secondary{background-color:transparent;border-color:var(--color-border-strong);color:var(--color-text-primary)}.ea-button--secondary:hover:not(.ea-button--disabled){background-color:var(--color-bg-muted);border-color:var(--color-neutral-500)}.ea-button--secondary:active:not(.ea-button--disabled){background-color:var(--color-neutral-200)}.ea-button--ghost{background-color:transparent;border-color:transparent;color:var(--color-text-primary)}.ea-button--ghost:hover:not(.ea-button--disabled){background-color:var(--color-bg-muted)}.ea-button--ghost:active:not(.ea-button--disabled){background-color:var(--color-neutral-200)}.ea-button--danger{background-color:var(--color-error-default);border-color:var(--color-error-default);color:var(--color-text-inverse)}.ea-button--danger:hover:not(.ea-button--disabled){background-color:var(--color-error-700);border-color:var(--color-error-700)}.ea-button--danger:active:not(.ea-button--disabled){background-color:var(--color-error-700);border-color:var(--color-error-700);filter:brightness(.9)}.ea-button--full-width{width:100%}.ea-button--disabled,.ea-button:disabled{opacity:.45;cursor:not-allowed;pointer-events:none}.ea-button--loading{cursor:wait;pointer-events:none}.ea-button__content{display:inline-flex;align-items:center;gap:var(--inline-xs)}.ea-button__content--hidden{visibility:hidden}.ea-button__label{display:inline-flex;align-items:center}.ea-button__spinner{position:absolute;inset:0;display:flex;align-items:center;justify-content:center}.ea-button__spinner svg{width:1.1em;height:1.1em;animation:ea-spin .75s linear infinite}:host(.ea-button--full-width){display:block;width:100%}@keyframes ea-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2676
2964
|
}
|
|
2677
2965
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: ButtonComponent, decorators: [{
|
|
2678
2966
|
type: Component,
|
|
2679
2967
|
args: [{ selector: 'ea-button', imports: [NgClass], changeDetection: ChangeDetectionStrategy.OnPush, host: {
|
|
2680
2968
|
'[class.ea-button--full-width]': 'fullWidth()',
|
|
2681
|
-
}, template: "<button\n class=\"ea-button\"\n [ngClass]=\"hostClasses()\"\n [type]=\"type()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-current]=\"ariaCurrent() || null\"\n [attr.aria-busy]=\"loading() || null\"\n (click)=\"handleClick($event)\">\n @if (loading()) {\n <span\n class=\"ea-button__spinner\"\n aria-hidden=\"true\">\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\">\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n stroke-dasharray=\"31.4\"\n stroke-dashoffset=\"10\" />\n </svg>\n </span>\n }\n\n <span\n class=\"ea-button__content\"\n [class.ea-button__content--hidden]=\"loading()\">\n <ng-content select=\"[slot=prefix]\" />\n <span class=\"ea-button__label\">\n <ng-content />\n </span>\n <ng-content select=\"[slot=suffix]\" />\n </span>\n</button>\n", styles: [".ea-button{display:inline-flex;align-items:center;justify-content:center;gap:var(--inline-xs);position:relative;white-space:nowrap;-webkit-user-select:none;user-select:none;font-family:var(--font-family-sans);font-weight:var(--ea-button-font-weight, var(--font-weight-medium));letter-spacing:var(--letter-spacing-wide);text-decoration:none;line-height:var(--line-height-none);border-width:var(--border-width-thin);border-style:solid;border-radius:var(--radius-md);transition:var(--transition-colors),var(--transition-shadow);cursor:pointer}.ea-button:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-button--sm{padding:var(--space-1-5) var(--space-3);font-size:var(--ea-button-font-size, var(--font-size-sm));min-height:2rem}.ea-button--md{padding:var(--space-2) var(--space-4);font-size:var(--ea-button-font-size, var(--font-size-sm));min-height:2.5rem}.ea-button--lg{padding:var(--space-2-5) var(--space-6);font-size:var(--ea-button-font-size, var(--font-size-md));min-height:3rem}.ea-button--primary{background-color:var(--color-brand-default);border-color:var(--color-brand-default);color:var(--color-text-inverse)}.ea-button--primary:hover:not(.ea-button--disabled){background-color:var(--color-brand-hover);border-color:var(--color-brand-hover)}.ea-button--primary:active:not(.ea-button--disabled){background-color:var(--color-brand-active);border-color:var(--color-brand-active)}.ea-button--secondary{background-color:transparent;border-color:var(--color-border-strong);color:var(--color-text-primary)}.ea-button--secondary:hover:not(.ea-button--disabled){background-color:var(--color-bg-muted);border-color:var(--color-neutral-500)}.ea-button--secondary:active:not(.ea-button--disabled){background-color:var(--color-neutral-200)}.ea-button--ghost{background-color:transparent;border-color:transparent;color:var(--color-text-primary)}.ea-button--ghost:hover:not(.ea-button--disabled){background-color:var(--color-bg-muted)}.ea-button--ghost:active:not(.ea-button--disabled){background-color:var(--color-neutral-200)}.ea-button--danger{background-color:var(--color-error-default);border-color:var(--color-error-default);color:var(--color-text-inverse)}.ea-button--danger:hover:not(.ea-button--disabled){background-color:var(--color-error-700);border-color:var(--color-error-700)}.ea-button--danger:active:not(.ea-button--disabled){background-color:var(--color-error-700);border-color:var(--color-error-700);filter:brightness(.9)}.ea-button--full-width{width:100%}.ea-button--disabled,.ea-button:disabled{opacity:.45;cursor:not-allowed;pointer-events:none}.ea-button--loading{cursor:wait;pointer-events:none}.ea-button__content{display:inline-flex;align-items:center;gap:var(--inline-xs)}.ea-button__content--hidden{visibility:hidden}.ea-button__label{display:inline-flex;align-items:center}.ea-button__spinner{position:absolute;inset:0;display:flex;align-items:center;justify-content:center}.ea-button__spinner svg{width:1.1em;height:1.1em;animation:ea-spin .75s linear infinite}:host(.ea-button--full-width){display:block;width:100%}@keyframes ea-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"] }]
|
|
2969
|
+
}, template: "<button\n class=\"ea-button\"\n [ngClass]=\"hostClasses()\"\n [type]=\"type()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.aria-current]=\"ariaCurrent() || null\"\n [attr.aria-busy]=\"loading() || null\"\n (click)=\"handleClick($event)\">\n @if (loading()) {\n <span\n class=\"ea-button__spinner\"\n aria-hidden=\"true\">\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\">\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n stroke-dasharray=\"31.4\"\n stroke-dashoffset=\"10\" />\n </svg>\n </span>\n }\n\n <span\n class=\"ea-button__content\"\n [class.ea-button__content--hidden]=\"loading()\">\n <ng-content select=\"[slot=prefix]\" />\n <span class=\"ea-button__label\">\n <ng-content />\n </span>\n <ng-content select=\"[slot=suffix]\" />\n </span>\n</button>\n", styles: [":host{display:inline-flex}.ea-button{display:inline-flex;align-items:center;justify-content:center;gap:var(--inline-xs);position:relative;white-space:nowrap;-webkit-user-select:none;user-select:none;font-family:var(--font-family-sans);font-weight:var(--ea-button-font-weight, var(--font-weight-medium));letter-spacing:var(--letter-spacing-wide);text-decoration:none;line-height:var(--line-height-none);border-width:var(--border-width-thin);border-style:solid;border-radius:var(--radius-md);transition:var(--transition-colors),var(--transition-shadow);cursor:pointer}.ea-button:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-button--sm{padding:var(--space-1-5) var(--space-3);font-size:var(--ea-button-font-size, var(--font-size-sm));min-height:2rem}.ea-button--md{padding:var(--space-2) var(--space-4);font-size:var(--ea-button-font-size, var(--font-size-sm));min-height:2.5rem}.ea-button--lg{padding:var(--space-2-5) var(--space-6);font-size:var(--ea-button-font-size, var(--font-size-md));min-height:3rem}.ea-button--primary{background-color:var(--color-brand-default);border-color:var(--color-brand-default);color:var(--color-text-inverse)}.ea-button--primary:hover:not(.ea-button--disabled){background-color:var(--color-brand-hover);border-color:var(--color-brand-hover)}.ea-button--primary:active:not(.ea-button--disabled){background-color:var(--color-brand-active);border-color:var(--color-brand-active)}.ea-button--secondary{background-color:transparent;border-color:var(--color-border-strong);color:var(--color-text-primary)}.ea-button--secondary:hover:not(.ea-button--disabled){background-color:var(--color-bg-muted);border-color:var(--color-neutral-500)}.ea-button--secondary:active:not(.ea-button--disabled){background-color:var(--color-neutral-200)}.ea-button--ghost{background-color:transparent;border-color:transparent;color:var(--color-text-primary)}.ea-button--ghost:hover:not(.ea-button--disabled){background-color:var(--color-bg-muted)}.ea-button--ghost:active:not(.ea-button--disabled){background-color:var(--color-neutral-200)}.ea-button--danger{background-color:var(--color-error-default);border-color:var(--color-error-default);color:var(--color-text-inverse)}.ea-button--danger:hover:not(.ea-button--disabled){background-color:var(--color-error-700);border-color:var(--color-error-700)}.ea-button--danger:active:not(.ea-button--disabled){background-color:var(--color-error-700);border-color:var(--color-error-700);filter:brightness(.9)}.ea-button--full-width{width:100%}.ea-button--disabled,.ea-button:disabled{opacity:.45;cursor:not-allowed;pointer-events:none}.ea-button--loading{cursor:wait;pointer-events:none}.ea-button__content{display:inline-flex;align-items:center;gap:var(--inline-xs)}.ea-button__content--hidden{visibility:hidden}.ea-button__label{display:inline-flex;align-items:center}.ea-button__spinner{position:absolute;inset:0;display:flex;align-items:center;justify-content:center}.ea-button__spinner svg{width:1.1em;height:1.1em;animation:ea-spin .75s linear infinite}:host(.ea-button--full-width){display:block;width:100%}@keyframes ea-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"] }]
|
|
2682
2970
|
}], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], fullWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "fullWidth", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-label", required: false }] }], ariaCurrent: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-current", required: false }] }], clicked: [{ type: i0.Output, args: ["clicked"] }] } });
|
|
2683
2971
|
|
|
2684
2972
|
/**
|
|
@@ -2693,11 +2981,11 @@ class DividerComponent {
|
|
|
2693
2981
|
'ea-divider--with-label': !!this.label(),
|
|
2694
2982
|
}), ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
|
|
2695
2983
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: DividerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2696
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.13", type: DividerComponent, isStandalone: true, selector: "ea-divider", inputs: { orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div\n class=\"ea-divider\"\n [ngClass]=\"hostClasses()\"\n [attr.role]=\"'separator'\"\n [attr.aria-orientation]=\"orientation()\">\n @if (label()) {\n <span class=\"ea-divider__label\">{{ label() }}</span>\n }\n</div>\n", styles: [".ea-divider{flex-shrink:0;border:0;font-family:var(--font-family-sans)}.ea-divider--horizontal{display:flex;align-items:center;width:100%;height:1px;background-color:var(--color-border-default)}.ea-divider--vertical{display:inline-block;width:1px;height:
|
|
2984
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.13", type: DividerComponent, isStandalone: true, selector: "ea-divider", inputs: { orientation: { classPropertyName: "orientation", publicName: "orientation", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div\n class=\"ea-divider\"\n [ngClass]=\"hostClasses()\"\n [attr.role]=\"'separator'\"\n [attr.aria-orientation]=\"orientation()\">\n @if (label()) {\n <span class=\"ea-divider__label\">{{ label() }}</span>\n }\n</div>\n", styles: [".ea-divider{flex-shrink:0;border:0;font-family:var(--font-family-sans)}.ea-divider--horizontal{display:flex;align-items:center;width:100%;height:1px;background-color:var(--color-border-default)}.ea-divider--vertical{display:inline-block;width:1px;height:1.5em;min-height:1rem;background-color:var(--color-border-default)}.ea-divider--with-label{height:auto;background-color:transparent;gap:var(--space-3)}.ea-divider--with-label:before,.ea-divider--with-label:after{content:\"\";flex:1;height:1px;background-color:var(--color-border-default)}.ea-divider__label{flex-shrink:0;font-size:var(--font-size-sm);line-height:var(--line-height-normal);color:var(--color-text-secondary);white-space:nowrap}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
2697
2985
|
}
|
|
2698
2986
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: DividerComponent, decorators: [{
|
|
2699
2987
|
type: Component,
|
|
2700
|
-
args: [{ selector: 'ea-divider', imports: [NgClass], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div\n class=\"ea-divider\"\n [ngClass]=\"hostClasses()\"\n [attr.role]=\"'separator'\"\n [attr.aria-orientation]=\"orientation()\">\n @if (label()) {\n <span class=\"ea-divider__label\">{{ label() }}</span>\n }\n</div>\n", styles: [".ea-divider{flex-shrink:0;border:0;font-family:var(--font-family-sans)}.ea-divider--horizontal{display:flex;align-items:center;width:100%;height:1px;background-color:var(--color-border-default)}.ea-divider--vertical{display:inline-block;width:1px;height:
|
|
2988
|
+
args: [{ selector: 'ea-divider', imports: [NgClass], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div\n class=\"ea-divider\"\n [ngClass]=\"hostClasses()\"\n [attr.role]=\"'separator'\"\n [attr.aria-orientation]=\"orientation()\">\n @if (label()) {\n <span class=\"ea-divider__label\">{{ label() }}</span>\n }\n</div>\n", styles: [".ea-divider{flex-shrink:0;border:0;font-family:var(--font-family-sans)}.ea-divider--horizontal{display:flex;align-items:center;width:100%;height:1px;background-color:var(--color-border-default)}.ea-divider--vertical{display:inline-block;width:1px;height:1.5em;min-height:1rem;background-color:var(--color-border-default)}.ea-divider--with-label{height:auto;background-color:transparent;gap:var(--space-3)}.ea-divider--with-label:before,.ea-divider--with-label:after{content:\"\";flex:1;height:1px;background-color:var(--color-border-default)}.ea-divider__label{flex-shrink:0;font-size:var(--font-size-sm);line-height:var(--line-height-normal);color:var(--color-text-secondary);white-space:nowrap}\n"] }]
|
|
2701
2989
|
}], propDecorators: { orientation: [{ type: i0.Input, args: [{ isSignal: true, alias: "orientation", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }] } });
|
|
2702
2990
|
|
|
2703
2991
|
/**
|
|
@@ -2872,6 +3160,237 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImpo
|
|
|
2872
3160
|
}]
|
|
2873
3161
|
}] });
|
|
2874
3162
|
|
|
3163
|
+
/**
|
|
3164
|
+
* Floating-element primitive. Renders projected content as `position: fixed`
|
|
3165
|
+
* anchored to an external element, with flip-on-overflow, viewport clamping,
|
|
3166
|
+
* outside-click and Escape dismissal, and SSR-safe scroll / resize handling.
|
|
3167
|
+
*
|
|
3168
|
+
* The primitive is intentionally low-level: a parent component drives the
|
|
3169
|
+
* `[open]` state and listens for `(closeRequested)` to mirror it back. Internal
|
|
3170
|
+
* library components (`<ea-menu>`, `<ea-dropdown>`, `<ea-color-picker>`,
|
|
3171
|
+
* `<ea-date-picker>`, `[eaTooltip]`) compose on top of it; downstream apps can
|
|
3172
|
+
* use it directly to build their own popover-based UI.
|
|
3173
|
+
*
|
|
3174
|
+
* @example
|
|
3175
|
+
* ```html
|
|
3176
|
+
* <button #trigger (click)="open.set(!open())">Open</button>
|
|
3177
|
+
* <ea-popover [anchor]="trigger" [open]="open()" (closeRequested)="open.set(false)">
|
|
3178
|
+
* <div>Popover content</div>
|
|
3179
|
+
* </ea-popover>
|
|
3180
|
+
* ```
|
|
3181
|
+
*/
|
|
3182
|
+
class PopoverComponent {
|
|
3183
|
+
destroyRef = inject(DestroyRef);
|
|
3184
|
+
surfaceEl = viewChild('surfaceEl', ...(ngDevMode ? [{ debugName: "surfaceEl" }] : /* istanbul ignore next */ []));
|
|
3185
|
+
/** Anchor element the popover positions itself against. */
|
|
3186
|
+
anchor = input.required(...(ngDevMode ? [{ debugName: "anchor" }] : /* istanbul ignore next */ []));
|
|
3187
|
+
/** Whether the popover is currently open. */
|
|
3188
|
+
open = input(false, ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
|
|
3189
|
+
/** Where the popover attaches relative to the anchor. */
|
|
3190
|
+
placement = input('bottom-start', ...(ngDevMode ? [{ debugName: "placement" }] : /* istanbul ignore next */ []));
|
|
3191
|
+
/** ARIA role applied to the popover surface. */
|
|
3192
|
+
role = input('dialog', ...(ngDevMode ? [{ debugName: "role" }] : /* istanbul ignore next */ []));
|
|
3193
|
+
/** Accessible label. Falls back to nothing; consumers should provide one when no visible heading is in the popover. */
|
|
3194
|
+
ariaLabel = input(undefined, { ...(ngDevMode ? { debugName: "ariaLabel" } : /* istanbul ignore next */ {}), alias: 'aria-label' });
|
|
3195
|
+
/** DOM id for the surface so trigger elements can reference it via aria-controls. */
|
|
3196
|
+
surfaceId = input(`ea-popover-${Math.random().toString(36).slice(2, 9)}`, ...(ngDevMode ? [{ debugName: "surfaceId" }] : /* istanbul ignore next */ []));
|
|
3197
|
+
/** Gap in px between the anchor and the popover. */
|
|
3198
|
+
offset = input(0, ...(ngDevMode ? [{ debugName: "offset" }] : /* istanbul ignore next */ []));
|
|
3199
|
+
/** Flip to the opposite side when the requested side overflows the viewport. */
|
|
3200
|
+
flip = input(true, ...(ngDevMode ? [{ debugName: "flip" }] : /* istanbul ignore next */ []));
|
|
3201
|
+
/** Clamp the popover inside the viewport when it would otherwise overflow. */
|
|
3202
|
+
clamp = input(true, ...(ngDevMode ? [{ debugName: "clamp" }] : /* istanbul ignore next */ []));
|
|
3203
|
+
/** Set the popover's `min-width` to match the anchor's width (dropdown pattern). */
|
|
3204
|
+
matchAnchorWidth = input(false, ...(ngDevMode ? [{ debugName: "matchAnchorWidth" }] : /* istanbul ignore next */ []));
|
|
3205
|
+
/** Close on click outside the popover and the anchor. */
|
|
3206
|
+
closeOnOutsideClick = input(true, ...(ngDevMode ? [{ debugName: "closeOnOutsideClick" }] : /* istanbul ignore next */ []));
|
|
3207
|
+
/** Close on Escape. */
|
|
3208
|
+
closeOnEscape = input(true, ...(ngDevMode ? [{ debugName: "closeOnEscape" }] : /* istanbul ignore next */ []));
|
|
3209
|
+
/** What to do on scroll / resize while open. */
|
|
3210
|
+
scrollBehavior = input('reposition', ...(ngDevMode ? [{ debugName: "scrollBehavior" }] : /* istanbul ignore next */ []));
|
|
3211
|
+
/** Requested close. The parent should mirror this into `[open]`. */
|
|
3212
|
+
closeRequested = output();
|
|
3213
|
+
position = signal(null, ...(ngDevMode ? [{ debugName: "position" }] : /* istanbul ignore next */ []));
|
|
3214
|
+
/** True placement after flip, for class-based styling (e.g. arrow direction). */
|
|
3215
|
+
effectivePlacement = computed(() => this.position()?.placement ?? this.placement(), ...(ngDevMode ? [{ debugName: "effectivePlacement" }] : /* istanbul ignore next */ []));
|
|
3216
|
+
/** Inline style applied to the surface element. */
|
|
3217
|
+
surfaceStyle = computed(() => {
|
|
3218
|
+
if (!this.open())
|
|
3219
|
+
return { display: 'none' };
|
|
3220
|
+
const p = this.position();
|
|
3221
|
+
// Before the first reposition, hide the surface — at this point it's
|
|
3222
|
+
// sitting at the top-left of the viewport with no coordinates applied
|
|
3223
|
+
// yet, and we don't want a flash on open.
|
|
3224
|
+
if (!p)
|
|
3225
|
+
return { visibility: 'hidden' };
|
|
3226
|
+
const style = {
|
|
3227
|
+
top: `${p.top}px`,
|
|
3228
|
+
left: `${p.left}px`,
|
|
3229
|
+
};
|
|
3230
|
+
if (p.width !== undefined) {
|
|
3231
|
+
style['min-width'] = `${p.width}px`;
|
|
3232
|
+
}
|
|
3233
|
+
return style;
|
|
3234
|
+
}, ...(ngDevMode ? [{ debugName: "surfaceStyle" }] : /* istanbul ignore next */ []));
|
|
3235
|
+
constructor() {
|
|
3236
|
+
// Re-measure and reposition whenever the anchor, placement, surface, or
|
|
3237
|
+
// open state changes. Reading `surfaceEl()` here makes it a tracked signal
|
|
3238
|
+
// dependency, so the effect re-runs once Angular has rendered the `@if`
|
|
3239
|
+
// block and the viewChild signal has updated — at that point both the
|
|
3240
|
+
// anchor and the surface have a `getBoundingClientRect`, and the position
|
|
3241
|
+
// can be computed. This is more reliable than `afterNextRender` because it
|
|
3242
|
+
// doesn't depend on a single render cycle landing in the expected order
|
|
3243
|
+
// (some host environments — Storybook docs mode, for example — defer that
|
|
3244
|
+
// callback in a way that leaves the surface stuck at `visibility: hidden`).
|
|
3245
|
+
// Naturally SSR-safe: the surface never renders on the server, so the
|
|
3246
|
+
// effect always early-returns during prerender.
|
|
3247
|
+
// Teleport the surface to `document.body` as soon as it exists so
|
|
3248
|
+
// `position: fixed` is always relative to the actual viewport (escaping
|
|
3249
|
+
// any transformed/contained ancestor that would otherwise create a new
|
|
3250
|
+
// containing block). Doing the move on init — not on open — also means
|
|
3251
|
+
// the first `getBoundingClientRect` call inside `reposition()` reads a
|
|
3252
|
+
// surface that's already in its final DOM home, so the browser's layout
|
|
3253
|
+
// is settled and dimensions are accurate. Skipped in SSR (no `document`).
|
|
3254
|
+
effect(() => {
|
|
3255
|
+
const surface = this.surfaceEl()?.nativeElement;
|
|
3256
|
+
if (surface &&
|
|
3257
|
+
typeof document !== 'undefined' &&
|
|
3258
|
+
surface.parentNode !== document.body) {
|
|
3259
|
+
document.body.appendChild(surface);
|
|
3260
|
+
}
|
|
3261
|
+
});
|
|
3262
|
+
effect(() => {
|
|
3263
|
+
const surface = this.surfaceEl()?.nativeElement;
|
|
3264
|
+
const anchor = this.resolveAnchor();
|
|
3265
|
+
const isOpen = this.open();
|
|
3266
|
+
if (!surface || !anchor || !isOpen) {
|
|
3267
|
+
this.position.set(null);
|
|
3268
|
+
return;
|
|
3269
|
+
}
|
|
3270
|
+
// Re-read inputs so signal subscriptions stay current after a re-open.
|
|
3271
|
+
this.placement();
|
|
3272
|
+
this.offset();
|
|
3273
|
+
this.flip();
|
|
3274
|
+
this.clamp();
|
|
3275
|
+
this.matchAnchorWidth();
|
|
3276
|
+
this.reposition();
|
|
3277
|
+
});
|
|
3278
|
+
// Watch the surface's own size and reposition whenever it changes. The
|
|
3279
|
+
// first `reposition()` after open fires synchronously inside the open
|
|
3280
|
+
// effect, while the surface is still transitioning out of `display: none`
|
|
3281
|
+
// — in some browsers the layout pass hasn't completed, so the
|
|
3282
|
+
// `getBoundingClientRect` width can read as the surface's natural width
|
|
3283
|
+
// even when that overflows the viewport, so the clamp can't kick in. The
|
|
3284
|
+
// ResizeObserver fires once the surface has been laid out with its real
|
|
3285
|
+
// dimensions, giving us a second, accurate measurement to clamp against.
|
|
3286
|
+
// Also catches projected-content size changes while the popover is open
|
|
3287
|
+
// (e.g. virtualised lists adding rows).
|
|
3288
|
+
if (typeof ResizeObserver !== 'undefined') {
|
|
3289
|
+
const surfaceResizeObserver = new ResizeObserver(() => {
|
|
3290
|
+
if (this.open())
|
|
3291
|
+
this.reposition();
|
|
3292
|
+
});
|
|
3293
|
+
effect(() => {
|
|
3294
|
+
const surface = this.surfaceEl()?.nativeElement;
|
|
3295
|
+
surfaceResizeObserver.disconnect();
|
|
3296
|
+
if (surface)
|
|
3297
|
+
surfaceResizeObserver.observe(surface);
|
|
3298
|
+
});
|
|
3299
|
+
this.destroyRef.onDestroy(() => surfaceResizeObserver.disconnect());
|
|
3300
|
+
}
|
|
3301
|
+
// Listen for scroll / resize while open. The `scrollBehavior` input picks
|
|
3302
|
+
// the response. SSR guard is required because the website prerenders pages
|
|
3303
|
+
// that mount popovers.
|
|
3304
|
+
if (typeof window !== 'undefined') {
|
|
3305
|
+
const onViewportChange = () => {
|
|
3306
|
+
if (!this.open())
|
|
3307
|
+
return;
|
|
3308
|
+
const behavior = this.scrollBehavior();
|
|
3309
|
+
if (behavior === 'close') {
|
|
3310
|
+
this.closeRequested.emit();
|
|
3311
|
+
}
|
|
3312
|
+
else if (behavior === 'reposition') {
|
|
3313
|
+
this.reposition();
|
|
3314
|
+
}
|
|
3315
|
+
};
|
|
3316
|
+
window.addEventListener('scroll', onViewportChange, {
|
|
3317
|
+
capture: true,
|
|
3318
|
+
passive: true,
|
|
3319
|
+
});
|
|
3320
|
+
window.addEventListener('resize', onViewportChange);
|
|
3321
|
+
this.destroyRef.onDestroy(() => {
|
|
3322
|
+
window.removeEventListener('scroll', onViewportChange, { capture: true });
|
|
3323
|
+
window.removeEventListener('resize', onViewportChange);
|
|
3324
|
+
});
|
|
3325
|
+
}
|
|
3326
|
+
// Explicitly remove the portaled surface on destroy. Angular's view
|
|
3327
|
+
// destruction normally removes nodes the renderer created, but moving the
|
|
3328
|
+
// surface via raw `appendChild` (out of its original anchor slot) is
|
|
3329
|
+
// enough to break that tracking in some host environments — Storybook's
|
|
3330
|
+
// SPA navigation between docs pages, for one, leaves the surface stranded
|
|
3331
|
+
// in `document.body` after the parent component is gone. Removing it here
|
|
3332
|
+
// guarantees cleanup regardless of how Angular's view destruction handles
|
|
3333
|
+
// the relocated node.
|
|
3334
|
+
this.destroyRef.onDestroy(() => {
|
|
3335
|
+
const surface = this.surfaceEl()?.nativeElement;
|
|
3336
|
+
surface?.parentNode?.removeChild(surface);
|
|
3337
|
+
});
|
|
3338
|
+
}
|
|
3339
|
+
resolveAnchor() {
|
|
3340
|
+
const a = this.anchor();
|
|
3341
|
+
if (!a)
|
|
3342
|
+
return null;
|
|
3343
|
+
return a instanceof ElementRef ? a.nativeElement : a;
|
|
3344
|
+
}
|
|
3345
|
+
reposition() {
|
|
3346
|
+
if (typeof window === 'undefined')
|
|
3347
|
+
return;
|
|
3348
|
+
const anchor = this.resolveAnchor();
|
|
3349
|
+
const surface = this.surfaceEl()?.nativeElement;
|
|
3350
|
+
if (!anchor || !surface)
|
|
3351
|
+
return;
|
|
3352
|
+
const anchorRect = anchor.getBoundingClientRect();
|
|
3353
|
+
const surfaceRect = surface.getBoundingClientRect();
|
|
3354
|
+
this.position.set(computePopoverPosition(anchorRect, { width: surfaceRect.width, height: surfaceRect.height }, { width: window.innerWidth, height: window.innerHeight }, {
|
|
3355
|
+
placement: this.placement(),
|
|
3356
|
+
offset: this.offset(),
|
|
3357
|
+
flip: this.flip(),
|
|
3358
|
+
clamp: this.clamp(),
|
|
3359
|
+
matchAnchorWidth: this.matchAnchorWidth(),
|
|
3360
|
+
}));
|
|
3361
|
+
}
|
|
3362
|
+
onDocumentClick(event) {
|
|
3363
|
+
if (!this.open() || !this.closeOnOutsideClick())
|
|
3364
|
+
return;
|
|
3365
|
+
const target = event.target;
|
|
3366
|
+
if (!target)
|
|
3367
|
+
return;
|
|
3368
|
+
const anchor = this.resolveAnchor();
|
|
3369
|
+
if (anchor?.contains(target))
|
|
3370
|
+
return;
|
|
3371
|
+
if (this.surfaceEl()?.nativeElement.contains(target))
|
|
3372
|
+
return;
|
|
3373
|
+
this.closeRequested.emit();
|
|
3374
|
+
}
|
|
3375
|
+
onEscape() {
|
|
3376
|
+
if (!this.open() || !this.closeOnEscape())
|
|
3377
|
+
return;
|
|
3378
|
+
this.closeRequested.emit();
|
|
3379
|
+
}
|
|
3380
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: PopoverComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3381
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.13", type: PopoverComponent, isStandalone: true, selector: "ea-popover", inputs: { anchor: { classPropertyName: "anchor", publicName: "anchor", isSignal: true, isRequired: true, transformFunction: null }, open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, placement: { classPropertyName: "placement", publicName: "placement", isSignal: true, isRequired: false, transformFunction: null }, role: { classPropertyName: "role", publicName: "role", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null }, surfaceId: { classPropertyName: "surfaceId", publicName: "surfaceId", isSignal: true, isRequired: false, transformFunction: null }, offset: { classPropertyName: "offset", publicName: "offset", isSignal: true, isRequired: false, transformFunction: null }, flip: { classPropertyName: "flip", publicName: "flip", isSignal: true, isRequired: false, transformFunction: null }, clamp: { classPropertyName: "clamp", publicName: "clamp", isSignal: true, isRequired: false, transformFunction: null }, matchAnchorWidth: { classPropertyName: "matchAnchorWidth", publicName: "matchAnchorWidth", isSignal: true, isRequired: false, transformFunction: null }, closeOnOutsideClick: { classPropertyName: "closeOnOutsideClick", publicName: "closeOnOutsideClick", isSignal: true, isRequired: false, transformFunction: null }, closeOnEscape: { classPropertyName: "closeOnEscape", publicName: "closeOnEscape", isSignal: true, isRequired: false, transformFunction: null }, scrollBehavior: { classPropertyName: "scrollBehavior", publicName: "scrollBehavior", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closeRequested: "closeRequested" }, host: { listeners: { "document:click": "onDocumentClick($event)", "document:keydown.escape": "onEscape()" } }, viewQueries: [{ propertyName: "surfaceEl", first: true, predicate: ["surfaceEl"], descendants: true, isSignal: true }], ngImport: i0, template: "<!--\n The surface is rendered unconditionally so the `<ng-content/>` slot always\n exists. If we gated it on `@if (open())`, Angular would re-project the\n consumer's content at the popover host's position whenever the surface was\n absent \u2014 leaking menu items / picker controls into the document flow (made\n worse by `display: contents` on the host). Hiding via `display: none` keeps\n the projected DOM owned by the surface and out of the flow when closed.\n-->\n<div\n #surfaceEl\n class=\"ea-popover__surface\"\n [class]=\"'ea-popover__surface--' + effectivePlacement()\"\n [id]=\"surfaceId()\"\n [attr.role]=\"open() ? role() : null\"\n [attr.aria-label]=\"open() ? ariaLabel() : null\"\n [attr.aria-hidden]=\"open() ? null : true\"\n [style]=\"surfaceStyle()\">\n <ng-content />\n</div>\n", styles: [":host{display:contents}.ea-popover__surface{z-index:var(--z-index-dropdown);position:fixed}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3382
|
+
}
|
|
3383
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: PopoverComponent, decorators: [{
|
|
3384
|
+
type: Component,
|
|
3385
|
+
args: [{ selector: 'ea-popover', changeDetection: ChangeDetectionStrategy.OnPush, template: "<!--\n The surface is rendered unconditionally so the `<ng-content/>` slot always\n exists. If we gated it on `@if (open())`, Angular would re-project the\n consumer's content at the popover host's position whenever the surface was\n absent \u2014 leaking menu items / picker controls into the document flow (made\n worse by `display: contents` on the host). Hiding via `display: none` keeps\n the projected DOM owned by the surface and out of the flow when closed.\n-->\n<div\n #surfaceEl\n class=\"ea-popover__surface\"\n [class]=\"'ea-popover__surface--' + effectivePlacement()\"\n [id]=\"surfaceId()\"\n [attr.role]=\"open() ? role() : null\"\n [attr.aria-label]=\"open() ? ariaLabel() : null\"\n [attr.aria-hidden]=\"open() ? null : true\"\n [style]=\"surfaceStyle()\">\n <ng-content />\n</div>\n", styles: [":host{display:contents}.ea-popover__surface{z-index:var(--z-index-dropdown);position:fixed}\n"] }]
|
|
3386
|
+
}], ctorParameters: () => [], propDecorators: { surfaceEl: [{ type: i0.ViewChild, args: ['surfaceEl', { isSignal: true }] }], anchor: [{ type: i0.Input, args: [{ isSignal: true, alias: "anchor", required: true }] }], open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }], placement: [{ type: i0.Input, args: [{ isSignal: true, alias: "placement", required: false }] }], role: [{ type: i0.Input, args: [{ isSignal: true, alias: "role", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-label", required: false }] }], surfaceId: [{ type: i0.Input, args: [{ isSignal: true, alias: "surfaceId", required: false }] }], offset: [{ type: i0.Input, args: [{ isSignal: true, alias: "offset", required: false }] }], flip: [{ type: i0.Input, args: [{ isSignal: true, alias: "flip", required: false }] }], clamp: [{ type: i0.Input, args: [{ isSignal: true, alias: "clamp", required: false }] }], matchAnchorWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "matchAnchorWidth", required: false }] }], closeOnOutsideClick: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnOutsideClick", required: false }] }], closeOnEscape: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnEscape", required: false }] }], scrollBehavior: [{ type: i0.Input, args: [{ isSignal: true, alias: "scrollBehavior", required: false }] }], closeRequested: [{ type: i0.Output, args: ["closeRequested"] }], onDocumentClick: [{
|
|
3387
|
+
type: HostListener,
|
|
3388
|
+
args: ['document:click', ['$event']]
|
|
3389
|
+
}], onEscape: [{
|
|
3390
|
+
type: HostListener,
|
|
3391
|
+
args: ['document:keydown.escape']
|
|
3392
|
+
}] } });
|
|
3393
|
+
|
|
2875
3394
|
const DEFAULT_PRESETS = [
|
|
2876
3395
|
'#ef4444',
|
|
2877
3396
|
'#f97316',
|
|
@@ -2901,14 +3420,11 @@ const DEFAULT_PRESETS = [
|
|
|
2901
3420
|
* `ControlValueAccessor`. Accepts any CSS color string in `writeValue`.
|
|
2902
3421
|
*/
|
|
2903
3422
|
class ColorPickerComponent {
|
|
2904
|
-
hostEl = viewChild('hostEl', ...(ngDevMode ? [{ debugName: "hostEl" }] : /* istanbul ignore next */ []));
|
|
2905
3423
|
triggerEl = viewChild('triggerEl', ...(ngDevMode ? [{ debugName: "triggerEl" }] : /* istanbul ignore next */ []));
|
|
2906
|
-
popoverEl = viewChild('popoverEl', ...(ngDevMode ? [{ debugName: "popoverEl" }] : /* istanbul ignore next */ []));
|
|
2907
3424
|
svAreaEl = viewChild('svAreaEl', ...(ngDevMode ? [{ debugName: "svAreaEl" }] : /* istanbul ignore next */ []));
|
|
2908
3425
|
hueTrackEl = viewChild('hueTrackEl', ...(ngDevMode ? [{ debugName: "hueTrackEl" }] : /* istanbul ignore next */ []));
|
|
2909
3426
|
alphaTrackEl = viewChild('alphaTrackEl', ...(ngDevMode ? [{ debugName: "alphaTrackEl" }] : /* istanbul ignore next */ []));
|
|
2910
3427
|
injector = inject(Injector);
|
|
2911
|
-
destroyRef = inject(DestroyRef);
|
|
2912
3428
|
i18n = inject(EagamiI18nService);
|
|
2913
3429
|
label = input(undefined, ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
2914
3430
|
placeholder = input(undefined, ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
|
|
@@ -2943,10 +3459,6 @@ class ColorPickerComponent {
|
|
|
2943
3459
|
* can type a partial value (`#1`, `#12`, `#123…`) without each keystroke being
|
|
2944
3460
|
* expanded back into a 6-digit canonical form. */
|
|
2945
3461
|
hexInputValue = signal('', ...(ngDevMode ? [{ debugName: "hexInputValue" }] : /* istanbul ignore next */ []));
|
|
2946
|
-
/** Pixel position of the popover when open. Calculated from the trigger's
|
|
2947
|
-
* bounding rect so the popover can use `position: fixed` and escape any
|
|
2948
|
-
* ancestor with `overflow: hidden`. */
|
|
2949
|
-
popoverPosition = signal(null, ...(ngDevMode ? [{ debugName: "popoverPosition" }] : /* istanbul ignore next */ []));
|
|
2950
3462
|
_formDisabled = signal(false, ...(ngDevMode ? [{ debugName: "_formDisabled" }] : /* istanbul ignore next */ []));
|
|
2951
3463
|
onChange = () => { };
|
|
2952
3464
|
onTouched = () => { };
|
|
@@ -2981,51 +3493,18 @@ class ColorPickerComponent {
|
|
|
2981
3493
|
'ea-color-picker__trigger--open': this.isOpen(),
|
|
2982
3494
|
'ea-color-picker__trigger--disabled': this.isDisabled(),
|
|
2983
3495
|
}), ...(ngDevMode ? [{ debugName: "triggerClasses" }] : /* istanbul ignore next */ []));
|
|
2984
|
-
/**
|
|
2985
|
-
|
|
3496
|
+
/**
|
|
3497
|
+
* True when the browser supports the EyeDropper API. Not a `computed` —
|
|
3498
|
+
* `window.EyeDropper` isn't a signal, so a memoized computed would cache the
|
|
3499
|
+
* first read (typically `false`, since the popover content's bindings now
|
|
3500
|
+
* evaluate at parent-view creation time via content projection, before any
|
|
3501
|
+
* polyfill / test setup runs). A plain method re-checks on every call.
|
|
3502
|
+
*/
|
|
3503
|
+
hasEyeDropper() {
|
|
2986
3504
|
if (typeof window === 'undefined')
|
|
2987
3505
|
return false;
|
|
2988
3506
|
return (typeof window.EyeDropper ===
|
|
2989
3507
|
'function');
|
|
2990
|
-
}, ...(ngDevMode ? [{ debugName: "hasEyeDropper" }] : /* istanbul ignore next */ []));
|
|
2991
|
-
constructor() {
|
|
2992
|
-
// When the popover opens, anchor it to the trigger using `position: fixed`
|
|
2993
|
-
// coordinates so it escapes any ancestor with `overflow: hidden` (a common
|
|
2994
|
-
// gotcha in scrollable content panels — same pattern as `<ea-dropdown>`).
|
|
2995
|
-
// After the popover renders we measure it and, if it would overflow the
|
|
2996
|
-
// viewport bottom, flip it above the trigger (or clamp against the top
|
|
2997
|
-
// edge when neither direction fits — better than getting trapped below
|
|
2998
|
-
// the fold with no way to scroll, which the page-scroll wouldn't reach
|
|
2999
|
-
// because the popover itself is fixed).
|
|
3000
|
-
effect(() => {
|
|
3001
|
-
const trigger = this.triggerEl()?.nativeElement;
|
|
3002
|
-
if (!trigger || !this.isOpen()) {
|
|
3003
|
-
this.popoverPosition.set(null);
|
|
3004
|
-
return;
|
|
3005
|
-
}
|
|
3006
|
-
const rect = trigger.getBoundingClientRect();
|
|
3007
|
-
this.popoverPosition.set({ top: rect.bottom + 4, left: rect.left });
|
|
3008
|
-
// Re-measure once the popover has actually rendered so we know its height.
|
|
3009
|
-
afterNextRender(() => this.clampPopoverToViewport(), { injector: this.injector });
|
|
3010
|
-
});
|
|
3011
|
-
// Close the popover on scroll / resize rather than try to track the trigger
|
|
3012
|
-
// — same pattern as `<ea-dropdown>`. SSR-guarded because the website
|
|
3013
|
-
// prerenders pages that render this component.
|
|
3014
|
-
if (typeof window !== 'undefined') {
|
|
3015
|
-
const closeOnViewportChange = () => {
|
|
3016
|
-
if (this.isOpen())
|
|
3017
|
-
this.close();
|
|
3018
|
-
};
|
|
3019
|
-
window.addEventListener('scroll', closeOnViewportChange, {
|
|
3020
|
-
capture: true,
|
|
3021
|
-
passive: true,
|
|
3022
|
-
});
|
|
3023
|
-
window.addEventListener('resize', closeOnViewportChange);
|
|
3024
|
-
this.destroyRef.onDestroy(() => {
|
|
3025
|
-
window.removeEventListener('scroll', closeOnViewportChange, { capture: true });
|
|
3026
|
-
window.removeEventListener('resize', closeOnViewportChange);
|
|
3027
|
-
});
|
|
3028
|
-
}
|
|
3029
3508
|
}
|
|
3030
3509
|
// ─── ControlValueAccessor ─────────────────────────────────────────────
|
|
3031
3510
|
writeValue(val) {
|
|
@@ -3366,42 +3845,9 @@ class ColorPickerComponent {
|
|
|
3366
3845
|
this.triggerEl()?.nativeElement.focus({ preventScroll: true });
|
|
3367
3846
|
}
|
|
3368
3847
|
}
|
|
3369
|
-
|
|
3370
|
-
|
|
3371
|
-
|
|
3372
|
-
const host = this.hostEl()?.nativeElement;
|
|
3373
|
-
if (host && !host.contains(event.target))
|
|
3374
|
-
this.close();
|
|
3375
|
-
}
|
|
3376
|
-
/**
|
|
3377
|
-
* Repositions the popover when it would extend past the viewport edges.
|
|
3378
|
-
* Prefers flipping above the trigger when there's more room there, then
|
|
3379
|
-
* clamps so the popover always has a small margin from the viewport edges.
|
|
3380
|
-
*/
|
|
3381
|
-
clampPopoverToViewport() {
|
|
3382
|
-
const popover = this.popoverEl()?.nativeElement;
|
|
3383
|
-
const trigger = this.triggerEl()?.nativeElement;
|
|
3384
|
-
const current = this.popoverPosition();
|
|
3385
|
-
if (!popover || !trigger || !current)
|
|
3386
|
-
return;
|
|
3387
|
-
const margin = 8;
|
|
3388
|
-
const triggerRect = trigger.getBoundingClientRect();
|
|
3389
|
-
const popoverRect = popover.getBoundingClientRect();
|
|
3390
|
-
const viewportH = window.innerHeight;
|
|
3391
|
-
const viewportW = window.innerWidth;
|
|
3392
|
-
let top = current.top;
|
|
3393
|
-
const overflowsBottom = top + popoverRect.height > viewportH - margin;
|
|
3394
|
-
const roomAbove = triggerRect.top - margin;
|
|
3395
|
-
if (overflowsBottom && roomAbove >= popoverRect.height + 4) {
|
|
3396
|
-
top = triggerRect.top - popoverRect.height - 4;
|
|
3397
|
-
}
|
|
3398
|
-
else if (overflowsBottom) {
|
|
3399
|
-
top = Math.max(margin, viewportH - popoverRect.height - margin);
|
|
3400
|
-
}
|
|
3401
|
-
const left = Math.max(margin, Math.min(current.left, viewportW - popoverRect.width - margin));
|
|
3402
|
-
if (top !== current.top || left !== current.left) {
|
|
3403
|
-
this.popoverPosition.set({ top, left });
|
|
3404
|
-
}
|
|
3848
|
+
/** Called by `<ea-popover>` when the user clicks outside the picker. */
|
|
3849
|
+
onPopoverCloseRequested() {
|
|
3850
|
+
this.close();
|
|
3405
3851
|
}
|
|
3406
3852
|
// ─── Internal: applying state and committing ──────────────────────────
|
|
3407
3853
|
applyHsv(h, s, v) {
|
|
@@ -3436,27 +3882,24 @@ class ColorPickerComponent {
|
|
|
3436
3882
|
this.hexInputValue.set(this.hexDisplay());
|
|
3437
3883
|
}
|
|
3438
3884
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: ColorPickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3439
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.13", type: ColorPickerComponent, isStandalone: true, selector: "ea-color-picker", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, errorMsg: { classPropertyName: "errorMsg", publicName: "errorMsg", isSignal: true, isRequired: false, transformFunction: null }, showAlpha: { classPropertyName: "showAlpha", publicName: "showAlpha", isSignal: true, isRequired: false, transformFunction: null }, format: { classPropertyName: "format", publicName: "format", isSignal: true, isRequired: false, transformFunction: null }, presets: { classPropertyName: "presets", publicName: "presets", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", changed: "changed" },
|
|
3885
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.13", type: ColorPickerComponent, isStandalone: true, selector: "ea-color-picker", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, errorMsg: { classPropertyName: "errorMsg", publicName: "errorMsg", isSignal: true, isRequired: false, transformFunction: null }, showAlpha: { classPropertyName: "showAlpha", publicName: "showAlpha", isSignal: true, isRequired: false, transformFunction: null }, format: { classPropertyName: "format", publicName: "format", isSignal: true, isRequired: false, transformFunction: null }, presets: { classPropertyName: "presets", publicName: "presets", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", changed: "changed" }, providers: [
|
|
3440
3886
|
{
|
|
3441
3887
|
provide: NG_VALUE_ACCESSOR,
|
|
3442
3888
|
useExisting: forwardRef(() => ColorPickerComponent),
|
|
3443
3889
|
multi: true,
|
|
3444
3890
|
},
|
|
3445
|
-
], viewQueries: [{ propertyName: "hostEl", first: true, predicate: ["hostEl"], descendants: true, isSignal: true }, { propertyName: "triggerEl", first: true, predicate: ["triggerEl"], descendants: true, isSignal: true }, { propertyName: "popoverEl", first: true, predicate: ["popoverEl"], descendants: true, isSignal: true }, { propertyName: "svAreaEl", first: true, predicate: ["svAreaEl"], descendants: true, isSignal: true }, { propertyName: "hueTrackEl", first: true, predicate: ["hueTrackEl"], descendants: true, isSignal: true }, { propertyName: "alphaTrackEl", first: true, predicate: ["alphaTrackEl"], descendants: true, isSignal: true }], ngImport: i0, template: "<div\n #hostEl\n class=\"ea-color-picker-field\">\n @if (label()) {\n <label\n class=\"ea-color-picker-field__label\"\n [for]=\"id()\"\n [class.ea-color-picker-field__label--required]=\"required()\">\n {{ label() }}\n </label>\n }\n\n <div class=\"ea-color-picker\">\n <div class=\"ea-color-picker__trigger-wrapper\">\n <button\n #triggerEl\n type=\"button\"\n class=\"ea-color-picker__trigger\"\n [ngClass]=\"triggerClasses()\"\n [id]=\"id()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-haspopup]=\"'dialog'\"\n [attr.aria-required]=\"required() || null\"\n [attr.aria-invalid]=\"hasError() || null\"\n [attr.aria-describedby]=\"\n showError() ? id() + '-error' : showHint() ? id() + '-hint' : null\n \"\n (click)=\"toggle()\"\n (keydown)=\"onTriggerKeydown($event)\">\n <span\n class=\"ea-color-picker__swatch\"\n aria-hidden=\"true\">\n <span\n class=\"ea-color-picker__swatch-fill\"\n [style.background-color]=\"value() ? displayColor() : null\">\n </span>\n </span>\n <span\n class=\"ea-color-picker__trigger-value\"\n [class.ea-color-picker__trigger-value--placeholder]=\"!displayValue()\">\n {{ displayValue() || resolvedPlaceholder() }}\n </span>\n </button>\n @if (value() && !isDisabled() && !readonly()) {\n <button\n type=\"button\"\n class=\"ea-color-picker__clear\"\n [attr.aria-label]=\"i18n.messages().colorPicker.clear\"\n (click)=\"clear($event)\">\n <span aria-hidden=\"true\">\u00D7</span>\n </button>\n }\n </div>\n\n @if (isOpen()) {\n <div\n #popoverEl\n class=\"ea-color-picker__popover\"\n role=\"dialog\"\n [attr.aria-label]=\"label() || i18n.messages().colorPicker.placeholder\"\n [style.top.px]=\"popoverPosition()?.top\"\n [style.left.px]=\"popoverPosition()?.left\"\n (keydown)=\"onPopoverKeydown($event)\">\n <div\n #svAreaEl\n class=\"ea-color-picker__sv-area\"\n role=\"application\"\n tabindex=\"0\"\n [attr.aria-label]=\"i18n.messages().colorPicker.saturationAndValue\"\n [style.background-color]=\"hueColor()\"\n (pointerdown)=\"onSvPointerDown($event)\"\n (pointermove)=\"onSvPointerMove($event)\"\n (pointerup)=\"onSvPointerUp($event)\"\n (pointercancel)=\"onSvPointerUp($event)\"\n (keydown)=\"onSvKeydown($event)\">\n <div class=\"ea-color-picker__sv-area-sat\"></div>\n <div class=\"ea-color-picker__sv-area-val\"></div>\n <div\n class=\"ea-color-picker__sv-pointer\"\n [style.background-color]=\"opaqueColor()\"\n [style.left]=\"svPointerLeft()\"\n [style.top]=\"svPointerTop()\">\n </div>\n </div>\n\n <div class=\"ea-color-picker__sliders\">\n <div class=\"ea-color-picker__slider-row\">\n <span\n class=\"ea-color-picker__swatch ea-color-picker__swatch--lg\"\n aria-hidden=\"true\">\n <span\n class=\"ea-color-picker__swatch-fill\"\n [style.background-color]=\"displayColor()\">\n </span>\n </span>\n <div class=\"ea-color-picker__strip-stack\">\n <div\n #hueTrackEl\n class=\"ea-color-picker__strip ea-color-picker__strip--hue\"\n role=\"slider\"\n tabindex=\"0\"\n [attr.aria-label]=\"i18n.messages().colorPicker.hue\"\n [attr.aria-valuemin]=\"0\"\n [attr.aria-valuemax]=\"360\"\n [attr.aria-valuenow]=\"hueRounded()\"\n (pointerdown)=\"onHuePointerDown($event)\"\n (pointermove)=\"onHuePointerMove($event)\"\n (pointerup)=\"onHuePointerUp($event)\"\n (pointercancel)=\"onHuePointerUp($event)\"\n (keydown)=\"onHueKeydown($event)\">\n <div\n class=\"ea-color-picker__strip-thumb\"\n [style.left]=\"huePointerLeft()\">\n </div>\n </div>\n @if (showAlpha()) {\n <div\n #alphaTrackEl\n class=\"ea-color-picker__strip ea-color-picker__strip--alpha\"\n role=\"slider\"\n tabindex=\"0\"\n [attr.aria-label]=\"i18n.messages().colorPicker.alpha\"\n [attr.aria-valuemin]=\"0\"\n [attr.aria-valuemax]=\"100\"\n [attr.aria-valuenow]=\"alphaPointerLeft()\"\n [style.--ea-color-picker-alpha-base]=\"opaqueColor()\"\n (pointerdown)=\"onAlphaPointerDown($event)\"\n (pointermove)=\"onAlphaPointerMove($event)\"\n (pointerup)=\"onAlphaPointerUp($event)\"\n (pointercancel)=\"onAlphaPointerUp($event)\"\n (keydown)=\"onAlphaKeydown($event)\">\n <div\n class=\"ea-color-picker__strip-thumb\"\n [style.left]=\"alphaPointerLeft()\">\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n\n <div\n class=\"ea-color-picker__inputs\"\n [class.ea-color-picker__inputs--hex]=\"inputMode() === 'hex'\">\n @if (inputMode() === 'hex') {\n <label class=\"ea-color-picker__input-group ea-color-picker__input-group--hex\">\n <span class=\"ea-color-picker__input-label\">HEX</span>\n <input\n class=\"ea-color-picker__input\"\n type=\"text\"\n spellcheck=\"false\"\n autocomplete=\"off\"\n maxlength=\"9\"\n [value]=\"hexInputValue()\"\n (input)=\"onHexInput($event)\"\n (blur)=\"onHexBlur()\" />\n </label>\n } @else {\n <label class=\"ea-color-picker__input-group\">\n <span class=\"ea-color-picker__input-label\">R</span>\n <input\n class=\"ea-color-picker__input ea-color-picker__input--num\"\n type=\"text\"\n inputmode=\"numeric\"\n pattern=\"\\d*\"\n maxlength=\"3\"\n [value]=\"rgb().r\"\n (input)=\"onRgbInput('r', $event)\" />\n </label>\n <label class=\"ea-color-picker__input-group\">\n <span class=\"ea-color-picker__input-label\">G</span>\n <input\n class=\"ea-color-picker__input ea-color-picker__input--num\"\n type=\"text\"\n inputmode=\"numeric\"\n pattern=\"\\d*\"\n maxlength=\"3\"\n [value]=\"rgb().g\"\n (input)=\"onRgbInput('g', $event)\" />\n </label>\n <label class=\"ea-color-picker__input-group\">\n <span class=\"ea-color-picker__input-label\">B</span>\n <input\n class=\"ea-color-picker__input ea-color-picker__input--num\"\n type=\"text\"\n inputmode=\"numeric\"\n pattern=\"\\d*\"\n maxlength=\"3\"\n [value]=\"rgb().b\"\n (input)=\"onRgbInput('b', $event)\" />\n </label>\n @if (showAlpha()) {\n <label class=\"ea-color-picker__input-group\">\n <span class=\"ea-color-picker__input-label\">A</span>\n <input\n class=\"ea-color-picker__input ea-color-picker__input--num\"\n type=\"text\"\n inputmode=\"numeric\"\n pattern=\"\\d*\"\n maxlength=\"3\"\n [value]=\"alphaPercentRounded()\"\n (input)=\"onAlphaInput($event)\" />\n </label>\n }\n }\n <button\n type=\"button\"\n class=\"ea-color-picker__format-toggle\"\n [attr.aria-label]=\"i18n.messages().colorPicker.toggleFormat\"\n (click)=\"cycleInputMode()\">\n {{ inputMode() === 'hex' ? 'HEX' : 'RGB' }}\n </button>\n </div>\n\n @if (hasEyeDropper()) {\n <div class=\"ea-color-picker__tools\">\n <button\n type=\"button\"\n class=\"ea-color-picker__tool-btn\"\n [attr.aria-label]=\"i18n.messages().colorPicker.eyedropper\"\n (click)=\"pickFromScreen()\">\n <ea-icon-droplet aria-hidden=\"true\" />\n <span>{{ i18n.messages().colorPicker.eyedropper }}</span>\n </button>\n </div>\n }\n\n @if (presets().length > 0) {\n <div class=\"ea-color-picker__presets\">\n <span class=\"ea-color-picker__presets-label\">\n {{ i18n.messages().colorPicker.presets }}\n </span>\n <div\n class=\"ea-color-picker__presets-grid\"\n role=\"listbox\">\n @for (preset of presets(); track preset) {\n <button\n type=\"button\"\n class=\"ea-color-picker__preset\"\n role=\"option\"\n [attr.aria-label]=\"preset\"\n [attr.aria-selected]=\"value() === preset\"\n [style.background-color]=\"preset\"\n (click)=\"selectPreset(preset)\">\n </button>\n }\n </div>\n </div>\n }\n </div>\n }\n </div>\n\n @if (showError()) {\n <p\n class=\"ea-color-picker-field__message ea-color-picker-field__message--error\"\n [id]=\"id() + '-error'\"\n role=\"alert\">\n <ea-icon-alert-circle class=\"ea-color-picker-field__message-icon\" />\n {{ errorMsg() }}\n </p>\n }\n\n @if (showHint()) {\n <p\n class=\"ea-color-picker-field__message ea-color-picker-field__message--hint\"\n [id]=\"id() + '-hint'\">\n {{ hint() }}\n </p>\n }\n</div>\n", styles: [".ea-color-picker-field{display:flex;flex-direction:column;gap:var(--space-1-5)}.ea-color-picker-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-color-picker-field__label--required:after{content:\" *\";color:var(--color-error-default)}.ea-color-picker-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-color-picker-field__message--hint{color:var(--color-text-secondary)}.ea-color-picker-field__message--error{color:var(--color-error-default)}.ea-color-picker-field__message-icon{flex-shrink:0;width:.875em;height:.875em}.ea-color-picker,.ea-color-picker__trigger-wrapper{position:relative}.ea-color-picker__trigger{display:flex;align-items:center;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-color-picker__trigger:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-color-picker__trigger--sm{padding:var(--space-1-5) var(--space-2);font-size:var(--font-size-sm);min-height:2rem}.ea-color-picker__trigger--md{padding:var(--space-2) var(--space-3);font-size:var(--font-size-sm);min-height:2.5rem}.ea-color-picker__trigger--lg{padding:var(--space-2-5) var(--space-4);font-size:var(--font-size-md);min-height:3rem}.ea-color-picker__trigger--open{border-color:var(--color-border-focus);box-shadow:var(--shadow-focus-ring)}.ea-color-picker__trigger--error{border-color:var(--color-error-default)}.ea-color-picker__trigger--error.ea-color-picker__trigger--open{box-shadow:var(--shadow-focus-ring-error)}.ea-color-picker__trigger--disabled{background-color:var(--color-bg-muted);opacity:.6;cursor:not-allowed}.ea-color-picker__trigger-value{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-family:var(--font-family-mono);font-size:.85em}.ea-color-picker__trigger-value--placeholder{color:var(--color-text-tertiary);font-family:var(--font-family-sans);font-size:1em}.ea-color-picker__clear{position:absolute;top:50%;right:var(--space-2);z-index:1;display:flex;align-items:center;justify-content:center;flex-shrink:0;width:1.25rem;height:1.25rem;padding:0;border:none;border-radius:var(--radius-sm);background:none;color:var(--color-text-secondary);font-size:1rem;line-height:1;cursor:pointer;transition:var(--transition-colors);transform:translateY(-50%)}.ea-color-picker__clear:hover{background-color:var(--color-bg-muted);color:var(--color-text-primary)}.ea-color-picker__clear:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-color-picker__swatch{position:relative;overflow:hidden;flex-shrink:0;width:1.125rem;height:1.125rem;border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-sm);background-color:var(--color-bg-base);background-image:linear-gradient(45deg,var(--color-neutral-200) 25%,transparent 25%),linear-gradient(-45deg,var(--color-neutral-200) 25%,transparent 25%),linear-gradient(45deg,transparent 75%,var(--color-neutral-200) 75%),linear-gradient(-45deg,transparent 75%,var(--color-neutral-200) 75%);background-size:8px 8px;background-position:0 0,0 4px,4px -4px,-4px 0}.ea-color-picker__swatch--lg{width:2.5rem;height:2.5rem;border-radius:var(--radius-md)}.ea-color-picker__swatch-fill{position:absolute;inset:0;display:block}.ea-color-picker__popover{position:fixed;z-index:var(--z-index-popover);display:flex;flex-direction:column;gap:var(--space-3);padding:var(--space-3);width:17.5rem;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)}.ea-color-picker__sv-area{position:relative;overflow:hidden;width:100%;height:10rem;border-radius:var(--radius-sm);cursor:crosshair;touch-action:none}.ea-color-picker__sv-area:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-color-picker__sv-area-sat{position:absolute;inset:0;background:linear-gradient(to right,var(--color-picker-sv-white),transparent)}.ea-color-picker__sv-area-val{position:absolute;inset:0;background:linear-gradient(to top,var(--color-picker-sv-black),transparent)}.ea-color-picker__sv-pointer{position:absolute;z-index:1;width:.875rem;height:.875rem;border:2px solid var(--color-neutral-0);border-radius:var(--radius-full);box-shadow:0 0 0 1px var(--color-picker-thumb-halo);pointer-events:none;transform:translate(-50%,-50%)}.ea-color-picker__slider-row{display:flex;align-items:center;gap:var(--space-2)}.ea-color-picker__strip-stack{display:flex;flex-direction:column;flex:1;gap:var(--space-2)}.ea-color-picker__strip{position:relative;width:100%;height:.75rem;border-radius:var(--radius-full);cursor:pointer;touch-action:none}.ea-color-picker__strip:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-color-picker__strip--hue{background:linear-gradient(to right,var(--color-picker-hue-red) 0%,var(--color-picker-hue-yellow) 17%,var(--color-picker-hue-green) 33%,var(--color-picker-hue-cyan) 50%,var(--color-picker-hue-blue) 67%,var(--color-picker-hue-magenta) 83%,var(--color-picker-hue-red) 100%)}.ea-color-picker__strip--alpha{background-color:var(--color-bg-base);background-image:linear-gradient(to right,transparent 0%,var(--ea-color-picker-alpha-base, currentcolor) 100%),linear-gradient(45deg,var(--color-neutral-200) 25%,transparent 25%),linear-gradient(-45deg,var(--color-neutral-200) 25%,transparent 25%),linear-gradient(45deg,transparent 75%,var(--color-neutral-200) 75%),linear-gradient(-45deg,transparent 75%,var(--color-neutral-200) 75%);background-size:100% 100%,8px 8px,8px 8px,8px 8px,8px 8px;background-position:0 0,0 0,0 4px,4px -4px,-4px 0}.ea-color-picker__strip-thumb{position:absolute;top:50%;width:.875rem;height:.875rem;border:2px solid var(--color-neutral-0);border-radius:var(--radius-full);box-shadow:0 0 0 1px var(--color-picker-thumb-halo);pointer-events:none;transform:translate(-50%,-50%)}.ea-color-picker__inputs{display:flex;align-items:end;gap:var(--space-1)}.ea-color-picker__input-group{display:flex;flex:1;flex-direction:column;gap:var(--space-1);min-width:0;text-align:center}.ea-color-picker__input-group--hex{flex:1}.ea-color-picker__format-toggle{flex-shrink:0;min-width:3.25rem;padding:var(--space-1) var(--space-2);border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-sm);background-color:var(--color-bg-base);font-family:var(--font-family-sans);font-size:var(--font-size-2xs);font-weight:var(--font-weight-medium);letter-spacing:.04em;color:var(--color-text-secondary);cursor:pointer;transition:var(--transition-colors)}.ea-color-picker__format-toggle:hover{background-color:var(--color-bg-muted);color:var(--color-text-primary)}.ea-color-picker__format-toggle:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-color-picker__input-label{font-size:var(--font-size-2xs);font-weight:var(--font-weight-medium);text-transform:uppercase;letter-spacing:.04em;color:var(--color-text-tertiary)}.ea-color-picker__input{width:100%;min-width:0;padding:var(--space-1) var(--space-1-5);background-color:var(--color-bg-base);border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-sm);font-family:var(--font-family-mono);font-size:var(--font-size-xs);text-align:center;color:var(--color-text-primary)}.ea-color-picker__input:focus-visible{outline:none;border-color:var(--color-border-focus);box-shadow:var(--shadow-focus-ring)}.ea-color-picker__input--num{appearance:textfield}.ea-color-picker__input--num::-webkit-outer-spin-button,.ea-color-picker__input--num::-webkit-inner-spin-button{appearance:none;margin:0}.ea-color-picker__tools{display:flex;justify-content:flex-start}.ea-color-picker__tool-btn{display:inline-flex;align-items:center;gap:var(--space-1-5);padding:var(--space-1) var(--space-2);border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-sm);background-color:var(--color-bg-base);font-family:var(--font-family-sans);font-size:var(--font-size-xs);color:var(--color-text-secondary);cursor:pointer;transition:var(--transition-colors)}.ea-color-picker__tool-btn:hover{background-color:var(--color-bg-muted);color:var(--color-text-primary)}.ea-color-picker__tool-btn:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-color-picker__tool-btn ea-icon-droplet{width:.875em;height:.875em}.ea-color-picker__presets{display:flex;flex-direction:column;gap:var(--space-1-5);padding-top:var(--space-2);border-top:var(--border-width-thin) solid var(--color-border-default)}.ea-color-picker__presets-label{font-size:var(--font-size-2xs);font-weight:var(--font-weight-medium);text-transform:uppercase;letter-spacing:.04em;color:var(--color-text-tertiary)}.ea-color-picker__presets-grid{display:grid;grid-template-columns:repeat(10,1fr);gap:var(--space-1)}.ea-color-picker__preset{width:100%;aspect-ratio:1;padding:0;border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-sm);cursor:pointer;transition:transform var(--duration-fast) var(--ease-out)}.ea-color-picker__preset:hover{transform:scale(1.1)}.ea-color-picker__preset:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-color-picker__preset[aria-selected=true]{box-shadow:0 0 0 2px var(--color-brand-default)}\n"], dependencies: [{ kind: "component", type: AlertCircleIconComponent, selector: "ea-icon-alert-circle" }, { kind: "component", type: DropletIconComponent, selector: "ea-icon-droplet" }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3891
|
+
], viewQueries: [{ propertyName: "triggerEl", first: true, predicate: ["triggerEl"], descendants: true, isSignal: true }, { propertyName: "svAreaEl", first: true, predicate: ["svAreaEl"], descendants: true, isSignal: true }, { propertyName: "hueTrackEl", first: true, predicate: ["hueTrackEl"], descendants: true, isSignal: true }, { propertyName: "alphaTrackEl", first: true, predicate: ["alphaTrackEl"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"ea-color-picker-field\">\n @if (label()) {\n <label\n class=\"ea-color-picker-field__label\"\n [for]=\"id()\"\n [class.ea-color-picker-field__label--required]=\"required()\">\n {{ label() }}\n </label>\n }\n\n <div class=\"ea-color-picker\">\n <div class=\"ea-color-picker__trigger-wrapper\">\n <button\n #triggerEl\n type=\"button\"\n class=\"ea-color-picker__trigger\"\n [ngClass]=\"triggerClasses()\"\n [id]=\"id()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-haspopup]=\"'dialog'\"\n [attr.aria-required]=\"required() || null\"\n [attr.aria-invalid]=\"hasError() || null\"\n [attr.aria-describedby]=\"\n showError() ? id() + '-error' : showHint() ? id() + '-hint' : null\n \"\n (click)=\"toggle()\"\n (keydown)=\"onTriggerKeydown($event)\">\n <span\n class=\"ea-color-picker__swatch\"\n aria-hidden=\"true\">\n <span\n class=\"ea-color-picker__swatch-fill\"\n [style.background-color]=\"value() ? displayColor() : null\">\n </span>\n </span>\n <span\n class=\"ea-color-picker__trigger-value\"\n [class.ea-color-picker__trigger-value--placeholder]=\"!displayValue()\">\n {{ displayValue() || resolvedPlaceholder() }}\n </span>\n </button>\n @if (value() && !isDisabled() && !readonly()) {\n <button\n type=\"button\"\n class=\"ea-color-picker__clear\"\n [attr.aria-label]=\"i18n.messages().colorPicker.clear\"\n (click)=\"clear($event)\">\n <span aria-hidden=\"true\">\u00D7</span>\n </button>\n }\n </div>\n\n <ea-popover\n [anchor]=\"triggerEl\"\n [open]=\"isOpen()\"\n placement=\"bottom-start\"\n role=\"dialog\"\n [ariaLabel]=\"label() || i18n.messages().colorPicker.placeholder\"\n [closeOnEscape]=\"false\"\n scrollBehavior=\"close\"\n (closeRequested)=\"onPopoverCloseRequested()\">\n <div\n class=\"ea-color-picker__popover\"\n (keydown)=\"onPopoverKeydown($event)\">\n <div\n #svAreaEl\n class=\"ea-color-picker__sv-area\"\n role=\"application\"\n tabindex=\"0\"\n [attr.aria-label]=\"i18n.messages().colorPicker.saturationAndValue\"\n [style.background-color]=\"hueColor()\"\n (pointerdown)=\"onSvPointerDown($event)\"\n (pointermove)=\"onSvPointerMove($event)\"\n (pointerup)=\"onSvPointerUp($event)\"\n (pointercancel)=\"onSvPointerUp($event)\"\n (keydown)=\"onSvKeydown($event)\">\n <div class=\"ea-color-picker__sv-area-sat\"></div>\n <div class=\"ea-color-picker__sv-area-val\"></div>\n <div\n class=\"ea-color-picker__sv-pointer\"\n [style.background-color]=\"opaqueColor()\"\n [style.left]=\"svPointerLeft()\"\n [style.top]=\"svPointerTop()\">\n </div>\n </div>\n\n <div class=\"ea-color-picker__sliders\">\n <div class=\"ea-color-picker__slider-row\">\n <span\n class=\"ea-color-picker__swatch ea-color-picker__swatch--lg\"\n aria-hidden=\"true\">\n <span\n class=\"ea-color-picker__swatch-fill\"\n [style.background-color]=\"displayColor()\">\n </span>\n </span>\n <div class=\"ea-color-picker__strip-stack\">\n <div\n #hueTrackEl\n class=\"ea-color-picker__strip ea-color-picker__strip--hue\"\n role=\"slider\"\n tabindex=\"0\"\n [attr.aria-label]=\"i18n.messages().colorPicker.hue\"\n [attr.aria-valuemin]=\"0\"\n [attr.aria-valuemax]=\"360\"\n [attr.aria-valuenow]=\"hueRounded()\"\n (pointerdown)=\"onHuePointerDown($event)\"\n (pointermove)=\"onHuePointerMove($event)\"\n (pointerup)=\"onHuePointerUp($event)\"\n (pointercancel)=\"onHuePointerUp($event)\"\n (keydown)=\"onHueKeydown($event)\">\n <div\n class=\"ea-color-picker__strip-thumb\"\n [style.left]=\"huePointerLeft()\">\n </div>\n </div>\n @if (showAlpha()) {\n <div\n #alphaTrackEl\n class=\"ea-color-picker__strip ea-color-picker__strip--alpha\"\n role=\"slider\"\n tabindex=\"0\"\n [attr.aria-label]=\"i18n.messages().colorPicker.alpha\"\n [attr.aria-valuemin]=\"0\"\n [attr.aria-valuemax]=\"100\"\n [attr.aria-valuenow]=\"alphaPointerLeft()\"\n [style.--ea-color-picker-alpha-base]=\"opaqueColor()\"\n (pointerdown)=\"onAlphaPointerDown($event)\"\n (pointermove)=\"onAlphaPointerMove($event)\"\n (pointerup)=\"onAlphaPointerUp($event)\"\n (pointercancel)=\"onAlphaPointerUp($event)\"\n (keydown)=\"onAlphaKeydown($event)\">\n <div\n class=\"ea-color-picker__strip-thumb\"\n [style.left]=\"alphaPointerLeft()\">\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n\n <div\n class=\"ea-color-picker__inputs\"\n [class.ea-color-picker__inputs--hex]=\"inputMode() === 'hex'\">\n @if (inputMode() === 'hex') {\n <label class=\"ea-color-picker__input-group ea-color-picker__input-group--hex\">\n <span class=\"ea-color-picker__input-label\">HEX</span>\n <input\n class=\"ea-color-picker__input\"\n type=\"text\"\n spellcheck=\"false\"\n autocomplete=\"off\"\n maxlength=\"9\"\n [value]=\"hexInputValue()\"\n (input)=\"onHexInput($event)\"\n (blur)=\"onHexBlur()\" />\n </label>\n } @else {\n <label class=\"ea-color-picker__input-group\">\n <span class=\"ea-color-picker__input-label\">R</span>\n <input\n class=\"ea-color-picker__input ea-color-picker__input--num\"\n type=\"text\"\n inputmode=\"numeric\"\n pattern=\"\\d*\"\n maxlength=\"3\"\n [value]=\"rgb().r\"\n (input)=\"onRgbInput('r', $event)\" />\n </label>\n <label class=\"ea-color-picker__input-group\">\n <span class=\"ea-color-picker__input-label\">G</span>\n <input\n class=\"ea-color-picker__input ea-color-picker__input--num\"\n type=\"text\"\n inputmode=\"numeric\"\n pattern=\"\\d*\"\n maxlength=\"3\"\n [value]=\"rgb().g\"\n (input)=\"onRgbInput('g', $event)\" />\n </label>\n <label class=\"ea-color-picker__input-group\">\n <span class=\"ea-color-picker__input-label\">B</span>\n <input\n class=\"ea-color-picker__input ea-color-picker__input--num\"\n type=\"text\"\n inputmode=\"numeric\"\n pattern=\"\\d*\"\n maxlength=\"3\"\n [value]=\"rgb().b\"\n (input)=\"onRgbInput('b', $event)\" />\n </label>\n @if (showAlpha()) {\n <label class=\"ea-color-picker__input-group\">\n <span class=\"ea-color-picker__input-label\">A</span>\n <input\n class=\"ea-color-picker__input ea-color-picker__input--num\"\n type=\"text\"\n inputmode=\"numeric\"\n pattern=\"\\d*\"\n maxlength=\"3\"\n [value]=\"alphaPercentRounded()\"\n (input)=\"onAlphaInput($event)\" />\n </label>\n }\n }\n <button\n type=\"button\"\n class=\"ea-color-picker__format-toggle\"\n [attr.aria-label]=\"i18n.messages().colorPicker.toggleFormat\"\n (click)=\"cycleInputMode()\">\n {{ inputMode() === 'hex' ? 'HEX' : 'RGB' }}\n </button>\n </div>\n\n @if (hasEyeDropper()) {\n <div class=\"ea-color-picker__tools\">\n <button\n type=\"button\"\n class=\"ea-color-picker__tool-btn\"\n [attr.aria-label]=\"i18n.messages().colorPicker.eyedropper\"\n (click)=\"pickFromScreen()\">\n <ea-icon-droplet aria-hidden=\"true\" />\n <span>{{ i18n.messages().colorPicker.eyedropper }}</span>\n </button>\n </div>\n }\n\n @if (presets().length > 0) {\n <div class=\"ea-color-picker__presets\">\n <span class=\"ea-color-picker__presets-label\">\n {{ i18n.messages().colorPicker.presets }}\n </span>\n <div\n class=\"ea-color-picker__presets-grid\"\n role=\"listbox\">\n @for (preset of presets(); track preset) {\n <button\n type=\"button\"\n class=\"ea-color-picker__preset\"\n role=\"option\"\n [attr.aria-label]=\"preset\"\n [attr.aria-selected]=\"value() === preset\"\n [style.background-color]=\"preset\"\n (click)=\"selectPreset(preset)\">\n </button>\n }\n </div>\n </div>\n }\n </div>\n </ea-popover>\n </div>\n\n @if (showError()) {\n <p\n class=\"ea-color-picker-field__message ea-color-picker-field__message--error\"\n [id]=\"id() + '-error'\"\n role=\"alert\">\n <ea-icon-alert-circle class=\"ea-color-picker-field__message-icon\" />\n {{ errorMsg() }}\n </p>\n }\n\n @if (showHint()) {\n <p\n class=\"ea-color-picker-field__message ea-color-picker-field__message--hint\"\n [id]=\"id() + '-hint'\">\n {{ hint() }}\n </p>\n }\n</div>\n", styles: [".ea-color-picker-field{display:flex;flex-direction:column;gap:var(--space-1-5)}.ea-color-picker-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-color-picker-field__label--required:after{content:\" *\";color:var(--color-error-default)}.ea-color-picker-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-color-picker-field__message--hint{color:var(--color-text-secondary)}.ea-color-picker-field__message--error{color:var(--color-error-default)}.ea-color-picker-field__message-icon{flex-shrink:0;width:.875em;height:.875em}.ea-color-picker,.ea-color-picker__trigger-wrapper{position:relative}.ea-color-picker__trigger{display:flex;align-items:center;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-color-picker__trigger:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-color-picker__trigger--sm{padding:var(--space-1-5) var(--space-2);font-size:var(--font-size-sm);min-height:2rem}.ea-color-picker__trigger--md{padding:var(--space-2) var(--space-3);font-size:var(--font-size-sm);min-height:2.5rem}.ea-color-picker__trigger--lg{padding:var(--space-2-5) var(--space-4);font-size:var(--font-size-md);min-height:3rem}.ea-color-picker__trigger--open{border-color:var(--color-border-focus);box-shadow:var(--shadow-focus-ring)}.ea-color-picker__trigger--error{border-color:var(--color-error-default)}.ea-color-picker__trigger--error.ea-color-picker__trigger--open{box-shadow:var(--shadow-focus-ring-error)}.ea-color-picker__trigger--disabled{background-color:var(--color-bg-muted);opacity:.6;cursor:not-allowed}.ea-color-picker__trigger-value{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-family:var(--font-family-mono);font-size:.85em}.ea-color-picker__trigger-value--placeholder{color:var(--color-text-tertiary);font-family:var(--font-family-sans);font-size:1em}.ea-color-picker__clear{position:absolute;top:50%;right:var(--space-2);z-index:1;display:flex;align-items:center;justify-content:center;flex-shrink:0;width:1.25rem;height:1.25rem;padding:0;border:none;border-radius:var(--radius-sm);background:none;color:var(--color-text-secondary);font-size:1rem;line-height:1;cursor:pointer;transition:var(--transition-colors);transform:translateY(-50%)}.ea-color-picker__clear:hover{background-color:var(--color-bg-muted);color:var(--color-text-primary)}.ea-color-picker__clear:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-color-picker__swatch{position:relative;overflow:hidden;flex-shrink:0;width:1.125rem;height:1.125rem;border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-sm);background-color:var(--color-bg-base);background-image:linear-gradient(45deg,var(--color-neutral-200) 25%,transparent 25%),linear-gradient(-45deg,var(--color-neutral-200) 25%,transparent 25%),linear-gradient(45deg,transparent 75%,var(--color-neutral-200) 75%),linear-gradient(-45deg,transparent 75%,var(--color-neutral-200) 75%);background-size:8px 8px;background-position:0 0,0 4px,4px -4px,-4px 0}.ea-color-picker__swatch--lg{width:2.5rem;height:2.5rem;border-radius:var(--radius-md)}.ea-color-picker__swatch-fill{position:absolute;inset:0;display:block}.ea-color-picker__popover{display:flex;flex-direction:column;gap:var(--space-3);width:17.5rem;padding:var(--space-3);border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-md);box-shadow:var(--shadow-lg);background-color:var(--color-bg-base)}.ea-color-picker__sv-area{position:relative;overflow:hidden;width:100%;height:10rem;border-radius:var(--radius-sm);cursor:crosshair;touch-action:none}.ea-color-picker__sv-area:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-color-picker__sv-area-sat{position:absolute;inset:0;background:linear-gradient(to right,var(--color-picker-sv-white),transparent)}.ea-color-picker__sv-area-val{position:absolute;inset:0;background:linear-gradient(to top,var(--color-picker-sv-black),transparent)}.ea-color-picker__sv-pointer{position:absolute;z-index:1;width:.875rem;height:.875rem;border:2px solid var(--color-neutral-0);border-radius:var(--radius-full);box-shadow:0 0 0 1px var(--color-picker-thumb-halo);pointer-events:none;transform:translate(-50%,-50%)}.ea-color-picker__slider-row{display:flex;align-items:center;gap:var(--space-2)}.ea-color-picker__strip-stack{display:flex;flex-direction:column;flex:1;gap:var(--space-2)}.ea-color-picker__strip{position:relative;width:100%;height:.75rem;border-radius:var(--radius-full);cursor:pointer;touch-action:none}.ea-color-picker__strip:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-color-picker__strip--hue{background:linear-gradient(to right,var(--color-picker-hue-red) 0%,var(--color-picker-hue-yellow) 17%,var(--color-picker-hue-green) 33%,var(--color-picker-hue-cyan) 50%,var(--color-picker-hue-blue) 67%,var(--color-picker-hue-magenta) 83%,var(--color-picker-hue-red) 100%)}.ea-color-picker__strip--alpha{background-color:var(--color-bg-base);background-image:linear-gradient(to right,transparent 0%,var(--ea-color-picker-alpha-base, currentcolor) 100%),linear-gradient(45deg,var(--color-neutral-200) 25%,transparent 25%),linear-gradient(-45deg,var(--color-neutral-200) 25%,transparent 25%),linear-gradient(45deg,transparent 75%,var(--color-neutral-200) 75%),linear-gradient(-45deg,transparent 75%,var(--color-neutral-200) 75%);background-size:100% 100%,8px 8px,8px 8px,8px 8px,8px 8px;background-position:0 0,0 0,0 4px,4px -4px,-4px 0}.ea-color-picker__strip-thumb{position:absolute;top:50%;width:.875rem;height:.875rem;border:2px solid var(--color-neutral-0);border-radius:var(--radius-full);box-shadow:0 0 0 1px var(--color-picker-thumb-halo);pointer-events:none;transform:translate(-50%,-50%)}.ea-color-picker__inputs{display:flex;align-items:end;gap:var(--space-1)}.ea-color-picker__input-group{display:flex;flex:1;flex-direction:column;gap:var(--space-1);min-width:0;text-align:center}.ea-color-picker__input-group--hex{flex:1}.ea-color-picker__format-toggle{flex-shrink:0;min-width:3.25rem;padding:var(--space-1) var(--space-2);border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-sm);background-color:var(--color-bg-base);font-family:var(--font-family-sans);font-size:var(--font-size-2xs);font-weight:var(--font-weight-medium);letter-spacing:.04em;color:var(--color-text-secondary);cursor:pointer;transition:var(--transition-colors)}.ea-color-picker__format-toggle:hover{background-color:var(--color-bg-muted);color:var(--color-text-primary)}.ea-color-picker__format-toggle:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-color-picker__input-label{font-size:var(--font-size-2xs);font-weight:var(--font-weight-medium);text-transform:uppercase;letter-spacing:.04em;color:var(--color-text-tertiary)}.ea-color-picker__input{width:100%;min-width:0;padding:var(--space-1) var(--space-1-5);background-color:var(--color-bg-base);border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-sm);font-family:var(--font-family-mono);font-size:var(--font-size-xs);text-align:center;color:var(--color-text-primary)}.ea-color-picker__input:focus-visible{outline:none;border-color:var(--color-border-focus);box-shadow:var(--shadow-focus-ring)}.ea-color-picker__input--num{appearance:textfield}.ea-color-picker__input--num::-webkit-outer-spin-button,.ea-color-picker__input--num::-webkit-inner-spin-button{appearance:none;margin:0}.ea-color-picker__tools{display:flex;justify-content:flex-start}.ea-color-picker__tool-btn{display:inline-flex;align-items:center;gap:var(--space-1-5);padding:var(--space-1) var(--space-2);border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-sm);background-color:var(--color-bg-base);font-family:var(--font-family-sans);font-size:var(--font-size-xs);color:var(--color-text-secondary);cursor:pointer;transition:var(--transition-colors)}.ea-color-picker__tool-btn:hover{background-color:var(--color-bg-muted);color:var(--color-text-primary)}.ea-color-picker__tool-btn:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-color-picker__tool-btn ea-icon-droplet{width:.875em;height:.875em}.ea-color-picker__presets{display:flex;flex-direction:column;gap:var(--space-1-5);padding-top:var(--space-2);border-top:var(--border-width-thin) solid var(--color-border-default)}.ea-color-picker__presets-label{font-size:var(--font-size-2xs);font-weight:var(--font-weight-medium);text-transform:uppercase;letter-spacing:.04em;color:var(--color-text-tertiary)}.ea-color-picker__presets-grid{display:grid;grid-template-columns:repeat(10,1fr);gap:var(--space-1)}.ea-color-picker__preset{width:100%;aspect-ratio:1;padding:0;border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-sm);cursor:pointer;transition:transform var(--duration-fast) var(--ease-out)}.ea-color-picker__preset:hover{transform:scale(1.1)}.ea-color-picker__preset:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-color-picker__preset[aria-selected=true]{box-shadow:0 0 0 2px var(--color-brand-default)}\n"], dependencies: [{ kind: "component", type: AlertCircleIconComponent, selector: "ea-icon-alert-circle" }, { kind: "component", type: DropletIconComponent, selector: "ea-icon-droplet" }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: PopoverComponent, selector: "ea-popover", inputs: ["anchor", "open", "placement", "role", "aria-label", "surfaceId", "offset", "flip", "clamp", "matchAnchorWidth", "closeOnOutsideClick", "closeOnEscape", "scrollBehavior"], outputs: ["closeRequested"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3446
3892
|
}
|
|
3447
3893
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: ColorPickerComponent, decorators: [{
|
|
3448
3894
|
type: Component,
|
|
3449
|
-
args: [{ selector: 'ea-color-picker', imports: [AlertCircleIconComponent, DropletIconComponent, NgClass], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
3895
|
+
args: [{ selector: 'ea-color-picker', imports: [AlertCircleIconComponent, DropletIconComponent, NgClass, PopoverComponent], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
3450
3896
|
{
|
|
3451
3897
|
provide: NG_VALUE_ACCESSOR,
|
|
3452
3898
|
useExisting: forwardRef(() => ColorPickerComponent),
|
|
3453
3899
|
multi: true,
|
|
3454
3900
|
},
|
|
3455
|
-
], template: "<div\n #hostEl\n class=\"ea-color-picker-field\">\n @if (label()) {\n <label\n class=\"ea-color-picker-field__label\"\n [for]=\"id()\"\n [class.ea-color-picker-field__label--required]=\"required()\">\n {{ label() }}\n </label>\n }\n\n <div class=\"ea-color-picker\">\n <div class=\"ea-color-picker__trigger-wrapper\">\n <button\n #triggerEl\n type=\"button\"\n class=\"ea-color-picker__trigger\"\n [ngClass]=\"triggerClasses()\"\n [id]=\"id()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-haspopup]=\"'dialog'\"\n [attr.aria-required]=\"required() || null\"\n [attr.aria-invalid]=\"hasError() || null\"\n [attr.aria-describedby]=\"\n showError() ? id() + '-error' : showHint() ? id() + '-hint' : null\n \"\n (click)=\"toggle()\"\n (keydown)=\"onTriggerKeydown($event)\">\n <span\n class=\"ea-color-picker__swatch\"\n aria-hidden=\"true\">\n <span\n class=\"ea-color-picker__swatch-fill\"\n [style.background-color]=\"value() ? displayColor() : null\">\n </span>\n </span>\n <span\n class=\"ea-color-picker__trigger-value\"\n [class.ea-color-picker__trigger-value--placeholder]=\"!displayValue()\">\n {{ displayValue() || resolvedPlaceholder() }}\n </span>\n </button>\n @if (value() && !isDisabled() && !readonly()) {\n <button\n type=\"button\"\n class=\"ea-color-picker__clear\"\n [attr.aria-label]=\"i18n.messages().colorPicker.clear\"\n (click)=\"clear($event)\">\n <span aria-hidden=\"true\">\u00D7</span>\n </button>\n }\n </div>\n\n @if (isOpen()) {\n <div\n #popoverEl\n class=\"ea-color-picker__popover\"\n role=\"dialog\"\n [attr.aria-label]=\"label() || i18n.messages().colorPicker.placeholder\"\n [style.top.px]=\"popoverPosition()?.top\"\n [style.left.px]=\"popoverPosition()?.left\"\n (keydown)=\"onPopoverKeydown($event)\">\n <div\n #svAreaEl\n class=\"ea-color-picker__sv-area\"\n role=\"application\"\n tabindex=\"0\"\n [attr.aria-label]=\"i18n.messages().colorPicker.saturationAndValue\"\n [style.background-color]=\"hueColor()\"\n (pointerdown)=\"onSvPointerDown($event)\"\n (pointermove)=\"onSvPointerMove($event)\"\n (pointerup)=\"onSvPointerUp($event)\"\n (pointercancel)=\"onSvPointerUp($event)\"\n (keydown)=\"onSvKeydown($event)\">\n <div class=\"ea-color-picker__sv-area-sat\"></div>\n <div class=\"ea-color-picker__sv-area-val\"></div>\n <div\n class=\"ea-color-picker__sv-pointer\"\n [style.background-color]=\"opaqueColor()\"\n [style.left]=\"svPointerLeft()\"\n [style.top]=\"svPointerTop()\">\n </div>\n </div>\n\n <div class=\"ea-color-picker__sliders\">\n <div class=\"ea-color-picker__slider-row\">\n <span\n class=\"ea-color-picker__swatch ea-color-picker__swatch--lg\"\n aria-hidden=\"true\">\n <span\n class=\"ea-color-picker__swatch-fill\"\n [style.background-color]=\"displayColor()\">\n </span>\n </span>\n <div class=\"ea-color-picker__strip-stack\">\n <div\n #hueTrackEl\n class=\"ea-color-picker__strip ea-color-picker__strip--hue\"\n role=\"slider\"\n tabindex=\"0\"\n [attr.aria-label]=\"i18n.messages().colorPicker.hue\"\n [attr.aria-valuemin]=\"0\"\n [attr.aria-valuemax]=\"360\"\n [attr.aria-valuenow]=\"hueRounded()\"\n (pointerdown)=\"onHuePointerDown($event)\"\n (pointermove)=\"onHuePointerMove($event)\"\n (pointerup)=\"onHuePointerUp($event)\"\n (pointercancel)=\"onHuePointerUp($event)\"\n (keydown)=\"onHueKeydown($event)\">\n <div\n class=\"ea-color-picker__strip-thumb\"\n [style.left]=\"huePointerLeft()\">\n </div>\n </div>\n @if (showAlpha()) {\n <div\n #alphaTrackEl\n class=\"ea-color-picker__strip ea-color-picker__strip--alpha\"\n role=\"slider\"\n tabindex=\"0\"\n [attr.aria-label]=\"i18n.messages().colorPicker.alpha\"\n [attr.aria-valuemin]=\"0\"\n [attr.aria-valuemax]=\"100\"\n [attr.aria-valuenow]=\"alphaPointerLeft()\"\n [style.--ea-color-picker-alpha-base]=\"opaqueColor()\"\n (pointerdown)=\"onAlphaPointerDown($event)\"\n (pointermove)=\"onAlphaPointerMove($event)\"\n (pointerup)=\"onAlphaPointerUp($event)\"\n (pointercancel)=\"onAlphaPointerUp($event)\"\n (keydown)=\"onAlphaKeydown($event)\">\n <div\n class=\"ea-color-picker__strip-thumb\"\n [style.left]=\"alphaPointerLeft()\">\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n\n <div\n class=\"ea-color-picker__inputs\"\n [class.ea-color-picker__inputs--hex]=\"inputMode() === 'hex'\">\n @if (inputMode() === 'hex') {\n <label class=\"ea-color-picker__input-group ea-color-picker__input-group--hex\">\n <span class=\"ea-color-picker__input-label\">HEX</span>\n <input\n class=\"ea-color-picker__input\"\n type=\"text\"\n spellcheck=\"false\"\n autocomplete=\"off\"\n maxlength=\"9\"\n [value]=\"hexInputValue()\"\n (input)=\"onHexInput($event)\"\n (blur)=\"onHexBlur()\" />\n </label>\n } @else {\n <label class=\"ea-color-picker__input-group\">\n <span class=\"ea-color-picker__input-label\">R</span>\n <input\n class=\"ea-color-picker__input ea-color-picker__input--num\"\n type=\"text\"\n inputmode=\"numeric\"\n pattern=\"\\d*\"\n maxlength=\"3\"\n [value]=\"rgb().r\"\n (input)=\"onRgbInput('r', $event)\" />\n </label>\n <label class=\"ea-color-picker__input-group\">\n <span class=\"ea-color-picker__input-label\">G</span>\n <input\n class=\"ea-color-picker__input ea-color-picker__input--num\"\n type=\"text\"\n inputmode=\"numeric\"\n pattern=\"\\d*\"\n maxlength=\"3\"\n [value]=\"rgb().g\"\n (input)=\"onRgbInput('g', $event)\" />\n </label>\n <label class=\"ea-color-picker__input-group\">\n <span class=\"ea-color-picker__input-label\">B</span>\n <input\n class=\"ea-color-picker__input ea-color-picker__input--num\"\n type=\"text\"\n inputmode=\"numeric\"\n pattern=\"\\d*\"\n maxlength=\"3\"\n [value]=\"rgb().b\"\n (input)=\"onRgbInput('b', $event)\" />\n </label>\n @if (showAlpha()) {\n <label class=\"ea-color-picker__input-group\">\n <span class=\"ea-color-picker__input-label\">A</span>\n <input\n class=\"ea-color-picker__input ea-color-picker__input--num\"\n type=\"text\"\n inputmode=\"numeric\"\n pattern=\"\\d*\"\n maxlength=\"3\"\n [value]=\"alphaPercentRounded()\"\n (input)=\"onAlphaInput($event)\" />\n </label>\n }\n }\n <button\n type=\"button\"\n class=\"ea-color-picker__format-toggle\"\n [attr.aria-label]=\"i18n.messages().colorPicker.toggleFormat\"\n (click)=\"cycleInputMode()\">\n {{ inputMode() === 'hex' ? 'HEX' : 'RGB' }}\n </button>\n </div>\n\n @if (hasEyeDropper()) {\n <div class=\"ea-color-picker__tools\">\n <button\n type=\"button\"\n class=\"ea-color-picker__tool-btn\"\n [attr.aria-label]=\"i18n.messages().colorPicker.eyedropper\"\n (click)=\"pickFromScreen()\">\n <ea-icon-droplet aria-hidden=\"true\" />\n <span>{{ i18n.messages().colorPicker.eyedropper }}</span>\n </button>\n </div>\n }\n\n @if (presets().length > 0) {\n <div class=\"ea-color-picker__presets\">\n <span class=\"ea-color-picker__presets-label\">\n {{ i18n.messages().colorPicker.presets }}\n </span>\n <div\n class=\"ea-color-picker__presets-grid\"\n role=\"listbox\">\n @for (preset of presets(); track preset) {\n <button\n type=\"button\"\n class=\"ea-color-picker__preset\"\n role=\"option\"\n [attr.aria-label]=\"preset\"\n [attr.aria-selected]=\"value() === preset\"\n [style.background-color]=\"preset\"\n (click)=\"selectPreset(preset)\">\n </button>\n }\n </div>\n </div>\n }\n </div>\n }\n </div>\n\n @if (showError()) {\n <p\n class=\"ea-color-picker-field__message ea-color-picker-field__message--error\"\n [id]=\"id() + '-error'\"\n role=\"alert\">\n <ea-icon-alert-circle class=\"ea-color-picker-field__message-icon\" />\n {{ errorMsg() }}\n </p>\n }\n\n @if (showHint()) {\n <p\n class=\"ea-color-picker-field__message ea-color-picker-field__message--hint\"\n [id]=\"id() + '-hint'\">\n {{ hint() }}\n </p>\n }\n</div>\n", styles: [".ea-color-picker-field{display:flex;flex-direction:column;gap:var(--space-1-5)}.ea-color-picker-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-color-picker-field__label--required:after{content:\" *\";color:var(--color-error-default)}.ea-color-picker-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-color-picker-field__message--hint{color:var(--color-text-secondary)}.ea-color-picker-field__message--error{color:var(--color-error-default)}.ea-color-picker-field__message-icon{flex-shrink:0;width:.875em;height:.875em}.ea-color-picker,.ea-color-picker__trigger-wrapper{position:relative}.ea-color-picker__trigger{display:flex;align-items:center;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-color-picker__trigger:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-color-picker__trigger--sm{padding:var(--space-1-5) var(--space-2);font-size:var(--font-size-sm);min-height:2rem}.ea-color-picker__trigger--md{padding:var(--space-2) var(--space-3);font-size:var(--font-size-sm);min-height:2.5rem}.ea-color-picker__trigger--lg{padding:var(--space-2-5) var(--space-4);font-size:var(--font-size-md);min-height:3rem}.ea-color-picker__trigger--open{border-color:var(--color-border-focus);box-shadow:var(--shadow-focus-ring)}.ea-color-picker__trigger--error{border-color:var(--color-error-default)}.ea-color-picker__trigger--error.ea-color-picker__trigger--open{box-shadow:var(--shadow-focus-ring-error)}.ea-color-picker__trigger--disabled{background-color:var(--color-bg-muted);opacity:.6;cursor:not-allowed}.ea-color-picker__trigger-value{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-family:var(--font-family-mono);font-size:.85em}.ea-color-picker__trigger-value--placeholder{color:var(--color-text-tertiary);font-family:var(--font-family-sans);font-size:1em}.ea-color-picker__clear{position:absolute;top:50%;right:var(--space-2);z-index:1;display:flex;align-items:center;justify-content:center;flex-shrink:0;width:1.25rem;height:1.25rem;padding:0;border:none;border-radius:var(--radius-sm);background:none;color:var(--color-text-secondary);font-size:1rem;line-height:1;cursor:pointer;transition:var(--transition-colors);transform:translateY(-50%)}.ea-color-picker__clear:hover{background-color:var(--color-bg-muted);color:var(--color-text-primary)}.ea-color-picker__clear:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-color-picker__swatch{position:relative;overflow:hidden;flex-shrink:0;width:1.125rem;height:1.125rem;border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-sm);background-color:var(--color-bg-base);background-image:linear-gradient(45deg,var(--color-neutral-200) 25%,transparent 25%),linear-gradient(-45deg,var(--color-neutral-200) 25%,transparent 25%),linear-gradient(45deg,transparent 75%,var(--color-neutral-200) 75%),linear-gradient(-45deg,transparent 75%,var(--color-neutral-200) 75%);background-size:8px 8px;background-position:0 0,0 4px,4px -4px,-4px 0}.ea-color-picker__swatch--lg{width:2.5rem;height:2.5rem;border-radius:var(--radius-md)}.ea-color-picker__swatch-fill{position:absolute;inset:0;display:block}.ea-color-picker__popover{position:fixed;z-index:var(--z-index-popover);display:flex;flex-direction:column;gap:var(--space-3);padding:var(--space-3);width:17.5rem;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)}.ea-color-picker__sv-area{position:relative;overflow:hidden;width:100%;height:10rem;border-radius:var(--radius-sm);cursor:crosshair;touch-action:none}.ea-color-picker__sv-area:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-color-picker__sv-area-sat{position:absolute;inset:0;background:linear-gradient(to right,var(--color-picker-sv-white),transparent)}.ea-color-picker__sv-area-val{position:absolute;inset:0;background:linear-gradient(to top,var(--color-picker-sv-black),transparent)}.ea-color-picker__sv-pointer{position:absolute;z-index:1;width:.875rem;height:.875rem;border:2px solid var(--color-neutral-0);border-radius:var(--radius-full);box-shadow:0 0 0 1px var(--color-picker-thumb-halo);pointer-events:none;transform:translate(-50%,-50%)}.ea-color-picker__slider-row{display:flex;align-items:center;gap:var(--space-2)}.ea-color-picker__strip-stack{display:flex;flex-direction:column;flex:1;gap:var(--space-2)}.ea-color-picker__strip{position:relative;width:100%;height:.75rem;border-radius:var(--radius-full);cursor:pointer;touch-action:none}.ea-color-picker__strip:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-color-picker__strip--hue{background:linear-gradient(to right,var(--color-picker-hue-red) 0%,var(--color-picker-hue-yellow) 17%,var(--color-picker-hue-green) 33%,var(--color-picker-hue-cyan) 50%,var(--color-picker-hue-blue) 67%,var(--color-picker-hue-magenta) 83%,var(--color-picker-hue-red) 100%)}.ea-color-picker__strip--alpha{background-color:var(--color-bg-base);background-image:linear-gradient(to right,transparent 0%,var(--ea-color-picker-alpha-base, currentcolor) 100%),linear-gradient(45deg,var(--color-neutral-200) 25%,transparent 25%),linear-gradient(-45deg,var(--color-neutral-200) 25%,transparent 25%),linear-gradient(45deg,transparent 75%,var(--color-neutral-200) 75%),linear-gradient(-45deg,transparent 75%,var(--color-neutral-200) 75%);background-size:100% 100%,8px 8px,8px 8px,8px 8px,8px 8px;background-position:0 0,0 0,0 4px,4px -4px,-4px 0}.ea-color-picker__strip-thumb{position:absolute;top:50%;width:.875rem;height:.875rem;border:2px solid var(--color-neutral-0);border-radius:var(--radius-full);box-shadow:0 0 0 1px var(--color-picker-thumb-halo);pointer-events:none;transform:translate(-50%,-50%)}.ea-color-picker__inputs{display:flex;align-items:end;gap:var(--space-1)}.ea-color-picker__input-group{display:flex;flex:1;flex-direction:column;gap:var(--space-1);min-width:0;text-align:center}.ea-color-picker__input-group--hex{flex:1}.ea-color-picker__format-toggle{flex-shrink:0;min-width:3.25rem;padding:var(--space-1) var(--space-2);border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-sm);background-color:var(--color-bg-base);font-family:var(--font-family-sans);font-size:var(--font-size-2xs);font-weight:var(--font-weight-medium);letter-spacing:.04em;color:var(--color-text-secondary);cursor:pointer;transition:var(--transition-colors)}.ea-color-picker__format-toggle:hover{background-color:var(--color-bg-muted);color:var(--color-text-primary)}.ea-color-picker__format-toggle:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-color-picker__input-label{font-size:var(--font-size-2xs);font-weight:var(--font-weight-medium);text-transform:uppercase;letter-spacing:.04em;color:var(--color-text-tertiary)}.ea-color-picker__input{width:100%;min-width:0;padding:var(--space-1) var(--space-1-5);background-color:var(--color-bg-base);border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-sm);font-family:var(--font-family-mono);font-size:var(--font-size-xs);text-align:center;color:var(--color-text-primary)}.ea-color-picker__input:focus-visible{outline:none;border-color:var(--color-border-focus);box-shadow:var(--shadow-focus-ring)}.ea-color-picker__input--num{appearance:textfield}.ea-color-picker__input--num::-webkit-outer-spin-button,.ea-color-picker__input--num::-webkit-inner-spin-button{appearance:none;margin:0}.ea-color-picker__tools{display:flex;justify-content:flex-start}.ea-color-picker__tool-btn{display:inline-flex;align-items:center;gap:var(--space-1-5);padding:var(--space-1) var(--space-2);border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-sm);background-color:var(--color-bg-base);font-family:var(--font-family-sans);font-size:var(--font-size-xs);color:var(--color-text-secondary);cursor:pointer;transition:var(--transition-colors)}.ea-color-picker__tool-btn:hover{background-color:var(--color-bg-muted);color:var(--color-text-primary)}.ea-color-picker__tool-btn:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-color-picker__tool-btn ea-icon-droplet{width:.875em;height:.875em}.ea-color-picker__presets{display:flex;flex-direction:column;gap:var(--space-1-5);padding-top:var(--space-2);border-top:var(--border-width-thin) solid var(--color-border-default)}.ea-color-picker__presets-label{font-size:var(--font-size-2xs);font-weight:var(--font-weight-medium);text-transform:uppercase;letter-spacing:.04em;color:var(--color-text-tertiary)}.ea-color-picker__presets-grid{display:grid;grid-template-columns:repeat(10,1fr);gap:var(--space-1)}.ea-color-picker__preset{width:100%;aspect-ratio:1;padding:0;border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-sm);cursor:pointer;transition:transform var(--duration-fast) var(--ease-out)}.ea-color-picker__preset:hover{transform:scale(1.1)}.ea-color-picker__preset:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-color-picker__preset[aria-selected=true]{box-shadow:0 0 0 2px var(--color-brand-default)}\n"] }]
|
|
3456
|
-
}],
|
|
3457
|
-
type: HostListener,
|
|
3458
|
-
args: ['document:click', ['$event']]
|
|
3459
|
-
}] } });
|
|
3901
|
+
], template: "<div class=\"ea-color-picker-field\">\n @if (label()) {\n <label\n class=\"ea-color-picker-field__label\"\n [for]=\"id()\"\n [class.ea-color-picker-field__label--required]=\"required()\">\n {{ label() }}\n </label>\n }\n\n <div class=\"ea-color-picker\">\n <div class=\"ea-color-picker__trigger-wrapper\">\n <button\n #triggerEl\n type=\"button\"\n class=\"ea-color-picker__trigger\"\n [ngClass]=\"triggerClasses()\"\n [id]=\"id()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-haspopup]=\"'dialog'\"\n [attr.aria-required]=\"required() || null\"\n [attr.aria-invalid]=\"hasError() || null\"\n [attr.aria-describedby]=\"\n showError() ? id() + '-error' : showHint() ? id() + '-hint' : null\n \"\n (click)=\"toggle()\"\n (keydown)=\"onTriggerKeydown($event)\">\n <span\n class=\"ea-color-picker__swatch\"\n aria-hidden=\"true\">\n <span\n class=\"ea-color-picker__swatch-fill\"\n [style.background-color]=\"value() ? displayColor() : null\">\n </span>\n </span>\n <span\n class=\"ea-color-picker__trigger-value\"\n [class.ea-color-picker__trigger-value--placeholder]=\"!displayValue()\">\n {{ displayValue() || resolvedPlaceholder() }}\n </span>\n </button>\n @if (value() && !isDisabled() && !readonly()) {\n <button\n type=\"button\"\n class=\"ea-color-picker__clear\"\n [attr.aria-label]=\"i18n.messages().colorPicker.clear\"\n (click)=\"clear($event)\">\n <span aria-hidden=\"true\">\u00D7</span>\n </button>\n }\n </div>\n\n <ea-popover\n [anchor]=\"triggerEl\"\n [open]=\"isOpen()\"\n placement=\"bottom-start\"\n role=\"dialog\"\n [ariaLabel]=\"label() || i18n.messages().colorPicker.placeholder\"\n [closeOnEscape]=\"false\"\n scrollBehavior=\"close\"\n (closeRequested)=\"onPopoverCloseRequested()\">\n <div\n class=\"ea-color-picker__popover\"\n (keydown)=\"onPopoverKeydown($event)\">\n <div\n #svAreaEl\n class=\"ea-color-picker__sv-area\"\n role=\"application\"\n tabindex=\"0\"\n [attr.aria-label]=\"i18n.messages().colorPicker.saturationAndValue\"\n [style.background-color]=\"hueColor()\"\n (pointerdown)=\"onSvPointerDown($event)\"\n (pointermove)=\"onSvPointerMove($event)\"\n (pointerup)=\"onSvPointerUp($event)\"\n (pointercancel)=\"onSvPointerUp($event)\"\n (keydown)=\"onSvKeydown($event)\">\n <div class=\"ea-color-picker__sv-area-sat\"></div>\n <div class=\"ea-color-picker__sv-area-val\"></div>\n <div\n class=\"ea-color-picker__sv-pointer\"\n [style.background-color]=\"opaqueColor()\"\n [style.left]=\"svPointerLeft()\"\n [style.top]=\"svPointerTop()\">\n </div>\n </div>\n\n <div class=\"ea-color-picker__sliders\">\n <div class=\"ea-color-picker__slider-row\">\n <span\n class=\"ea-color-picker__swatch ea-color-picker__swatch--lg\"\n aria-hidden=\"true\">\n <span\n class=\"ea-color-picker__swatch-fill\"\n [style.background-color]=\"displayColor()\">\n </span>\n </span>\n <div class=\"ea-color-picker__strip-stack\">\n <div\n #hueTrackEl\n class=\"ea-color-picker__strip ea-color-picker__strip--hue\"\n role=\"slider\"\n tabindex=\"0\"\n [attr.aria-label]=\"i18n.messages().colorPicker.hue\"\n [attr.aria-valuemin]=\"0\"\n [attr.aria-valuemax]=\"360\"\n [attr.aria-valuenow]=\"hueRounded()\"\n (pointerdown)=\"onHuePointerDown($event)\"\n (pointermove)=\"onHuePointerMove($event)\"\n (pointerup)=\"onHuePointerUp($event)\"\n (pointercancel)=\"onHuePointerUp($event)\"\n (keydown)=\"onHueKeydown($event)\">\n <div\n class=\"ea-color-picker__strip-thumb\"\n [style.left]=\"huePointerLeft()\">\n </div>\n </div>\n @if (showAlpha()) {\n <div\n #alphaTrackEl\n class=\"ea-color-picker__strip ea-color-picker__strip--alpha\"\n role=\"slider\"\n tabindex=\"0\"\n [attr.aria-label]=\"i18n.messages().colorPicker.alpha\"\n [attr.aria-valuemin]=\"0\"\n [attr.aria-valuemax]=\"100\"\n [attr.aria-valuenow]=\"alphaPointerLeft()\"\n [style.--ea-color-picker-alpha-base]=\"opaqueColor()\"\n (pointerdown)=\"onAlphaPointerDown($event)\"\n (pointermove)=\"onAlphaPointerMove($event)\"\n (pointerup)=\"onAlphaPointerUp($event)\"\n (pointercancel)=\"onAlphaPointerUp($event)\"\n (keydown)=\"onAlphaKeydown($event)\">\n <div\n class=\"ea-color-picker__strip-thumb\"\n [style.left]=\"alphaPointerLeft()\">\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n\n <div\n class=\"ea-color-picker__inputs\"\n [class.ea-color-picker__inputs--hex]=\"inputMode() === 'hex'\">\n @if (inputMode() === 'hex') {\n <label class=\"ea-color-picker__input-group ea-color-picker__input-group--hex\">\n <span class=\"ea-color-picker__input-label\">HEX</span>\n <input\n class=\"ea-color-picker__input\"\n type=\"text\"\n spellcheck=\"false\"\n autocomplete=\"off\"\n maxlength=\"9\"\n [value]=\"hexInputValue()\"\n (input)=\"onHexInput($event)\"\n (blur)=\"onHexBlur()\" />\n </label>\n } @else {\n <label class=\"ea-color-picker__input-group\">\n <span class=\"ea-color-picker__input-label\">R</span>\n <input\n class=\"ea-color-picker__input ea-color-picker__input--num\"\n type=\"text\"\n inputmode=\"numeric\"\n pattern=\"\\d*\"\n maxlength=\"3\"\n [value]=\"rgb().r\"\n (input)=\"onRgbInput('r', $event)\" />\n </label>\n <label class=\"ea-color-picker__input-group\">\n <span class=\"ea-color-picker__input-label\">G</span>\n <input\n class=\"ea-color-picker__input ea-color-picker__input--num\"\n type=\"text\"\n inputmode=\"numeric\"\n pattern=\"\\d*\"\n maxlength=\"3\"\n [value]=\"rgb().g\"\n (input)=\"onRgbInput('g', $event)\" />\n </label>\n <label class=\"ea-color-picker__input-group\">\n <span class=\"ea-color-picker__input-label\">B</span>\n <input\n class=\"ea-color-picker__input ea-color-picker__input--num\"\n type=\"text\"\n inputmode=\"numeric\"\n pattern=\"\\d*\"\n maxlength=\"3\"\n [value]=\"rgb().b\"\n (input)=\"onRgbInput('b', $event)\" />\n </label>\n @if (showAlpha()) {\n <label class=\"ea-color-picker__input-group\">\n <span class=\"ea-color-picker__input-label\">A</span>\n <input\n class=\"ea-color-picker__input ea-color-picker__input--num\"\n type=\"text\"\n inputmode=\"numeric\"\n pattern=\"\\d*\"\n maxlength=\"3\"\n [value]=\"alphaPercentRounded()\"\n (input)=\"onAlphaInput($event)\" />\n </label>\n }\n }\n <button\n type=\"button\"\n class=\"ea-color-picker__format-toggle\"\n [attr.aria-label]=\"i18n.messages().colorPicker.toggleFormat\"\n (click)=\"cycleInputMode()\">\n {{ inputMode() === 'hex' ? 'HEX' : 'RGB' }}\n </button>\n </div>\n\n @if (hasEyeDropper()) {\n <div class=\"ea-color-picker__tools\">\n <button\n type=\"button\"\n class=\"ea-color-picker__tool-btn\"\n [attr.aria-label]=\"i18n.messages().colorPicker.eyedropper\"\n (click)=\"pickFromScreen()\">\n <ea-icon-droplet aria-hidden=\"true\" />\n <span>{{ i18n.messages().colorPicker.eyedropper }}</span>\n </button>\n </div>\n }\n\n @if (presets().length > 0) {\n <div class=\"ea-color-picker__presets\">\n <span class=\"ea-color-picker__presets-label\">\n {{ i18n.messages().colorPicker.presets }}\n </span>\n <div\n class=\"ea-color-picker__presets-grid\"\n role=\"listbox\">\n @for (preset of presets(); track preset) {\n <button\n type=\"button\"\n class=\"ea-color-picker__preset\"\n role=\"option\"\n [attr.aria-label]=\"preset\"\n [attr.aria-selected]=\"value() === preset\"\n [style.background-color]=\"preset\"\n (click)=\"selectPreset(preset)\">\n </button>\n }\n </div>\n </div>\n }\n </div>\n </ea-popover>\n </div>\n\n @if (showError()) {\n <p\n class=\"ea-color-picker-field__message ea-color-picker-field__message--error\"\n [id]=\"id() + '-error'\"\n role=\"alert\">\n <ea-icon-alert-circle class=\"ea-color-picker-field__message-icon\" />\n {{ errorMsg() }}\n </p>\n }\n\n @if (showHint()) {\n <p\n class=\"ea-color-picker-field__message ea-color-picker-field__message--hint\"\n [id]=\"id() + '-hint'\">\n {{ hint() }}\n </p>\n }\n</div>\n", styles: [".ea-color-picker-field{display:flex;flex-direction:column;gap:var(--space-1-5)}.ea-color-picker-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-color-picker-field__label--required:after{content:\" *\";color:var(--color-error-default)}.ea-color-picker-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-color-picker-field__message--hint{color:var(--color-text-secondary)}.ea-color-picker-field__message--error{color:var(--color-error-default)}.ea-color-picker-field__message-icon{flex-shrink:0;width:.875em;height:.875em}.ea-color-picker,.ea-color-picker__trigger-wrapper{position:relative}.ea-color-picker__trigger{display:flex;align-items:center;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-color-picker__trigger:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-color-picker__trigger--sm{padding:var(--space-1-5) var(--space-2);font-size:var(--font-size-sm);min-height:2rem}.ea-color-picker__trigger--md{padding:var(--space-2) var(--space-3);font-size:var(--font-size-sm);min-height:2.5rem}.ea-color-picker__trigger--lg{padding:var(--space-2-5) var(--space-4);font-size:var(--font-size-md);min-height:3rem}.ea-color-picker__trigger--open{border-color:var(--color-border-focus);box-shadow:var(--shadow-focus-ring)}.ea-color-picker__trigger--error{border-color:var(--color-error-default)}.ea-color-picker__trigger--error.ea-color-picker__trigger--open{box-shadow:var(--shadow-focus-ring-error)}.ea-color-picker__trigger--disabled{background-color:var(--color-bg-muted);opacity:.6;cursor:not-allowed}.ea-color-picker__trigger-value{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-family:var(--font-family-mono);font-size:.85em}.ea-color-picker__trigger-value--placeholder{color:var(--color-text-tertiary);font-family:var(--font-family-sans);font-size:1em}.ea-color-picker__clear{position:absolute;top:50%;right:var(--space-2);z-index:1;display:flex;align-items:center;justify-content:center;flex-shrink:0;width:1.25rem;height:1.25rem;padding:0;border:none;border-radius:var(--radius-sm);background:none;color:var(--color-text-secondary);font-size:1rem;line-height:1;cursor:pointer;transition:var(--transition-colors);transform:translateY(-50%)}.ea-color-picker__clear:hover{background-color:var(--color-bg-muted);color:var(--color-text-primary)}.ea-color-picker__clear:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-color-picker__swatch{position:relative;overflow:hidden;flex-shrink:0;width:1.125rem;height:1.125rem;border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-sm);background-color:var(--color-bg-base);background-image:linear-gradient(45deg,var(--color-neutral-200) 25%,transparent 25%),linear-gradient(-45deg,var(--color-neutral-200) 25%,transparent 25%),linear-gradient(45deg,transparent 75%,var(--color-neutral-200) 75%),linear-gradient(-45deg,transparent 75%,var(--color-neutral-200) 75%);background-size:8px 8px;background-position:0 0,0 4px,4px -4px,-4px 0}.ea-color-picker__swatch--lg{width:2.5rem;height:2.5rem;border-radius:var(--radius-md)}.ea-color-picker__swatch-fill{position:absolute;inset:0;display:block}.ea-color-picker__popover{display:flex;flex-direction:column;gap:var(--space-3);width:17.5rem;padding:var(--space-3);border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-md);box-shadow:var(--shadow-lg);background-color:var(--color-bg-base)}.ea-color-picker__sv-area{position:relative;overflow:hidden;width:100%;height:10rem;border-radius:var(--radius-sm);cursor:crosshair;touch-action:none}.ea-color-picker__sv-area:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-color-picker__sv-area-sat{position:absolute;inset:0;background:linear-gradient(to right,var(--color-picker-sv-white),transparent)}.ea-color-picker__sv-area-val{position:absolute;inset:0;background:linear-gradient(to top,var(--color-picker-sv-black),transparent)}.ea-color-picker__sv-pointer{position:absolute;z-index:1;width:.875rem;height:.875rem;border:2px solid var(--color-neutral-0);border-radius:var(--radius-full);box-shadow:0 0 0 1px var(--color-picker-thumb-halo);pointer-events:none;transform:translate(-50%,-50%)}.ea-color-picker__slider-row{display:flex;align-items:center;gap:var(--space-2)}.ea-color-picker__strip-stack{display:flex;flex-direction:column;flex:1;gap:var(--space-2)}.ea-color-picker__strip{position:relative;width:100%;height:.75rem;border-radius:var(--radius-full);cursor:pointer;touch-action:none}.ea-color-picker__strip:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-color-picker__strip--hue{background:linear-gradient(to right,var(--color-picker-hue-red) 0%,var(--color-picker-hue-yellow) 17%,var(--color-picker-hue-green) 33%,var(--color-picker-hue-cyan) 50%,var(--color-picker-hue-blue) 67%,var(--color-picker-hue-magenta) 83%,var(--color-picker-hue-red) 100%)}.ea-color-picker__strip--alpha{background-color:var(--color-bg-base);background-image:linear-gradient(to right,transparent 0%,var(--ea-color-picker-alpha-base, currentcolor) 100%),linear-gradient(45deg,var(--color-neutral-200) 25%,transparent 25%),linear-gradient(-45deg,var(--color-neutral-200) 25%,transparent 25%),linear-gradient(45deg,transparent 75%,var(--color-neutral-200) 75%),linear-gradient(-45deg,transparent 75%,var(--color-neutral-200) 75%);background-size:100% 100%,8px 8px,8px 8px,8px 8px,8px 8px;background-position:0 0,0 0,0 4px,4px -4px,-4px 0}.ea-color-picker__strip-thumb{position:absolute;top:50%;width:.875rem;height:.875rem;border:2px solid var(--color-neutral-0);border-radius:var(--radius-full);box-shadow:0 0 0 1px var(--color-picker-thumb-halo);pointer-events:none;transform:translate(-50%,-50%)}.ea-color-picker__inputs{display:flex;align-items:end;gap:var(--space-1)}.ea-color-picker__input-group{display:flex;flex:1;flex-direction:column;gap:var(--space-1);min-width:0;text-align:center}.ea-color-picker__input-group--hex{flex:1}.ea-color-picker__format-toggle{flex-shrink:0;min-width:3.25rem;padding:var(--space-1) var(--space-2);border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-sm);background-color:var(--color-bg-base);font-family:var(--font-family-sans);font-size:var(--font-size-2xs);font-weight:var(--font-weight-medium);letter-spacing:.04em;color:var(--color-text-secondary);cursor:pointer;transition:var(--transition-colors)}.ea-color-picker__format-toggle:hover{background-color:var(--color-bg-muted);color:var(--color-text-primary)}.ea-color-picker__format-toggle:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-color-picker__input-label{font-size:var(--font-size-2xs);font-weight:var(--font-weight-medium);text-transform:uppercase;letter-spacing:.04em;color:var(--color-text-tertiary)}.ea-color-picker__input{width:100%;min-width:0;padding:var(--space-1) var(--space-1-5);background-color:var(--color-bg-base);border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-sm);font-family:var(--font-family-mono);font-size:var(--font-size-xs);text-align:center;color:var(--color-text-primary)}.ea-color-picker__input:focus-visible{outline:none;border-color:var(--color-border-focus);box-shadow:var(--shadow-focus-ring)}.ea-color-picker__input--num{appearance:textfield}.ea-color-picker__input--num::-webkit-outer-spin-button,.ea-color-picker__input--num::-webkit-inner-spin-button{appearance:none;margin:0}.ea-color-picker__tools{display:flex;justify-content:flex-start}.ea-color-picker__tool-btn{display:inline-flex;align-items:center;gap:var(--space-1-5);padding:var(--space-1) var(--space-2);border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-sm);background-color:var(--color-bg-base);font-family:var(--font-family-sans);font-size:var(--font-size-xs);color:var(--color-text-secondary);cursor:pointer;transition:var(--transition-colors)}.ea-color-picker__tool-btn:hover{background-color:var(--color-bg-muted);color:var(--color-text-primary)}.ea-color-picker__tool-btn:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-color-picker__tool-btn ea-icon-droplet{width:.875em;height:.875em}.ea-color-picker__presets{display:flex;flex-direction:column;gap:var(--space-1-5);padding-top:var(--space-2);border-top:var(--border-width-thin) solid var(--color-border-default)}.ea-color-picker__presets-label{font-size:var(--font-size-2xs);font-weight:var(--font-weight-medium);text-transform:uppercase;letter-spacing:.04em;color:var(--color-text-tertiary)}.ea-color-picker__presets-grid{display:grid;grid-template-columns:repeat(10,1fr);gap:var(--space-1)}.ea-color-picker__preset{width:100%;aspect-ratio:1;padding:0;border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-sm);cursor:pointer;transition:transform var(--duration-fast) var(--ease-out)}.ea-color-picker__preset:hover{transform:scale(1.1)}.ea-color-picker__preset:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-color-picker__preset[aria-selected=true]{box-shadow:0 0 0 2px var(--color-brand-default)}\n"] }]
|
|
3902
|
+
}], propDecorators: { triggerEl: [{ type: i0.ViewChild, args: ['triggerEl', { isSignal: true }] }], svAreaEl: [{ type: i0.ViewChild, args: ['svAreaEl', { isSignal: true }] }], hueTrackEl: [{ type: i0.ViewChild, args: ['hueTrackEl', { isSignal: true }] }], alphaTrackEl: [{ type: i0.ViewChild, args: ['alphaTrackEl', { 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 }] }], 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 }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], errorMsg: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMsg", required: false }] }], showAlpha: [{ type: i0.Input, args: [{ isSignal: true, alias: "showAlpha", required: false }] }], format: [{ type: i0.Input, args: [{ isSignal: true, alias: "format", required: false }] }], presets: [{ type: i0.Input, args: [{ isSignal: true, alias: "presets", 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"] }] } });
|
|
3460
3903
|
// ─── Pure color helpers (module-private) ──────────────────────────────────
|
|
3461
3904
|
function clamp01(n) {
|
|
3462
3905
|
return Math.min(1, Math.max(0, n));
|
|
@@ -4268,7 +4711,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImpo
|
|
|
4268
4711
|
* Escape). Integrates with Angular forms via `ControlValueAccessor`.
|
|
4269
4712
|
*/
|
|
4270
4713
|
class DatePickerComponent {
|
|
4271
|
-
hostEl = viewChild('hostEl', ...(ngDevMode ? [{ debugName: "hostEl" }] : /* istanbul ignore next */ []));
|
|
4272
4714
|
triggerEl = viewChild('triggerEl', ...(ngDevMode ? [{ debugName: "triggerEl" }] : /* istanbul ignore next */ []));
|
|
4273
4715
|
injector = inject(Injector);
|
|
4274
4716
|
i18n = inject(EagamiI18nService);
|
|
@@ -4426,8 +4868,12 @@ class DatePickerComponent {
|
|
|
4426
4868
|
this.focusedDate.set(null);
|
|
4427
4869
|
}
|
|
4428
4870
|
focusFocusedDayCell() {
|
|
4429
|
-
|
|
4430
|
-
|
|
4871
|
+
// The calendar lives inside the popover surface, which `<ea-popover>`
|
|
4872
|
+
// teleports to `document.body`. Query the document directly so the lookup
|
|
4873
|
+
// works regardless of where the surface is mounted.
|
|
4874
|
+
if (typeof document === 'undefined')
|
|
4875
|
+
return;
|
|
4876
|
+
const focusedCell = document.querySelector('.ea-date-picker__day--focused');
|
|
4431
4877
|
focusedCell?.focus();
|
|
4432
4878
|
}
|
|
4433
4879
|
/** Moves keyboard focus to the trigger button. */
|
|
@@ -4572,14 +5018,10 @@ class DatePickerComponent {
|
|
|
4572
5018
|
this.viewMonth.set(next.getMonth());
|
|
4573
5019
|
}
|
|
4574
5020
|
}
|
|
4575
|
-
|
|
4576
|
-
|
|
4577
|
-
|
|
4578
|
-
|
|
4579
|
-
if (host && !host.contains(event.target)) {
|
|
4580
|
-
this.close();
|
|
4581
|
-
this.onTouched();
|
|
4582
|
-
}
|
|
5021
|
+
/** Called by `<ea-popover>` when the user clicks outside the picker. */
|
|
5022
|
+
onPopoverCloseRequested() {
|
|
5023
|
+
this.close();
|
|
5024
|
+
this.onTouched();
|
|
4583
5025
|
}
|
|
4584
5026
|
// Internal helpers
|
|
4585
5027
|
formatOptions() {
|
|
@@ -4620,13 +5062,13 @@ class DatePickerComponent {
|
|
|
4620
5062
|
return result;
|
|
4621
5063
|
}
|
|
4622
5064
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: DatePickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
4623
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.13", type: DatePickerComponent, isStandalone: true, selector: "ea-date-picker", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, errorMsg: { classPropertyName: "errorMsg", publicName: "errorMsg", isSignal: true, isRequired: false, transformFunction: null }, minDate: { classPropertyName: "minDate", publicName: "minDate", isSignal: true, isRequired: false, transformFunction: null }, maxDate: { classPropertyName: "maxDate", publicName: "maxDate", isSignal: true, isRequired: false, transformFunction: null }, format: { classPropertyName: "format", publicName: "format", isSignal: true, isRequired: false, transformFunction: null }, weekStartsOn: { classPropertyName: "weekStartsOn", publicName: "weekStartsOn", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", changed: "changed" },
|
|
5065
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.13", type: DatePickerComponent, isStandalone: true, selector: "ea-date-picker", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, errorMsg: { classPropertyName: "errorMsg", publicName: "errorMsg", isSignal: true, isRequired: false, transformFunction: null }, minDate: { classPropertyName: "minDate", publicName: "minDate", isSignal: true, isRequired: false, transformFunction: null }, maxDate: { classPropertyName: "maxDate", publicName: "maxDate", isSignal: true, isRequired: false, transformFunction: null }, format: { classPropertyName: "format", publicName: "format", isSignal: true, isRequired: false, transformFunction: null }, weekStartsOn: { classPropertyName: "weekStartsOn", publicName: "weekStartsOn", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", changed: "changed" }, providers: [
|
|
4624
5066
|
{
|
|
4625
5067
|
provide: NG_VALUE_ACCESSOR,
|
|
4626
5068
|
useExisting: forwardRef(() => DatePickerComponent),
|
|
4627
5069
|
multi: true,
|
|
4628
5070
|
},
|
|
4629
|
-
], viewQueries: [{ propertyName: "hostEl", first: true, predicate: ["hostEl"], descendants: true, isSignal: true }, { propertyName: "triggerEl", first: true, predicate: ["triggerEl"], descendants: true, isSignal: true }], ngImport: i0, template: "<div\n #hostEl\n class=\"ea-date-picker-field\">\n @if (label()) {\n <label\n class=\"ea-date-picker-field__label\"\n [for]=\"id()\"\n [class.ea-date-picker-field__label--required]=\"required()\">\n {{ label() }}\n </label>\n }\n\n <div class=\"ea-date-picker\">\n <div class=\"ea-date-picker__trigger-wrapper\">\n <button\n #triggerEl\n type=\"button\"\n class=\"ea-date-picker__trigger\"\n [ngClass]=\"triggerClasses()\"\n [id]=\"id()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-haspopup]=\"'dialog'\"\n [attr.aria-required]=\"required() || null\"\n [attr.aria-invalid]=\"hasError() || null\"\n [attr.aria-describedby]=\"\n showError() ? id() + '-error' : showHint() ? id() + '-hint' : null\n \"\n (click)=\"toggle()\"\n (keydown)=\"handleTriggerKeydown($event)\">\n <ea-icon-calendar\n class=\"ea-date-picker__trigger-icon\"\n aria-hidden=\"true\" />\n <span\n class=\"ea-date-picker__trigger-value\"\n [class.ea-date-picker__trigger-value--placeholder]=\"!displayValue()\">\n {{ displayValue() || resolvedPlaceholder() }}\n </span>\n </button>\n @if (value() && !isDisabled() && !readonly()) {\n <button\n type=\"button\"\n class=\"ea-date-picker__clear\"\n [attr.aria-label]=\"i18n.messages().datePicker.clear\"\n (click)=\"clear($event)\">\n <span aria-hidden=\"true\">\u00D7</span>\n </button>\n }\n </div>\n\n @if (isOpen()) {\n <div\n class=\"ea-date-picker__popover\"\n role=\"dialog\"\n [attr.aria-labelledby]=\"id() + '-label'\"\n (keydown)=\"handleGridKeydown($event)\">\n <div class=\"ea-date-picker__header\">\n <button\n type=\"button\"\n class=\"ea-date-picker__nav-btn\"\n [attr.aria-label]=\"i18n.messages().datePicker.previousYear\"\n (click)=\"goToPrevYear()\">\n <ea-icon-chevron-left aria-hidden=\"true\" />\n <ea-icon-chevron-left aria-hidden=\"true\" />\n </button>\n <button\n type=\"button\"\n class=\"ea-date-picker__nav-btn\"\n [attr.aria-label]=\"i18n.messages().datePicker.previousMonth\"\n (click)=\"goToPrevMonth()\">\n <ea-icon-chevron-left aria-hidden=\"true\" />\n </button>\n <span\n class=\"ea-date-picker__month-label\"\n [id]=\"id() + '-label'\"\n aria-live=\"polite\">\n {{ monthYearLabel() }}\n </span>\n <button\n type=\"button\"\n class=\"ea-date-picker__nav-btn\"\n [attr.aria-label]=\"i18n.messages().datePicker.nextMonth\"\n (click)=\"goToNextMonth()\">\n <ea-icon-chevron-right aria-hidden=\"true\" />\n </button>\n <button\n type=\"button\"\n class=\"ea-date-picker__nav-btn\"\n [attr.aria-label]=\"i18n.messages().datePicker.nextYear\"\n (click)=\"goToNextYear()\">\n <ea-icon-chevron-right aria-hidden=\"true\" />\n <ea-icon-chevron-right aria-hidden=\"true\" />\n </button>\n </div>\n\n <div\n class=\"ea-date-picker__grid\"\n role=\"grid\">\n <div\n class=\"ea-date-picker__weekday-row\"\n role=\"row\">\n @for (label of weekdayLabels(); track label) {\n <div\n class=\"ea-date-picker__weekday\"\n role=\"columnheader\">\n {{ label }}\n </div>\n }\n </div>\n @for (week of weeks(); track $index) {\n <div\n class=\"ea-date-picker__week\"\n role=\"row\">\n @for (day of week; track day.date.getTime()) {\n <button\n type=\"button\"\n class=\"ea-date-picker__day\"\n role=\"gridcell\"\n [class.ea-date-picker__day--outside]=\"!day.isCurrentMonth\"\n [class.ea-date-picker__day--today]=\"day.isToday\"\n [class.ea-date-picker__day--selected]=\"day.isSelected\"\n [class.ea-date-picker__day--focused]=\"day.isFocused\"\n [class.ea-date-picker__day--disabled]=\"day.isDisabled\"\n [disabled]=\"day.isDisabled\"\n [attr.aria-selected]=\"day.isSelected\"\n [attr.aria-current]=\"day.isToday ? 'date' : null\"\n [attr.tabindex]=\"day.isFocused ? 0 : -1\"\n (click)=\"selectDay(day)\">\n {{ day.day }}\n </button>\n }\n </div>\n }\n </div>\n\n <div class=\"ea-date-picker__footer\">\n <button\n type=\"button\"\n class=\"ea-date-picker__today-btn\"\n (click)=\"goToToday()\">\n {{ i18n.messages().datePicker.today }}\n </button>\n </div>\n </div>\n }\n </div>\n\n @if (showError()) {\n <p\n class=\"ea-date-picker-field__message ea-date-picker-field__message--error\"\n [id]=\"id() + '-error'\"\n role=\"alert\">\n <ea-icon-alert-circle class=\"ea-date-picker-field__message-icon\" />\n {{ errorMsg() }}\n </p>\n }\n\n @if (showHint()) {\n <p\n class=\"ea-date-picker-field__message ea-date-picker-field__message--hint\"\n [id]=\"id() + '-hint'\">\n {{ hint() }}\n </p>\n }\n</div>\n", styles: [".ea-date-picker-field{display:flex;flex-direction:column;gap:var(--space-1-5)}.ea-date-picker-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-date-picker-field__label--required:after{content:\" *\";color:var(--color-error-default)}.ea-date-picker-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-date-picker-field__message--hint{color:var(--color-text-secondary)}.ea-date-picker-field__message--error{color:var(--color-error-default)}.ea-date-picker-field__message-icon{flex-shrink:0;width:.875em;height:.875em}.ea-date-picker,.ea-date-picker__trigger-wrapper{position:relative}.ea-date-picker__trigger{display:flex;align-items:center;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-date-picker__trigger:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-date-picker__trigger--sm{padding:var(--space-1-5) var(--space-2);font-size:var(--font-size-sm);min-height:2rem}.ea-date-picker__trigger--md{padding:var(--space-2) var(--space-3);font-size:var(--font-size-sm);min-height:2.5rem}.ea-date-picker__trigger--lg{padding:var(--space-2-5) var(--space-4);font-size:var(--font-size-md);min-height:3rem}.ea-date-picker__trigger--open{border-color:var(--color-border-focus);box-shadow:var(--shadow-focus-ring)}.ea-date-picker__trigger--error{border-color:var(--color-error-default)}.ea-date-picker__trigger--error.ea-date-picker__trigger--open{box-shadow:var(--shadow-focus-ring-error)}.ea-date-picker__trigger--disabled{background-color:var(--color-bg-muted);opacity:.6;cursor:not-allowed}.ea-date-picker__trigger-icon{flex-shrink:0;width:1em;height:1em;color:var(--color-text-secondary)}.ea-date-picker__trigger-value{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ea-date-picker__trigger-value--placeholder{color:var(--color-text-tertiary)}.ea-date-picker__clear{position:absolute;top:50%;right:var(--space-2);z-index:1;display:flex;align-items:center;justify-content:center;flex-shrink:0;width:1.25rem;height:1.25rem;padding:0;border:none;border-radius:var(--radius-sm);background:none;color:var(--color-text-secondary);font-size:1rem;line-height:1;cursor:pointer;transition:var(--transition-colors);transform:translateY(-50%)}.ea-date-picker__clear:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-date-picker__clear:hover{background-color:var(--color-bg-muted);color:var(--color-text-primary)}.ea-date-picker__popover{position:absolute;top:calc(100% + var(--space-1));left:0;z-index:var(--z-index-dropdown);display:flex;flex-direction:column;gap:var(--space-2);padding:var(--space-3);min-width:17.5rem;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)}.ea-date-picker__header{display:flex;align-items:center;gap:var(--space-1)}.ea-date-picker__nav-btn{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:1.75rem;height:1.75rem;padding:0;border:none;border-radius:var(--radius-sm);background:none;color:var(--color-text-secondary);cursor:pointer;transition:var(--transition-colors)}.ea-date-picker__nav-btn:hover{background-color:var(--color-bg-muted);color:var(--color-text-primary)}.ea-date-picker__nav-btn:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-date-picker__nav-btn ea-icon-chevron-left,.ea-date-picker__nav-btn ea-icon-chevron-right{width:.875em;height:.875em}.ea-date-picker__nav-btn ea-icon-chevron-left+ea-icon-chevron-left,.ea-date-picker__nav-btn ea-icon-chevron-right+ea-icon-chevron-right{margin-left:-.375em}.ea-date-picker__month-label{flex:1;font-size:var(--font-size-sm);font-weight:var(--font-weight-medium);text-align:center;color:var(--color-text-primary)}.ea-date-picker__grid{display:flex;flex-direction:column;gap:var(--space-1)}.ea-date-picker__weekday-row,.ea-date-picker__week{display:grid;grid-template-columns:repeat(7,1fr);gap:var(--space-1)}.ea-date-picker__weekday{display:flex;align-items:center;justify-content:center;height:1.5rem;font-size:var(--font-size-xs);font-weight:var(--font-weight-medium);text-transform:uppercase;color:var(--color-text-tertiary)}.ea-date-picker__day{display:flex;align-items:center;justify-content:center;width:2rem;height:2rem;padding:0;border:none;border-radius:var(--radius-sm);background:none;font-family:var(--font-family-sans);font-size:var(--font-size-sm);color:var(--color-text-primary);cursor:pointer;transition:var(--transition-colors)}.ea-date-picker__day:hover:not(:disabled){background-color:var(--color-bg-muted)}.ea-date-picker__day:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-date-picker__day--outside{color:var(--color-text-tertiary)}.ea-date-picker__day--today{font-weight:var(--font-weight-semibold);color:var(--color-brand-default)}.ea-date-picker__day--focused:not(.ea-date-picker__day--selected){background-color:var(--color-bg-muted)}.ea-date-picker__day--selected{background-color:var(--color-brand-default);color:var(--color-text-inverse);font-weight:var(--font-weight-medium)}.ea-date-picker__day--selected:hover{background-color:var(--color-brand-hover)}.ea-date-picker__day--disabled{color:var(--color-text-disabled);cursor:not-allowed}.ea-date-picker__day--disabled:hover{background-color:transparent}.ea-date-picker__footer{display:flex;justify-content:flex-end;padding-top:var(--space-2);border-top:var(--border-width-thin) solid var(--color-border-default)}.ea-date-picker__today-btn{padding:var(--space-1) var(--space-2);border:none;border-radius:var(--radius-sm);background:none;font-family:var(--font-family-sans);font-size:var(--font-size-sm);font-weight:var(--font-weight-medium);color:var(--color-brand-default);cursor:pointer;transition:var(--transition-colors)}.ea-date-picker__today-btn:hover{background-color:var(--color-brand-subtle)}.ea-date-picker__today-btn:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}\n"], dependencies: [{ kind: "component", type: AlertCircleIconComponent, selector: "ea-icon-alert-circle" }, { kind: "component", type: CalendarIconComponent, selector: "ea-icon-calendar" }, { kind: "component", type: ChevronLeftIconComponent, selector: "ea-icon-chevron-left" }, { kind: "component", type: ChevronRightIconComponent, selector: "ea-icon-chevron-right" }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
5071
|
+
], viewQueries: [{ propertyName: "triggerEl", first: true, predicate: ["triggerEl"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"ea-date-picker-field\">\n @if (label()) {\n <label\n class=\"ea-date-picker-field__label\"\n [for]=\"id()\"\n [class.ea-date-picker-field__label--required]=\"required()\">\n {{ label() }}\n </label>\n }\n\n <div class=\"ea-date-picker\">\n <div class=\"ea-date-picker__trigger-wrapper\">\n <button\n #triggerEl\n type=\"button\"\n class=\"ea-date-picker__trigger\"\n [ngClass]=\"triggerClasses()\"\n [id]=\"id()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-haspopup]=\"'dialog'\"\n [attr.aria-required]=\"required() || null\"\n [attr.aria-invalid]=\"hasError() || null\"\n [attr.aria-describedby]=\"\n showError() ? id() + '-error' : showHint() ? id() + '-hint' : null\n \"\n (click)=\"toggle()\"\n (keydown)=\"handleTriggerKeydown($event)\">\n <ea-icon-calendar\n class=\"ea-date-picker__trigger-icon\"\n aria-hidden=\"true\" />\n <span\n class=\"ea-date-picker__trigger-value\"\n [class.ea-date-picker__trigger-value--placeholder]=\"!displayValue()\">\n {{ displayValue() || resolvedPlaceholder() }}\n </span>\n </button>\n @if (value() && !isDisabled() && !readonly()) {\n <button\n type=\"button\"\n class=\"ea-date-picker__clear\"\n [attr.aria-label]=\"i18n.messages().datePicker.clear\"\n (click)=\"clear($event)\">\n <span aria-hidden=\"true\">\u00D7</span>\n </button>\n }\n </div>\n\n <ea-popover\n [anchor]=\"triggerEl\"\n [open]=\"isOpen()\"\n placement=\"bottom-start\"\n role=\"dialog\"\n [closeOnEscape]=\"false\"\n scrollBehavior=\"close\"\n (closeRequested)=\"onPopoverCloseRequested()\">\n <div\n class=\"ea-date-picker__popover\"\n [attr.aria-labelledby]=\"id() + '-label'\"\n (keydown)=\"handleGridKeydown($event)\">\n <div class=\"ea-date-picker__header\">\n <button\n type=\"button\"\n class=\"ea-date-picker__nav-btn\"\n [attr.aria-label]=\"i18n.messages().datePicker.previousYear\"\n (click)=\"goToPrevYear()\">\n <ea-icon-chevron-left aria-hidden=\"true\" />\n <ea-icon-chevron-left aria-hidden=\"true\" />\n </button>\n <button\n type=\"button\"\n class=\"ea-date-picker__nav-btn\"\n [attr.aria-label]=\"i18n.messages().datePicker.previousMonth\"\n (click)=\"goToPrevMonth()\">\n <ea-icon-chevron-left aria-hidden=\"true\" />\n </button>\n <span\n class=\"ea-date-picker__month-label\"\n [id]=\"id() + '-label'\"\n aria-live=\"polite\">\n {{ monthYearLabel() }}\n </span>\n <button\n type=\"button\"\n class=\"ea-date-picker__nav-btn\"\n [attr.aria-label]=\"i18n.messages().datePicker.nextMonth\"\n (click)=\"goToNextMonth()\">\n <ea-icon-chevron-right aria-hidden=\"true\" />\n </button>\n <button\n type=\"button\"\n class=\"ea-date-picker__nav-btn\"\n [attr.aria-label]=\"i18n.messages().datePicker.nextYear\"\n (click)=\"goToNextYear()\">\n <ea-icon-chevron-right aria-hidden=\"true\" />\n <ea-icon-chevron-right aria-hidden=\"true\" />\n </button>\n </div>\n\n <div\n class=\"ea-date-picker__grid\"\n role=\"grid\">\n <div\n class=\"ea-date-picker__weekday-row\"\n role=\"row\">\n @for (label of weekdayLabels(); track label) {\n <div\n class=\"ea-date-picker__weekday\"\n role=\"columnheader\">\n {{ label }}\n </div>\n }\n </div>\n @for (week of weeks(); track $index) {\n <div\n class=\"ea-date-picker__week\"\n role=\"row\">\n @for (day of week; track day.date.getTime()) {\n <button\n type=\"button\"\n class=\"ea-date-picker__day\"\n role=\"gridcell\"\n [class.ea-date-picker__day--outside]=\"!day.isCurrentMonth\"\n [class.ea-date-picker__day--today]=\"day.isToday\"\n [class.ea-date-picker__day--selected]=\"day.isSelected\"\n [class.ea-date-picker__day--focused]=\"day.isFocused\"\n [class.ea-date-picker__day--disabled]=\"day.isDisabled\"\n [disabled]=\"day.isDisabled\"\n [attr.aria-selected]=\"day.isSelected\"\n [attr.aria-current]=\"day.isToday ? 'date' : null\"\n [attr.tabindex]=\"day.isFocused ? 0 : -1\"\n (click)=\"selectDay(day)\">\n {{ day.day }}\n </button>\n }\n </div>\n }\n </div>\n\n <div class=\"ea-date-picker__footer\">\n <button\n type=\"button\"\n class=\"ea-date-picker__today-btn\"\n (click)=\"goToToday()\">\n {{ i18n.messages().datePicker.today }}\n </button>\n </div>\n </div>\n </ea-popover>\n </div>\n\n @if (showError()) {\n <p\n class=\"ea-date-picker-field__message ea-date-picker-field__message--error\"\n [id]=\"id() + '-error'\"\n role=\"alert\">\n <ea-icon-alert-circle class=\"ea-date-picker-field__message-icon\" />\n {{ errorMsg() }}\n </p>\n }\n\n @if (showHint()) {\n <p\n class=\"ea-date-picker-field__message ea-date-picker-field__message--hint\"\n [id]=\"id() + '-hint'\">\n {{ hint() }}\n </p>\n }\n</div>\n", styles: [".ea-date-picker-field{display:flex;flex-direction:column;gap:var(--space-1-5)}.ea-date-picker-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-date-picker-field__label--required:after{content:\" *\";color:var(--color-error-default)}.ea-date-picker-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-date-picker-field__message--hint{color:var(--color-text-secondary)}.ea-date-picker-field__message--error{color:var(--color-error-default)}.ea-date-picker-field__message-icon{flex-shrink:0;width:.875em;height:.875em}.ea-date-picker,.ea-date-picker__trigger-wrapper{position:relative}.ea-date-picker__trigger{display:flex;align-items:center;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-date-picker__trigger:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-date-picker__trigger--sm{padding:var(--space-1-5) var(--space-2);font-size:var(--font-size-sm);min-height:2rem}.ea-date-picker__trigger--md{padding:var(--space-2) var(--space-3);font-size:var(--font-size-sm);min-height:2.5rem}.ea-date-picker__trigger--lg{padding:var(--space-2-5) var(--space-4);font-size:var(--font-size-md);min-height:3rem}.ea-date-picker__trigger--open{border-color:var(--color-border-focus);box-shadow:var(--shadow-focus-ring)}.ea-date-picker__trigger--error{border-color:var(--color-error-default)}.ea-date-picker__trigger--error.ea-date-picker__trigger--open{box-shadow:var(--shadow-focus-ring-error)}.ea-date-picker__trigger--disabled{background-color:var(--color-bg-muted);opacity:.6;cursor:not-allowed}.ea-date-picker__trigger-icon{flex-shrink:0;width:1em;height:1em;color:var(--color-text-secondary)}.ea-date-picker__trigger-value{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ea-date-picker__trigger-value--placeholder{color:var(--color-text-tertiary)}.ea-date-picker__clear{position:absolute;top:50%;right:var(--space-2);z-index:1;display:flex;align-items:center;justify-content:center;flex-shrink:0;width:1.25rem;height:1.25rem;padding:0;border:none;border-radius:var(--radius-sm);background:none;color:var(--color-text-secondary);font-size:1rem;line-height:1;cursor:pointer;transition:var(--transition-colors);transform:translateY(-50%)}.ea-date-picker__clear:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-date-picker__clear:hover{background-color:var(--color-bg-muted);color:var(--color-text-primary)}.ea-date-picker__popover{display:flex;flex-direction:column;gap:var(--space-2);min-width:17.5rem;padding:var(--space-3);border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-md);box-shadow:var(--shadow-lg);background-color:var(--color-bg-base)}.ea-date-picker__header{display:flex;align-items:center;gap:var(--space-1)}.ea-date-picker__nav-btn{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:1.75rem;height:1.75rem;padding:0;border:none;border-radius:var(--radius-sm);background:none;color:var(--color-text-secondary);cursor:pointer;transition:var(--transition-colors)}.ea-date-picker__nav-btn:hover{background-color:var(--color-bg-muted);color:var(--color-text-primary)}.ea-date-picker__nav-btn:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-date-picker__nav-btn ea-icon-chevron-left,.ea-date-picker__nav-btn ea-icon-chevron-right{width:.875em;height:.875em}.ea-date-picker__nav-btn ea-icon-chevron-left+ea-icon-chevron-left,.ea-date-picker__nav-btn ea-icon-chevron-right+ea-icon-chevron-right{margin-left:-.375em}.ea-date-picker__month-label{flex:1;font-size:var(--font-size-sm);font-weight:var(--font-weight-medium);text-align:center;color:var(--color-text-primary)}.ea-date-picker__grid{display:flex;flex-direction:column;gap:var(--space-1)}.ea-date-picker__weekday-row,.ea-date-picker__week{display:grid;grid-template-columns:repeat(7,1fr);gap:var(--space-1)}.ea-date-picker__weekday{display:flex;align-items:center;justify-content:center;height:1.5rem;font-size:var(--font-size-xs);font-weight:var(--font-weight-medium);text-transform:uppercase;color:var(--color-text-tertiary)}.ea-date-picker__day{display:flex;align-items:center;justify-content:center;width:2rem;height:2rem;padding:0;border:none;border-radius:var(--radius-sm);background:none;font-family:var(--font-family-sans);font-size:var(--font-size-sm);color:var(--color-text-primary);cursor:pointer;transition:var(--transition-colors)}.ea-date-picker__day:hover:not(:disabled){background-color:var(--color-bg-muted)}.ea-date-picker__day:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-date-picker__day--outside{color:var(--color-text-tertiary)}.ea-date-picker__day--today{font-weight:var(--font-weight-semibold);color:var(--color-brand-default)}.ea-date-picker__day--focused:not(.ea-date-picker__day--selected){background-color:var(--color-bg-muted)}.ea-date-picker__day--selected{background-color:var(--color-brand-default);color:var(--color-text-inverse);font-weight:var(--font-weight-medium)}.ea-date-picker__day--selected:hover{background-color:var(--color-brand-hover)}.ea-date-picker__day--disabled{color:var(--color-text-disabled);cursor:not-allowed}.ea-date-picker__day--disabled:hover{background-color:transparent}.ea-date-picker__footer{display:flex;justify-content:flex-end;padding-top:var(--space-2);border-top:var(--border-width-thin) solid var(--color-border-default)}.ea-date-picker__today-btn{padding:var(--space-1) var(--space-2);border:none;border-radius:var(--radius-sm);background:none;font-family:var(--font-family-sans);font-size:var(--font-size-sm);font-weight:var(--font-weight-medium);color:var(--color-brand-default);cursor:pointer;transition:var(--transition-colors)}.ea-date-picker__today-btn:hover{background-color:var(--color-brand-subtle)}.ea-date-picker__today-btn:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}\n"], dependencies: [{ kind: "component", type: AlertCircleIconComponent, selector: "ea-icon-alert-circle" }, { kind: "component", type: CalendarIconComponent, selector: "ea-icon-calendar" }, { kind: "component", type: ChevronLeftIconComponent, selector: "ea-icon-chevron-left" }, { kind: "component", type: ChevronRightIconComponent, selector: "ea-icon-chevron-right" }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: PopoverComponent, selector: "ea-popover", inputs: ["anchor", "open", "placement", "role", "aria-label", "surfaceId", "offset", "flip", "clamp", "matchAnchorWidth", "closeOnOutsideClick", "closeOnEscape", "scrollBehavior"], outputs: ["closeRequested"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
4630
5072
|
}
|
|
4631
5073
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: DatePickerComponent, decorators: [{
|
|
4632
5074
|
type: Component,
|
|
@@ -4636,17 +5078,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImpo
|
|
|
4636
5078
|
ChevronLeftIconComponent,
|
|
4637
5079
|
ChevronRightIconComponent,
|
|
4638
5080
|
NgClass,
|
|
5081
|
+
PopoverComponent,
|
|
4639
5082
|
], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
4640
5083
|
{
|
|
4641
5084
|
provide: NG_VALUE_ACCESSOR,
|
|
4642
5085
|
useExisting: forwardRef(() => DatePickerComponent),
|
|
4643
5086
|
multi: true,
|
|
4644
5087
|
},
|
|
4645
|
-
], template: "<div\n #hostEl\n class=\"ea-date-picker-field\">\n @if (label()) {\n <label\n class=\"ea-date-picker-field__label\"\n [for]=\"id()\"\n [class.ea-date-picker-field__label--required]=\"required()\">\n {{ label() }}\n </label>\n }\n\n <div class=\"ea-date-picker\">\n <div class=\"ea-date-picker__trigger-wrapper\">\n <button\n #triggerEl\n type=\"button\"\n class=\"ea-date-picker__trigger\"\n [ngClass]=\"triggerClasses()\"\n [id]=\"id()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-haspopup]=\"'dialog'\"\n [attr.aria-required]=\"required() || null\"\n [attr.aria-invalid]=\"hasError() || null\"\n [attr.aria-describedby]=\"\n showError() ? id() + '-error' : showHint() ? id() + '-hint' : null\n \"\n (click)=\"toggle()\"\n (keydown)=\"handleTriggerKeydown($event)\">\n <ea-icon-calendar\n class=\"ea-date-picker__trigger-icon\"\n aria-hidden=\"true\" />\n <span\n class=\"ea-date-picker__trigger-value\"\n [class.ea-date-picker__trigger-value--placeholder]=\"!displayValue()\">\n {{ displayValue() || resolvedPlaceholder() }}\n </span>\n </button>\n @if (value() && !isDisabled() && !readonly()) {\n <button\n type=\"button\"\n class=\"ea-date-picker__clear\"\n [attr.aria-label]=\"i18n.messages().datePicker.clear\"\n (click)=\"clear($event)\">\n <span aria-hidden=\"true\">\u00D7</span>\n </button>\n }\n </div>\n\n @if (isOpen()) {\n <div\n class=\"ea-date-picker__popover\"\n role=\"dialog\"\n [attr.aria-labelledby]=\"id() + '-label'\"\n (keydown)=\"handleGridKeydown($event)\">\n <div class=\"ea-date-picker__header\">\n <button\n type=\"button\"\n class=\"ea-date-picker__nav-btn\"\n [attr.aria-label]=\"i18n.messages().datePicker.previousYear\"\n (click)=\"goToPrevYear()\">\n <ea-icon-chevron-left aria-hidden=\"true\" />\n <ea-icon-chevron-left aria-hidden=\"true\" />\n </button>\n <button\n type=\"button\"\n class=\"ea-date-picker__nav-btn\"\n [attr.aria-label]=\"i18n.messages().datePicker.previousMonth\"\n (click)=\"goToPrevMonth()\">\n <ea-icon-chevron-left aria-hidden=\"true\" />\n </button>\n <span\n class=\"ea-date-picker__month-label\"\n [id]=\"id() + '-label'\"\n aria-live=\"polite\">\n {{ monthYearLabel() }}\n </span>\n <button\n type=\"button\"\n class=\"ea-date-picker__nav-btn\"\n [attr.aria-label]=\"i18n.messages().datePicker.nextMonth\"\n (click)=\"goToNextMonth()\">\n <ea-icon-chevron-right aria-hidden=\"true\" />\n </button>\n <button\n type=\"button\"\n class=\"ea-date-picker__nav-btn\"\n [attr.aria-label]=\"i18n.messages().datePicker.nextYear\"\n (click)=\"goToNextYear()\">\n <ea-icon-chevron-right aria-hidden=\"true\" />\n <ea-icon-chevron-right aria-hidden=\"true\" />\n </button>\n </div>\n\n <div\n class=\"ea-date-picker__grid\"\n role=\"grid\">\n <div\n class=\"ea-date-picker__weekday-row\"\n role=\"row\">\n @for (label of weekdayLabels(); track label) {\n <div\n class=\"ea-date-picker__weekday\"\n role=\"columnheader\">\n {{ label }}\n </div>\n }\n </div>\n @for (week of weeks(); track $index) {\n <div\n class=\"ea-date-picker__week\"\n role=\"row\">\n @for (day of week; track day.date.getTime()) {\n <button\n type=\"button\"\n class=\"ea-date-picker__day\"\n role=\"gridcell\"\n [class.ea-date-picker__day--outside]=\"!day.isCurrentMonth\"\n [class.ea-date-picker__day--today]=\"day.isToday\"\n [class.ea-date-picker__day--selected]=\"day.isSelected\"\n [class.ea-date-picker__day--focused]=\"day.isFocused\"\n [class.ea-date-picker__day--disabled]=\"day.isDisabled\"\n [disabled]=\"day.isDisabled\"\n [attr.aria-selected]=\"day.isSelected\"\n [attr.aria-current]=\"day.isToday ? 'date' : null\"\n [attr.tabindex]=\"day.isFocused ? 0 : -1\"\n (click)=\"selectDay(day)\">\n {{ day.day }}\n </button>\n }\n </div>\n }\n </div>\n\n <div class=\"ea-date-picker__footer\">\n <button\n type=\"button\"\n class=\"ea-date-picker__today-btn\"\n (click)=\"goToToday()\">\n {{ i18n.messages().datePicker.today }}\n </button>\n </div>\n </div>\n }\n </div>\n\n @if (showError()) {\n <p\n class=\"ea-date-picker-field__message ea-date-picker-field__message--error\"\n [id]=\"id() + '-error'\"\n role=\"alert\">\n <ea-icon-alert-circle class=\"ea-date-picker-field__message-icon\" />\n {{ errorMsg() }}\n </p>\n }\n\n @if (showHint()) {\n <p\n class=\"ea-date-picker-field__message ea-date-picker-field__message--hint\"\n [id]=\"id() + '-hint'\">\n {{ hint() }}\n </p>\n }\n</div>\n", styles: [".ea-date-picker-field{display:flex;flex-direction:column;gap:var(--space-1-5)}.ea-date-picker-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-date-picker-field__label--required:after{content:\" *\";color:var(--color-error-default)}.ea-date-picker-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-date-picker-field__message--hint{color:var(--color-text-secondary)}.ea-date-picker-field__message--error{color:var(--color-error-default)}.ea-date-picker-field__message-icon{flex-shrink:0;width:.875em;height:.875em}.ea-date-picker,.ea-date-picker__trigger-wrapper{position:relative}.ea-date-picker__trigger{display:flex;align-items:center;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-date-picker__trigger:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-date-picker__trigger--sm{padding:var(--space-1-5) var(--space-2);font-size:var(--font-size-sm);min-height:2rem}.ea-date-picker__trigger--md{padding:var(--space-2) var(--space-3);font-size:var(--font-size-sm);min-height:2.5rem}.ea-date-picker__trigger--lg{padding:var(--space-2-5) var(--space-4);font-size:var(--font-size-md);min-height:3rem}.ea-date-picker__trigger--open{border-color:var(--color-border-focus);box-shadow:var(--shadow-focus-ring)}.ea-date-picker__trigger--error{border-color:var(--color-error-default)}.ea-date-picker__trigger--error.ea-date-picker__trigger--open{box-shadow:var(--shadow-focus-ring-error)}.ea-date-picker__trigger--disabled{background-color:var(--color-bg-muted);opacity:.6;cursor:not-allowed}.ea-date-picker__trigger-icon{flex-shrink:0;width:1em;height:1em;color:var(--color-text-secondary)}.ea-date-picker__trigger-value{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ea-date-picker__trigger-value--placeholder{color:var(--color-text-tertiary)}.ea-date-picker__clear{position:absolute;top:50%;right:var(--space-2);z-index:1;display:flex;align-items:center;justify-content:center;flex-shrink:0;width:1.25rem;height:1.25rem;padding:0;border:none;border-radius:var(--radius-sm);background:none;color:var(--color-text-secondary);font-size:1rem;line-height:1;cursor:pointer;transition:var(--transition-colors);transform:translateY(-50%)}.ea-date-picker__clear:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-date-picker__clear:hover{background-color:var(--color-bg-muted);color:var(--color-text-primary)}.ea-date-picker__popover{position:absolute;top:calc(100% + var(--space-1));left:0;z-index:var(--z-index-dropdown);display:flex;flex-direction:column;gap:var(--space-2);padding:var(--space-3);min-width:17.5rem;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)}.ea-date-picker__header{display:flex;align-items:center;gap:var(--space-1)}.ea-date-picker__nav-btn{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:1.75rem;height:1.75rem;padding:0;border:none;border-radius:var(--radius-sm);background:none;color:var(--color-text-secondary);cursor:pointer;transition:var(--transition-colors)}.ea-date-picker__nav-btn:hover{background-color:var(--color-bg-muted);color:var(--color-text-primary)}.ea-date-picker__nav-btn:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-date-picker__nav-btn ea-icon-chevron-left,.ea-date-picker__nav-btn ea-icon-chevron-right{width:.875em;height:.875em}.ea-date-picker__nav-btn ea-icon-chevron-left+ea-icon-chevron-left,.ea-date-picker__nav-btn ea-icon-chevron-right+ea-icon-chevron-right{margin-left:-.375em}.ea-date-picker__month-label{flex:1;font-size:var(--font-size-sm);font-weight:var(--font-weight-medium);text-align:center;color:var(--color-text-primary)}.ea-date-picker__grid{display:flex;flex-direction:column;gap:var(--space-1)}.ea-date-picker__weekday-row,.ea-date-picker__week{display:grid;grid-template-columns:repeat(7,1fr);gap:var(--space-1)}.ea-date-picker__weekday{display:flex;align-items:center;justify-content:center;height:1.5rem;font-size:var(--font-size-xs);font-weight:var(--font-weight-medium);text-transform:uppercase;color:var(--color-text-tertiary)}.ea-date-picker__day{display:flex;align-items:center;justify-content:center;width:2rem;height:2rem;padding:0;border:none;border-radius:var(--radius-sm);background:none;font-family:var(--font-family-sans);font-size:var(--font-size-sm);color:var(--color-text-primary);cursor:pointer;transition:var(--transition-colors)}.ea-date-picker__day:hover:not(:disabled){background-color:var(--color-bg-muted)}.ea-date-picker__day:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-date-picker__day--outside{color:var(--color-text-tertiary)}.ea-date-picker__day--today{font-weight:var(--font-weight-semibold);color:var(--color-brand-default)}.ea-date-picker__day--focused:not(.ea-date-picker__day--selected){background-color:var(--color-bg-muted)}.ea-date-picker__day--selected{background-color:var(--color-brand-default);color:var(--color-text-inverse);font-weight:var(--font-weight-medium)}.ea-date-picker__day--selected:hover{background-color:var(--color-brand-hover)}.ea-date-picker__day--disabled{color:var(--color-text-disabled);cursor:not-allowed}.ea-date-picker__day--disabled:hover{background-color:transparent}.ea-date-picker__footer{display:flex;justify-content:flex-end;padding-top:var(--space-2);border-top:var(--border-width-thin) solid var(--color-border-default)}.ea-date-picker__today-btn{padding:var(--space-1) var(--space-2);border:none;border-radius:var(--radius-sm);background:none;font-family:var(--font-family-sans);font-size:var(--font-size-sm);font-weight:var(--font-weight-medium);color:var(--color-brand-default);cursor:pointer;transition:var(--transition-colors)}.ea-date-picker__today-btn:hover{background-color:var(--color-brand-subtle)}.ea-date-picker__today-btn:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}\n"] }]
|
|
4646
|
-
}], propDecorators: {
|
|
4647
|
-
type: HostListener,
|
|
4648
|
-
args: ['document:click', ['$event']]
|
|
4649
|
-
}] } });
|
|
5088
|
+
], template: "<div class=\"ea-date-picker-field\">\n @if (label()) {\n <label\n class=\"ea-date-picker-field__label\"\n [for]=\"id()\"\n [class.ea-date-picker-field__label--required]=\"required()\">\n {{ label() }}\n </label>\n }\n\n <div class=\"ea-date-picker\">\n <div class=\"ea-date-picker__trigger-wrapper\">\n <button\n #triggerEl\n type=\"button\"\n class=\"ea-date-picker__trigger\"\n [ngClass]=\"triggerClasses()\"\n [id]=\"id()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-haspopup]=\"'dialog'\"\n [attr.aria-required]=\"required() || null\"\n [attr.aria-invalid]=\"hasError() || null\"\n [attr.aria-describedby]=\"\n showError() ? id() + '-error' : showHint() ? id() + '-hint' : null\n \"\n (click)=\"toggle()\"\n (keydown)=\"handleTriggerKeydown($event)\">\n <ea-icon-calendar\n class=\"ea-date-picker__trigger-icon\"\n aria-hidden=\"true\" />\n <span\n class=\"ea-date-picker__trigger-value\"\n [class.ea-date-picker__trigger-value--placeholder]=\"!displayValue()\">\n {{ displayValue() || resolvedPlaceholder() }}\n </span>\n </button>\n @if (value() && !isDisabled() && !readonly()) {\n <button\n type=\"button\"\n class=\"ea-date-picker__clear\"\n [attr.aria-label]=\"i18n.messages().datePicker.clear\"\n (click)=\"clear($event)\">\n <span aria-hidden=\"true\">\u00D7</span>\n </button>\n }\n </div>\n\n <ea-popover\n [anchor]=\"triggerEl\"\n [open]=\"isOpen()\"\n placement=\"bottom-start\"\n role=\"dialog\"\n [closeOnEscape]=\"false\"\n scrollBehavior=\"close\"\n (closeRequested)=\"onPopoverCloseRequested()\">\n <div\n class=\"ea-date-picker__popover\"\n [attr.aria-labelledby]=\"id() + '-label'\"\n (keydown)=\"handleGridKeydown($event)\">\n <div class=\"ea-date-picker__header\">\n <button\n type=\"button\"\n class=\"ea-date-picker__nav-btn\"\n [attr.aria-label]=\"i18n.messages().datePicker.previousYear\"\n (click)=\"goToPrevYear()\">\n <ea-icon-chevron-left aria-hidden=\"true\" />\n <ea-icon-chevron-left aria-hidden=\"true\" />\n </button>\n <button\n type=\"button\"\n class=\"ea-date-picker__nav-btn\"\n [attr.aria-label]=\"i18n.messages().datePicker.previousMonth\"\n (click)=\"goToPrevMonth()\">\n <ea-icon-chevron-left aria-hidden=\"true\" />\n </button>\n <span\n class=\"ea-date-picker__month-label\"\n [id]=\"id() + '-label'\"\n aria-live=\"polite\">\n {{ monthYearLabel() }}\n </span>\n <button\n type=\"button\"\n class=\"ea-date-picker__nav-btn\"\n [attr.aria-label]=\"i18n.messages().datePicker.nextMonth\"\n (click)=\"goToNextMonth()\">\n <ea-icon-chevron-right aria-hidden=\"true\" />\n </button>\n <button\n type=\"button\"\n class=\"ea-date-picker__nav-btn\"\n [attr.aria-label]=\"i18n.messages().datePicker.nextYear\"\n (click)=\"goToNextYear()\">\n <ea-icon-chevron-right aria-hidden=\"true\" />\n <ea-icon-chevron-right aria-hidden=\"true\" />\n </button>\n </div>\n\n <div\n class=\"ea-date-picker__grid\"\n role=\"grid\">\n <div\n class=\"ea-date-picker__weekday-row\"\n role=\"row\">\n @for (label of weekdayLabels(); track label) {\n <div\n class=\"ea-date-picker__weekday\"\n role=\"columnheader\">\n {{ label }}\n </div>\n }\n </div>\n @for (week of weeks(); track $index) {\n <div\n class=\"ea-date-picker__week\"\n role=\"row\">\n @for (day of week; track day.date.getTime()) {\n <button\n type=\"button\"\n class=\"ea-date-picker__day\"\n role=\"gridcell\"\n [class.ea-date-picker__day--outside]=\"!day.isCurrentMonth\"\n [class.ea-date-picker__day--today]=\"day.isToday\"\n [class.ea-date-picker__day--selected]=\"day.isSelected\"\n [class.ea-date-picker__day--focused]=\"day.isFocused\"\n [class.ea-date-picker__day--disabled]=\"day.isDisabled\"\n [disabled]=\"day.isDisabled\"\n [attr.aria-selected]=\"day.isSelected\"\n [attr.aria-current]=\"day.isToday ? 'date' : null\"\n [attr.tabindex]=\"day.isFocused ? 0 : -1\"\n (click)=\"selectDay(day)\">\n {{ day.day }}\n </button>\n }\n </div>\n }\n </div>\n\n <div class=\"ea-date-picker__footer\">\n <button\n type=\"button\"\n class=\"ea-date-picker__today-btn\"\n (click)=\"goToToday()\">\n {{ i18n.messages().datePicker.today }}\n </button>\n </div>\n </div>\n </ea-popover>\n </div>\n\n @if (showError()) {\n <p\n class=\"ea-date-picker-field__message ea-date-picker-field__message--error\"\n [id]=\"id() + '-error'\"\n role=\"alert\">\n <ea-icon-alert-circle class=\"ea-date-picker-field__message-icon\" />\n {{ errorMsg() }}\n </p>\n }\n\n @if (showHint()) {\n <p\n class=\"ea-date-picker-field__message ea-date-picker-field__message--hint\"\n [id]=\"id() + '-hint'\">\n {{ hint() }}\n </p>\n }\n</div>\n", styles: [".ea-date-picker-field{display:flex;flex-direction:column;gap:var(--space-1-5)}.ea-date-picker-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-date-picker-field__label--required:after{content:\" *\";color:var(--color-error-default)}.ea-date-picker-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-date-picker-field__message--hint{color:var(--color-text-secondary)}.ea-date-picker-field__message--error{color:var(--color-error-default)}.ea-date-picker-field__message-icon{flex-shrink:0;width:.875em;height:.875em}.ea-date-picker,.ea-date-picker__trigger-wrapper{position:relative}.ea-date-picker__trigger{display:flex;align-items:center;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-date-picker__trigger:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-date-picker__trigger--sm{padding:var(--space-1-5) var(--space-2);font-size:var(--font-size-sm);min-height:2rem}.ea-date-picker__trigger--md{padding:var(--space-2) var(--space-3);font-size:var(--font-size-sm);min-height:2.5rem}.ea-date-picker__trigger--lg{padding:var(--space-2-5) var(--space-4);font-size:var(--font-size-md);min-height:3rem}.ea-date-picker__trigger--open{border-color:var(--color-border-focus);box-shadow:var(--shadow-focus-ring)}.ea-date-picker__trigger--error{border-color:var(--color-error-default)}.ea-date-picker__trigger--error.ea-date-picker__trigger--open{box-shadow:var(--shadow-focus-ring-error)}.ea-date-picker__trigger--disabled{background-color:var(--color-bg-muted);opacity:.6;cursor:not-allowed}.ea-date-picker__trigger-icon{flex-shrink:0;width:1em;height:1em;color:var(--color-text-secondary)}.ea-date-picker__trigger-value{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ea-date-picker__trigger-value--placeholder{color:var(--color-text-tertiary)}.ea-date-picker__clear{position:absolute;top:50%;right:var(--space-2);z-index:1;display:flex;align-items:center;justify-content:center;flex-shrink:0;width:1.25rem;height:1.25rem;padding:0;border:none;border-radius:var(--radius-sm);background:none;color:var(--color-text-secondary);font-size:1rem;line-height:1;cursor:pointer;transition:var(--transition-colors);transform:translateY(-50%)}.ea-date-picker__clear:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-date-picker__clear:hover{background-color:var(--color-bg-muted);color:var(--color-text-primary)}.ea-date-picker__popover{display:flex;flex-direction:column;gap:var(--space-2);min-width:17.5rem;padding:var(--space-3);border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-md);box-shadow:var(--shadow-lg);background-color:var(--color-bg-base)}.ea-date-picker__header{display:flex;align-items:center;gap:var(--space-1)}.ea-date-picker__nav-btn{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:1.75rem;height:1.75rem;padding:0;border:none;border-radius:var(--radius-sm);background:none;color:var(--color-text-secondary);cursor:pointer;transition:var(--transition-colors)}.ea-date-picker__nav-btn:hover{background-color:var(--color-bg-muted);color:var(--color-text-primary)}.ea-date-picker__nav-btn:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-date-picker__nav-btn ea-icon-chevron-left,.ea-date-picker__nav-btn ea-icon-chevron-right{width:.875em;height:.875em}.ea-date-picker__nav-btn ea-icon-chevron-left+ea-icon-chevron-left,.ea-date-picker__nav-btn ea-icon-chevron-right+ea-icon-chevron-right{margin-left:-.375em}.ea-date-picker__month-label{flex:1;font-size:var(--font-size-sm);font-weight:var(--font-weight-medium);text-align:center;color:var(--color-text-primary)}.ea-date-picker__grid{display:flex;flex-direction:column;gap:var(--space-1)}.ea-date-picker__weekday-row,.ea-date-picker__week{display:grid;grid-template-columns:repeat(7,1fr);gap:var(--space-1)}.ea-date-picker__weekday{display:flex;align-items:center;justify-content:center;height:1.5rem;font-size:var(--font-size-xs);font-weight:var(--font-weight-medium);text-transform:uppercase;color:var(--color-text-tertiary)}.ea-date-picker__day{display:flex;align-items:center;justify-content:center;width:2rem;height:2rem;padding:0;border:none;border-radius:var(--radius-sm);background:none;font-family:var(--font-family-sans);font-size:var(--font-size-sm);color:var(--color-text-primary);cursor:pointer;transition:var(--transition-colors)}.ea-date-picker__day:hover:not(:disabled){background-color:var(--color-bg-muted)}.ea-date-picker__day:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-date-picker__day--outside{color:var(--color-text-tertiary)}.ea-date-picker__day--today{font-weight:var(--font-weight-semibold);color:var(--color-brand-default)}.ea-date-picker__day--focused:not(.ea-date-picker__day--selected){background-color:var(--color-bg-muted)}.ea-date-picker__day--selected{background-color:var(--color-brand-default);color:var(--color-text-inverse);font-weight:var(--font-weight-medium)}.ea-date-picker__day--selected:hover{background-color:var(--color-brand-hover)}.ea-date-picker__day--disabled{color:var(--color-text-disabled);cursor:not-allowed}.ea-date-picker__day--disabled:hover{background-color:transparent}.ea-date-picker__footer{display:flex;justify-content:flex-end;padding-top:var(--space-2);border-top:var(--border-width-thin) solid var(--color-border-default)}.ea-date-picker__today-btn{padding:var(--space-1) var(--space-2);border:none;border-radius:var(--radius-sm);background:none;font-family:var(--font-family-sans);font-size:var(--font-size-sm);font-weight:var(--font-weight-medium);color:var(--color-brand-default);cursor:pointer;transition:var(--transition-colors)}.ea-date-picker__today-btn:hover{background-color:var(--color-brand-subtle)}.ea-date-picker__today-btn:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}\n"] }]
|
|
5089
|
+
}], propDecorators: { triggerEl: [{ 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 }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", 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 }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], errorMsg: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMsg", required: false }] }], minDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "minDate", required: false }] }], maxDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxDate", required: false }] }], format: [{ type: i0.Input, args: [{ isSignal: true, alias: "format", required: false }] }], weekStartsOn: [{ type: i0.Input, args: [{ isSignal: true, alias: "weekStartsOn", required: false }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", 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"] }] } });
|
|
4650
5090
|
|
|
4651
5091
|
/**
|
|
4652
5092
|
* Modal dialog backed by the native `<dialog>` element. Uses `showModal()`
|
|
@@ -4806,12 +5246,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImpo
|
|
|
4806
5246
|
* Single-select dropdown with a custom popup list. Supports keyboard
|
|
4807
5247
|
* navigation (arrow keys, Enter/Space to select, Escape to close), closes
|
|
4808
5248
|
* on outside click or viewport scroll/resize, and integrates with Angular
|
|
4809
|
-
* forms via `ControlValueAccessor`.
|
|
5249
|
+
* forms via `ControlValueAccessor`. Positioning, dismissal, and SSR-safe
|
|
5250
|
+
* scroll handling are provided by `<ea-popover>`.
|
|
4810
5251
|
*/
|
|
4811
5252
|
class DropdownComponent {
|
|
4812
5253
|
elRef = viewChild('triggerEl', ...(ngDevMode ? [{ debugName: "elRef" }] : /* istanbul ignore next */ []));
|
|
4813
|
-
menuEl = viewChild('menuEl', ...(ngDevMode ? [{ debugName: "menuEl" }] : /* istanbul ignore next */ []));
|
|
4814
|
-
destroyRef = inject(DestroyRef);
|
|
4815
5254
|
i18n = inject(EagamiI18nService);
|
|
4816
5255
|
// Inputs
|
|
4817
5256
|
label = input(undefined, ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
@@ -4853,36 +5292,6 @@ class DropdownComponent {
|
|
|
4853
5292
|
'ea-dropdown__trigger--open': this.isOpen(),
|
|
4854
5293
|
'ea-dropdown__trigger--disabled': this.isDisabled(),
|
|
4855
5294
|
}), ...(ngDevMode ? [{ debugName: "triggerClasses" }] : /* istanbul ignore next */ []));
|
|
4856
|
-
constructor() {
|
|
4857
|
-
effect(() => {
|
|
4858
|
-
const menu = this.menuEl()?.nativeElement;
|
|
4859
|
-
const trigger = this.elRef()?.nativeElement;
|
|
4860
|
-
if (!menu || !trigger || !this.isOpen())
|
|
4861
|
-
return;
|
|
4862
|
-
const rect = trigger.getBoundingClientRect();
|
|
4863
|
-
menu.style.top = `${rect.bottom + 4}px`;
|
|
4864
|
-
menu.style.left = `${rect.left}px`;
|
|
4865
|
-
menu.style.minWidth = `${rect.width}px`;
|
|
4866
|
-
});
|
|
4867
|
-
// Guard `window` for SSR: the website prerenders 42 routes, and the
|
|
4868
|
-
// dropdown can appear inside any of them. Without this, prerendering
|
|
4869
|
-
// throws `ReferenceError: window is not defined`.
|
|
4870
|
-
if (typeof window !== 'undefined') {
|
|
4871
|
-
const closeOnViewportChange = () => {
|
|
4872
|
-
if (this.isOpen())
|
|
4873
|
-
this.close();
|
|
4874
|
-
};
|
|
4875
|
-
window.addEventListener('scroll', closeOnViewportChange, {
|
|
4876
|
-
capture: true,
|
|
4877
|
-
passive: true,
|
|
4878
|
-
});
|
|
4879
|
-
window.addEventListener('resize', closeOnViewportChange);
|
|
4880
|
-
this.destroyRef.onDestroy(() => {
|
|
4881
|
-
window.removeEventListener('scroll', closeOnViewportChange, { capture: true });
|
|
4882
|
-
window.removeEventListener('resize', closeOnViewportChange);
|
|
4883
|
-
});
|
|
4884
|
-
}
|
|
4885
|
-
}
|
|
4886
5295
|
// ControlValueAccessor
|
|
4887
5296
|
writeValue(val) {
|
|
4888
5297
|
this.value.set(val ?? '');
|
|
@@ -4926,6 +5335,11 @@ class DropdownComponent {
|
|
|
4926
5335
|
focus() {
|
|
4927
5336
|
this.elRef()?.nativeElement.focus();
|
|
4928
5337
|
}
|
|
5338
|
+
/** Called by `<ea-popover>` when the user clicks outside the dropdown. */
|
|
5339
|
+
onPopoverCloseRequested() {
|
|
5340
|
+
this.close();
|
|
5341
|
+
this.onTouched();
|
|
5342
|
+
}
|
|
4929
5343
|
handleKeydown(event) {
|
|
4930
5344
|
if (this.isDisabled() || this.readonly())
|
|
4931
5345
|
return;
|
|
@@ -4978,38 +5392,30 @@ class DropdownComponent {
|
|
|
4978
5392
|
this.focusedIndex.set(idx);
|
|
4979
5393
|
}
|
|
4980
5394
|
}
|
|
4981
|
-
onDocumentClick(event) {
|
|
4982
|
-
if (!this.isOpen())
|
|
4983
|
-
return;
|
|
4984
|
-
const el = event.target;
|
|
4985
|
-
const host = this.elRef()?.nativeElement.closest('ea-dropdown');
|
|
4986
|
-
if (host && !host.contains(el)) {
|
|
4987
|
-
this.close();
|
|
4988
|
-
this.onTouched();
|
|
4989
|
-
}
|
|
4990
|
-
}
|
|
4991
5395
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: DropdownComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
4992
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.13", type: DropdownComponent, isStandalone: true, selector: "ea-dropdown", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, errorMsg: { classPropertyName: "errorMsg", publicName: "errorMsg", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", changed: "changed" },
|
|
5396
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.13", type: DropdownComponent, isStandalone: true, selector: "ea-dropdown", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, errorMsg: { classPropertyName: "errorMsg", publicName: "errorMsg", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", changed: "changed" }, providers: [
|
|
4993
5397
|
{
|
|
4994
5398
|
provide: NG_VALUE_ACCESSOR,
|
|
4995
5399
|
useExisting: forwardRef(() => DropdownComponent),
|
|
4996
5400
|
multi: true,
|
|
4997
5401
|
},
|
|
4998
|
-
], viewQueries: [{ propertyName: "elRef", first: true, predicate: ["triggerEl"], descendants: true, isSignal: true }
|
|
5402
|
+
], 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 [id]=\"id() + '-label'\"\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-controls]=\"isOpen() ? id() + '-listbox' : null\"\n [attr.aria-activedescendant]=\"\n isOpen() && focusedIndex() >= 0 ? id() + '-option-' + focusedIndex() : null\n \"\n [attr.aria-labelledby]=\"label() ? id() + '-label' : null\"\n [attr.aria-required]=\"required() || null\"\n [attr.aria-invalid]=\"hasError() || null\"\n [attr.aria-describedby]=\"\n showError() ? id() + '-error' : showHint() ? id() + '-hint' : null\n \"\n (click)=\"toggle()\"\n (keydown)=\"handleKeydown($event)\">\n <span\n class=\"ea-dropdown__value\"\n [class.ea-dropdown__value--placeholder]=\"!selectedLabel()\">\n {{ selectedLabel() || resolvedPlaceholder() }}\n </span>\n <ea-icon-chevron-down\n class=\"ea-dropdown__chevron\"\n [class.ea-dropdown__chevron--open]=\"isOpen()\" />\n </button>\n\n <ea-popover\n [anchor]=\"triggerEl\"\n [open]=\"isOpen()\"\n placement=\"bottom-start\"\n role=\"listbox\"\n [surfaceId]=\"id() + '-listbox'\"\n [matchAnchorWidth]=\"true\"\n [closeOnEscape]=\"false\"\n scrollBehavior=\"close\"\n (closeRequested)=\"onPopoverCloseRequested()\">\n <div class=\"ea-dropdown__menu\">\n @for (option of options(); track option.value; let i = $index) {\n <div\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 </div>\n }\n </div>\n </ea-popover>\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 <ea-icon-alert-circle class=\"ea-dropdown-field__message-icon\" />\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-field__message-icon{flex-shrink:0;width:.875em;height:.875em}.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{max-height:15rem;padding:var(--space-1) 0;overflow-y:auto;border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-md);box-shadow:var(--shadow-lg);background-color:var(--color-bg-base)}.ea-dropdown__option{padding:var(--space-2) var(--space-3);font-size:var(--font-size-sm);white-space:nowrap;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: "component", type: AlertCircleIconComponent, selector: "ea-icon-alert-circle" }, { kind: "component", type: ChevronDownIconComponent, selector: "ea-icon-chevron-down" }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: PopoverComponent, selector: "ea-popover", inputs: ["anchor", "open", "placement", "role", "aria-label", "surfaceId", "offset", "flip", "clamp", "matchAnchorWidth", "closeOnOutsideClick", "closeOnEscape", "scrollBehavior"], outputs: ["closeRequested"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
4999
5403
|
}
|
|
5000
5404
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: DropdownComponent, decorators: [{
|
|
5001
5405
|
type: Component,
|
|
5002
|
-
args: [{ selector: 'ea-dropdown', imports: [
|
|
5406
|
+
args: [{ selector: 'ea-dropdown', imports: [
|
|
5407
|
+
AlertCircleIconComponent,
|
|
5408
|
+
ChevronDownIconComponent,
|
|
5409
|
+
NgClass,
|
|
5410
|
+
PopoverComponent,
|
|
5411
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
5003
5412
|
{
|
|
5004
5413
|
provide: NG_VALUE_ACCESSOR,
|
|
5005
5414
|
useExisting: forwardRef(() => DropdownComponent),
|
|
5006
5415
|
multi: true,
|
|
5007
5416
|
},
|
|
5008
|
-
], template: "<div class=\"ea-dropdown-field\">\n @if (label()) {\n <label\n class=\"ea-dropdown-field__label\"\n [for]=\"id()\"\n [id]=\"id() + '-label'\"\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-controls]=\"isOpen() ? id() + '-listbox' : null\"\n [attr.aria-activedescendant]=\"\n isOpen() && focusedIndex() >= 0 ? id() + '-option-' + focusedIndex() : null\n \"\n [attr.aria-labelledby]=\"label() ? id() + '-label' : null\"\n [attr.aria-required]=\"required() || null\"\n [attr.aria-invalid]=\"hasError() || null\"\n [attr.aria-describedby]=\"\n showError() ? id() + '-error' : showHint() ? id() + '-hint' : null\n \"\n (click)=\"toggle()\"\n (keydown)=\"handleKeydown($event)\">\n <span\n class=\"ea-dropdown__value\"\n [class.ea-dropdown__value--placeholder]=\"!selectedLabel()\">\n {{ selectedLabel() || resolvedPlaceholder() }}\n </span>\n <ea-icon-chevron-down\n class=\"ea-dropdown__chevron\"\n [class.ea-dropdown__chevron--open]=\"isOpen()\" />\n </button>\n\n
|
|
5009
|
-
}],
|
|
5010
|
-
type: HostListener,
|
|
5011
|
-
args: ['document:click', ['$event']]
|
|
5012
|
-
}] } });
|
|
5417
|
+
], template: "<div class=\"ea-dropdown-field\">\n @if (label()) {\n <label\n class=\"ea-dropdown-field__label\"\n [for]=\"id()\"\n [id]=\"id() + '-label'\"\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-controls]=\"isOpen() ? id() + '-listbox' : null\"\n [attr.aria-activedescendant]=\"\n isOpen() && focusedIndex() >= 0 ? id() + '-option-' + focusedIndex() : null\n \"\n [attr.aria-labelledby]=\"label() ? id() + '-label' : null\"\n [attr.aria-required]=\"required() || null\"\n [attr.aria-invalid]=\"hasError() || null\"\n [attr.aria-describedby]=\"\n showError() ? id() + '-error' : showHint() ? id() + '-hint' : null\n \"\n (click)=\"toggle()\"\n (keydown)=\"handleKeydown($event)\">\n <span\n class=\"ea-dropdown__value\"\n [class.ea-dropdown__value--placeholder]=\"!selectedLabel()\">\n {{ selectedLabel() || resolvedPlaceholder() }}\n </span>\n <ea-icon-chevron-down\n class=\"ea-dropdown__chevron\"\n [class.ea-dropdown__chevron--open]=\"isOpen()\" />\n </button>\n\n <ea-popover\n [anchor]=\"triggerEl\"\n [open]=\"isOpen()\"\n placement=\"bottom-start\"\n role=\"listbox\"\n [surfaceId]=\"id() + '-listbox'\"\n [matchAnchorWidth]=\"true\"\n [closeOnEscape]=\"false\"\n scrollBehavior=\"close\"\n (closeRequested)=\"onPopoverCloseRequested()\">\n <div class=\"ea-dropdown__menu\">\n @for (option of options(); track option.value; let i = $index) {\n <div\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 </div>\n }\n </div>\n </ea-popover>\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 <ea-icon-alert-circle class=\"ea-dropdown-field__message-icon\" />\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-field__message-icon{flex-shrink:0;width:.875em;height:.875em}.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{max-height:15rem;padding:var(--space-1) 0;overflow-y:auto;border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-md);box-shadow:var(--shadow-lg);background-color:var(--color-bg-base)}.ea-dropdown__option{padding:var(--space-2) var(--space-3);font-size:var(--font-size-sm);white-space:nowrap;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"] }]
|
|
5418
|
+
}], 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 }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", 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: "errorMsg", 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"] }] } });
|
|
5013
5419
|
|
|
5014
5420
|
class EagamiIconComponent extends IconComponentBase {
|
|
5015
5421
|
static slug = 'eagami';
|
|
@@ -15477,6 +15883,69 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImpo
|
|
|
15477
15883
|
}]
|
|
15478
15884
|
}] });
|
|
15479
15885
|
|
|
15886
|
+
class LeftHalfStarIconComponent extends IconComponentBase {
|
|
15887
|
+
static slug = 'left-half-star';
|
|
15888
|
+
static category = 'eagami';
|
|
15889
|
+
static tags = [
|
|
15890
|
+
'left-half-star',
|
|
15891
|
+
'half-star',
|
|
15892
|
+
'half',
|
|
15893
|
+
'left',
|
|
15894
|
+
'partial',
|
|
15895
|
+
'rating',
|
|
15896
|
+
'star',
|
|
15897
|
+
'shape',
|
|
15898
|
+
'demi-étoile',
|
|
15899
|
+
'demi',
|
|
15900
|
+
'gauche',
|
|
15901
|
+
'media-estrella',
|
|
15902
|
+
'media',
|
|
15903
|
+
'izquierda',
|
|
15904
|
+
'μισό-αστέρι',
|
|
15905
|
+
'μισό',
|
|
15906
|
+
'αριστερά',
|
|
15907
|
+
'pół-gwiazdy',
|
|
15908
|
+
'pół',
|
|
15909
|
+
'lewa',
|
|
15910
|
+
];
|
|
15911
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: LeftHalfStarIconComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
15912
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.13", type: LeftHalfStarIconComponent, isStandalone: true, selector: "ea-icon-left-half-star", usesInheritance: true, ngImport: i0, template: `
|
|
15913
|
+
<svg
|
|
15914
|
+
viewBox="0 0 24 24"
|
|
15915
|
+
fill="none"
|
|
15916
|
+
stroke="currentColor"
|
|
15917
|
+
stroke-width="2"
|
|
15918
|
+
stroke-linecap="round"
|
|
15919
|
+
stroke-linejoin="round"
|
|
15920
|
+
aria-hidden="true"
|
|
15921
|
+
width="100%"
|
|
15922
|
+
height="100%">
|
|
15923
|
+
<path d="M12 2 L8.91 8.26 L2 9.27 L7 14.14 L5.82 21.02 L12 17.77 Z" />
|
|
15924
|
+
</svg>
|
|
15925
|
+
`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
15926
|
+
}
|
|
15927
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: LeftHalfStarIconComponent, decorators: [{
|
|
15928
|
+
type: Component,
|
|
15929
|
+
args: [{
|
|
15930
|
+
selector: 'ea-icon-left-half-star',
|
|
15931
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
15932
|
+
template: `
|
|
15933
|
+
<svg
|
|
15934
|
+
viewBox="0 0 24 24"
|
|
15935
|
+
fill="none"
|
|
15936
|
+
stroke="currentColor"
|
|
15937
|
+
stroke-width="2"
|
|
15938
|
+
stroke-linecap="round"
|
|
15939
|
+
stroke-linejoin="round"
|
|
15940
|
+
aria-hidden="true"
|
|
15941
|
+
width="100%"
|
|
15942
|
+
height="100%">
|
|
15943
|
+
<path d="M12 2 L8.91 8.26 L2 9.27 L7 14.14 L5.82 21.02 L12 17.77 Z" />
|
|
15944
|
+
</svg>
|
|
15945
|
+
`,
|
|
15946
|
+
}]
|
|
15947
|
+
}] });
|
|
15948
|
+
|
|
15480
15949
|
class LifeBuoyIconComponent extends IconComponentBase {
|
|
15481
15950
|
static slug = 'life-buoy';
|
|
15482
15951
|
static category = 'feather';
|
|
@@ -20402,6 +20871,69 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImpo
|
|
|
20402
20871
|
}]
|
|
20403
20872
|
}] });
|
|
20404
20873
|
|
|
20874
|
+
class RightHalfStarIconComponent extends IconComponentBase {
|
|
20875
|
+
static slug = 'right-half-star';
|
|
20876
|
+
static category = 'eagami';
|
|
20877
|
+
static tags = [
|
|
20878
|
+
'right-half-star',
|
|
20879
|
+
'half-star',
|
|
20880
|
+
'half',
|
|
20881
|
+
'right',
|
|
20882
|
+
'partial',
|
|
20883
|
+
'rating',
|
|
20884
|
+
'star',
|
|
20885
|
+
'shape',
|
|
20886
|
+
'demi-étoile',
|
|
20887
|
+
'demi',
|
|
20888
|
+
'droite',
|
|
20889
|
+
'media-estrella',
|
|
20890
|
+
'media',
|
|
20891
|
+
'derecha',
|
|
20892
|
+
'μισό-αστέρι',
|
|
20893
|
+
'μισό',
|
|
20894
|
+
'δεξιά',
|
|
20895
|
+
'pół-gwiazdy',
|
|
20896
|
+
'pół',
|
|
20897
|
+
'prawa',
|
|
20898
|
+
];
|
|
20899
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: RightHalfStarIconComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
20900
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.13", type: RightHalfStarIconComponent, isStandalone: true, selector: "ea-icon-right-half-star", usesInheritance: true, ngImport: i0, template: `
|
|
20901
|
+
<svg
|
|
20902
|
+
viewBox="0 0 24 24"
|
|
20903
|
+
fill="none"
|
|
20904
|
+
stroke="currentColor"
|
|
20905
|
+
stroke-width="2"
|
|
20906
|
+
stroke-linecap="round"
|
|
20907
|
+
stroke-linejoin="round"
|
|
20908
|
+
aria-hidden="true"
|
|
20909
|
+
width="100%"
|
|
20910
|
+
height="100%">
|
|
20911
|
+
<path d="M12 2 L15.09 8.26 L22 9.27 L17 14.14 L18.18 21.02 L12 17.77 Z" />
|
|
20912
|
+
</svg>
|
|
20913
|
+
`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
20914
|
+
}
|
|
20915
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: RightHalfStarIconComponent, decorators: [{
|
|
20916
|
+
type: Component,
|
|
20917
|
+
args: [{
|
|
20918
|
+
selector: 'ea-icon-right-half-star',
|
|
20919
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
20920
|
+
template: `
|
|
20921
|
+
<svg
|
|
20922
|
+
viewBox="0 0 24 24"
|
|
20923
|
+
fill="none"
|
|
20924
|
+
stroke="currentColor"
|
|
20925
|
+
stroke-width="2"
|
|
20926
|
+
stroke-linecap="round"
|
|
20927
|
+
stroke-linejoin="round"
|
|
20928
|
+
aria-hidden="true"
|
|
20929
|
+
width="100%"
|
|
20930
|
+
height="100%">
|
|
20931
|
+
<path d="M12 2 L15.09 8.26 L22 9.27 L17 14.14 L18.18 21.02 L12 17.77 Z" />
|
|
20932
|
+
</svg>
|
|
20933
|
+
`,
|
|
20934
|
+
}]
|
|
20935
|
+
}] });
|
|
20936
|
+
|
|
20405
20937
|
class RotateCwIconComponent extends IconComponentBase {
|
|
20406
20938
|
static slug = 'rotate-cw';
|
|
20407
20939
|
static category = 'feather';
|
|
@@ -26781,9 +27313,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImpo
|
|
|
26781
27313
|
* the full set. For single-icon usage import the component directly (e.g.
|
|
26782
27314
|
* `import { HomeIconComponent } from '@eagami/ui'`) and the bundler will
|
|
26783
27315
|
* tree-shake `ICONS` away.
|
|
26784
|
-
*
|
|
26785
|
-
* Deprecated aliases (e.g. `PencilIconComponent`) are intentionally excluded
|
|
26786
|
-
* so they don't surface in generated catalogues.
|
|
26787
27316
|
*/
|
|
26788
27317
|
const ICONS = [
|
|
26789
27318
|
ActivityIconComponent,
|
|
@@ -26942,6 +27471,7 @@ const ICONS = [
|
|
|
26942
27471
|
LampIconComponent,
|
|
26943
27472
|
LayersIconComponent,
|
|
26944
27473
|
LayoutIconComponent,
|
|
27474
|
+
LeftHalfStarIconComponent,
|
|
26945
27475
|
LifeBuoyIconComponent,
|
|
26946
27476
|
Link2IconComponent,
|
|
26947
27477
|
LinkIconComponent,
|
|
@@ -27016,6 +27546,7 @@ const ICONS = [
|
|
|
27016
27546
|
RefreshCwIconComponent,
|
|
27017
27547
|
RepeatIconComponent,
|
|
27018
27548
|
RewindIconComponent,
|
|
27549
|
+
RightHalfStarIconComponent,
|
|
27019
27550
|
RotateCcwIconComponent,
|
|
27020
27551
|
RotateCwIconComponent,
|
|
27021
27552
|
RssIconComponent,
|
|
@@ -27111,110 +27642,6 @@ const ICONS = [
|
|
|
27111
27642
|
ZoomOutIconComponent,
|
|
27112
27643
|
].sort((a, b) => a.slug.localeCompare(b.slug));
|
|
27113
27644
|
|
|
27114
|
-
/**
|
|
27115
|
-
* @deprecated Will be removed in v2.0.0. The icon depicts Apple Inc.'s logo,
|
|
27116
|
-
* which is more strictly protected than other brand marks. Source the asset
|
|
27117
|
-
* directly from Apple per their brand guidelines for use cases like "Sign in
|
|
27118
|
-
* with Apple".
|
|
27119
|
-
*/
|
|
27120
|
-
class AppleIconComponent extends IconComponentBase {
|
|
27121
|
-
brand = input(false, ...(ngDevMode ? [{ debugName: "brand" }] : /* istanbul ignore next */ []));
|
|
27122
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: AppleIconComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
27123
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.13", type: AppleIconComponent, isStandalone: true, selector: "ea-icon-apple", inputs: { brand: { classPropertyName: "brand", publicName: "brand", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "style.color": "brand() ? '#000000' : null" } }, usesInheritance: true, ngImport: i0, template: `
|
|
27124
|
-
<svg
|
|
27125
|
-
viewBox="0 0 24 24"
|
|
27126
|
-
fill="currentColor"
|
|
27127
|
-
aria-hidden="true"
|
|
27128
|
-
width="100%"
|
|
27129
|
-
height="100%">
|
|
27130
|
-
<path
|
|
27131
|
-
d="M17.05 20.28c-.98.95-2.05.88-3.08.4-1.09-.5-2.08-.48-3.24 0-1.44.62-2.2.44-3.06-.4C2.79 15.25 3.51 7.59 9.05 7.31c1.35.07 2.29.74 3.08.8 1.18-.24 2.31-.93 3.57-.84 1.51.12 2.65.72 3.4 1.8-3.12 1.87-2.38 5.98.48 7.13-.57 1.5-1.31 2.99-2.54 4.09ZM12.03 7.25c-.15-2.23 1.66-4.07 3.74-4.25.32 2.32-1.55 4.3-3.74 4.25Z" />
|
|
27132
|
-
</svg>
|
|
27133
|
-
`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
27134
|
-
}
|
|
27135
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: AppleIconComponent, decorators: [{
|
|
27136
|
-
type: Component,
|
|
27137
|
-
args: [{
|
|
27138
|
-
selector: 'ea-icon-apple',
|
|
27139
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
27140
|
-
host: { '[style.color]': "brand() ? '#000000' : null" },
|
|
27141
|
-
template: `
|
|
27142
|
-
<svg
|
|
27143
|
-
viewBox="0 0 24 24"
|
|
27144
|
-
fill="currentColor"
|
|
27145
|
-
aria-hidden="true"
|
|
27146
|
-
width="100%"
|
|
27147
|
-
height="100%">
|
|
27148
|
-
<path
|
|
27149
|
-
d="M17.05 20.28c-.98.95-2.05.88-3.08.4-1.09-.5-2.08-.48-3.24 0-1.44.62-2.2.44-3.06-.4C2.79 15.25 3.51 7.59 9.05 7.31c1.35.07 2.29.74 3.08.8 1.18-.24 2.31-.93 3.57-.84 1.51.12 2.65.72 3.4 1.8-3.12 1.87-2.38 5.98.48 7.13-.57 1.5-1.31 2.99-2.54 4.09ZM12.03 7.25c-.15-2.23 1.66-4.07 3.74-4.25.32 2.32-1.55 4.3-3.74 4.25Z" />
|
|
27150
|
-
</svg>
|
|
27151
|
-
`,
|
|
27152
|
-
}]
|
|
27153
|
-
}], propDecorators: { brand: [{ type: i0.Input, args: [{ isSignal: true, alias: "brand", required: false }] }] } });
|
|
27154
|
-
|
|
27155
|
-
/**
|
|
27156
|
-
* @deprecated Will be removed in v2.0.0. The `pencil` icon depicts the same
|
|
27157
|
-
* mark as Feather's canonical `edit-2` (with a marginally different cap
|
|
27158
|
-
* curvature) and is being retired as redundant. Switch to `<ea-icon-edit-2>`
|
|
27159
|
-
* / `Edit2IconComponent`.
|
|
27160
|
-
*/
|
|
27161
|
-
class PencilIconComponent extends IconComponentBase {
|
|
27162
|
-
static slug = 'pencil';
|
|
27163
|
-
static category = 'feather';
|
|
27164
|
-
static tags = [
|
|
27165
|
-
'edit-2',
|
|
27166
|
-
'edit',
|
|
27167
|
-
'2',
|
|
27168
|
-
'pencil',
|
|
27169
|
-
'modify',
|
|
27170
|
-
'write',
|
|
27171
|
-
'éditer',
|
|
27172
|
-
'crayon',
|
|
27173
|
-
'editar',
|
|
27174
|
-
'lápiz',
|
|
27175
|
-
'επεξεργασία',
|
|
27176
|
-
'μολύβι',
|
|
27177
|
-
'edytuj',
|
|
27178
|
-
'ołówek',
|
|
27179
|
-
];
|
|
27180
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: PencilIconComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
27181
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.13", type: PencilIconComponent, isStandalone: true, selector: "ea-icon-pencil", usesInheritance: true, ngImport: i0, template: `
|
|
27182
|
-
<svg
|
|
27183
|
-
viewBox="0 0 24 24"
|
|
27184
|
-
fill="none"
|
|
27185
|
-
stroke="currentColor"
|
|
27186
|
-
stroke-width="2"
|
|
27187
|
-
stroke-linecap="round"
|
|
27188
|
-
stroke-linejoin="round"
|
|
27189
|
-
aria-hidden="true"
|
|
27190
|
-
width="100%"
|
|
27191
|
-
height="100%">
|
|
27192
|
-
<path d="M17 3a2.83 2.83 0 0 1 4 4L7.5 20.5 2 22l1.5-5.5Z" />
|
|
27193
|
-
</svg>
|
|
27194
|
-
`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
27195
|
-
}
|
|
27196
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: PencilIconComponent, decorators: [{
|
|
27197
|
-
type: Component,
|
|
27198
|
-
args: [{
|
|
27199
|
-
selector: 'ea-icon-pencil',
|
|
27200
|
-
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
27201
|
-
template: `
|
|
27202
|
-
<svg
|
|
27203
|
-
viewBox="0 0 24 24"
|
|
27204
|
-
fill="none"
|
|
27205
|
-
stroke="currentColor"
|
|
27206
|
-
stroke-width="2"
|
|
27207
|
-
stroke-linecap="round"
|
|
27208
|
-
stroke-linejoin="round"
|
|
27209
|
-
aria-hidden="true"
|
|
27210
|
-
width="100%"
|
|
27211
|
-
height="100%">
|
|
27212
|
-
<path d="M17 3a2.83 2.83 0 0 1 4 4L7.5 20.5 2 22l1.5-5.5Z" />
|
|
27213
|
-
</svg>
|
|
27214
|
-
`,
|
|
27215
|
-
}]
|
|
27216
|
-
}] });
|
|
27217
|
-
|
|
27218
27645
|
/**
|
|
27219
27646
|
* Single-line text field with label, hint, and error message support.
|
|
27220
27647
|
* Includes a built-in show/hide toggle for `password` inputs and integrates
|
|
@@ -27335,7 +27762,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImpo
|
|
|
27335
27762
|
* Popup action menu attached to any focusable element via the
|
|
27336
27763
|
* `[eaMenuTrigger]` directive. Supports keyboard navigation
|
|
27337
27764
|
* (arrow keys, Home/End), closes on outside click or Escape, and restores
|
|
27338
|
-
* focus to the trigger on close.
|
|
27765
|
+
* focus to the trigger on close. Positioning, dismissal, and SSR-safe scroll
|
|
27766
|
+
* handling are provided by `<ea-popover>`.
|
|
27339
27767
|
*/
|
|
27340
27768
|
class MenuComponent {
|
|
27341
27769
|
injector = inject(Injector);
|
|
@@ -27352,32 +27780,8 @@ class MenuComponent {
|
|
|
27352
27780
|
opened = output();
|
|
27353
27781
|
/** Fires when the menu closes. */
|
|
27354
27782
|
closed = output();
|
|
27355
|
-
|
|
27356
|
-
|
|
27357
|
-
listClasses = computed(() => ({
|
|
27358
|
-
[`ea-menu__list--${this.placement()}`]: true,
|
|
27359
|
-
}), ...(ngDevMode ? [{ debugName: "listClasses" }] : /* istanbul ignore next */ []));
|
|
27360
|
-
listStyle = computed(() => {
|
|
27361
|
-
const rect = this.triggerRect();
|
|
27362
|
-
if (!rect)
|
|
27363
|
-
return {};
|
|
27364
|
-
const placement = this.placement();
|
|
27365
|
-
const gap = 4;
|
|
27366
|
-
const style = {};
|
|
27367
|
-
if (placement === 'bottom-start' || placement === 'bottom-end') {
|
|
27368
|
-
style['top'] = `${rect.bottom + gap}px`;
|
|
27369
|
-
}
|
|
27370
|
-
else {
|
|
27371
|
-
style['bottom'] = `${window.innerHeight - rect.top + gap}px`;
|
|
27372
|
-
}
|
|
27373
|
-
if (placement === 'bottom-start' || placement === 'top-start') {
|
|
27374
|
-
style['left'] = `${rect.left}px`;
|
|
27375
|
-
}
|
|
27376
|
-
else {
|
|
27377
|
-
style['right'] = `${window.innerWidth - rect.right}px`;
|
|
27378
|
-
}
|
|
27379
|
-
return style;
|
|
27380
|
-
}, ...(ngDevMode ? [{ debugName: "listStyle" }] : /* istanbul ignore next */ []));
|
|
27783
|
+
/** Trigger element currently anchoring the menu. Signal-typed so `<ea-popover>` reacts when it changes. */
|
|
27784
|
+
triggerEl = signal(undefined, ...(ngDevMode ? [{ debugName: "triggerEl" }] : /* istanbul ignore next */ []));
|
|
27381
27785
|
/** Toggles the menu open state, anchoring it to the given trigger element. */
|
|
27382
27786
|
toggleAt(triggerEl) {
|
|
27383
27787
|
if (this.disabled())
|
|
@@ -27393,8 +27797,7 @@ class MenuComponent {
|
|
|
27393
27797
|
openAt(triggerEl) {
|
|
27394
27798
|
if (this.disabled())
|
|
27395
27799
|
return;
|
|
27396
|
-
this.triggerEl
|
|
27397
|
-
this.triggerRect.set(triggerEl.getBoundingClientRect());
|
|
27800
|
+
this.triggerEl.set(triggerEl);
|
|
27398
27801
|
this.open.set(true);
|
|
27399
27802
|
this.opened.emit();
|
|
27400
27803
|
afterNextRender(() => this.focusFirstItem(), { injector: this.injector });
|
|
@@ -27410,7 +27813,11 @@ class MenuComponent {
|
|
|
27410
27813
|
this.open.set(false);
|
|
27411
27814
|
this.closed.emit();
|
|
27412
27815
|
if (restoreFocus)
|
|
27413
|
-
this.triggerEl?.focus({ preventScroll: true });
|
|
27816
|
+
this.triggerEl()?.focus({ preventScroll: true });
|
|
27817
|
+
}
|
|
27818
|
+
/** Called by `<ea-popover>` when the user clicks outside the menu. */
|
|
27819
|
+
onPopoverCloseRequested() {
|
|
27820
|
+
this.close();
|
|
27414
27821
|
}
|
|
27415
27822
|
getEnabledItems() {
|
|
27416
27823
|
const list = this.listEl()?.nativeElement;
|
|
@@ -27464,47 +27871,23 @@ class MenuComponent {
|
|
|
27464
27871
|
if (next >= 0)
|
|
27465
27872
|
items[next].focus({ preventScroll: true });
|
|
27466
27873
|
}
|
|
27467
|
-
onDocumentClick(event) {
|
|
27468
|
-
if (!this.open())
|
|
27469
|
-
return;
|
|
27470
|
-
const target = event.target;
|
|
27471
|
-
if (this.triggerEl?.contains(target))
|
|
27472
|
-
return;
|
|
27473
|
-
if (this.listEl()?.nativeElement.contains(target))
|
|
27474
|
-
return;
|
|
27475
|
-
this.close();
|
|
27476
|
-
}
|
|
27477
27874
|
onEscape() {
|
|
27478
27875
|
if (!this.open())
|
|
27479
27876
|
return;
|
|
27480
27877
|
this.close(true);
|
|
27481
27878
|
}
|
|
27482
|
-
onViewportChange() {
|
|
27483
|
-
if (!this.open() || !this.triggerEl)
|
|
27484
|
-
return;
|
|
27485
|
-
this.triggerRect.set(this.triggerEl.getBoundingClientRect());
|
|
27486
|
-
}
|
|
27487
27879
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: MenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
27488
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.
|
|
27880
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.13", type: MenuComponent, isStandalone: true, selector: "ea-menu", inputs: { placement: { classPropertyName: "placement", publicName: "placement", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { open: "openChange", opened: "opened", closed: "closed" }, host: { listeners: { "document:keydown": "onKeydown($event)", "document:keydown.escape": "onEscape()" } }, viewQueries: [{ propertyName: "listEl", first: true, predicate: ["listEl"], descendants: true, isSignal: true }], ngImport: i0, template: "<ea-popover\n [anchor]=\"triggerEl()\"\n [open]=\"open()\"\n [placement]=\"placement()\"\n role=\"menu\"\n [surfaceId]=\"id()\"\n [ariaLabel]=\"resolvedAriaLabel()\"\n [closeOnEscape]=\"false\"\n scrollBehavior=\"reposition\"\n (closeRequested)=\"onPopoverCloseRequested()\">\n <div\n #listEl\n class=\"ea-menu__list\">\n <ng-content />\n </div>\n</ea-popover>\n", styles: [":host{display:contents}.ea-menu__list{min-width:10rem;max-height:20rem;padding:var(--space-1) 0;overflow-y:auto;border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-md);box-shadow:var(--shadow-lg);background-color:var(--color-bg-base)}\n"], dependencies: [{ kind: "component", type: PopoverComponent, selector: "ea-popover", inputs: ["anchor", "open", "placement", "role", "aria-label", "surfaceId", "offset", "flip", "clamp", "matchAnchorWidth", "closeOnOutsideClick", "closeOnEscape", "scrollBehavior"], outputs: ["closeRequested"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
27489
27881
|
}
|
|
27490
27882
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: MenuComponent, decorators: [{
|
|
27491
27883
|
type: Component,
|
|
27492
|
-
args: [{ selector: 'ea-menu', imports: [
|
|
27884
|
+
args: [{ selector: 'ea-menu', imports: [PopoverComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ea-popover\n [anchor]=\"triggerEl()\"\n [open]=\"open()\"\n [placement]=\"placement()\"\n role=\"menu\"\n [surfaceId]=\"id()\"\n [ariaLabel]=\"resolvedAriaLabel()\"\n [closeOnEscape]=\"false\"\n scrollBehavior=\"reposition\"\n (closeRequested)=\"onPopoverCloseRequested()\">\n <div\n #listEl\n class=\"ea-menu__list\">\n <ng-content />\n </div>\n</ea-popover>\n", styles: [":host{display:contents}.ea-menu__list{min-width:10rem;max-height:20rem;padding:var(--space-1) 0;overflow-y:auto;border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-md);box-shadow:var(--shadow-lg);background-color:var(--color-bg-base)}\n"] }]
|
|
27493
27885
|
}], propDecorators: { listEl: [{ type: i0.ViewChild, args: ['listEl', { isSignal: true }] }], placement: [{ type: i0.Input, args: [{ isSignal: true, alias: "placement", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-label", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }, { type: i0.Output, args: ["openChange"] }], opened: [{ type: i0.Output, args: ["opened"] }], closed: [{ type: i0.Output, args: ["closed"] }], onKeydown: [{
|
|
27494
27886
|
type: HostListener,
|
|
27495
27887
|
args: ['document:keydown', ['$event']]
|
|
27496
|
-
}], onDocumentClick: [{
|
|
27497
|
-
type: HostListener,
|
|
27498
|
-
args: ['document:click', ['$event']]
|
|
27499
27888
|
}], onEscape: [{
|
|
27500
27889
|
type: HostListener,
|
|
27501
27890
|
args: ['document:keydown.escape']
|
|
27502
|
-
}], onViewportChange: [{
|
|
27503
|
-
type: HostListener,
|
|
27504
|
-
args: ['window:resize']
|
|
27505
|
-
}, {
|
|
27506
|
-
type: HostListener,
|
|
27507
|
-
args: ['window:scroll']
|
|
27508
27891
|
}] } });
|
|
27509
27892
|
|
|
27510
27893
|
/**
|
|
@@ -27583,97 +27966,440 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImpo
|
|
|
27583
27966
|
}], propDecorators: { menu: [{ type: i0.Input, args: [{ isSignal: true, alias: "eaMenuTrigger", required: true }] }] } });
|
|
27584
27967
|
|
|
27585
27968
|
/**
|
|
27586
|
-
*
|
|
27587
|
-
*
|
|
27588
|
-
*
|
|
27589
|
-
*
|
|
27969
|
+
* Inline label commonly used to represent filters, categories, or selected
|
|
27970
|
+
* items. When `removable`, renders a close button that emits `removed`; the
|
|
27971
|
+
* accessible name of that button is configurable via `removeLabel` and
|
|
27972
|
+
* otherwise falls back to the active locale's translation.
|
|
27590
27973
|
*/
|
|
27591
|
-
class
|
|
27974
|
+
class TagComponent {
|
|
27592
27975
|
i18n = inject(EagamiI18nService);
|
|
27593
|
-
|
|
27594
|
-
|
|
27595
|
-
|
|
27596
|
-
showRangeLabel = input(true, ...(ngDevMode ? [{ debugName: "showRangeLabel" }] : /* istanbul ignore next */ []));
|
|
27597
|
-
align = input('right', ...(ngDevMode ? [{ debugName: "align" }] : /* istanbul ignore next */ []));
|
|
27976
|
+
variant = input('default', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
27977
|
+
size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
27978
|
+
removable = input(false, ...(ngDevMode ? [{ debugName: "removable" }] : /* istanbul ignore next */ []));
|
|
27598
27979
|
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
27599
|
-
|
|
27600
|
-
|
|
27601
|
-
|
|
27602
|
-
|
|
27603
|
-
|
|
27604
|
-
|
|
27605
|
-
|
|
27606
|
-
|
|
27607
|
-
|
|
27608
|
-
|
|
27609
|
-
|
|
27610
|
-
|
|
27611
|
-
|
|
27612
|
-
if (total <= 7) {
|
|
27613
|
-
for (let i = 1; i <= total; i++)
|
|
27614
|
-
pages.push(i);
|
|
27615
|
-
return pages;
|
|
27616
|
-
}
|
|
27617
|
-
pages.push(1);
|
|
27618
|
-
if (current > 3) {
|
|
27619
|
-
pages.push('ellipsis');
|
|
27620
|
-
}
|
|
27621
|
-
const start = Math.max(2, current - 1);
|
|
27622
|
-
const end = Math.min(total - 1, current + 1);
|
|
27623
|
-
for (let i = start; i <= end; i++) {
|
|
27624
|
-
pages.push(i);
|
|
27625
|
-
}
|
|
27626
|
-
if (current < total - 2) {
|
|
27627
|
-
pages.push('ellipsis');
|
|
27628
|
-
}
|
|
27629
|
-
pages.push(total);
|
|
27630
|
-
return pages;
|
|
27631
|
-
}, ...(ngDevMode ? [{ debugName: "visiblePages" }] : /* istanbul ignore next */ []));
|
|
27632
|
-
/** Navigates to the given page, clamped into the valid range. */
|
|
27633
|
-
goToPage(page) {
|
|
27634
|
-
if (this.disabled())
|
|
27635
|
-
return;
|
|
27636
|
-
const clamped = Math.max(1, Math.min(page, this.totalPages()));
|
|
27637
|
-
if (clamped === this.page())
|
|
27638
|
-
return;
|
|
27639
|
-
this.page.set(clamped);
|
|
27640
|
-
this.changed.emit({ page: clamped, pageSize: this.pageSize() });
|
|
27641
|
-
}
|
|
27642
|
-
/** Navigates to the previous page if one exists. */
|
|
27643
|
-
prevPage() {
|
|
27644
|
-
if (this.canGoPrev())
|
|
27645
|
-
this.goToPage(this.page() - 1);
|
|
27646
|
-
}
|
|
27647
|
-
/** Navigates to the next page if one exists. */
|
|
27648
|
-
nextPage() {
|
|
27649
|
-
if (this.canGoNext())
|
|
27650
|
-
this.goToPage(this.page() + 1);
|
|
27651
|
-
}
|
|
27652
|
-
onPageSizeChange(event) {
|
|
27653
|
-
if (this.disabled())
|
|
27654
|
-
return;
|
|
27655
|
-
const newSize = Number(event.target.value);
|
|
27656
|
-
this.pageSize.set(newSize);
|
|
27657
|
-
this.page.set(1);
|
|
27658
|
-
this.changed.emit({ page: 1, pageSize: newSize });
|
|
27980
|
+
removeLabel = input(undefined, ...(ngDevMode ? [{ debugName: "removeLabel" }] : /* istanbul ignore next */ []));
|
|
27981
|
+
/** Fires when the user activates the remove button on a `removable` tag. */
|
|
27982
|
+
removed = output();
|
|
27983
|
+
/** Accessible label for the remove button, falling back to the active locale. */
|
|
27984
|
+
resolvedRemoveLabel = computed(() => this.removeLabel() ?? this.i18n.messages().tag.remove, ...(ngDevMode ? [{ debugName: "resolvedRemoveLabel" }] : /* istanbul ignore next */ []));
|
|
27985
|
+
hostClasses = computed(() => ({
|
|
27986
|
+
[`ea-tag--${this.variant()}`]: true,
|
|
27987
|
+
[`ea-tag--${this.size()}`]: true,
|
|
27988
|
+
'ea-tag--disabled': this.disabled(),
|
|
27989
|
+
}), ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
|
|
27990
|
+
onRemove(event) {
|
|
27991
|
+
event.stopPropagation();
|
|
27992
|
+
this.removed.emit();
|
|
27659
27993
|
}
|
|
27660
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type:
|
|
27661
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.13", type:
|
|
27994
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: TagComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
27995
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.13", type: TagComponent, isStandalone: true, selector: "ea-tag", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, removable: { classPropertyName: "removable", publicName: "removable", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, removeLabel: { classPropertyName: "removeLabel", publicName: "removeLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { removed: "removed" }, ngImport: i0, template: "<span\n class=\"ea-tag\"\n [ngClass]=\"hostClasses()\">\n <ng-content />\n @if (removable()) {\n <button\n type=\"button\"\n class=\"ea-tag__remove\"\n [disabled]=\"disabled() || null\"\n [attr.aria-label]=\"resolvedRemoveLabel()\"\n (click)=\"onRemove($event)\">\n <ea-icon-x />\n </button>\n }\n</span>\n", styles: [".ea-tag{display:inline-flex;align-items:center;gap:var(--space-1);font-weight:var(--font-weight-medium);line-height:var(--line-height-none);white-space:nowrap;font-family:var(--font-family-sans);border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-lg);background-color:var(--color-bg-subtle);color:var(--color-text-secondary)}.ea-tag--sm{padding:var(--space-0-5) var(--space-1-5);font-size:var(--font-size-xs)}.ea-tag--sm .ea-tag__remove ea-icon-x{width:.625rem;height:.625rem}.ea-tag--md{padding:var(--space-1) var(--space-2);font-size:var(--font-size-xs)}.ea-tag--md .ea-tag__remove ea-icon-x{width:.75rem;height:.75rem}.ea-tag--lg{padding:var(--space-1) var(--space-2-5);font-size:var(--font-size-sm)}.ea-tag--lg .ea-tag__remove ea-icon-x{width:.875rem;height:.875rem}.ea-tag--success{border-color:var(--color-success-muted);background-color:var(--color-success-subtle);color:var(--color-success-700)}.ea-tag--warning{border-color:var(--color-warning-muted);background-color:var(--color-warning-subtle);color:var(--color-warning-700)}.ea-tag--error{border-color:var(--color-error-muted);background-color:var(--color-error-subtle);color:var(--color-error-700)}.ea-tag--info{border-color:var(--color-info-muted);background-color:var(--color-info-subtle);color:var(--color-info-700)}.ea-tag--disabled{opacity:.6;cursor:not-allowed}.ea-tag__remove{opacity:.7;display:flex;align-items:center;justify-content:center;flex-shrink:0;padding:0;border:none;border-radius:var(--radius-xs);background:none;color:inherit;cursor:pointer;transition:var(--transition-colors)}.ea-tag__remove:hover{opacity:1}.ea-tag__remove:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-tag__remove:disabled{cursor:not-allowed}.ea-tag__remove ea-icon-x{pointer-events:none}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: XIconComponent, selector: "ea-icon-x" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
27662
27996
|
}
|
|
27663
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type:
|
|
27997
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: TagComponent, decorators: [{
|
|
27664
27998
|
type: Component,
|
|
27665
|
-
args: [{ selector: 'ea-
|
|
27666
|
-
}], propDecorators: {
|
|
27999
|
+
args: [{ selector: 'ea-tag', imports: [NgClass, XIconComponent], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<span\n class=\"ea-tag\"\n [ngClass]=\"hostClasses()\">\n <ng-content />\n @if (removable()) {\n <button\n type=\"button\"\n class=\"ea-tag__remove\"\n [disabled]=\"disabled() || null\"\n [attr.aria-label]=\"resolvedRemoveLabel()\"\n (click)=\"onRemove($event)\">\n <ea-icon-x />\n </button>\n }\n</span>\n", styles: [".ea-tag{display:inline-flex;align-items:center;gap:var(--space-1);font-weight:var(--font-weight-medium);line-height:var(--line-height-none);white-space:nowrap;font-family:var(--font-family-sans);border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-lg);background-color:var(--color-bg-subtle);color:var(--color-text-secondary)}.ea-tag--sm{padding:var(--space-0-5) var(--space-1-5);font-size:var(--font-size-xs)}.ea-tag--sm .ea-tag__remove ea-icon-x{width:.625rem;height:.625rem}.ea-tag--md{padding:var(--space-1) var(--space-2);font-size:var(--font-size-xs)}.ea-tag--md .ea-tag__remove ea-icon-x{width:.75rem;height:.75rem}.ea-tag--lg{padding:var(--space-1) var(--space-2-5);font-size:var(--font-size-sm)}.ea-tag--lg .ea-tag__remove ea-icon-x{width:.875rem;height:.875rem}.ea-tag--success{border-color:var(--color-success-muted);background-color:var(--color-success-subtle);color:var(--color-success-700)}.ea-tag--warning{border-color:var(--color-warning-muted);background-color:var(--color-warning-subtle);color:var(--color-warning-700)}.ea-tag--error{border-color:var(--color-error-muted);background-color:var(--color-error-subtle);color:var(--color-error-700)}.ea-tag--info{border-color:var(--color-info-muted);background-color:var(--color-info-subtle);color:var(--color-info-700)}.ea-tag--disabled{opacity:.6;cursor:not-allowed}.ea-tag__remove{opacity:.7;display:flex;align-items:center;justify-content:center;flex-shrink:0;padding:0;border:none;border-radius:var(--radius-xs);background:none;color:inherit;cursor:pointer;transition:var(--transition-colors)}.ea-tag__remove:hover{opacity:1}.ea-tag__remove:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-tag__remove:disabled{cursor:not-allowed}.ea-tag__remove ea-icon-x{pointer-events:none}\n"] }]
|
|
28000
|
+
}], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], removable: [{ type: i0.Input, args: [{ isSignal: true, alias: "removable", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], removeLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "removeLabel", required: false }] }], removed: [{ type: i0.Output, args: ["removed"] }] } });
|
|
27667
28001
|
|
|
27668
28002
|
/**
|
|
27669
|
-
*
|
|
27670
|
-
*
|
|
27671
|
-
* and
|
|
28003
|
+
* Multi-select dropdown. Renders selections as removable `<ea-tag>` chips
|
|
28004
|
+
* inside the trigger, opens a popover containing an optional search input,
|
|
28005
|
+
* a tri-state "Select all" toggle, and a list of `<ea-checkbox>` options.
|
|
28006
|
+
* The wire value is a `readonly string[]` of selected option values, ordered
|
|
28007
|
+
* to match the input `options` array. Closes on outside click / scroll, and
|
|
28008
|
+
* integrates with Angular forms via `ControlValueAccessor`.
|
|
27672
28009
|
*/
|
|
27673
|
-
class
|
|
28010
|
+
class MultiSelectComponent {
|
|
28011
|
+
triggerEl = viewChild('triggerEl', ...(ngDevMode ? [{ debugName: "triggerEl" }] : /* istanbul ignore next */ []));
|
|
28012
|
+
searchEl = viewChild('searchEl', ...(ngDevMode ? [{ debugName: "searchEl" }] : /* istanbul ignore next */ []));
|
|
27674
28013
|
i18n = inject(EagamiI18nService);
|
|
27675
|
-
|
|
27676
|
-
|
|
28014
|
+
injector = inject(Injector);
|
|
28015
|
+
// ─── Inputs ───────────────────────────────────────────────────────────
|
|
28016
|
+
label = input(undefined, ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
28017
|
+
placeholder = input(undefined, ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
|
|
28018
|
+
searchPlaceholder = input(undefined, ...(ngDevMode ? [{ debugName: "searchPlaceholder" }] : /* istanbul ignore next */ []));
|
|
28019
|
+
options = input([], ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
|
|
28020
|
+
size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
28021
|
+
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
28022
|
+
readonly = input(false, ...(ngDevMode ? [{ debugName: "readonly" }] : /* istanbul ignore next */ []));
|
|
28023
|
+
required = input(false, ...(ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []));
|
|
28024
|
+
hint = input(undefined, ...(ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []));
|
|
28025
|
+
errorMsg = input(undefined, ...(ngDevMode ? [{ debugName: "errorMsg" }] : /* istanbul ignore next */ []));
|
|
28026
|
+
/** Toggle the search input at the top of the popover. */
|
|
28027
|
+
searchable = input(true, ...(ngDevMode ? [{ debugName: "searchable" }] : /* istanbul ignore next */ []));
|
|
28028
|
+
/** Toggle the "Select all" row at the top of the option list. */
|
|
28029
|
+
selectAll = input(true, ...(ngDevMode ? [{ debugName: "selectAll" }] : /* istanbul ignore next */ []));
|
|
28030
|
+
/** Max number of chips shown inside the trigger; the rest collapse into a "+N more" pill. `0` removes the cap. */
|
|
28031
|
+
maxVisibleChips = input(3, ...(ngDevMode ? [{ debugName: "maxVisibleChips" }] : /* istanbul ignore next */ []));
|
|
28032
|
+
id = input(`ea-multi-select-${Math.random().toString(36).slice(2, 9)}`, ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
|
|
28033
|
+
/** Selected option values, in the original options order. */
|
|
28034
|
+
value = model([], ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
28035
|
+
/** Fires with the new value whenever the selection changes. */
|
|
28036
|
+
changed = output();
|
|
28037
|
+
// ─── State ────────────────────────────────────────────────────────────
|
|
28038
|
+
isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
|
|
28039
|
+
searchTerm = signal('', ...(ngDevMode ? [{ debugName: "searchTerm" }] : /* istanbul ignore next */ []));
|
|
28040
|
+
/** Index into `filteredOptions()` for keyboard navigation. `-1` when none focused. */
|
|
28041
|
+
focusedIndex = signal(-1, ...(ngDevMode ? [{ debugName: "focusedIndex" }] : /* istanbul ignore next */ []));
|
|
28042
|
+
_formDisabled = signal(false, ...(ngDevMode ? [{ debugName: "_formDisabled" }] : /* istanbul ignore next */ []));
|
|
28043
|
+
onChange = () => { };
|
|
28044
|
+
onTouched = () => { };
|
|
28045
|
+
// ─── Computed ─────────────────────────────────────────────────────────
|
|
28046
|
+
isDisabled = computed(() => this.disabled() || this._formDisabled(), ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
|
|
28047
|
+
hasError = computed(() => !!this.errorMsg(), ...(ngDevMode ? [{ debugName: "hasError" }] : /* istanbul ignore next */ []));
|
|
28048
|
+
showError = this.hasError;
|
|
28049
|
+
showHint = computed(() => !!this.hint() && !this.hasError(), ...(ngDevMode ? [{ debugName: "showHint" }] : /* istanbul ignore next */ []));
|
|
28050
|
+
/** Set-backed lookup for `selectedSet().has(value)`. */
|
|
28051
|
+
selectedSet = computed(() => new Set(this.value()), ...(ngDevMode ? [{ debugName: "selectedSet" }] : /* istanbul ignore next */ []));
|
|
28052
|
+
/** Options matching the current search term (case-insensitive substring on label). */
|
|
28053
|
+
filteredOptions = computed(() => {
|
|
28054
|
+
const term = this.searchTerm().trim().toLowerCase();
|
|
28055
|
+
const opts = this.options();
|
|
28056
|
+
if (!term)
|
|
28057
|
+
return opts;
|
|
28058
|
+
return opts.filter(o => o.label.toLowerCase().includes(term));
|
|
28059
|
+
}, ...(ngDevMode ? [{ debugName: "filteredOptions" }] : /* istanbul ignore next */ []));
|
|
28060
|
+
/** Currently selected options, ordered to match the input `options`. */
|
|
28061
|
+
selectedOptions = computed(() => {
|
|
28062
|
+
const set = this.selectedSet();
|
|
28063
|
+
return this.options().filter(o => set.has(o.value));
|
|
28064
|
+
}, ...(ngDevMode ? [{ debugName: "selectedOptions" }] : /* istanbul ignore next */ []));
|
|
28065
|
+
hasValue = computed(() => this.value().length > 0, ...(ngDevMode ? [{ debugName: "hasValue" }] : /* istanbul ignore next */ []));
|
|
28066
|
+
/** Chips visible inside the trigger, capped by `maxVisibleChips`. */
|
|
28067
|
+
visibleChips = computed(() => {
|
|
28068
|
+
const sel = this.selectedOptions();
|
|
28069
|
+
const cap = this.maxVisibleChips();
|
|
28070
|
+
return cap <= 0 || sel.length <= cap ? sel : sel.slice(0, cap);
|
|
28071
|
+
}, ...(ngDevMode ? [{ debugName: "visibleChips" }] : /* istanbul ignore next */ []));
|
|
28072
|
+
/** Count behind the "+N more" pill, or `0` when all chips fit. */
|
|
28073
|
+
hiddenChipCount = computed(() => {
|
|
28074
|
+
const sel = this.selectedOptions();
|
|
28075
|
+
const cap = this.maxVisibleChips();
|
|
28076
|
+
return cap <= 0 || sel.length <= cap ? 0 : sel.length - cap;
|
|
28077
|
+
}, ...(ngDevMode ? [{ debugName: "hiddenChipCount" }] : /* istanbul ignore next */ []));
|
|
28078
|
+
/** Tri-state of the Select-all checkbox over the **currently filtered** list. */
|
|
28079
|
+
selectAllState = computed(() => {
|
|
28080
|
+
const filtered = this.filteredOptions().filter(o => !o.disabled);
|
|
28081
|
+
if (filtered.length === 0)
|
|
28082
|
+
return 'none';
|
|
28083
|
+
const set = this.selectedSet();
|
|
28084
|
+
let count = 0;
|
|
28085
|
+
for (const o of filtered)
|
|
28086
|
+
if (set.has(o.value))
|
|
28087
|
+
count++;
|
|
28088
|
+
if (count === 0)
|
|
28089
|
+
return 'none';
|
|
28090
|
+
if (count === filtered.length)
|
|
28091
|
+
return 'all';
|
|
28092
|
+
return 'some';
|
|
28093
|
+
}, ...(ngDevMode ? [{ debugName: "selectAllState" }] : /* istanbul ignore next */ []));
|
|
28094
|
+
resolvedPlaceholder = computed(() => this.placeholder() ?? this.i18n.messages().multiSelect.placeholder, ...(ngDevMode ? [{ debugName: "resolvedPlaceholder" }] : /* istanbul ignore next */ []));
|
|
28095
|
+
resolvedSearchPlaceholder = computed(() => this.searchPlaceholder() ?? this.i18n.messages().multiSelect.searchPlaceholder, ...(ngDevMode ? [{ debugName: "resolvedSearchPlaceholder" }] : /* istanbul ignore next */ []));
|
|
28096
|
+
triggerClasses = computed(() => ({
|
|
28097
|
+
[`ea-multi-select__trigger--${this.size()}`]: true,
|
|
28098
|
+
'ea-multi-select__trigger--error': this.hasError(),
|
|
28099
|
+
'ea-multi-select__trigger--open': this.isOpen(),
|
|
28100
|
+
'ea-multi-select__trigger--disabled': this.isDisabled(),
|
|
28101
|
+
'ea-multi-select__trigger--placeholder': !this.hasValue(),
|
|
28102
|
+
}), ...(ngDevMode ? [{ debugName: "triggerClasses" }] : /* istanbul ignore next */ []));
|
|
28103
|
+
// ─── ControlValueAccessor ─────────────────────────────────────────────
|
|
28104
|
+
writeValue(val) {
|
|
28105
|
+
this.value.set(val ?? []);
|
|
28106
|
+
}
|
|
28107
|
+
registerOnChange(fn) {
|
|
28108
|
+
this.onChange = fn;
|
|
28109
|
+
}
|
|
28110
|
+
registerOnTouched(fn) {
|
|
28111
|
+
this.onTouched = fn;
|
|
28112
|
+
}
|
|
28113
|
+
setDisabledState(isDisabled) {
|
|
28114
|
+
this._formDisabled.set(isDisabled);
|
|
28115
|
+
}
|
|
28116
|
+
// ─── Handlers ─────────────────────────────────────────────────────────
|
|
28117
|
+
toggle() {
|
|
28118
|
+
if (this.isDisabled() || this.readonly())
|
|
28119
|
+
return;
|
|
28120
|
+
const opening = !this.isOpen();
|
|
28121
|
+
this.isOpen.set(opening);
|
|
28122
|
+
if (opening)
|
|
28123
|
+
this.focusSearchWhenReady();
|
|
28124
|
+
else
|
|
28125
|
+
this.resetEditState();
|
|
28126
|
+
}
|
|
28127
|
+
close() {
|
|
28128
|
+
this.isOpen.set(false);
|
|
28129
|
+
this.resetEditState();
|
|
28130
|
+
}
|
|
28131
|
+
/** Called by `<ea-popover>` when the user clicks outside or scrolls. */
|
|
28132
|
+
onPopoverCloseRequested() {
|
|
28133
|
+
this.close();
|
|
28134
|
+
this.onTouched();
|
|
28135
|
+
}
|
|
28136
|
+
/** Toggle one option's membership in the selection. */
|
|
28137
|
+
toggleOption(opt) {
|
|
28138
|
+
if (this.isDisabled() || this.readonly() || opt.disabled)
|
|
28139
|
+
return;
|
|
28140
|
+
const set = new Set(this.value());
|
|
28141
|
+
if (set.has(opt.value))
|
|
28142
|
+
set.delete(opt.value);
|
|
28143
|
+
else
|
|
28144
|
+
set.add(opt.value);
|
|
28145
|
+
this.commit(this.orderedValues(set));
|
|
28146
|
+
}
|
|
28147
|
+
/**
|
|
28148
|
+
* Remove a single chip from the trigger. `<ea-tag>` already stops the
|
|
28149
|
+
* click from bubbling to the trigger's `(click)`, so no event handling
|
|
28150
|
+
* is needed here.
|
|
28151
|
+
*/
|
|
28152
|
+
removeChip(opt) {
|
|
28153
|
+
if (this.isDisabled() || this.readonly())
|
|
28154
|
+
return;
|
|
28155
|
+
this.commit(this.value().filter(v => v !== opt.value));
|
|
28156
|
+
}
|
|
28157
|
+
/** Clear every selection via the trigger × button. */
|
|
28158
|
+
clear(event) {
|
|
28159
|
+
event.stopPropagation();
|
|
28160
|
+
if (this.isDisabled() || this.readonly())
|
|
28161
|
+
return;
|
|
28162
|
+
this.commit([]);
|
|
28163
|
+
}
|
|
28164
|
+
/**
|
|
28165
|
+
* Toggle the Select-all checkbox. If any filtered option is unselected, the
|
|
28166
|
+
* action selects all filtered. Otherwise, the action removes every filtered
|
|
28167
|
+
* value from the selection. Disabled options are skipped either way.
|
|
28168
|
+
*/
|
|
28169
|
+
toggleSelectAll() {
|
|
28170
|
+
if (this.isDisabled() || this.readonly())
|
|
28171
|
+
return;
|
|
28172
|
+
const filteredValues = this.filteredOptions()
|
|
28173
|
+
.filter(o => !o.disabled)
|
|
28174
|
+
.map(o => o.value);
|
|
28175
|
+
const set = new Set(this.value());
|
|
28176
|
+
if (this.selectAllState() === 'all') {
|
|
28177
|
+
for (const v of filteredValues)
|
|
28178
|
+
set.delete(v);
|
|
28179
|
+
}
|
|
28180
|
+
else {
|
|
28181
|
+
for (const v of filteredValues)
|
|
28182
|
+
set.add(v);
|
|
28183
|
+
}
|
|
28184
|
+
this.commit(this.orderedValues(set));
|
|
28185
|
+
}
|
|
28186
|
+
onSearchInput(event) {
|
|
28187
|
+
const target = event.target;
|
|
28188
|
+
this.searchTerm.set(target.value);
|
|
28189
|
+
this.focusedIndex.set(-1);
|
|
28190
|
+
}
|
|
28191
|
+
handleTriggerKeydown(event) {
|
|
28192
|
+
if (this.isDisabled() || this.readonly())
|
|
28193
|
+
return;
|
|
28194
|
+
if (event.key === 'Enter' || event.key === ' ' || event.key === 'ArrowDown') {
|
|
28195
|
+
event.preventDefault();
|
|
28196
|
+
if (!this.isOpen()) {
|
|
28197
|
+
this.isOpen.set(true);
|
|
28198
|
+
this.focusSearchWhenReady();
|
|
28199
|
+
}
|
|
28200
|
+
}
|
|
28201
|
+
else if (event.key === 'Escape' && this.isOpen()) {
|
|
28202
|
+
event.preventDefault();
|
|
28203
|
+
this.close();
|
|
28204
|
+
this.triggerEl()?.nativeElement.focus();
|
|
28205
|
+
}
|
|
28206
|
+
else if (event.key === 'Backspace' && this.hasValue() && !this.isOpen()) {
|
|
28207
|
+
// Quick-remove the last chip when the trigger is focused and no popover.
|
|
28208
|
+
event.preventDefault();
|
|
28209
|
+
this.commit(this.value().slice(0, -1));
|
|
28210
|
+
}
|
|
28211
|
+
}
|
|
28212
|
+
/**
|
|
28213
|
+
* Keyboard navigation inside the popover. Bound to both the search input
|
|
28214
|
+
* and each option row; Space passes through to the search input naturally
|
|
28215
|
+
* so users can type spaces in their query.
|
|
28216
|
+
*/
|
|
28217
|
+
handlePopoverKeydown(event) {
|
|
28218
|
+
if (this.isDisabled() || this.readonly())
|
|
28219
|
+
return;
|
|
28220
|
+
const opts = this.filteredOptions();
|
|
28221
|
+
const onSearchInput = event.target === this.searchEl()?.nativeElement;
|
|
28222
|
+
if (event.key === 'ArrowDown') {
|
|
28223
|
+
event.preventDefault();
|
|
28224
|
+
const next = Math.min(opts.length - 1, this.focusedIndex() + 1);
|
|
28225
|
+
this.focusedIndex.set(next);
|
|
28226
|
+
}
|
|
28227
|
+
else if (event.key === 'ArrowUp') {
|
|
28228
|
+
event.preventDefault();
|
|
28229
|
+
const next = Math.max(0, this.focusedIndex() - 1);
|
|
28230
|
+
this.focusedIndex.set(next);
|
|
28231
|
+
}
|
|
28232
|
+
else if (event.key === 'Home') {
|
|
28233
|
+
event.preventDefault();
|
|
28234
|
+
this.focusedIndex.set(0);
|
|
28235
|
+
}
|
|
28236
|
+
else if (event.key === 'End') {
|
|
28237
|
+
event.preventDefault();
|
|
28238
|
+
this.focusedIndex.set(opts.length - 1);
|
|
28239
|
+
}
|
|
28240
|
+
else if (event.key === 'Enter') {
|
|
28241
|
+
event.preventDefault();
|
|
28242
|
+
const idx = this.focusedIndex();
|
|
28243
|
+
if (idx >= 0 && idx < opts.length)
|
|
28244
|
+
this.toggleOption(opts[idx]);
|
|
28245
|
+
}
|
|
28246
|
+
else if (event.key === ' ' && !onSearchInput) {
|
|
28247
|
+
// Toggle on Space only when an option row has focus; the search input
|
|
28248
|
+
// needs Space for typing.
|
|
28249
|
+
event.preventDefault();
|
|
28250
|
+
const idx = this.focusedIndex();
|
|
28251
|
+
if (idx >= 0 && idx < opts.length)
|
|
28252
|
+
this.toggleOption(opts[idx]);
|
|
28253
|
+
}
|
|
28254
|
+
else if (event.key === 'Escape') {
|
|
28255
|
+
event.preventDefault();
|
|
28256
|
+
this.close();
|
|
28257
|
+
this.triggerEl()?.nativeElement.focus();
|
|
28258
|
+
}
|
|
28259
|
+
}
|
|
28260
|
+
// ─── Internals ────────────────────────────────────────────────────────
|
|
28261
|
+
focusSearchWhenReady() {
|
|
28262
|
+
afterNextRender(() => this.searchEl()?.nativeElement.focus(), {
|
|
28263
|
+
injector: this.injector,
|
|
28264
|
+
});
|
|
28265
|
+
}
|
|
28266
|
+
/** Reorder a value-set against the input `options` array. */
|
|
28267
|
+
orderedValues(set) {
|
|
28268
|
+
return this.options()
|
|
28269
|
+
.filter(o => set.has(o.value))
|
|
28270
|
+
.map(o => o.value);
|
|
28271
|
+
}
|
|
28272
|
+
resetEditState() {
|
|
28273
|
+
this.searchTerm.set('');
|
|
28274
|
+
this.focusedIndex.set(-1);
|
|
28275
|
+
}
|
|
28276
|
+
commit(next) {
|
|
28277
|
+
this.value.set(next);
|
|
28278
|
+
this.onChange(next);
|
|
28279
|
+
this.onTouched();
|
|
28280
|
+
this.changed.emit(next);
|
|
28281
|
+
}
|
|
28282
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: MultiSelectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
28283
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.13", type: MultiSelectComponent, isStandalone: true, selector: "ea-multi-select", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, searchPlaceholder: { classPropertyName: "searchPlaceholder", publicName: "searchPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, errorMsg: { classPropertyName: "errorMsg", publicName: "errorMsg", isSignal: true, isRequired: false, transformFunction: null }, searchable: { classPropertyName: "searchable", publicName: "searchable", isSignal: true, isRequired: false, transformFunction: null }, selectAll: { classPropertyName: "selectAll", publicName: "selectAll", isSignal: true, isRequired: false, transformFunction: null }, maxVisibleChips: { classPropertyName: "maxVisibleChips", publicName: "maxVisibleChips", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", changed: "changed" }, providers: [
|
|
28284
|
+
{
|
|
28285
|
+
provide: NG_VALUE_ACCESSOR,
|
|
28286
|
+
useExisting: forwardRef(() => MultiSelectComponent),
|
|
28287
|
+
multi: true,
|
|
28288
|
+
},
|
|
28289
|
+
], viewQueries: [{ propertyName: "triggerEl", first: true, predicate: ["triggerEl"], descendants: true, isSignal: true }, { propertyName: "searchEl", first: true, predicate: ["searchEl"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"ea-multi-select-field\">\n @if (label()) {\n <label\n class=\"ea-multi-select-field__label\"\n [for]=\"id()\"\n [class.ea-multi-select-field__label--required]=\"required()\">\n {{ label() }}\n </label>\n }\n\n <div class=\"ea-multi-select\">\n <div class=\"ea-multi-select__trigger-wrapper\">\n <div\n #triggerEl\n class=\"ea-multi-select__trigger\"\n [ngClass]=\"triggerClasses()\"\n [id]=\"id()\"\n role=\"combobox\"\n [attr.tabindex]=\"isDisabled() ? -1 : 0\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-haspopup]=\"'listbox'\"\n [attr.aria-disabled]=\"isDisabled() || null\"\n [attr.aria-required]=\"required() || null\"\n [attr.aria-invalid]=\"hasError() || null\"\n [attr.aria-describedby]=\"\n showError() ? id() + '-error' : showHint() ? id() + '-hint' : null\n \"\n (click)=\"toggle()\"\n (keydown)=\"handleTriggerKeydown($event)\">\n <span class=\"ea-multi-select__trigger-content\">\n @if (!hasValue()) {\n <span class=\"ea-multi-select__trigger-placeholder\">\n {{ resolvedPlaceholder() }}\n </span>\n } @else {\n @for (opt of visibleChips(); track opt.value) {\n <ea-tag\n size=\"sm\"\n variant=\"default\"\n [removable]=\"!isDisabled() && !readonly()\"\n [removeLabel]=\"i18n.messages().multiSelect.removeOption(opt.label)\"\n (removed)=\"removeChip(opt)\">\n {{ opt.label }}\n </ea-tag>\n }\n @if (hiddenChipCount() > 0) {\n <span class=\"ea-multi-select__more\">+{{ hiddenChipCount() }}</span>\n }\n }\n </span>\n <ea-icon-chevron-down\n class=\"ea-multi-select__trigger-icon\"\n aria-hidden=\"true\" />\n </div>\n @if (hasValue() && !isDisabled() && !readonly()) {\n <button\n type=\"button\"\n class=\"ea-multi-select__clear\"\n [attr.aria-label]=\"i18n.messages().multiSelect.clearAll\"\n (click)=\"clear($event)\">\n <ea-icon-x\n class=\"ea-multi-select__clear-icon\"\n aria-hidden=\"true\" />\n </button>\n }\n </div>\n\n <ea-popover\n [anchor]=\"triggerEl\"\n [open]=\"isOpen()\"\n placement=\"bottom-start\"\n role=\"listbox\"\n [matchAnchorWidth]=\"true\"\n [closeOnEscape]=\"false\"\n scrollBehavior=\"reposition\"\n (closeRequested)=\"onPopoverCloseRequested()\">\n <div class=\"ea-multi-select__popover\">\n @if (searchable()) {\n <div class=\"ea-multi-select__search\">\n <ea-icon-search\n class=\"ea-multi-select__search-icon\"\n aria-hidden=\"true\" />\n <input\n #searchEl\n type=\"text\"\n class=\"ea-multi-select__search-input\"\n autocomplete=\"off\"\n [placeholder]=\"resolvedSearchPlaceholder()\"\n [value]=\"searchTerm()\"\n (input)=\"onSearchInput($event)\"\n (keydown)=\"handlePopoverKeydown($event)\" />\n </div>\n }\n\n @if (selectAll() && filteredOptions().length > 0) {\n <div\n class=\"ea-multi-select__option ea-multi-select__option--select-all\"\n (click)=\"toggleSelectAll()\">\n <ea-checkbox\n size=\"sm\"\n [checked]=\"selectAllState() === 'all'\"\n [indeterminate]=\"selectAllState() === 'some'\"\n [ariaLabel]=\"i18n.messages().multiSelect.selectAll\" />\n <span class=\"ea-multi-select__option-label\">\n {{ i18n.messages().multiSelect.selectAll }}\n </span>\n </div>\n }\n\n <ul\n class=\"ea-multi-select__list\"\n role=\"presentation\">\n @for (opt of filteredOptions(); track opt.value; let i = $index) {\n <li\n class=\"ea-multi-select__option\"\n [class.ea-multi-select__option--focused]=\"focusedIndex() === i\"\n [class.ea-multi-select__option--disabled]=\"opt.disabled\"\n role=\"option\"\n tabindex=\"-1\"\n [attr.aria-selected]=\"selectedSet().has(opt.value)\"\n [attr.aria-disabled]=\"opt.disabled || null\"\n (click)=\"toggleOption(opt)\"\n (keydown)=\"handlePopoverKeydown($event)\">\n <ea-checkbox\n size=\"sm\"\n [checked]=\"selectedSet().has(opt.value)\"\n [disabled]=\"!!opt.disabled\"\n [ariaLabel]=\"opt.label\" />\n <span class=\"ea-multi-select__option-label\">\n {{ opt.label }}\n </span>\n </li>\n } @empty {\n <li class=\"ea-multi-select__empty\">\n {{ i18n.messages().multiSelect.searchEmpty }}\n </li>\n }\n </ul>\n </div>\n </ea-popover>\n </div>\n\n @if (showError()) {\n <p\n class=\"ea-multi-select-field__message ea-multi-select-field__message--error\"\n [id]=\"id() + '-error'\"\n role=\"alert\">\n <ea-icon-alert-circle class=\"ea-multi-select-field__message-icon\" />\n {{ errorMsg() }}\n </p>\n }\n\n @if (showHint()) {\n <p\n class=\"ea-multi-select-field__message ea-multi-select-field__message--hint\"\n [id]=\"id() + '-hint'\">\n {{ hint() }}\n </p>\n }\n</div>\n", styles: [".ea-multi-select-field{display:flex;flex-direction:column;gap:var(--space-1-5)}.ea-multi-select-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-multi-select-field__label--required:after{content:\" *\";color:var(--color-error-default)}.ea-multi-select-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-multi-select-field__message--hint{color:var(--color-text-secondary)}.ea-multi-select-field__message--error{color:var(--color-error-default)}.ea-multi-select-field__message-icon{flex-shrink:0;width:.875em;height:.875em}.ea-multi-select,.ea-multi-select__trigger-wrapper{position:relative}.ea-multi-select__trigger{display:flex;align-items:center;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-multi-select__trigger:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-multi-select__trigger--sm{padding:var(--space-1) var(--space-2);font-size:var(--font-size-sm);min-height:2rem}.ea-multi-select__trigger--md{padding:var(--space-1-5) var(--space-3);font-size:var(--font-size-sm);min-height:2.5rem}.ea-multi-select__trigger--lg{padding:var(--space-2) var(--space-4);font-size:var(--font-size-md);min-height:3rem}.ea-multi-select__trigger--open{border-color:var(--color-border-focus);box-shadow:var(--shadow-focus-ring)}.ea-multi-select__trigger--error{border-color:var(--color-error-default)}.ea-multi-select__trigger--error.ea-multi-select__trigger--open{box-shadow:var(--shadow-focus-ring-error)}.ea-multi-select__trigger--disabled{background-color:var(--color-bg-muted);opacity:.6;cursor:not-allowed}.ea-multi-select__trigger-content{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-1);flex:1;min-width:0}.ea-multi-select__trigger-placeholder{color:var(--color-text-tertiary)}.ea-multi-select__trigger-icon{flex-shrink:0;width:1em;height:1em;color:var(--color-text-secondary);transition:var(--transition-transform)}.ea-multi-select__trigger--open .ea-multi-select__trigger-icon{transform:rotate(180deg)}.ea-multi-select__more{display:inline-flex;align-items:center;padding:0 var(--space-1-5);border-radius:var(--radius-lg);background-color:var(--color-bg-muted);font-size:var(--font-size-xs);font-weight:var(--font-weight-medium);color:var(--color-text-secondary)}.ea-multi-select__clear{position:absolute;top:50%;right:var(--space-7);z-index:1;display:flex;align-items:center;justify-content:center;flex-shrink:0;width:1.25rem;height:1.25rem;padding:0;border:none;border-radius:var(--radius-sm);background:none;color:var(--color-text-secondary);cursor:pointer;transition:var(--transition-colors);transform:translateY(-50%)}.ea-multi-select__clear:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-multi-select__clear:hover{background-color:var(--color-bg-muted);color:var(--color-text-primary)}.ea-multi-select__clear-icon{width:.875em;height:.875em}.ea-multi-select__popover{display:flex;flex-direction:column;overflow:hidden;max-height:20rem;border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-md);box-shadow:var(--shadow-lg);background-color:var(--color-bg-base)}.ea-multi-select__search{display:flex;align-items:center;gap:var(--space-2);flex-shrink:0;padding:var(--space-2) var(--space-3);border-bottom:var(--border-width-thin) solid var(--color-border-default)}.ea-multi-select__search-icon{flex-shrink:0;width:1em;height:1em;color:var(--color-text-tertiary)}.ea-multi-select__search-input{flex:1;min-width:0;padding:0;border:none;background:none;font-family:var(--font-family-sans);font-size:var(--font-size-sm);color:var(--color-text-primary)}.ea-multi-select__search-input::placeholder{color:var(--color-text-tertiary);opacity:1}.ea-multi-select__search-input:focus{outline:none}.ea-multi-select__list{overflow-y:auto;flex:1;margin:0;padding:var(--space-1) 0;list-style:none}.ea-multi-select__option{display:flex;align-items:center;gap:var(--space-2);padding:var(--space-1-5) 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-multi-select__option--focused{background-color:var(--color-bg-muted)}.ea-multi-select__option--disabled{color:var(--color-text-disabled);cursor:not-allowed}.ea-multi-select__option--select-all{border-bottom:var(--border-width-thin) solid var(--color-border-default);font-weight:var(--font-weight-medium)}.ea-multi-select__option:hover:not(.ea-multi-select__option--disabled){background-color:var(--color-bg-muted)}.ea-multi-select__option ea-checkbox{pointer-events:none;display:inline-flex;align-items:center;line-height:1}.ea-multi-select__option-label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ea-multi-select__empty{padding:var(--space-3);font-size:var(--font-size-sm);text-align:center;color:var(--color-text-tertiary);list-style:none}\n"], dependencies: [{ kind: "component", type: AlertCircleIconComponent, selector: "ea-icon-alert-circle" }, { kind: "component", type: CheckboxComponent, selector: "ea-checkbox", inputs: ["label", "count", "hint", "errorMsg", "size", "disabled", "required", "indeterminate", "aria-label", "id", "checked"], outputs: ["checkedChange", "changed"] }, { kind: "component", type: ChevronDownIconComponent, selector: "ea-icon-chevron-down" }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: PopoverComponent, selector: "ea-popover", inputs: ["anchor", "open", "placement", "role", "aria-label", "surfaceId", "offset", "flip", "clamp", "matchAnchorWidth", "closeOnOutsideClick", "closeOnEscape", "scrollBehavior"], outputs: ["closeRequested"] }, { kind: "component", type: SearchIconComponent, selector: "ea-icon-search" }, { kind: "component", type: TagComponent, selector: "ea-tag", inputs: ["variant", "size", "removable", "disabled", "removeLabel"], outputs: ["removed"] }, { kind: "component", type: XIconComponent, selector: "ea-icon-x" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
28290
|
+
}
|
|
28291
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: MultiSelectComponent, decorators: [{
|
|
28292
|
+
type: Component,
|
|
28293
|
+
args: [{ selector: 'ea-multi-select', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
28294
|
+
AlertCircleIconComponent,
|
|
28295
|
+
CheckboxComponent,
|
|
28296
|
+
ChevronDownIconComponent,
|
|
28297
|
+
NgClass,
|
|
28298
|
+
PopoverComponent,
|
|
28299
|
+
SearchIconComponent,
|
|
28300
|
+
TagComponent,
|
|
28301
|
+
XIconComponent,
|
|
28302
|
+
], providers: [
|
|
28303
|
+
{
|
|
28304
|
+
provide: NG_VALUE_ACCESSOR,
|
|
28305
|
+
useExisting: forwardRef(() => MultiSelectComponent),
|
|
28306
|
+
multi: true,
|
|
28307
|
+
},
|
|
28308
|
+
], template: "<div class=\"ea-multi-select-field\">\n @if (label()) {\n <label\n class=\"ea-multi-select-field__label\"\n [for]=\"id()\"\n [class.ea-multi-select-field__label--required]=\"required()\">\n {{ label() }}\n </label>\n }\n\n <div class=\"ea-multi-select\">\n <div class=\"ea-multi-select__trigger-wrapper\">\n <div\n #triggerEl\n class=\"ea-multi-select__trigger\"\n [ngClass]=\"triggerClasses()\"\n [id]=\"id()\"\n role=\"combobox\"\n [attr.tabindex]=\"isDisabled() ? -1 : 0\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-haspopup]=\"'listbox'\"\n [attr.aria-disabled]=\"isDisabled() || null\"\n [attr.aria-required]=\"required() || null\"\n [attr.aria-invalid]=\"hasError() || null\"\n [attr.aria-describedby]=\"\n showError() ? id() + '-error' : showHint() ? id() + '-hint' : null\n \"\n (click)=\"toggle()\"\n (keydown)=\"handleTriggerKeydown($event)\">\n <span class=\"ea-multi-select__trigger-content\">\n @if (!hasValue()) {\n <span class=\"ea-multi-select__trigger-placeholder\">\n {{ resolvedPlaceholder() }}\n </span>\n } @else {\n @for (opt of visibleChips(); track opt.value) {\n <ea-tag\n size=\"sm\"\n variant=\"default\"\n [removable]=\"!isDisabled() && !readonly()\"\n [removeLabel]=\"i18n.messages().multiSelect.removeOption(opt.label)\"\n (removed)=\"removeChip(opt)\">\n {{ opt.label }}\n </ea-tag>\n }\n @if (hiddenChipCount() > 0) {\n <span class=\"ea-multi-select__more\">+{{ hiddenChipCount() }}</span>\n }\n }\n </span>\n <ea-icon-chevron-down\n class=\"ea-multi-select__trigger-icon\"\n aria-hidden=\"true\" />\n </div>\n @if (hasValue() && !isDisabled() && !readonly()) {\n <button\n type=\"button\"\n class=\"ea-multi-select__clear\"\n [attr.aria-label]=\"i18n.messages().multiSelect.clearAll\"\n (click)=\"clear($event)\">\n <ea-icon-x\n class=\"ea-multi-select__clear-icon\"\n aria-hidden=\"true\" />\n </button>\n }\n </div>\n\n <ea-popover\n [anchor]=\"triggerEl\"\n [open]=\"isOpen()\"\n placement=\"bottom-start\"\n role=\"listbox\"\n [matchAnchorWidth]=\"true\"\n [closeOnEscape]=\"false\"\n scrollBehavior=\"reposition\"\n (closeRequested)=\"onPopoverCloseRequested()\">\n <div class=\"ea-multi-select__popover\">\n @if (searchable()) {\n <div class=\"ea-multi-select__search\">\n <ea-icon-search\n class=\"ea-multi-select__search-icon\"\n aria-hidden=\"true\" />\n <input\n #searchEl\n type=\"text\"\n class=\"ea-multi-select__search-input\"\n autocomplete=\"off\"\n [placeholder]=\"resolvedSearchPlaceholder()\"\n [value]=\"searchTerm()\"\n (input)=\"onSearchInput($event)\"\n (keydown)=\"handlePopoverKeydown($event)\" />\n </div>\n }\n\n @if (selectAll() && filteredOptions().length > 0) {\n <div\n class=\"ea-multi-select__option ea-multi-select__option--select-all\"\n (click)=\"toggleSelectAll()\">\n <ea-checkbox\n size=\"sm\"\n [checked]=\"selectAllState() === 'all'\"\n [indeterminate]=\"selectAllState() === 'some'\"\n [ariaLabel]=\"i18n.messages().multiSelect.selectAll\" />\n <span class=\"ea-multi-select__option-label\">\n {{ i18n.messages().multiSelect.selectAll }}\n </span>\n </div>\n }\n\n <ul\n class=\"ea-multi-select__list\"\n role=\"presentation\">\n @for (opt of filteredOptions(); track opt.value; let i = $index) {\n <li\n class=\"ea-multi-select__option\"\n [class.ea-multi-select__option--focused]=\"focusedIndex() === i\"\n [class.ea-multi-select__option--disabled]=\"opt.disabled\"\n role=\"option\"\n tabindex=\"-1\"\n [attr.aria-selected]=\"selectedSet().has(opt.value)\"\n [attr.aria-disabled]=\"opt.disabled || null\"\n (click)=\"toggleOption(opt)\"\n (keydown)=\"handlePopoverKeydown($event)\">\n <ea-checkbox\n size=\"sm\"\n [checked]=\"selectedSet().has(opt.value)\"\n [disabled]=\"!!opt.disabled\"\n [ariaLabel]=\"opt.label\" />\n <span class=\"ea-multi-select__option-label\">\n {{ opt.label }}\n </span>\n </li>\n } @empty {\n <li class=\"ea-multi-select__empty\">\n {{ i18n.messages().multiSelect.searchEmpty }}\n </li>\n }\n </ul>\n </div>\n </ea-popover>\n </div>\n\n @if (showError()) {\n <p\n class=\"ea-multi-select-field__message ea-multi-select-field__message--error\"\n [id]=\"id() + '-error'\"\n role=\"alert\">\n <ea-icon-alert-circle class=\"ea-multi-select-field__message-icon\" />\n {{ errorMsg() }}\n </p>\n }\n\n @if (showHint()) {\n <p\n class=\"ea-multi-select-field__message ea-multi-select-field__message--hint\"\n [id]=\"id() + '-hint'\">\n {{ hint() }}\n </p>\n }\n</div>\n", styles: [".ea-multi-select-field{display:flex;flex-direction:column;gap:var(--space-1-5)}.ea-multi-select-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-multi-select-field__label--required:after{content:\" *\";color:var(--color-error-default)}.ea-multi-select-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-multi-select-field__message--hint{color:var(--color-text-secondary)}.ea-multi-select-field__message--error{color:var(--color-error-default)}.ea-multi-select-field__message-icon{flex-shrink:0;width:.875em;height:.875em}.ea-multi-select,.ea-multi-select__trigger-wrapper{position:relative}.ea-multi-select__trigger{display:flex;align-items:center;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-multi-select__trigger:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-multi-select__trigger--sm{padding:var(--space-1) var(--space-2);font-size:var(--font-size-sm);min-height:2rem}.ea-multi-select__trigger--md{padding:var(--space-1-5) var(--space-3);font-size:var(--font-size-sm);min-height:2.5rem}.ea-multi-select__trigger--lg{padding:var(--space-2) var(--space-4);font-size:var(--font-size-md);min-height:3rem}.ea-multi-select__trigger--open{border-color:var(--color-border-focus);box-shadow:var(--shadow-focus-ring)}.ea-multi-select__trigger--error{border-color:var(--color-error-default)}.ea-multi-select__trigger--error.ea-multi-select__trigger--open{box-shadow:var(--shadow-focus-ring-error)}.ea-multi-select__trigger--disabled{background-color:var(--color-bg-muted);opacity:.6;cursor:not-allowed}.ea-multi-select__trigger-content{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-1);flex:1;min-width:0}.ea-multi-select__trigger-placeholder{color:var(--color-text-tertiary)}.ea-multi-select__trigger-icon{flex-shrink:0;width:1em;height:1em;color:var(--color-text-secondary);transition:var(--transition-transform)}.ea-multi-select__trigger--open .ea-multi-select__trigger-icon{transform:rotate(180deg)}.ea-multi-select__more{display:inline-flex;align-items:center;padding:0 var(--space-1-5);border-radius:var(--radius-lg);background-color:var(--color-bg-muted);font-size:var(--font-size-xs);font-weight:var(--font-weight-medium);color:var(--color-text-secondary)}.ea-multi-select__clear{position:absolute;top:50%;right:var(--space-7);z-index:1;display:flex;align-items:center;justify-content:center;flex-shrink:0;width:1.25rem;height:1.25rem;padding:0;border:none;border-radius:var(--radius-sm);background:none;color:var(--color-text-secondary);cursor:pointer;transition:var(--transition-colors);transform:translateY(-50%)}.ea-multi-select__clear:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-multi-select__clear:hover{background-color:var(--color-bg-muted);color:var(--color-text-primary)}.ea-multi-select__clear-icon{width:.875em;height:.875em}.ea-multi-select__popover{display:flex;flex-direction:column;overflow:hidden;max-height:20rem;border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-md);box-shadow:var(--shadow-lg);background-color:var(--color-bg-base)}.ea-multi-select__search{display:flex;align-items:center;gap:var(--space-2);flex-shrink:0;padding:var(--space-2) var(--space-3);border-bottom:var(--border-width-thin) solid var(--color-border-default)}.ea-multi-select__search-icon{flex-shrink:0;width:1em;height:1em;color:var(--color-text-tertiary)}.ea-multi-select__search-input{flex:1;min-width:0;padding:0;border:none;background:none;font-family:var(--font-family-sans);font-size:var(--font-size-sm);color:var(--color-text-primary)}.ea-multi-select__search-input::placeholder{color:var(--color-text-tertiary);opacity:1}.ea-multi-select__search-input:focus{outline:none}.ea-multi-select__list{overflow-y:auto;flex:1;margin:0;padding:var(--space-1) 0;list-style:none}.ea-multi-select__option{display:flex;align-items:center;gap:var(--space-2);padding:var(--space-1-5) 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-multi-select__option--focused{background-color:var(--color-bg-muted)}.ea-multi-select__option--disabled{color:var(--color-text-disabled);cursor:not-allowed}.ea-multi-select__option--select-all{border-bottom:var(--border-width-thin) solid var(--color-border-default);font-weight:var(--font-weight-medium)}.ea-multi-select__option:hover:not(.ea-multi-select__option--disabled){background-color:var(--color-bg-muted)}.ea-multi-select__option ea-checkbox{pointer-events:none;display:inline-flex;align-items:center;line-height:1}.ea-multi-select__option-label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ea-multi-select__empty{padding:var(--space-3);font-size:var(--font-size-sm);text-align:center;color:var(--color-text-tertiary);list-style:none}\n"] }]
|
|
28309
|
+
}], propDecorators: { triggerEl: [{ type: i0.ViewChild, args: ['triggerEl', { isSignal: true }] }], searchEl: [{ type: i0.ViewChild, args: ['searchEl', { isSignal: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], searchPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchPlaceholder", 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 }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", 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: "errorMsg", required: false }] }], searchable: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchable", required: false }] }], selectAll: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectAll", required: false }] }], maxVisibleChips: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxVisibleChips", 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"] }] } });
|
|
28310
|
+
|
|
28311
|
+
/**
|
|
28312
|
+
* Page navigation control with previous/next buttons, numbered page jumps,
|
|
28313
|
+
* an optional page-size selector, and a range label. Exposes `page` and
|
|
28314
|
+
* `pageSize` as two-way `model()` bindings and emits a single `changed`
|
|
28315
|
+
* event whenever either changes.
|
|
28316
|
+
*/
|
|
28317
|
+
class PaginatorComponent {
|
|
28318
|
+
i18n = inject(EagamiI18nService);
|
|
28319
|
+
totalItems = input.required(...(ngDevMode ? [{ debugName: "totalItems" }] : /* istanbul ignore next */ []));
|
|
28320
|
+
pageSizeOptions = input([10, 25, 50, 100], ...(ngDevMode ? [{ debugName: "pageSizeOptions" }] : /* istanbul ignore next */ []));
|
|
28321
|
+
showPageSizeSelector = input(true, ...(ngDevMode ? [{ debugName: "showPageSizeSelector" }] : /* istanbul ignore next */ []));
|
|
28322
|
+
showRangeLabel = input(true, ...(ngDevMode ? [{ debugName: "showRangeLabel" }] : /* istanbul ignore next */ []));
|
|
28323
|
+
align = input('right', ...(ngDevMode ? [{ debugName: "align" }] : /* istanbul ignore next */ []));
|
|
28324
|
+
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
28325
|
+
page = model(1, ...(ngDevMode ? [{ debugName: "page" }] : /* istanbul ignore next */ []));
|
|
28326
|
+
pageSize = model(10, ...(ngDevMode ? [{ debugName: "pageSize" }] : /* istanbul ignore next */ []));
|
|
28327
|
+
/** Fires when the user changes either the current page or the page size. */
|
|
28328
|
+
changed = output();
|
|
28329
|
+
totalPages = computed(() => Math.max(1, Math.ceil(this.totalItems() / this.pageSize())), ...(ngDevMode ? [{ debugName: "totalPages" }] : /* istanbul ignore next */ []));
|
|
28330
|
+
rangeStart = computed(() => this.totalItems() === 0 ? 0 : (this.page() - 1) * this.pageSize() + 1, ...(ngDevMode ? [{ debugName: "rangeStart" }] : /* istanbul ignore next */ []));
|
|
28331
|
+
rangeEnd = computed(() => Math.min(this.page() * this.pageSize(), this.totalItems()), ...(ngDevMode ? [{ debugName: "rangeEnd" }] : /* istanbul ignore next */ []));
|
|
28332
|
+
canGoPrev = computed(() => this.page() > 1, ...(ngDevMode ? [{ debugName: "canGoPrev" }] : /* istanbul ignore next */ []));
|
|
28333
|
+
canGoNext = computed(() => this.page() < this.totalPages(), ...(ngDevMode ? [{ debugName: "canGoNext" }] : /* istanbul ignore next */ []));
|
|
28334
|
+
visiblePages = computed(() => {
|
|
28335
|
+
const total = this.totalPages();
|
|
28336
|
+
const current = this.page();
|
|
28337
|
+
const pages = [];
|
|
28338
|
+
if (total <= 7) {
|
|
28339
|
+
for (let i = 1; i <= total; i++)
|
|
28340
|
+
pages.push(i);
|
|
28341
|
+
return pages;
|
|
28342
|
+
}
|
|
28343
|
+
pages.push(1);
|
|
28344
|
+
if (current > 3) {
|
|
28345
|
+
pages.push('ellipsis');
|
|
28346
|
+
}
|
|
28347
|
+
const start = Math.max(2, current - 1);
|
|
28348
|
+
const end = Math.min(total - 1, current + 1);
|
|
28349
|
+
for (let i = start; i <= end; i++) {
|
|
28350
|
+
pages.push(i);
|
|
28351
|
+
}
|
|
28352
|
+
if (current < total - 2) {
|
|
28353
|
+
pages.push('ellipsis');
|
|
28354
|
+
}
|
|
28355
|
+
pages.push(total);
|
|
28356
|
+
return pages;
|
|
28357
|
+
}, ...(ngDevMode ? [{ debugName: "visiblePages" }] : /* istanbul ignore next */ []));
|
|
28358
|
+
/** Navigates to the given page, clamped into the valid range. */
|
|
28359
|
+
goToPage(page) {
|
|
28360
|
+
if (this.disabled())
|
|
28361
|
+
return;
|
|
28362
|
+
const clamped = Math.max(1, Math.min(page, this.totalPages()));
|
|
28363
|
+
if (clamped === this.page())
|
|
28364
|
+
return;
|
|
28365
|
+
this.page.set(clamped);
|
|
28366
|
+
this.changed.emit({ page: clamped, pageSize: this.pageSize() });
|
|
28367
|
+
}
|
|
28368
|
+
/** Navigates to the previous page if one exists. */
|
|
28369
|
+
prevPage() {
|
|
28370
|
+
if (this.canGoPrev())
|
|
28371
|
+
this.goToPage(this.page() - 1);
|
|
28372
|
+
}
|
|
28373
|
+
/** Navigates to the next page if one exists. */
|
|
28374
|
+
nextPage() {
|
|
28375
|
+
if (this.canGoNext())
|
|
28376
|
+
this.goToPage(this.page() + 1);
|
|
28377
|
+
}
|
|
28378
|
+
onPageSizeChange(event) {
|
|
28379
|
+
if (this.disabled())
|
|
28380
|
+
return;
|
|
28381
|
+
const newSize = Number(event.target.value);
|
|
28382
|
+
this.pageSize.set(newSize);
|
|
28383
|
+
this.page.set(1);
|
|
28384
|
+
this.changed.emit({ page: 1, pageSize: newSize });
|
|
28385
|
+
}
|
|
28386
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: PaginatorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
28387
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.13", type: PaginatorComponent, isStandalone: true, selector: "ea-paginator", inputs: { totalItems: { classPropertyName: "totalItems", publicName: "totalItems", isSignal: true, isRequired: true, transformFunction: null }, pageSizeOptions: { classPropertyName: "pageSizeOptions", publicName: "pageSizeOptions", isSignal: true, isRequired: false, transformFunction: null }, showPageSizeSelector: { classPropertyName: "showPageSizeSelector", publicName: "showPageSizeSelector", isSignal: true, isRequired: false, transformFunction: null }, showRangeLabel: { classPropertyName: "showRangeLabel", publicName: "showRangeLabel", isSignal: true, isRequired: false, transformFunction: null }, align: { classPropertyName: "align", publicName: "align", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, page: { classPropertyName: "page", publicName: "page", isSignal: true, isRequired: false, transformFunction: null }, pageSize: { classPropertyName: "pageSize", publicName: "pageSize", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { page: "pageChange", pageSize: "pageSizeChange", changed: "changed" }, ngImport: i0, template: "<div\n class=\"ea-paginator\"\n [class.ea-paginator--left]=\"align() === 'left'\"\n [class.ea-paginator--center]=\"align() === 'center'\"\n [class.ea-paginator--disabled]=\"disabled()\"\n role=\"navigation\"\n [attr.aria-label]=\"i18n.messages().paginator.label\">\n @if (showPageSizeSelector()) {\n <div class=\"ea-paginator__page-size\">\n <label\n class=\"ea-paginator__label\"\n for=\"ea-paginator-size\">\n {{ i18n.messages().paginator.rowsPerPage }}\n </label>\n <select\n class=\"ea-paginator__select\"\n id=\"ea-paginator-size\"\n [disabled]=\"disabled()\"\n (change)=\"onPageSizeChange($event)\">\n @for (size of pageSizeOptions(); track size) {\n <option\n [value]=\"size\"\n [selected]=\"size === pageSize()\">\n {{ size }}\n </option>\n }\n </select>\n </div>\n }\n\n @if (showRangeLabel()) {\n <span class=\"ea-paginator__range\">\n {{ i18n.messages().paginator.range(rangeStart(), rangeEnd(), totalItems()) }}\n </span>\n }\n\n <div class=\"ea-paginator__controls\">\n <ea-button\n variant=\"ghost\"\n size=\"sm\"\n [disabled]=\"disabled() || !canGoPrev()\"\n [aria-label]=\"i18n.messages().paginator.previousPage\"\n (clicked)=\"prevPage()\">\n <ea-icon-chevron-left />\n </ea-button>\n\n @for (p of visiblePages(); track $index) {\n @if (p === 'ellipsis') {\n <span class=\"ea-paginator__ellipsis\">\u2026</span>\n } @else {\n <ea-button\n class=\"ea-paginator__page-btn\"\n [class.ea-paginator__page-btn--active]=\"p === page()\"\n variant=\"ghost\"\n size=\"sm\"\n [disabled]=\"disabled()\"\n [aria-current]=\"p === page() ? 'page' : undefined\"\n (clicked)=\"goToPage(p)\">\n {{ p }}\n </ea-button>\n }\n }\n\n <ea-button\n variant=\"ghost\"\n size=\"sm\"\n [disabled]=\"disabled() || !canGoNext()\"\n [aria-label]=\"i18n.messages().paginator.nextPage\"\n (clicked)=\"nextPage()\">\n <ea-icon-chevron-right />\n </ea-button>\n </div>\n</div>\n", styles: [".ea-paginator{display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-end;gap:var(--space-4);padding:var(--space-3) var(--space-4);font-family:var(--font-family-sans);font-size:var(--font-size-sm);color:var(--color-text-secondary);border-top:var(--border-width-thin) solid var(--color-border-default)}.ea-paginator--left{justify-content:flex-start}.ea-paginator--center{justify-content:center}.ea-paginator__page-size{display:flex;align-items:center;gap:var(--space-2)}.ea-paginator__label{white-space:nowrap;color:var(--color-text-secondary)}.ea-paginator__select{padding:var(--space-1) calc(var(--space-2) + 1rem) var(--space-1) var(--space-2);font-size:var(--font-size-sm);font-family:var(--font-family-sans);border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-md);background-color:var(--color-bg-base);background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23666' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E\");background-repeat:no-repeat;background-position:right 6px center;color:var(--color-text-primary);cursor:pointer;appearance:none;transition:var(--transition-colors),var(--transition-shadow)}.ea-paginator__select:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-paginator__select:disabled{opacity:.5;cursor:not-allowed}.ea-paginator__range{white-space:nowrap;color:var(--color-text-secondary)}.ea-paginator__controls{display:flex;align-items:center;gap:var(--space-1)}.ea-paginator__controls ea-icon-chevron-left,.ea-paginator__controls ea-icon-chevron-right{width:1rem;height:1rem}.ea-paginator__page-btn--active .ea-button{font-weight:var(--font-weight-medium);border-color:var(--color-brand-default);background-color:var(--color-brand-subtle);color:var(--color-brand-default)}.ea-paginator__page-btn--active .ea-button:hover:not(.ea-button--disabled){background-color:var(--color-brand-muted)}.ea-paginator__ellipsis{display:inline-flex;align-items:center;justify-content:center;min-width:2rem;height:2rem;color:var(--color-text-tertiary);pointer-events:none;-webkit-user-select:none;user-select:none}.ea-paginator--disabled{pointer-events:none}.ea-paginator--disabled .ea-paginator__range,.ea-paginator--disabled .ea-paginator__label{opacity:.5}\n"], dependencies: [{ kind: "component", type: ButtonComponent, selector: "ea-button", inputs: ["variant", "size", "type", "disabled", "loading", "fullWidth", "aria-label", "aria-current"], outputs: ["clicked"] }, { kind: "component", type: ChevronLeftIconComponent, selector: "ea-icon-chevron-left" }, { kind: "component", type: ChevronRightIconComponent, selector: "ea-icon-chevron-right" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
28388
|
+
}
|
|
28389
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: PaginatorComponent, decorators: [{
|
|
28390
|
+
type: Component,
|
|
28391
|
+
args: [{ selector: 'ea-paginator', imports: [ButtonComponent, ChevronLeftIconComponent, ChevronRightIconComponent], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div\n class=\"ea-paginator\"\n [class.ea-paginator--left]=\"align() === 'left'\"\n [class.ea-paginator--center]=\"align() === 'center'\"\n [class.ea-paginator--disabled]=\"disabled()\"\n role=\"navigation\"\n [attr.aria-label]=\"i18n.messages().paginator.label\">\n @if (showPageSizeSelector()) {\n <div class=\"ea-paginator__page-size\">\n <label\n class=\"ea-paginator__label\"\n for=\"ea-paginator-size\">\n {{ i18n.messages().paginator.rowsPerPage }}\n </label>\n <select\n class=\"ea-paginator__select\"\n id=\"ea-paginator-size\"\n [disabled]=\"disabled()\"\n (change)=\"onPageSizeChange($event)\">\n @for (size of pageSizeOptions(); track size) {\n <option\n [value]=\"size\"\n [selected]=\"size === pageSize()\">\n {{ size }}\n </option>\n }\n </select>\n </div>\n }\n\n @if (showRangeLabel()) {\n <span class=\"ea-paginator__range\">\n {{ i18n.messages().paginator.range(rangeStart(), rangeEnd(), totalItems()) }}\n </span>\n }\n\n <div class=\"ea-paginator__controls\">\n <ea-button\n variant=\"ghost\"\n size=\"sm\"\n [disabled]=\"disabled() || !canGoPrev()\"\n [aria-label]=\"i18n.messages().paginator.previousPage\"\n (clicked)=\"prevPage()\">\n <ea-icon-chevron-left />\n </ea-button>\n\n @for (p of visiblePages(); track $index) {\n @if (p === 'ellipsis') {\n <span class=\"ea-paginator__ellipsis\">\u2026</span>\n } @else {\n <ea-button\n class=\"ea-paginator__page-btn\"\n [class.ea-paginator__page-btn--active]=\"p === page()\"\n variant=\"ghost\"\n size=\"sm\"\n [disabled]=\"disabled()\"\n [aria-current]=\"p === page() ? 'page' : undefined\"\n (clicked)=\"goToPage(p)\">\n {{ p }}\n </ea-button>\n }\n }\n\n <ea-button\n variant=\"ghost\"\n size=\"sm\"\n [disabled]=\"disabled() || !canGoNext()\"\n [aria-label]=\"i18n.messages().paginator.nextPage\"\n (clicked)=\"nextPage()\">\n <ea-icon-chevron-right />\n </ea-button>\n </div>\n</div>\n", styles: [".ea-paginator{display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-end;gap:var(--space-4);padding:var(--space-3) var(--space-4);font-family:var(--font-family-sans);font-size:var(--font-size-sm);color:var(--color-text-secondary);border-top:var(--border-width-thin) solid var(--color-border-default)}.ea-paginator--left{justify-content:flex-start}.ea-paginator--center{justify-content:center}.ea-paginator__page-size{display:flex;align-items:center;gap:var(--space-2)}.ea-paginator__label{white-space:nowrap;color:var(--color-text-secondary)}.ea-paginator__select{padding:var(--space-1) calc(var(--space-2) + 1rem) var(--space-1) var(--space-2);font-size:var(--font-size-sm);font-family:var(--font-family-sans);border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-md);background-color:var(--color-bg-base);background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23666' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E\");background-repeat:no-repeat;background-position:right 6px center;color:var(--color-text-primary);cursor:pointer;appearance:none;transition:var(--transition-colors),var(--transition-shadow)}.ea-paginator__select:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-paginator__select:disabled{opacity:.5;cursor:not-allowed}.ea-paginator__range{white-space:nowrap;color:var(--color-text-secondary)}.ea-paginator__controls{display:flex;align-items:center;gap:var(--space-1)}.ea-paginator__controls ea-icon-chevron-left,.ea-paginator__controls ea-icon-chevron-right{width:1rem;height:1rem}.ea-paginator__page-btn--active .ea-button{font-weight:var(--font-weight-medium);border-color:var(--color-brand-default);background-color:var(--color-brand-subtle);color:var(--color-brand-default)}.ea-paginator__page-btn--active .ea-button:hover:not(.ea-button--disabled){background-color:var(--color-brand-muted)}.ea-paginator__ellipsis{display:inline-flex;align-items:center;justify-content:center;min-width:2rem;height:2rem;color:var(--color-text-tertiary);pointer-events:none;-webkit-user-select:none;user-select:none}.ea-paginator--disabled{pointer-events:none}.ea-paginator--disabled .ea-paginator__range,.ea-paginator--disabled .ea-paginator__label{opacity:.5}\n"] }]
|
|
28392
|
+
}], propDecorators: { totalItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "totalItems", required: true }] }], pageSizeOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSizeOptions", required: false }] }], showPageSizeSelector: [{ type: i0.Input, args: [{ isSignal: true, alias: "showPageSizeSelector", required: false }] }], showRangeLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "showRangeLabel", required: false }] }], align: [{ type: i0.Input, args: [{ isSignal: true, alias: "align", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], page: [{ type: i0.Input, args: [{ isSignal: true, alias: "page", required: false }] }, { type: i0.Output, args: ["pageChange"] }], pageSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageSize", required: false }] }, { type: i0.Output, args: ["pageSizeChange"] }], changed: [{ type: i0.Output, args: ["changed"] }] } });
|
|
28393
|
+
|
|
28394
|
+
/**
|
|
28395
|
+
* Linear progress indicator supporting both determinate (driven by `value`
|
|
28396
|
+
* and `max`) and indeterminate modes. Optionally renders an inline label
|
|
28397
|
+
* and/or the current percentage.
|
|
28398
|
+
*/
|
|
28399
|
+
class ProgressBarComponent {
|
|
28400
|
+
i18n = inject(EagamiI18nService);
|
|
28401
|
+
value = input(0, ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
28402
|
+
max = input(100, ...(ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []));
|
|
27677
28403
|
variant = input('default', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
27678
28404
|
size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
27679
28405
|
label = input(undefined, ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
@@ -27808,6 +28534,213 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImpo
|
|
|
27808
28534
|
args: [{ selector: 'ea-radio', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgClass], template: "<label\n class=\"ea-radio\"\n [ngClass]=\"hostClasses()\"\n [for]=\"id()\">\n <input\n type=\"radio\"\n class=\"ea-radio__input\"\n [id]=\"id()\"\n [name]=\"name()\"\n [value]=\"value()\"\n [checked]=\"isChecked()\"\n [disabled]=\"isDisabled()\"\n (change)=\"handleChange()\" />\n\n <span\n class=\"ea-radio__circle\"\n aria-hidden=\"true\">\n </span>\n\n @if (label()) {\n <span class=\"ea-radio__label\">{{ label() }}</span>\n }\n</label>\n", styles: [".ea-radio{display:inline-flex;align-items:center;gap:var(--space-2);cursor:pointer;-webkit-user-select:none;user-select:none;font-family:var(--font-family-sans);color:var(--color-text-primary)}.ea-radio--sm .ea-radio__circle{width:1rem;height:1rem}.ea-radio--sm .ea-radio__label{font-size:var(--font-size-sm);line-height:1rem}.ea-radio--md .ea-radio__circle{width:1.25rem;height:1.25rem}.ea-radio--md .ea-radio__label{font-size:var(--font-size-sm);line-height:1.25rem}.ea-radio--lg .ea-radio__circle{width:1.5rem;height:1.5rem}.ea-radio--lg .ea-radio__label{font-size:var(--font-size-md);line-height:1.5rem}.ea-radio--disabled{opacity:.45;cursor:not-allowed}.ea-radio--checked .ea-radio__circle{border-color:var(--color-brand-default)}.ea-radio--checked .ea-radio__circle:after{transform:scale(1)}.ea-radio:hover:not(.ea-radio--disabled) .ea-radio__circle{border-color:var(--color-brand-default)}.ea-radio__input{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.ea-radio__input:focus-visible+.ea-radio__circle{box-shadow:var(--shadow-focus-ring)}.ea-radio__circle{display:flex;align-items:center;justify-content:center;flex-shrink:0;border-radius:var(--radius-full);background-color:var(--color-bg-base);border:var(--border-width-medium) solid var(--color-border-strong);transition:var(--transition-colors),var(--transition-shadow)}.ea-radio__circle:after{content:\"\";display:block;width:45%;height:45%;border-radius:var(--radius-full);background-color:var(--color-brand-default);transform:scale(0);transition:var(--transition-transform)}.ea-radio__label{font-weight:var(--font-weight-regular)}\n"] }]
|
|
27809
28535
|
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }] } });
|
|
27810
28536
|
|
|
28537
|
+
/**
|
|
28538
|
+
* Two-thumb extension of `<ea-slider>`. Drives a `[low, high]` numeric range
|
|
28539
|
+
* with pointer drag (the closer thumb to the pointer responds) and full
|
|
28540
|
+
* keyboard navigation per thumb (arrows / PageUp / PageDown / Home / End).
|
|
28541
|
+
* Tab moves between thumbs. Configurable `min`, `max`, `step`, optional value
|
|
28542
|
+
* display, and integrates with Angular forms via `ControlValueAccessor`.
|
|
28543
|
+
*
|
|
28544
|
+
* Overlap rule: a thumb cannot cross past the other; once it reaches the
|
|
28545
|
+
* opposite thumb's position, it clamps to that boundary. Drag-induced
|
|
28546
|
+
* overlap (where the user yanks the low thumb past the high) is resolved by
|
|
28547
|
+
* keeping the moving thumb on its side and the other thumb pinned.
|
|
28548
|
+
*/
|
|
28549
|
+
class RangeSliderComponent {
|
|
28550
|
+
trackEl = viewChild('trackEl', ...(ngDevMode ? [{ debugName: "trackEl" }] : /* istanbul ignore next */ []));
|
|
28551
|
+
label = input(undefined, ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
28552
|
+
hint = input(undefined, ...(ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []));
|
|
28553
|
+
errorMsg = input(undefined, ...(ngDevMode ? [{ debugName: "errorMsg" }] : /* istanbul ignore next */ []));
|
|
28554
|
+
min = input(0, ...(ngDevMode ? [{ debugName: "min" }] : /* istanbul ignore next */ []));
|
|
28555
|
+
max = input(100, ...(ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []));
|
|
28556
|
+
step = input(1, ...(ngDevMode ? [{ debugName: "step" }] : /* istanbul ignore next */ []));
|
|
28557
|
+
size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
28558
|
+
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
28559
|
+
required = input(false, ...(ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []));
|
|
28560
|
+
showValue = input(false, ...(ngDevMode ? [{ debugName: "showValue" }] : /* istanbul ignore next */ []));
|
|
28561
|
+
showMinMaxLabels = input(false, ...(ngDevMode ? [{ debugName: "showMinMaxLabels" }] : /* istanbul ignore next */ []));
|
|
28562
|
+
formatValue = input(value => `${value}`, ...(ngDevMode ? [{ debugName: "formatValue" }] : /* istanbul ignore next */ []));
|
|
28563
|
+
/** Accessible label for the low (start) thumb. Falls back to the field label when omitted. */
|
|
28564
|
+
ariaLabelLow = input(undefined, { ...(ngDevMode ? { debugName: "ariaLabelLow" } : /* istanbul ignore next */ {}), alias: 'aria-label-low' });
|
|
28565
|
+
/** Accessible label for the high (end) thumb. Falls back to the field label when omitted. */
|
|
28566
|
+
ariaLabelHigh = input(undefined, { ...(ngDevMode ? { debugName: "ariaLabelHigh" } : /* istanbul ignore next */ {}), alias: 'aria-label-high' });
|
|
28567
|
+
id = input(`ea-range-slider-${Math.random().toString(36).slice(2, 9)}`, ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
|
|
28568
|
+
value = model([0, 100], ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
28569
|
+
/** Fires with the new `[low, high]` tuple whenever either thumb moves. */
|
|
28570
|
+
changed = output();
|
|
28571
|
+
_formDisabled = signal(false, ...(ngDevMode ? [{ debugName: "_formDisabled" }] : /* istanbul ignore next */ []));
|
|
28572
|
+
dragging = signal(null, ...(ngDevMode ? [{ debugName: "dragging" }] : /* istanbul ignore next */ []));
|
|
28573
|
+
onChange = () => { };
|
|
28574
|
+
onTouched = () => { };
|
|
28575
|
+
isDisabled = computed(() => this.disabled() || this._formDisabled(), ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
|
|
28576
|
+
/** Clamped, ordered `[low, high]` tuple — `low <= high`, both within `[min, max]`. */
|
|
28577
|
+
clampedValue = computed(() => {
|
|
28578
|
+
const [a, b] = this.value();
|
|
28579
|
+
const min = this.min();
|
|
28580
|
+
const max = this.max();
|
|
28581
|
+
const lo = Math.min(max, Math.max(min, Math.min(a, b)));
|
|
28582
|
+
const hi = Math.min(max, Math.max(min, Math.max(a, b)));
|
|
28583
|
+
return [lo, hi];
|
|
28584
|
+
}, ...(ngDevMode ? [{ debugName: "clampedValue" }] : /* istanbul ignore next */ []));
|
|
28585
|
+
lowPercent = computed(() => this.toPercent(this.clampedValue()[0]), ...(ngDevMode ? [{ debugName: "lowPercent" }] : /* istanbul ignore next */ []));
|
|
28586
|
+
highPercent = computed(() => this.toPercent(this.clampedValue()[1]), ...(ngDevMode ? [{ debugName: "highPercent" }] : /* istanbul ignore next */ []));
|
|
28587
|
+
hasError = computed(() => !!this.errorMsg(), ...(ngDevMode ? [{ debugName: "hasError" }] : /* istanbul ignore next */ []));
|
|
28588
|
+
showError = this.hasError;
|
|
28589
|
+
showHint = computed(() => !!this.hint() && !this.hasError(), ...(ngDevMode ? [{ debugName: "showHint" }] : /* istanbul ignore next */ []));
|
|
28590
|
+
hostClasses = computed(() => ({
|
|
28591
|
+
[`ea-range-slider--${this.size()}`]: true,
|
|
28592
|
+
'ea-range-slider--error': this.hasError(),
|
|
28593
|
+
'ea-range-slider--disabled': this.isDisabled(),
|
|
28594
|
+
'ea-range-slider--dragging': this.dragging() !== null,
|
|
28595
|
+
}), ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
|
|
28596
|
+
// ─── ControlValueAccessor ───────────────────────────────────────────────
|
|
28597
|
+
writeValue(val) {
|
|
28598
|
+
if (Array.isArray(val) && val.length === 2) {
|
|
28599
|
+
const [a, b] = val;
|
|
28600
|
+
const safeA = typeof a === 'number' && !isNaN(a) ? a : this.min();
|
|
28601
|
+
const safeB = typeof b === 'number' && !isNaN(b) ? b : this.max();
|
|
28602
|
+
this.value.set([safeA, safeB]);
|
|
28603
|
+
}
|
|
28604
|
+
else {
|
|
28605
|
+
this.value.set([this.min(), this.max()]);
|
|
28606
|
+
}
|
|
28607
|
+
}
|
|
28608
|
+
registerOnChange(fn) {
|
|
28609
|
+
this.onChange = fn;
|
|
28610
|
+
}
|
|
28611
|
+
registerOnTouched(fn) {
|
|
28612
|
+
this.onTouched = fn;
|
|
28613
|
+
}
|
|
28614
|
+
setDisabledState(isDisabled) {
|
|
28615
|
+
this._formDisabled.set(isDisabled);
|
|
28616
|
+
}
|
|
28617
|
+
// ─── Keyboard ───────────────────────────────────────────────────────────
|
|
28618
|
+
handleKeydown(event, thumb) {
|
|
28619
|
+
if (this.isDisabled())
|
|
28620
|
+
return;
|
|
28621
|
+
const [lo, hi] = this.clampedValue();
|
|
28622
|
+
const current = thumb === 'low' ? lo : hi;
|
|
28623
|
+
const step = this.step();
|
|
28624
|
+
const bigStep = Math.max(step * 10, (this.max() - this.min()) / 10);
|
|
28625
|
+
let next;
|
|
28626
|
+
switch (event.key) {
|
|
28627
|
+
case 'ArrowRight':
|
|
28628
|
+
case 'ArrowUp':
|
|
28629
|
+
next = current + step;
|
|
28630
|
+
break;
|
|
28631
|
+
case 'ArrowLeft':
|
|
28632
|
+
case 'ArrowDown':
|
|
28633
|
+
next = current - step;
|
|
28634
|
+
break;
|
|
28635
|
+
case 'PageUp':
|
|
28636
|
+
next = current + bigStep;
|
|
28637
|
+
break;
|
|
28638
|
+
case 'PageDown':
|
|
28639
|
+
next = current - bigStep;
|
|
28640
|
+
break;
|
|
28641
|
+
case 'Home':
|
|
28642
|
+
next = this.min();
|
|
28643
|
+
break;
|
|
28644
|
+
case 'End':
|
|
28645
|
+
next = this.max();
|
|
28646
|
+
break;
|
|
28647
|
+
default:
|
|
28648
|
+
return;
|
|
28649
|
+
}
|
|
28650
|
+
event.preventDefault();
|
|
28651
|
+
this.commitThumb(thumb, next);
|
|
28652
|
+
}
|
|
28653
|
+
handleBlur() {
|
|
28654
|
+
this.onTouched();
|
|
28655
|
+
}
|
|
28656
|
+
// ─── Pointer ────────────────────────────────────────────────────────────
|
|
28657
|
+
handleTrackPointerDown(event) {
|
|
28658
|
+
if (this.isDisabled())
|
|
28659
|
+
return;
|
|
28660
|
+
const track = this.trackEl()?.nativeElement;
|
|
28661
|
+
if (!track)
|
|
28662
|
+
return;
|
|
28663
|
+
// Pick whichever thumb is closer to the pointer's track-relative ratio,
|
|
28664
|
+
// breaking ties toward the low thumb. Then begin dragging that thumb.
|
|
28665
|
+
const raw = this.pointerToValue(event, track);
|
|
28666
|
+
const [lo, hi] = this.clampedValue();
|
|
28667
|
+
const target = Math.abs(raw - lo) <= Math.abs(raw - hi) ? 'low' : 'high';
|
|
28668
|
+
event.target.setPointerCapture?.(event.pointerId);
|
|
28669
|
+
this.dragging.set(target);
|
|
28670
|
+
this.commitThumb(target, raw);
|
|
28671
|
+
}
|
|
28672
|
+
handleTrackPointerMove(event) {
|
|
28673
|
+
const active = this.dragging();
|
|
28674
|
+
if (!active || this.isDisabled())
|
|
28675
|
+
return;
|
|
28676
|
+
const track = this.trackEl()?.nativeElement;
|
|
28677
|
+
if (!track)
|
|
28678
|
+
return;
|
|
28679
|
+
this.commitThumb(active, this.pointerToValue(event, track));
|
|
28680
|
+
}
|
|
28681
|
+
handleTrackPointerUp(event) {
|
|
28682
|
+
if (!this.dragging())
|
|
28683
|
+
return;
|
|
28684
|
+
event.target.releasePointerCapture?.(event.pointerId);
|
|
28685
|
+
this.dragging.set(null);
|
|
28686
|
+
this.onTouched();
|
|
28687
|
+
}
|
|
28688
|
+
// ─── Internals ──────────────────────────────────────────────────────────
|
|
28689
|
+
toPercent(value) {
|
|
28690
|
+
const range = this.max() - this.min();
|
|
28691
|
+
if (range <= 0)
|
|
28692
|
+
return 0;
|
|
28693
|
+
return ((value - this.min()) / range) * 100;
|
|
28694
|
+
}
|
|
28695
|
+
pointerToValue(event, track) {
|
|
28696
|
+
const rect = track.getBoundingClientRect();
|
|
28697
|
+
const ratio = Math.min(1, Math.max(0, (event.clientX - rect.left) / rect.width));
|
|
28698
|
+
return this.min() + ratio * (this.max() - this.min());
|
|
28699
|
+
}
|
|
28700
|
+
/** Snap to step, clamp to `[min, max]`, then constrain by the opposite thumb. */
|
|
28701
|
+
commitThumb(thumb, raw) {
|
|
28702
|
+
const step = this.step();
|
|
28703
|
+
const min = this.min();
|
|
28704
|
+
const max = this.max();
|
|
28705
|
+
const snapped = Math.round((raw - min) / step) * step + min;
|
|
28706
|
+
const clamped = Math.min(max, Math.max(min, snapped));
|
|
28707
|
+
const rounded = Number(clamped.toFixed(10));
|
|
28708
|
+
const [lo, hi] = this.clampedValue();
|
|
28709
|
+
let nextLo = lo;
|
|
28710
|
+
let nextHi = hi;
|
|
28711
|
+
if (thumb === 'low') {
|
|
28712
|
+
nextLo = Math.min(rounded, hi);
|
|
28713
|
+
}
|
|
28714
|
+
else {
|
|
28715
|
+
nextHi = Math.max(rounded, lo);
|
|
28716
|
+
}
|
|
28717
|
+
if (nextLo === lo && nextHi === hi)
|
|
28718
|
+
return;
|
|
28719
|
+
const next = [nextLo, nextHi];
|
|
28720
|
+
this.value.set(next);
|
|
28721
|
+
this.onChange(next);
|
|
28722
|
+
this.changed.emit(next);
|
|
28723
|
+
}
|
|
28724
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: RangeSliderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
28725
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.13", type: RangeSliderComponent, isStandalone: true, selector: "ea-range-slider", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, errorMsg: { classPropertyName: "errorMsg", publicName: "errorMsg", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, step: { classPropertyName: "step", publicName: "step", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, showValue: { classPropertyName: "showValue", publicName: "showValue", isSignal: true, isRequired: false, transformFunction: null }, showMinMaxLabels: { classPropertyName: "showMinMaxLabels", publicName: "showMinMaxLabels", isSignal: true, isRequired: false, transformFunction: null }, formatValue: { classPropertyName: "formatValue", publicName: "formatValue", isSignal: true, isRequired: false, transformFunction: null }, ariaLabelLow: { classPropertyName: "ariaLabelLow", publicName: "aria-label-low", isSignal: true, isRequired: false, transformFunction: null }, ariaLabelHigh: { classPropertyName: "ariaLabelHigh", publicName: "aria-label-high", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", changed: "changed" }, providers: [
|
|
28726
|
+
{
|
|
28727
|
+
provide: NG_VALUE_ACCESSOR,
|
|
28728
|
+
useExisting: forwardRef(() => RangeSliderComponent),
|
|
28729
|
+
multi: true,
|
|
28730
|
+
},
|
|
28731
|
+
], viewQueries: [{ propertyName: "trackEl", first: true, predicate: ["trackEl"], descendants: true, isSignal: true }], ngImport: i0, template: "<div\n class=\"ea-range-slider-field\"\n [ngClass]=\"hostClasses()\">\n @if (label()) {\n <span\n class=\"ea-range-slider-field__label\"\n [id]=\"id() + '-label'\"\n [class.ea-range-slider-field__label--required]=\"required()\">\n {{ label() }}\n @if (showValue()) {\n <span class=\"ea-range-slider-field__value\">\n {{ formatValue()(clampedValue()[0]) }} \u2013 {{ formatValue()(clampedValue()[1]) }}\n </span>\n }\n </span>\n }\n\n <div class=\"ea-range-slider\">\n <div\n #trackEl\n class=\"ea-range-slider__track\"\n (pointerdown)=\"handleTrackPointerDown($event)\"\n (pointermove)=\"handleTrackPointerMove($event)\"\n (pointerup)=\"handleTrackPointerUp($event)\"\n (pointercancel)=\"handleTrackPointerUp($event)\">\n <div\n class=\"ea-range-slider__fill\"\n [style.left.%]=\"lowPercent()\"\n [style.right.%]=\"100 - highPercent()\">\n </div>\n <div\n class=\"ea-range-slider__thumb ea-range-slider__thumb--low\"\n role=\"slider\"\n tabindex=\"0\"\n [id]=\"id() + '-low'\"\n [attr.aria-labelledby]=\"label() ? id() + '-label' : null\"\n [attr.aria-label]=\"!label() ? (ariaLabelLow() ?? null) : null\"\n [attr.aria-valuemin]=\"min()\"\n [attr.aria-valuemax]=\"clampedValue()[1]\"\n [attr.aria-valuenow]=\"clampedValue()[0]\"\n [attr.aria-valuetext]=\"formatValue()(clampedValue()[0])\"\n [attr.aria-disabled]=\"isDisabled() || null\"\n [attr.aria-required]=\"required() || null\"\n [attr.aria-invalid]=\"hasError() || null\"\n [attr.aria-describedby]=\"\n showError() ? id() + '-error' : showHint() ? id() + '-hint' : null\n \"\n [style.left.%]=\"lowPercent()\"\n (keydown)=\"handleKeydown($event, 'low')\"\n (blur)=\"handleBlur()\">\n </div>\n <div\n class=\"ea-range-slider__thumb ea-range-slider__thumb--high\"\n role=\"slider\"\n tabindex=\"0\"\n [id]=\"id() + '-high'\"\n [attr.aria-labelledby]=\"label() ? id() + '-label' : null\"\n [attr.aria-label]=\"!label() ? (ariaLabelHigh() ?? null) : null\"\n [attr.aria-valuemin]=\"clampedValue()[0]\"\n [attr.aria-valuemax]=\"max()\"\n [attr.aria-valuenow]=\"clampedValue()[1]\"\n [attr.aria-valuetext]=\"formatValue()(clampedValue()[1])\"\n [attr.aria-disabled]=\"isDisabled() || null\"\n [attr.aria-required]=\"required() || null\"\n [attr.aria-invalid]=\"hasError() || null\"\n [attr.aria-describedby]=\"\n showError() ? id() + '-error' : showHint() ? id() + '-hint' : null\n \"\n [style.left.%]=\"highPercent()\"\n (keydown)=\"handleKeydown($event, 'high')\"\n (blur)=\"handleBlur()\">\n </div>\n </div>\n\n @if (showMinMaxLabels()) {\n <div class=\"ea-range-slider__minmax\">\n <span class=\"ea-range-slider__minmax-label\">\n {{ formatValue()(min()) }}\n </span>\n <span class=\"ea-range-slider__minmax-label\">\n {{ formatValue()(max()) }}\n </span>\n </div>\n }\n </div>\n\n @if (showError()) {\n <p\n class=\"ea-range-slider-field__message ea-range-slider-field__message--error\"\n [id]=\"id() + '-error'\"\n role=\"alert\">\n <ea-icon-alert-circle class=\"ea-range-slider-field__message-icon\" />\n {{ errorMsg() }}\n </p>\n }\n\n @if (showHint()) {\n <p\n class=\"ea-range-slider-field__message ea-range-slider-field__message--hint\"\n [id]=\"id() + '-hint'\">\n {{ hint() }}\n </p>\n }\n</div>\n", styles: [".ea-range-slider-field{display:flex;flex-direction:column;gap:var(--space-2);font-family:var(--font-family-sans);color:var(--color-text-secondary)}.ea-range-slider-field__label{display:flex;justify-content:space-between;align-items:baseline;gap:var(--space-2);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-range-slider-field__label--required:after{content:\" *\";color:var(--color-error-default)}.ea-range-slider-field__value{font-variant-numeric:tabular-nums;font-weight:var(--font-weight-medium);color:var(--color-text-secondary)}.ea-range-slider-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-range-slider-field__message--hint{color:inherit}.ea-range-slider-field__message--error{color:var(--color-error-default)}.ea-range-slider-field__message-icon{flex-shrink:0;width:.875em;height:.875em}.ea-range-slider{display:flex;flex-direction:column;gap:var(--space-1);width:100%}.ea-range-slider--sm .ea-range-slider .ea-range-slider__track{height:.25rem}.ea-range-slider--sm .ea-range-slider .ea-range-slider__thumb{width:.875rem;height:.875rem}.ea-range-slider--md .ea-range-slider .ea-range-slider__track{height:.375rem}.ea-range-slider--md .ea-range-slider .ea-range-slider__thumb{width:1.125rem;height:1.125rem}.ea-range-slider--lg .ea-range-slider .ea-range-slider__track{height:.5rem}.ea-range-slider--lg .ea-range-slider .ea-range-slider__thumb{width:1.375rem;height:1.375rem}.ea-range-slider__track{position:relative;width:100%;background-color:var(--color-bg-muted);border-radius:var(--radius-full);cursor:pointer;touch-action:none}.ea-range-slider__fill{position:absolute;top:0;height:100%;background-color:var(--color-brand-default);border-radius:inherit;transition:var(--transition-colors)}.ea-range-slider__thumb{position:absolute;top:50%;background-color:var(--color-neutral-0);border:var(--border-width-medium) solid var(--color-brand-default);border-radius:var(--radius-full);box-shadow:var(--shadow-sm);cursor:grab;transform:translate(-50%,-50%);transition:box-shadow var(--duration-fast) var(--ease-out),transform var(--duration-fast) var(--ease-out)}.ea-range-slider__thumb:focus-visible{z-index:1;box-shadow:var(--shadow-focus-ring);outline:none}.ea-range-slider__minmax{display:flex;justify-content:space-between;margin-top:var(--space-1)}.ea-range-slider__minmax-label{font-size:var(--font-size-xs);color:var(--color-text-tertiary);font-variant-numeric:tabular-nums}.ea-range-slider--dragging .ea-range-slider__thumb{cursor:grabbing;transform:translate(-50%,-50%) scale(1.1)}.ea-range-slider--disabled{opacity:.5;cursor:not-allowed}.ea-range-slider--disabled .ea-range-slider__track,.ea-range-slider--disabled .ea-range-slider__thumb{cursor:not-allowed}.ea-range-slider--error .ea-range-slider__fill{background-color:var(--color-error-default)}.ea-range-slider--error .ea-range-slider__thumb{border-color:var(--color-error-default)}.ea-range-slider--error .ea-range-slider__thumb:focus-visible{box-shadow:var(--shadow-focus-ring-error)}\n"], dependencies: [{ kind: "component", type: AlertCircleIconComponent, selector: "ea-icon-alert-circle" }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
28732
|
+
}
|
|
28733
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: RangeSliderComponent, decorators: [{
|
|
28734
|
+
type: Component,
|
|
28735
|
+
args: [{ selector: 'ea-range-slider', changeDetection: ChangeDetectionStrategy.OnPush, imports: [AlertCircleIconComponent, NgClass], providers: [
|
|
28736
|
+
{
|
|
28737
|
+
provide: NG_VALUE_ACCESSOR,
|
|
28738
|
+
useExisting: forwardRef(() => RangeSliderComponent),
|
|
28739
|
+
multi: true,
|
|
28740
|
+
},
|
|
28741
|
+
], template: "<div\n class=\"ea-range-slider-field\"\n [ngClass]=\"hostClasses()\">\n @if (label()) {\n <span\n class=\"ea-range-slider-field__label\"\n [id]=\"id() + '-label'\"\n [class.ea-range-slider-field__label--required]=\"required()\">\n {{ label() }}\n @if (showValue()) {\n <span class=\"ea-range-slider-field__value\">\n {{ formatValue()(clampedValue()[0]) }} \u2013 {{ formatValue()(clampedValue()[1]) }}\n </span>\n }\n </span>\n }\n\n <div class=\"ea-range-slider\">\n <div\n #trackEl\n class=\"ea-range-slider__track\"\n (pointerdown)=\"handleTrackPointerDown($event)\"\n (pointermove)=\"handleTrackPointerMove($event)\"\n (pointerup)=\"handleTrackPointerUp($event)\"\n (pointercancel)=\"handleTrackPointerUp($event)\">\n <div\n class=\"ea-range-slider__fill\"\n [style.left.%]=\"lowPercent()\"\n [style.right.%]=\"100 - highPercent()\">\n </div>\n <div\n class=\"ea-range-slider__thumb ea-range-slider__thumb--low\"\n role=\"slider\"\n tabindex=\"0\"\n [id]=\"id() + '-low'\"\n [attr.aria-labelledby]=\"label() ? id() + '-label' : null\"\n [attr.aria-label]=\"!label() ? (ariaLabelLow() ?? null) : null\"\n [attr.aria-valuemin]=\"min()\"\n [attr.aria-valuemax]=\"clampedValue()[1]\"\n [attr.aria-valuenow]=\"clampedValue()[0]\"\n [attr.aria-valuetext]=\"formatValue()(clampedValue()[0])\"\n [attr.aria-disabled]=\"isDisabled() || null\"\n [attr.aria-required]=\"required() || null\"\n [attr.aria-invalid]=\"hasError() || null\"\n [attr.aria-describedby]=\"\n showError() ? id() + '-error' : showHint() ? id() + '-hint' : null\n \"\n [style.left.%]=\"lowPercent()\"\n (keydown)=\"handleKeydown($event, 'low')\"\n (blur)=\"handleBlur()\">\n </div>\n <div\n class=\"ea-range-slider__thumb ea-range-slider__thumb--high\"\n role=\"slider\"\n tabindex=\"0\"\n [id]=\"id() + '-high'\"\n [attr.aria-labelledby]=\"label() ? id() + '-label' : null\"\n [attr.aria-label]=\"!label() ? (ariaLabelHigh() ?? null) : null\"\n [attr.aria-valuemin]=\"clampedValue()[0]\"\n [attr.aria-valuemax]=\"max()\"\n [attr.aria-valuenow]=\"clampedValue()[1]\"\n [attr.aria-valuetext]=\"formatValue()(clampedValue()[1])\"\n [attr.aria-disabled]=\"isDisabled() || null\"\n [attr.aria-required]=\"required() || null\"\n [attr.aria-invalid]=\"hasError() || null\"\n [attr.aria-describedby]=\"\n showError() ? id() + '-error' : showHint() ? id() + '-hint' : null\n \"\n [style.left.%]=\"highPercent()\"\n (keydown)=\"handleKeydown($event, 'high')\"\n (blur)=\"handleBlur()\">\n </div>\n </div>\n\n @if (showMinMaxLabels()) {\n <div class=\"ea-range-slider__minmax\">\n <span class=\"ea-range-slider__minmax-label\">\n {{ formatValue()(min()) }}\n </span>\n <span class=\"ea-range-slider__minmax-label\">\n {{ formatValue()(max()) }}\n </span>\n </div>\n }\n </div>\n\n @if (showError()) {\n <p\n class=\"ea-range-slider-field__message ea-range-slider-field__message--error\"\n [id]=\"id() + '-error'\"\n role=\"alert\">\n <ea-icon-alert-circle class=\"ea-range-slider-field__message-icon\" />\n {{ errorMsg() }}\n </p>\n }\n\n @if (showHint()) {\n <p\n class=\"ea-range-slider-field__message ea-range-slider-field__message--hint\"\n [id]=\"id() + '-hint'\">\n {{ hint() }}\n </p>\n }\n</div>\n", styles: [".ea-range-slider-field{display:flex;flex-direction:column;gap:var(--space-2);font-family:var(--font-family-sans);color:var(--color-text-secondary)}.ea-range-slider-field__label{display:flex;justify-content:space-between;align-items:baseline;gap:var(--space-2);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-range-slider-field__label--required:after{content:\" *\";color:var(--color-error-default)}.ea-range-slider-field__value{font-variant-numeric:tabular-nums;font-weight:var(--font-weight-medium);color:var(--color-text-secondary)}.ea-range-slider-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-range-slider-field__message--hint{color:inherit}.ea-range-slider-field__message--error{color:var(--color-error-default)}.ea-range-slider-field__message-icon{flex-shrink:0;width:.875em;height:.875em}.ea-range-slider{display:flex;flex-direction:column;gap:var(--space-1);width:100%}.ea-range-slider--sm .ea-range-slider .ea-range-slider__track{height:.25rem}.ea-range-slider--sm .ea-range-slider .ea-range-slider__thumb{width:.875rem;height:.875rem}.ea-range-slider--md .ea-range-slider .ea-range-slider__track{height:.375rem}.ea-range-slider--md .ea-range-slider .ea-range-slider__thumb{width:1.125rem;height:1.125rem}.ea-range-slider--lg .ea-range-slider .ea-range-slider__track{height:.5rem}.ea-range-slider--lg .ea-range-slider .ea-range-slider__thumb{width:1.375rem;height:1.375rem}.ea-range-slider__track{position:relative;width:100%;background-color:var(--color-bg-muted);border-radius:var(--radius-full);cursor:pointer;touch-action:none}.ea-range-slider__fill{position:absolute;top:0;height:100%;background-color:var(--color-brand-default);border-radius:inherit;transition:var(--transition-colors)}.ea-range-slider__thumb{position:absolute;top:50%;background-color:var(--color-neutral-0);border:var(--border-width-medium) solid var(--color-brand-default);border-radius:var(--radius-full);box-shadow:var(--shadow-sm);cursor:grab;transform:translate(-50%,-50%);transition:box-shadow var(--duration-fast) var(--ease-out),transform var(--duration-fast) var(--ease-out)}.ea-range-slider__thumb:focus-visible{z-index:1;box-shadow:var(--shadow-focus-ring);outline:none}.ea-range-slider__minmax{display:flex;justify-content:space-between;margin-top:var(--space-1)}.ea-range-slider__minmax-label{font-size:var(--font-size-xs);color:var(--color-text-tertiary);font-variant-numeric:tabular-nums}.ea-range-slider--dragging .ea-range-slider__thumb{cursor:grabbing;transform:translate(-50%,-50%) scale(1.1)}.ea-range-slider--disabled{opacity:.5;cursor:not-allowed}.ea-range-slider--disabled .ea-range-slider__track,.ea-range-slider--disabled .ea-range-slider__thumb{cursor:not-allowed}.ea-range-slider--error .ea-range-slider__fill{background-color:var(--color-error-default)}.ea-range-slider--error .ea-range-slider__thumb{border-color:var(--color-error-default)}.ea-range-slider--error .ea-range-slider__thumb:focus-visible{box-shadow:var(--shadow-focus-ring-error)}\n"] }]
|
|
28742
|
+
}], propDecorators: { trackEl: [{ type: i0.ViewChild, args: ['trackEl', { isSignal: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], errorMsg: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMsg", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], step: [{ type: i0.Input, args: [{ isSignal: true, alias: "step", 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 }] }], showValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "showValue", required: false }] }], showMinMaxLabels: [{ type: i0.Input, args: [{ isSignal: true, alias: "showMinMaxLabels", required: false }] }], formatValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "formatValue", required: false }] }], ariaLabelLow: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-label-low", required: false }] }], ariaLabelHigh: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-label-high", 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"] }] } });
|
|
28743
|
+
|
|
27811
28744
|
/**
|
|
27812
28745
|
* Compact toggle button group for picking one of a small set of options
|
|
27813
28746
|
* (e.g. List/Grid/Kanban or Light/Dark). Implements `radiogroup` semantics
|
|
@@ -28106,26 +29039,219 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImpo
|
|
|
28106
29039
|
}], propDecorators: { trackEl: [{ type: i0.ViewChild, args: ['trackEl', { isSignal: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], errorMsg: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMsg", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], step: [{ type: i0.Input, args: [{ isSignal: true, alias: "step", 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 }] }], showValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "showValue", required: false }] }], showMinMaxLabels: [{ type: i0.Input, args: [{ isSignal: true, alias: "showMinMaxLabels", required: false }] }], formatValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "formatValue", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-label", 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"] }] } });
|
|
28107
29040
|
|
|
28108
29041
|
/**
|
|
28109
|
-
* SVG loading indicator with an accessible `role="status"`. The `label` input
|
|
28110
|
-
* overrides the accessible name announced to assistive technology; when unset
|
|
28111
|
-
* it falls back to the active locale's translation.
|
|
29042
|
+
* SVG loading indicator with an accessible `role="status"`. The `label` input
|
|
29043
|
+
* overrides the accessible name announced to assistive technology; when unset
|
|
29044
|
+
* it falls back to the active locale's translation.
|
|
29045
|
+
*/
|
|
29046
|
+
class SpinnerComponent {
|
|
29047
|
+
i18n = inject(EagamiI18nService);
|
|
29048
|
+
size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
29049
|
+
label = input(undefined, ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
29050
|
+
/** Accessible label, falling back to the active locale's translation. */
|
|
29051
|
+
resolvedLabel = computed(() => this.label() ?? this.i18n.messages().spinner.label, ...(ngDevMode ? [{ debugName: "resolvedLabel" }] : /* istanbul ignore next */ []));
|
|
29052
|
+
hostClasses = computed(() => ({
|
|
29053
|
+
[`ea-spinner--${this.size()}`]: true,
|
|
29054
|
+
}), ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
|
|
29055
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: SpinnerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
29056
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.13", type: SpinnerComponent, isStandalone: true, selector: "ea-spinner", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div\n class=\"ea-spinner\"\n [ngClass]=\"hostClasses()\"\n role=\"status\">\n <svg\n class=\"ea-spinner__circle\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n aria-hidden=\"true\">\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n opacity=\"0.25\" />\n <path\n d=\"M12 2a10 10 0 0 1 10 10\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\" />\n </svg>\n <span class=\"ea-spinner__label\">{{ resolvedLabel() }}</span>\n</div>\n", styles: [".ea-spinner{display:inline-flex;align-items:center;gap:var(--space-2);color:var(--color-brand-default)}.ea-spinner--sm .ea-spinner__circle{width:1rem;height:1rem}.ea-spinner--sm .ea-spinner__label{font-size:var(--font-size-sm)}.ea-spinner--md .ea-spinner__circle{width:1.5rem;height:1.5rem}.ea-spinner--md .ea-spinner__label{font-size:var(--font-size-sm)}.ea-spinner--lg .ea-spinner__circle{width:2rem;height:2rem}.ea-spinner--lg .ea-spinner__label{font-size:var(--font-size-md)}.ea-spinner__circle{animation:ea-spin .75s linear infinite}@media(prefers-reduced-motion:reduce){.ea-spinner__circle{animation-duration:2.5s}}.ea-spinner__label{font-family:var(--font-family-sans);color:var(--color-text-secondary);line-height:var(--line-height-normal)}@keyframes ea-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
29057
|
+
}
|
|
29058
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: SpinnerComponent, decorators: [{
|
|
29059
|
+
type: Component,
|
|
29060
|
+
args: [{ selector: 'ea-spinner', imports: [NgClass], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div\n class=\"ea-spinner\"\n [ngClass]=\"hostClasses()\"\n role=\"status\">\n <svg\n class=\"ea-spinner__circle\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n aria-hidden=\"true\">\n <circle\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n opacity=\"0.25\" />\n <path\n d=\"M12 2a10 10 0 0 1 10 10\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\" />\n </svg>\n <span class=\"ea-spinner__label\">{{ resolvedLabel() }}</span>\n</div>\n", styles: [".ea-spinner{display:inline-flex;align-items:center;gap:var(--space-2);color:var(--color-brand-default)}.ea-spinner--sm .ea-spinner__circle{width:1rem;height:1rem}.ea-spinner--sm .ea-spinner__label{font-size:var(--font-size-sm)}.ea-spinner--md .ea-spinner__circle{width:1.5rem;height:1.5rem}.ea-spinner--md .ea-spinner__label{font-size:var(--font-size-sm)}.ea-spinner--lg .ea-spinner__circle{width:2rem;height:2rem}.ea-spinner--lg .ea-spinner__label{font-size:var(--font-size-md)}.ea-spinner__circle{animation:ea-spin .75s linear infinite}@media(prefers-reduced-motion:reduce){.ea-spinner__circle{animation-duration:2.5s}}.ea-spinner__label{font-family:var(--font-family-sans);color:var(--color-text-secondary);line-height:var(--line-height-normal)}@keyframes ea-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"] }]
|
|
29061
|
+
}], propDecorators: { size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }] } });
|
|
29062
|
+
|
|
29063
|
+
/**
|
|
29064
|
+
* Multi-step navigation paired with content panels. Child `<ea-step>`
|
|
29065
|
+
* components register themselves automatically and the active panel is
|
|
29066
|
+
* shown based on the `activeStep` (zero-based index) two-way binding.
|
|
29067
|
+
*
|
|
29068
|
+
* In `linear` mode, steps cannot be navigated to until all earlier
|
|
29069
|
+
* non-optional steps are marked `completed`. Otherwise any step can be
|
|
29070
|
+
* clicked. ArrowLeft / ArrowRight walk through reachable steps; Home/End
|
|
29071
|
+
* jump to the extremes.
|
|
29072
|
+
*/
|
|
29073
|
+
class StepperComponent {
|
|
29074
|
+
i18n = inject(EagamiI18nService);
|
|
29075
|
+
registeredSteps = signal([], ...(ngDevMode ? [{ debugName: "registeredSteps" }] : /* istanbul ignore next */ []));
|
|
29076
|
+
// ─── Inputs ───────────────────────────────────────────────────────────
|
|
29077
|
+
activeStep = model(0, ...(ngDevMode ? [{ debugName: "activeStep" }] : /* istanbul ignore next */ []));
|
|
29078
|
+
linear = input(false, ...(ngDevMode ? [{ debugName: "linear" }] : /* istanbul ignore next */ []));
|
|
29079
|
+
size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
29080
|
+
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
29081
|
+
id = input(`ea-stepper-${Math.random().toString(36).slice(2, 9)}`, ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
|
|
29082
|
+
// ─── Outputs ──────────────────────────────────────────────────────────
|
|
29083
|
+
/** Fires with the new active step index when the user navigates. */
|
|
29084
|
+
changed = output();
|
|
29085
|
+
// ─── Computed ─────────────────────────────────────────────────────────
|
|
29086
|
+
hostClasses = computed(() => ({
|
|
29087
|
+
[`ea-stepper--${this.size()}`]: true,
|
|
29088
|
+
'ea-stepper--disabled': this.disabled(),
|
|
29089
|
+
}), ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
|
|
29090
|
+
// ─── Registration ─────────────────────────────────────────────────────
|
|
29091
|
+
registerStep(step) {
|
|
29092
|
+
this.registeredSteps.update(steps => [...steps, step]);
|
|
29093
|
+
}
|
|
29094
|
+
unregisterStep(step) {
|
|
29095
|
+
this.registeredSteps.update(steps => steps.filter(s => s !== step));
|
|
29096
|
+
}
|
|
29097
|
+
/** Returns the index of a given step, or `-1` if it isn't registered. */
|
|
29098
|
+
indexOf(step) {
|
|
29099
|
+
return this.registeredSteps().indexOf(step);
|
|
29100
|
+
}
|
|
29101
|
+
// ─── Navigation ───────────────────────────────────────────────────────
|
|
29102
|
+
/**
|
|
29103
|
+
* True when the user can navigate directly to the step at `index`. In
|
|
29104
|
+
* non-linear mode this is true for any non-disabled step; in linear mode,
|
|
29105
|
+
* every non-optional earlier step must also be marked `completed`.
|
|
29106
|
+
*/
|
|
29107
|
+
canNavigateTo(index) {
|
|
29108
|
+
if (this.disabled())
|
|
29109
|
+
return false;
|
|
29110
|
+
const steps = this.registeredSteps();
|
|
29111
|
+
if (index < 0 || index >= steps.length)
|
|
29112
|
+
return false;
|
|
29113
|
+
if (steps[index].disabled())
|
|
29114
|
+
return false;
|
|
29115
|
+
if (!this.linear())
|
|
29116
|
+
return true;
|
|
29117
|
+
if (index <= this.activeStep())
|
|
29118
|
+
return true;
|
|
29119
|
+
for (let i = 0; i < index; i++) {
|
|
29120
|
+
const step = steps[i];
|
|
29121
|
+
if (!step.completed() && !step.optional())
|
|
29122
|
+
return false;
|
|
29123
|
+
}
|
|
29124
|
+
return true;
|
|
29125
|
+
}
|
|
29126
|
+
/** Activate the step at `index` if reachable. */
|
|
29127
|
+
selectStep(index) {
|
|
29128
|
+
if (!this.canNavigateTo(index))
|
|
29129
|
+
return;
|
|
29130
|
+
if (index === this.activeStep())
|
|
29131
|
+
return;
|
|
29132
|
+
this.activeStep.set(index);
|
|
29133
|
+
this.changed.emit(index);
|
|
29134
|
+
}
|
|
29135
|
+
handleKeydown(event) {
|
|
29136
|
+
if (this.disabled())
|
|
29137
|
+
return;
|
|
29138
|
+
const steps = this.registeredSteps();
|
|
29139
|
+
if (steps.length === 0)
|
|
29140
|
+
return;
|
|
29141
|
+
let nextIndex = -1;
|
|
29142
|
+
if (event.key === 'ArrowRight') {
|
|
29143
|
+
event.preventDefault();
|
|
29144
|
+
nextIndex = this.nextReachable(this.activeStep(), 1);
|
|
29145
|
+
}
|
|
29146
|
+
else if (event.key === 'ArrowLeft') {
|
|
29147
|
+
event.preventDefault();
|
|
29148
|
+
nextIndex = this.nextReachable(this.activeStep(), -1);
|
|
29149
|
+
}
|
|
29150
|
+
else if (event.key === 'Home') {
|
|
29151
|
+
event.preventDefault();
|
|
29152
|
+
nextIndex = this.firstReachable();
|
|
29153
|
+
}
|
|
29154
|
+
else if (event.key === 'End') {
|
|
29155
|
+
event.preventDefault();
|
|
29156
|
+
nextIndex = this.lastReachable();
|
|
29157
|
+
}
|
|
29158
|
+
if (nextIndex >= 0 && nextIndex !== this.activeStep()) {
|
|
29159
|
+
this.selectStep(nextIndex);
|
|
29160
|
+
const buttons = event.currentTarget.querySelectorAll('.ea-stepper__button:not([disabled])');
|
|
29161
|
+
// Match the focused button to the new index (visit order matches DOM order).
|
|
29162
|
+
const reachableIndices = this.registeredSteps()
|
|
29163
|
+
.map((_, i) => i)
|
|
29164
|
+
.filter(i => this.canNavigateTo(i));
|
|
29165
|
+
const buttonIdx = reachableIndices.indexOf(nextIndex);
|
|
29166
|
+
buttons[buttonIdx]?.focus();
|
|
29167
|
+
}
|
|
29168
|
+
}
|
|
29169
|
+
// ─── Internals ────────────────────────────────────────────────────────
|
|
29170
|
+
nextReachable(from, direction) {
|
|
29171
|
+
const steps = this.registeredSteps();
|
|
29172
|
+
for (let i = from + direction; i >= 0 && i < steps.length; i += direction) {
|
|
29173
|
+
if (this.canNavigateTo(i))
|
|
29174
|
+
return i;
|
|
29175
|
+
}
|
|
29176
|
+
return -1;
|
|
29177
|
+
}
|
|
29178
|
+
firstReachable() {
|
|
29179
|
+
const steps = this.registeredSteps();
|
|
29180
|
+
for (let i = 0; i < steps.length; i++) {
|
|
29181
|
+
if (this.canNavigateTo(i))
|
|
29182
|
+
return i;
|
|
29183
|
+
}
|
|
29184
|
+
return -1;
|
|
29185
|
+
}
|
|
29186
|
+
lastReachable() {
|
|
29187
|
+
const steps = this.registeredSteps();
|
|
29188
|
+
for (let i = steps.length - 1; i >= 0; i--) {
|
|
29189
|
+
if (this.canNavigateTo(i))
|
|
29190
|
+
return i;
|
|
29191
|
+
}
|
|
29192
|
+
return -1;
|
|
29193
|
+
}
|
|
29194
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: StepperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
29195
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.13", type: StepperComponent, isStandalone: true, selector: "ea-stepper", inputs: { activeStep: { classPropertyName: "activeStep", publicName: "activeStep", isSignal: true, isRequired: false, transformFunction: null }, linear: { classPropertyName: "linear", publicName: "linear", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeStep: "activeStepChange", changed: "changed" }, ngImport: i0, template: "<div\n class=\"ea-stepper\"\n [ngClass]=\"hostClasses()\">\n <ol\n class=\"ea-stepper__list\"\n role=\"tablist\"\n (keydown)=\"handleKeydown($event)\">\n @for (step of registeredSteps(); let i = $index; track step) {\n <li class=\"ea-stepper__item\">\n <button\n type=\"button\"\n role=\"tab\"\n class=\"ea-stepper__button\"\n [class.ea-stepper__button--active]=\"i === activeStep()\"\n [class.ea-stepper__button--completed]=\"step.completed()\"\n [id]=\"step.id() + '-tab'\"\n [attr.aria-controls]=\"step.id() + '-panel'\"\n [attr.aria-selected]=\"i === activeStep()\"\n [attr.aria-current]=\"i === activeStep() ? 'step' : null\"\n [disabled]=\"!canNavigateTo(i)\"\n [tabindex]=\"i === activeStep() ? 0 : -1\"\n (click)=\"selectStep(i)\">\n <span\n class=\"ea-stepper__circle\"\n aria-hidden=\"true\">\n @if (step.completed()) {\n <ea-icon-check />\n } @else {\n {{ i + 1 }}\n }\n </span>\n <span class=\"ea-stepper__label\">\n {{ step.label() }}\n @if (step.optional()) {\n <span class=\"ea-stepper__optional\">\n ({{ i18n.messages().stepper.optional }})\n </span>\n }\n </span>\n </button>\n @if (i < registeredSteps().length - 1) {\n <span\n class=\"ea-stepper__connector\"\n [class.ea-stepper__connector--completed]=\"step.completed()\"\n aria-hidden=\"true\">\n </span>\n }\n </li>\n }\n </ol>\n <ng-content />\n</div>\n", styles: [".ea-stepper{display:flex;flex-direction:column;gap:var(--space-4)}.ea-stepper__list{display:flex;align-items:stretch;gap:var(--space-2);margin:0;padding:0;list-style:none}.ea-stepper__item{display:flex;align-items:center;flex:1;min-width:0}.ea-stepper__button{display:flex;align-items:center;gap:var(--space-2);flex-shrink:0;padding:0;border:none;background:none;color:var(--color-text-secondary);cursor:pointer;transition:var(--transition-colors)}.ea-stepper__button:focus-visible{outline:none}.ea-stepper__button:focus-visible .ea-stepper__circle{box-shadow:var(--shadow-focus-ring)}.ea-stepper__button:hover:not(:disabled){color:var(--color-text-primary)}.ea-stepper__button:disabled{cursor:not-allowed;color:var(--color-text-disabled)}.ea-stepper__circle{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:2rem;height:2rem;border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-full);background-color:var(--color-bg-base);font-size:var(--font-size-sm);font-weight:var(--font-weight-medium);color:var(--color-text-secondary);transition:var(--transition-colors)}.ea-stepper__circle ea-icon-check{width:.875em;height:.875em}.ea-stepper__button--active .ea-stepper__circle,.ea-stepper__button--completed .ea-stepper__circle{border-color:var(--color-brand-default);background-color:var(--color-brand-default);color:var(--color-text-inverse)}.ea-stepper__button:disabled .ea-stepper__circle{border-color:var(--color-border-default);background-color:var(--color-bg-muted);color:var(--color-text-disabled)}.ea-stepper__label{display:flex;flex-direction:column;align-items:flex-start;font-size:var(--font-size-sm);font-weight:var(--font-weight-medium);text-align:left;line-height:var(--line-height-tight)}.ea-stepper__button--active .ea-stepper__label{color:var(--color-text-primary)}.ea-stepper__optional{font-size:var(--font-size-xs);font-weight:var(--font-weight-regular);color:var(--color-text-tertiary)}.ea-stepper__connector{display:block;flex:1;align-self:center;min-width:var(--space-4);height:var(--border-width-thin);margin:0 var(--space-2);background-color:var(--color-border-default);transition:var(--transition-colors)}.ea-stepper__connector--completed{background-color:var(--color-brand-default)}.ea-stepper--sm .ea-stepper__circle{width:1.5rem;height:1.5rem;font-size:var(--font-size-xs)}.ea-stepper--sm .ea-stepper__label{font-size:var(--font-size-xs)}.ea-stepper--lg .ea-stepper__circle{width:2.5rem;height:2.5rem;font-size:var(--font-size-md)}.ea-stepper--lg .ea-stepper__label{font-size:var(--font-size-md)}.ea-stepper--disabled{opacity:.6;pointer-events:none}.ea-step__panel:focus-visible{outline:none}\n"], dependencies: [{ kind: "component", type: CheckIconComponent, selector: "ea-icon-check" }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
29196
|
+
}
|
|
29197
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: StepperComponent, decorators: [{
|
|
29198
|
+
type: Component,
|
|
29199
|
+
args: [{ selector: 'ea-stepper', changeDetection: ChangeDetectionStrategy.OnPush, imports: [CheckIconComponent, NgClass], template: "<div\n class=\"ea-stepper\"\n [ngClass]=\"hostClasses()\">\n <ol\n class=\"ea-stepper__list\"\n role=\"tablist\"\n (keydown)=\"handleKeydown($event)\">\n @for (step of registeredSteps(); let i = $index; track step) {\n <li class=\"ea-stepper__item\">\n <button\n type=\"button\"\n role=\"tab\"\n class=\"ea-stepper__button\"\n [class.ea-stepper__button--active]=\"i === activeStep()\"\n [class.ea-stepper__button--completed]=\"step.completed()\"\n [id]=\"step.id() + '-tab'\"\n [attr.aria-controls]=\"step.id() + '-panel'\"\n [attr.aria-selected]=\"i === activeStep()\"\n [attr.aria-current]=\"i === activeStep() ? 'step' : null\"\n [disabled]=\"!canNavigateTo(i)\"\n [tabindex]=\"i === activeStep() ? 0 : -1\"\n (click)=\"selectStep(i)\">\n <span\n class=\"ea-stepper__circle\"\n aria-hidden=\"true\">\n @if (step.completed()) {\n <ea-icon-check />\n } @else {\n {{ i + 1 }}\n }\n </span>\n <span class=\"ea-stepper__label\">\n {{ step.label() }}\n @if (step.optional()) {\n <span class=\"ea-stepper__optional\">\n ({{ i18n.messages().stepper.optional }})\n </span>\n }\n </span>\n </button>\n @if (i < registeredSteps().length - 1) {\n <span\n class=\"ea-stepper__connector\"\n [class.ea-stepper__connector--completed]=\"step.completed()\"\n aria-hidden=\"true\">\n </span>\n }\n </li>\n }\n </ol>\n <ng-content />\n</div>\n", styles: [".ea-stepper{display:flex;flex-direction:column;gap:var(--space-4)}.ea-stepper__list{display:flex;align-items:stretch;gap:var(--space-2);margin:0;padding:0;list-style:none}.ea-stepper__item{display:flex;align-items:center;flex:1;min-width:0}.ea-stepper__button{display:flex;align-items:center;gap:var(--space-2);flex-shrink:0;padding:0;border:none;background:none;color:var(--color-text-secondary);cursor:pointer;transition:var(--transition-colors)}.ea-stepper__button:focus-visible{outline:none}.ea-stepper__button:focus-visible .ea-stepper__circle{box-shadow:var(--shadow-focus-ring)}.ea-stepper__button:hover:not(:disabled){color:var(--color-text-primary)}.ea-stepper__button:disabled{cursor:not-allowed;color:var(--color-text-disabled)}.ea-stepper__circle{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:2rem;height:2rem;border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-full);background-color:var(--color-bg-base);font-size:var(--font-size-sm);font-weight:var(--font-weight-medium);color:var(--color-text-secondary);transition:var(--transition-colors)}.ea-stepper__circle ea-icon-check{width:.875em;height:.875em}.ea-stepper__button--active .ea-stepper__circle,.ea-stepper__button--completed .ea-stepper__circle{border-color:var(--color-brand-default);background-color:var(--color-brand-default);color:var(--color-text-inverse)}.ea-stepper__button:disabled .ea-stepper__circle{border-color:var(--color-border-default);background-color:var(--color-bg-muted);color:var(--color-text-disabled)}.ea-stepper__label{display:flex;flex-direction:column;align-items:flex-start;font-size:var(--font-size-sm);font-weight:var(--font-weight-medium);text-align:left;line-height:var(--line-height-tight)}.ea-stepper__button--active .ea-stepper__label{color:var(--color-text-primary)}.ea-stepper__optional{font-size:var(--font-size-xs);font-weight:var(--font-weight-regular);color:var(--color-text-tertiary)}.ea-stepper__connector{display:block;flex:1;align-self:center;min-width:var(--space-4);height:var(--border-width-thin);margin:0 var(--space-2);background-color:var(--color-border-default);transition:var(--transition-colors)}.ea-stepper__connector--completed{background-color:var(--color-brand-default)}.ea-stepper--sm .ea-stepper__circle{width:1.5rem;height:1.5rem;font-size:var(--font-size-xs)}.ea-stepper--sm .ea-stepper__label{font-size:var(--font-size-xs)}.ea-stepper--lg .ea-stepper__circle{width:2.5rem;height:2.5rem;font-size:var(--font-size-md)}.ea-stepper--lg .ea-stepper__label{font-size:var(--font-size-md)}.ea-stepper--disabled{opacity:.6;pointer-events:none}.ea-step__panel:focus-visible{outline:none}\n"] }]
|
|
29200
|
+
}], propDecorators: { activeStep: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeStep", required: false }] }, { type: i0.Output, args: ["activeStepChange"] }], linear: [{ type: i0.Input, args: [{ isSignal: true, alias: "linear", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }], changed: [{ type: i0.Output, args: ["changed"] }] } });
|
|
29201
|
+
|
|
29202
|
+
/**
|
|
29203
|
+
* Single step within an `<ea-stepper>`. Registers itself with the parent on
|
|
29204
|
+
* init, exposes its `label` / `completed` / `optional` flags, and shows its
|
|
29205
|
+
* projected content when active.
|
|
28112
29206
|
*/
|
|
28113
|
-
class
|
|
28114
|
-
|
|
28115
|
-
|
|
28116
|
-
|
|
28117
|
-
|
|
28118
|
-
|
|
28119
|
-
|
|
28120
|
-
|
|
28121
|
-
|
|
28122
|
-
|
|
28123
|
-
|
|
29207
|
+
class StepComponent {
|
|
29208
|
+
stepper = inject(StepperComponent);
|
|
29209
|
+
label = input.required(...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
29210
|
+
completed = input(false, ...(ngDevMode ? [{ debugName: "completed" }] : /* istanbul ignore next */ []));
|
|
29211
|
+
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
29212
|
+
optional = input(false, ...(ngDevMode ? [{ debugName: "optional" }] : /* istanbul ignore next */ []));
|
|
29213
|
+
id = input(`ea-step-${Math.random().toString(36).slice(2, 9)}`, ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
|
|
29214
|
+
isActive = computed(() => this.stepper.indexOf(this) === this.stepper.activeStep(), ...(ngDevMode ? [{ debugName: "isActive" }] : /* istanbul ignore next */ []));
|
|
29215
|
+
ngOnInit() {
|
|
29216
|
+
this.stepper.registerStep(this);
|
|
29217
|
+
}
|
|
29218
|
+
ngOnDestroy() {
|
|
29219
|
+
this.stepper.unregisterStep(this);
|
|
29220
|
+
}
|
|
29221
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: StepComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
29222
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.13", type: StepComponent, isStandalone: true, selector: "ea-step", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, completed: { classPropertyName: "completed", publicName: "completed", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, optional: { classPropertyName: "optional", publicName: "optional", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "style.display": "isActive() ? null : \"none\"" } }, ngImport: i0, template: `
|
|
29223
|
+
@if (isActive()) {
|
|
29224
|
+
<div
|
|
29225
|
+
class="ea-step__panel"
|
|
29226
|
+
role="tabpanel"
|
|
29227
|
+
[id]="id() + '-panel'"
|
|
29228
|
+
[attr.aria-labelledby]="id() + '-tab'"
|
|
29229
|
+
tabindex="0">
|
|
29230
|
+
<ng-content />
|
|
29231
|
+
</div>
|
|
29232
|
+
}
|
|
29233
|
+
`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
28124
29234
|
}
|
|
28125
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type:
|
|
29235
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: StepComponent, decorators: [{
|
|
28126
29236
|
type: Component,
|
|
28127
|
-
args: [{
|
|
28128
|
-
|
|
29237
|
+
args: [{
|
|
29238
|
+
selector: 'ea-step',
|
|
29239
|
+
host: { '[style.display]': 'isActive() ? null : "none"' },
|
|
29240
|
+
template: `
|
|
29241
|
+
@if (isActive()) {
|
|
29242
|
+
<div
|
|
29243
|
+
class="ea-step__panel"
|
|
29244
|
+
role="tabpanel"
|
|
29245
|
+
[id]="id() + '-panel'"
|
|
29246
|
+
[attr.aria-labelledby]="id() + '-tab'"
|
|
29247
|
+
tabindex="0">
|
|
29248
|
+
<ng-content />
|
|
29249
|
+
</div>
|
|
29250
|
+
}
|
|
29251
|
+
`,
|
|
29252
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
29253
|
+
}]
|
|
29254
|
+
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], completed: [{ type: i0.Input, args: [{ isSignal: true, alias: "completed", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], optional: [{ type: i0.Input, args: [{ isSignal: true, alias: "optional", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }] } });
|
|
28129
29255
|
|
|
28130
29256
|
/**
|
|
28131
29257
|
* On/off toggle styled as a sliding switch. Backed by a visually hidden
|
|
@@ -28312,40 +29438,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImpo
|
|
|
28312
29438
|
}]
|
|
28313
29439
|
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], id: [{ type: i0.Input, args: [{ isSignal: true, alias: "id", required: false }] }] } });
|
|
28314
29440
|
|
|
28315
|
-
/**
|
|
28316
|
-
* Inline label commonly used to represent filters, categories, or selected
|
|
28317
|
-
* items. When `removable`, renders a close button that emits `removed`; the
|
|
28318
|
-
* accessible name of that button is configurable via `removeLabel` and
|
|
28319
|
-
* otherwise falls back to the active locale's translation.
|
|
28320
|
-
*/
|
|
28321
|
-
class TagComponent {
|
|
28322
|
-
i18n = inject(EagamiI18nService);
|
|
28323
|
-
variant = input('default', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
28324
|
-
size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
28325
|
-
removable = input(false, ...(ngDevMode ? [{ debugName: "removable" }] : /* istanbul ignore next */ []));
|
|
28326
|
-
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
28327
|
-
removeLabel = input(undefined, ...(ngDevMode ? [{ debugName: "removeLabel" }] : /* istanbul ignore next */ []));
|
|
28328
|
-
/** Fires when the user activates the remove button on a `removable` tag. */
|
|
28329
|
-
removed = output();
|
|
28330
|
-
/** Accessible label for the remove button, falling back to the active locale. */
|
|
28331
|
-
resolvedRemoveLabel = computed(() => this.removeLabel() ?? this.i18n.messages().tag.remove, ...(ngDevMode ? [{ debugName: "resolvedRemoveLabel" }] : /* istanbul ignore next */ []));
|
|
28332
|
-
hostClasses = computed(() => ({
|
|
28333
|
-
[`ea-tag--${this.variant()}`]: true,
|
|
28334
|
-
[`ea-tag--${this.size()}`]: true,
|
|
28335
|
-
'ea-tag--disabled': this.disabled(),
|
|
28336
|
-
}), ...(ngDevMode ? [{ debugName: "hostClasses" }] : /* istanbul ignore next */ []));
|
|
28337
|
-
onRemove(event) {
|
|
28338
|
-
event.stopPropagation();
|
|
28339
|
-
this.removed.emit();
|
|
28340
|
-
}
|
|
28341
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: TagComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
28342
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.13", type: TagComponent, isStandalone: true, selector: "ea-tag", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, removable: { classPropertyName: "removable", publicName: "removable", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, removeLabel: { classPropertyName: "removeLabel", publicName: "removeLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { removed: "removed" }, ngImport: i0, template: "<span\n class=\"ea-tag\"\n [ngClass]=\"hostClasses()\">\n <ng-content />\n @if (removable()) {\n <button\n type=\"button\"\n class=\"ea-tag__remove\"\n [disabled]=\"disabled() || null\"\n [attr.aria-label]=\"resolvedRemoveLabel()\"\n (click)=\"onRemove($event)\">\n <ea-icon-x />\n </button>\n }\n</span>\n", styles: [".ea-tag{display:inline-flex;align-items:center;gap:var(--space-1);font-weight:var(--font-weight-medium);line-height:var(--line-height-none);white-space:nowrap;font-family:var(--font-family-sans);border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-lg);background-color:var(--color-bg-subtle);color:var(--color-text-secondary)}.ea-tag--sm{padding:var(--space-0-5) var(--space-1-5);font-size:var(--font-size-xs)}.ea-tag--sm .ea-tag__remove ea-icon-x{width:.625rem;height:.625rem}.ea-tag--md{padding:var(--space-1) var(--space-2);font-size:var(--font-size-xs)}.ea-tag--md .ea-tag__remove ea-icon-x{width:.75rem;height:.75rem}.ea-tag--lg{padding:var(--space-1) var(--space-2-5);font-size:var(--font-size-sm)}.ea-tag--lg .ea-tag__remove ea-icon-x{width:.875rem;height:.875rem}.ea-tag--success{border-color:var(--color-success-muted);background-color:var(--color-success-subtle);color:var(--color-success-700)}.ea-tag--warning{border-color:var(--color-warning-muted);background-color:var(--color-warning-subtle);color:var(--color-warning-700)}.ea-tag--error{border-color:var(--color-error-muted);background-color:var(--color-error-subtle);color:var(--color-error-700)}.ea-tag--info{border-color:var(--color-info-muted);background-color:var(--color-info-subtle);color:var(--color-info-700)}.ea-tag--disabled{opacity:.6;cursor:not-allowed}.ea-tag__remove{opacity:.7;display:flex;align-items:center;justify-content:center;flex-shrink:0;padding:0;border:none;border-radius:var(--radius-xs);background:none;color:inherit;cursor:pointer;transition:var(--transition-colors)}.ea-tag__remove:hover{opacity:1}.ea-tag__remove:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-tag__remove:disabled{cursor:not-allowed}.ea-tag__remove ea-icon-x{pointer-events:none}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: XIconComponent, selector: "ea-icon-x" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
28343
|
-
}
|
|
28344
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: TagComponent, decorators: [{
|
|
28345
|
-
type: Component,
|
|
28346
|
-
args: [{ selector: 'ea-tag', imports: [NgClass, XIconComponent], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<span\n class=\"ea-tag\"\n [ngClass]=\"hostClasses()\">\n <ng-content />\n @if (removable()) {\n <button\n type=\"button\"\n class=\"ea-tag__remove\"\n [disabled]=\"disabled() || null\"\n [attr.aria-label]=\"resolvedRemoveLabel()\"\n (click)=\"onRemove($event)\">\n <ea-icon-x />\n </button>\n }\n</span>\n", styles: [".ea-tag{display:inline-flex;align-items:center;gap:var(--space-1);font-weight:var(--font-weight-medium);line-height:var(--line-height-none);white-space:nowrap;font-family:var(--font-family-sans);border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-lg);background-color:var(--color-bg-subtle);color:var(--color-text-secondary)}.ea-tag--sm{padding:var(--space-0-5) var(--space-1-5);font-size:var(--font-size-xs)}.ea-tag--sm .ea-tag__remove ea-icon-x{width:.625rem;height:.625rem}.ea-tag--md{padding:var(--space-1) var(--space-2);font-size:var(--font-size-xs)}.ea-tag--md .ea-tag__remove ea-icon-x{width:.75rem;height:.75rem}.ea-tag--lg{padding:var(--space-1) var(--space-2-5);font-size:var(--font-size-sm)}.ea-tag--lg .ea-tag__remove ea-icon-x{width:.875rem;height:.875rem}.ea-tag--success{border-color:var(--color-success-muted);background-color:var(--color-success-subtle);color:var(--color-success-700)}.ea-tag--warning{border-color:var(--color-warning-muted);background-color:var(--color-warning-subtle);color:var(--color-warning-700)}.ea-tag--error{border-color:var(--color-error-muted);background-color:var(--color-error-subtle);color:var(--color-error-700)}.ea-tag--info{border-color:var(--color-info-muted);background-color:var(--color-info-subtle);color:var(--color-info-700)}.ea-tag--disabled{opacity:.6;cursor:not-allowed}.ea-tag__remove{opacity:.7;display:flex;align-items:center;justify-content:center;flex-shrink:0;padding:0;border:none;border-radius:var(--radius-xs);background:none;color:inherit;cursor:pointer;transition:var(--transition-colors)}.ea-tag__remove:hover{opacity:1}.ea-tag__remove:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-tag__remove:disabled{cursor:not-allowed}.ea-tag__remove ea-icon-x{pointer-events:none}\n"] }]
|
|
28347
|
-
}], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], removable: [{ type: i0.Input, args: [{ isSignal: true, alias: "removable", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], removeLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "removeLabel", required: false }] }], removed: [{ type: i0.Output, args: ["removed"] }] } });
|
|
28348
|
-
|
|
28349
29441
|
/**
|
|
28350
29442
|
* Multiline text field that mirrors the `ea-input` API. Supports configurable
|
|
28351
29443
|
* `rows`, `resize` direction, and `maxlength`, and integrates with Angular
|
|
@@ -28422,7 +29514,7 @@ class TextareaComponent {
|
|
|
28422
29514
|
useExisting: forwardRef(() => TextareaComponent),
|
|
28423
29515
|
multi: true,
|
|
28424
29516
|
},
|
|
28425
|
-
], 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]=\"hasError() || 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--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: "component", type: AlertCircleIconComponent, selector: "ea-icon-alert-circle" }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
29517
|
+
], 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]=\"hasError() || 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{min-height:calc(1.5em + var(--space-2) * 2);padding:var(--space-2);font-size:var(--font-size-sm)}.ea-textarea-wrapper--md .ea-textarea{min-height:calc(1.5em + var(--space-3) * 2);padding:var(--space-3);font-size:var(--font-size-md)}.ea-textarea-wrapper--lg .ea-textarea{min-height:calc(1.5em + var(--space-4) * 2);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--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: "component", type: AlertCircleIconComponent, selector: "ea-icon-alert-circle" }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
28426
29518
|
}
|
|
28427
29519
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: TextareaComponent, decorators: [{
|
|
28428
29520
|
type: Component,
|
|
@@ -28432,9 +29524,503 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImpo
|
|
|
28432
29524
|
useExisting: forwardRef(() => TextareaComponent),
|
|
28433
29525
|
multi: true,
|
|
28434
29526
|
},
|
|
28435
|
-
], 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]=\"hasError() || 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--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"] }]
|
|
29527
|
+
], 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]=\"hasError() || 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{min-height:calc(1.5em + var(--space-2) * 2);padding:var(--space-2);font-size:var(--font-size-sm)}.ea-textarea-wrapper--md .ea-textarea{min-height:calc(1.5em + var(--space-3) * 2);padding:var(--space-3);font-size:var(--font-size-md)}.ea-textarea-wrapper--lg .ea-textarea{min-height:calc(1.5em + var(--space-4) * 2);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--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"] }]
|
|
28436
29528
|
}], 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 }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], errorMsg: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMsg", 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"] }], focused: [{ type: i0.Output, args: ["focused"] }], blurred: [{ type: i0.Output, args: ["blurred"] }] } });
|
|
28437
29529
|
|
|
29530
|
+
/**
|
|
29531
|
+
* Pops a stepper UI for selecting an `HH:MM[:SS]` time. The wire value is
|
|
29532
|
+
* always a 24-hour string (`"14:30"` or `"14:30:00"`); the `format` input
|
|
29533
|
+
* toggles the trigger's display between 12-hour and 24-hour styles. Supports
|
|
29534
|
+
* configurable steps for minutes and seconds, optional seconds column, and
|
|
29535
|
+
* integrates with Angular forms via `ControlValueAccessor`.
|
|
29536
|
+
*
|
|
29537
|
+
* Keyboard: Tab moves between the hour, minute, (seconds), and AM/PM columns.
|
|
29538
|
+
* Each spinner accepts ArrowUp/ArrowDown to step by 1 (or by the configured
|
|
29539
|
+
* step), PageUp/PageDown for a coarser bump, and digit keys to type a value
|
|
29540
|
+
* directly. After typing two digits (or one digit that already maxes the
|
|
29541
|
+
* unit), focus auto-advances to the next column. Backspace clears the typed
|
|
29542
|
+
* buffer; Escape closes the popover.
|
|
29543
|
+
*/
|
|
29544
|
+
class TimePickerComponent {
|
|
29545
|
+
triggerEl = viewChild('triggerEl', ...(ngDevMode ? [{ debugName: "triggerEl" }] : /* istanbul ignore next */ []));
|
|
29546
|
+
hoursEl = viewChild('hoursEl', ...(ngDevMode ? [{ debugName: "hoursEl" }] : /* istanbul ignore next */ []));
|
|
29547
|
+
minutesEl = viewChild('minutesEl', ...(ngDevMode ? [{ debugName: "minutesEl" }] : /* istanbul ignore next */ []));
|
|
29548
|
+
secondsEl = viewChild('secondsEl', ...(ngDevMode ? [{ debugName: "secondsEl" }] : /* istanbul ignore next */ []));
|
|
29549
|
+
i18n = inject(EagamiI18nService);
|
|
29550
|
+
destroyRef = inject(DestroyRef);
|
|
29551
|
+
injector = inject(Injector);
|
|
29552
|
+
// ─── Inputs ───────────────────────────────────────────────────────────
|
|
29553
|
+
label = input(undefined, ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
29554
|
+
placeholder = input(undefined, ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
|
|
29555
|
+
size = input('md', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
29556
|
+
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
29557
|
+
readonly = input(false, ...(ngDevMode ? [{ debugName: "readonly" }] : /* istanbul ignore next */ []));
|
|
29558
|
+
required = input(false, ...(ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []));
|
|
29559
|
+
hint = input(undefined, ...(ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []));
|
|
29560
|
+
errorMsg = input(undefined, ...(ngDevMode ? [{ debugName: "errorMsg" }] : /* istanbul ignore next */ []));
|
|
29561
|
+
/** Display format for the trigger label. Wire value is always 24h. */
|
|
29562
|
+
format = input('24h', ...(ngDevMode ? [{ debugName: "format" }] : /* istanbul ignore next */ []));
|
|
29563
|
+
includeSeconds = input(false, ...(ngDevMode ? [{ debugName: "includeSeconds" }] : /* istanbul ignore next */ []));
|
|
29564
|
+
minuteStep = input(1, ...(ngDevMode ? [{ debugName: "minuteStep" }] : /* istanbul ignore next */ []));
|
|
29565
|
+
secondStep = input(1, ...(ngDevMode ? [{ debugName: "secondStep" }] : /* istanbul ignore next */ []));
|
|
29566
|
+
id = input(`ea-time-picker-${Math.random().toString(36).slice(2, 9)}`, ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []));
|
|
29567
|
+
/** `"HH:MM"` or `"HH:MM:SS"` in 24-hour notation, or `null` when unset. */
|
|
29568
|
+
value = model(null, ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
29569
|
+
/** Fires with the new value whenever the user changes the time. */
|
|
29570
|
+
changed = output();
|
|
29571
|
+
// ─── State ────────────────────────────────────────────────────────────
|
|
29572
|
+
isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
|
|
29573
|
+
/** Typed-digit buffer for the currently focused column, or `null` when idle. */
|
|
29574
|
+
editBuffer = signal(null, ...(ngDevMode ? [{ debugName: "editBuffer" }] : /* istanbul ignore next */ []));
|
|
29575
|
+
_formDisabled = signal(false, ...(ngDevMode ? [{ debugName: "_formDisabled" }] : /* istanbul ignore next */ []));
|
|
29576
|
+
onChange = () => { };
|
|
29577
|
+
onTouched = () => { };
|
|
29578
|
+
/** Long-press timers for the chevron buttons. Cleared on release/destroy. */
|
|
29579
|
+
holdDelayTimer = null;
|
|
29580
|
+
holdIntervalTimer = null;
|
|
29581
|
+
holdStartedAt = 0;
|
|
29582
|
+
// ─── Computed ─────────────────────────────────────────────────────────
|
|
29583
|
+
isDisabled = computed(() => this.disabled() || this._formDisabled(), ...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
|
|
29584
|
+
hasError = computed(() => !!this.errorMsg(), ...(ngDevMode ? [{ debugName: "hasError" }] : /* istanbul ignore next */ []));
|
|
29585
|
+
showError = this.hasError;
|
|
29586
|
+
showHint = computed(() => !!this.hint() && !this.hasError(), ...(ngDevMode ? [{ debugName: "showHint" }] : /* istanbul ignore next */ []));
|
|
29587
|
+
/** Parsed `[hh, mm, ss]` from the current value, defaulting to midnight. */
|
|
29588
|
+
parsed = computed(() => {
|
|
29589
|
+
const parsed = parseTime(this.value());
|
|
29590
|
+
return parsed ?? { hours: 0, minutes: 0, seconds: 0 };
|
|
29591
|
+
}, ...(ngDevMode ? [{ debugName: "parsed" }] : /* istanbul ignore next */ []));
|
|
29592
|
+
/** True when the picker has a non-null value. Drives the clear button + placeholder fallback. */
|
|
29593
|
+
hasValue = computed(() => this.value() !== null, ...(ngDevMode ? [{ debugName: "hasValue" }] : /* istanbul ignore next */ []));
|
|
29594
|
+
/** Hours digit displayed in the popover stepper. Honors the `format` input. */
|
|
29595
|
+
displayHours = computed(() => {
|
|
29596
|
+
const h = this.parsed().hours;
|
|
29597
|
+
if (this.format() === '24h')
|
|
29598
|
+
return h;
|
|
29599
|
+
// 12h: 0 → 12 (midnight as 12 AM), 13–23 → 1–11
|
|
29600
|
+
return h % 12 === 0 ? 12 : h % 12;
|
|
29601
|
+
}, ...(ngDevMode ? [{ debugName: "displayHours" }] : /* istanbul ignore next */ []));
|
|
29602
|
+
/**
|
|
29603
|
+
* Text shown in a column's value cell. Reflects the typed-digit buffer when
|
|
29604
|
+
* the user is mid-edit on that column; otherwise renders the committed
|
|
29605
|
+
* value. Hours pad to two digits in 24h mode only (so 9 AM still reads as
|
|
29606
|
+
* "9", but 09:00 in 24h reads as "09").
|
|
29607
|
+
*/
|
|
29608
|
+
hoursText = computed(() => {
|
|
29609
|
+
const buf = this.editBuffer();
|
|
29610
|
+
if (buf && buf.unit === 'hours')
|
|
29611
|
+
return buf.digits;
|
|
29612
|
+
const h = this.displayHours();
|
|
29613
|
+
return this.format() === '24h' ? pad2(h) : String(h);
|
|
29614
|
+
}, ...(ngDevMode ? [{ debugName: "hoursText" }] : /* istanbul ignore next */ []));
|
|
29615
|
+
minutesText = computed(() => {
|
|
29616
|
+
const buf = this.editBuffer();
|
|
29617
|
+
if (buf && buf.unit === 'minutes')
|
|
29618
|
+
return buf.digits;
|
|
29619
|
+
return pad2(this.parsed().minutes);
|
|
29620
|
+
}, ...(ngDevMode ? [{ debugName: "minutesText" }] : /* istanbul ignore next */ []));
|
|
29621
|
+
secondsText = computed(() => {
|
|
29622
|
+
const buf = this.editBuffer();
|
|
29623
|
+
if (buf && buf.unit === 'seconds')
|
|
29624
|
+
return buf.digits;
|
|
29625
|
+
return pad2(this.parsed().seconds);
|
|
29626
|
+
}, ...(ngDevMode ? [{ debugName: "secondsText" }] : /* istanbul ignore next */ []));
|
|
29627
|
+
/** `'AM' | 'PM'` for 12h mode; `null` in 24h. */
|
|
29628
|
+
period = computed(() => {
|
|
29629
|
+
if (this.format() === '24h')
|
|
29630
|
+
return null;
|
|
29631
|
+
return this.parsed().hours < 12 ? 'AM' : 'PM';
|
|
29632
|
+
}, ...(ngDevMode ? [{ debugName: "period" }] : /* istanbul ignore next */ []));
|
|
29633
|
+
/** Localized text shown on the trigger. Falls back to placeholder when no value. */
|
|
29634
|
+
displayValue = computed(() => {
|
|
29635
|
+
if (!this.hasValue())
|
|
29636
|
+
return null;
|
|
29637
|
+
const { hours, minutes, seconds } = this.parsed();
|
|
29638
|
+
const m = pad2(minutes);
|
|
29639
|
+
const s = this.includeSeconds() ? `:${pad2(seconds)}` : '';
|
|
29640
|
+
if (this.format() === '24h') {
|
|
29641
|
+
return `${pad2(hours)}:${m}${s}`;
|
|
29642
|
+
}
|
|
29643
|
+
const display = hours % 12 === 0 ? 12 : hours % 12;
|
|
29644
|
+
const period = hours < 12
|
|
29645
|
+
? this.i18n.messages().timePicker.amLabel
|
|
29646
|
+
: this.i18n.messages().timePicker.pmLabel;
|
|
29647
|
+
return `${display}:${m}${s} ${period}`;
|
|
29648
|
+
}, ...(ngDevMode ? [{ debugName: "displayValue" }] : /* istanbul ignore next */ []));
|
|
29649
|
+
resolvedPlaceholder = computed(() => this.placeholder() ?? this.i18n.messages().timePicker.placeholder, ...(ngDevMode ? [{ debugName: "resolvedPlaceholder" }] : /* istanbul ignore next */ []));
|
|
29650
|
+
triggerClasses = computed(() => ({
|
|
29651
|
+
[`ea-time-picker__trigger--${this.size()}`]: true,
|
|
29652
|
+
'ea-time-picker__trigger--error': this.hasError(),
|
|
29653
|
+
'ea-time-picker__trigger--open': this.isOpen(),
|
|
29654
|
+
'ea-time-picker__trigger--disabled': this.isDisabled(),
|
|
29655
|
+
'ea-time-picker__trigger--placeholder': !this.hasValue(),
|
|
29656
|
+
}), ...(ngDevMode ? [{ debugName: "triggerClasses" }] : /* istanbul ignore next */ []));
|
|
29657
|
+
// ─── ControlValueAccessor ─────────────────────────────────────────────
|
|
29658
|
+
writeValue(val) {
|
|
29659
|
+
this.value.set(val ?? null);
|
|
29660
|
+
}
|
|
29661
|
+
registerOnChange(fn) {
|
|
29662
|
+
this.onChange = fn;
|
|
29663
|
+
}
|
|
29664
|
+
registerOnTouched(fn) {
|
|
29665
|
+
this.onTouched = fn;
|
|
29666
|
+
}
|
|
29667
|
+
setDisabledState(isDisabled) {
|
|
29668
|
+
this._formDisabled.set(isDisabled);
|
|
29669
|
+
}
|
|
29670
|
+
constructor() {
|
|
29671
|
+
this.destroyRef.onDestroy(() => this.stopHold());
|
|
29672
|
+
}
|
|
29673
|
+
// ─── Handlers ─────────────────────────────────────────────────────────
|
|
29674
|
+
toggle() {
|
|
29675
|
+
if (this.isDisabled() || this.readonly())
|
|
29676
|
+
return;
|
|
29677
|
+
const opening = !this.isOpen();
|
|
29678
|
+
this.isOpen.set(opening);
|
|
29679
|
+
if (opening)
|
|
29680
|
+
this.focusHoursWhenReady();
|
|
29681
|
+
}
|
|
29682
|
+
/**
|
|
29683
|
+
* Push focus into the hours input once the popover surface has been
|
|
29684
|
+
* rendered. `afterNextRender` guarantees the DOM has been updated (and the
|
|
29685
|
+
* surface is no longer `display: none`) before we call `.focus()`.
|
|
29686
|
+
*/
|
|
29687
|
+
focusHoursWhenReady() {
|
|
29688
|
+
afterNextRender(() => {
|
|
29689
|
+
const el = this.hoursEl()?.nativeElement;
|
|
29690
|
+
el?.focus();
|
|
29691
|
+
el?.select();
|
|
29692
|
+
}, { injector: this.injector });
|
|
29693
|
+
}
|
|
29694
|
+
close() {
|
|
29695
|
+
this.isOpen.set(false);
|
|
29696
|
+
}
|
|
29697
|
+
/** Called by `<ea-popover>` when the user clicks outside or scrolls. */
|
|
29698
|
+
onPopoverCloseRequested() {
|
|
29699
|
+
this.close();
|
|
29700
|
+
this.onTouched();
|
|
29701
|
+
}
|
|
29702
|
+
clear(event) {
|
|
29703
|
+
event.stopPropagation();
|
|
29704
|
+
if (this.isDisabled() || this.readonly())
|
|
29705
|
+
return;
|
|
29706
|
+
this.value.set(null);
|
|
29707
|
+
this.onChange(null);
|
|
29708
|
+
this.onTouched();
|
|
29709
|
+
this.changed.emit(null);
|
|
29710
|
+
}
|
|
29711
|
+
handleTriggerKeydown(event) {
|
|
29712
|
+
if (this.isDisabled() || this.readonly())
|
|
29713
|
+
return;
|
|
29714
|
+
if (event.key === 'Enter' || event.key === ' ' || event.key === 'ArrowDown') {
|
|
29715
|
+
event.preventDefault();
|
|
29716
|
+
if (!this.isOpen()) {
|
|
29717
|
+
this.isOpen.set(true);
|
|
29718
|
+
this.focusHoursWhenReady();
|
|
29719
|
+
}
|
|
29720
|
+
}
|
|
29721
|
+
else if (event.key === 'Escape' && this.isOpen()) {
|
|
29722
|
+
event.preventDefault();
|
|
29723
|
+
this.close();
|
|
29724
|
+
this.triggerEl()?.nativeElement.focus();
|
|
29725
|
+
}
|
|
29726
|
+
}
|
|
29727
|
+
/** Stepper button or keyboard arrow nudges one column up or down. */
|
|
29728
|
+
step(unit, direction) {
|
|
29729
|
+
if (this.isDisabled() || this.readonly())
|
|
29730
|
+
return;
|
|
29731
|
+
const { hours, minutes, seconds } = this.parsed();
|
|
29732
|
+
const next = nextTime({ hours, minutes, seconds }, unit, direction, this.minuteStep(), this.secondStep());
|
|
29733
|
+
this.commit(next);
|
|
29734
|
+
}
|
|
29735
|
+
/**
|
|
29736
|
+
* Begin a long-press repeat on a chevron button. Fires once immediately,
|
|
29737
|
+
* then after a `HOLD_INITIAL_DELAY` pause repeats at `HOLD_INTERVAL_MS`,
|
|
29738
|
+
* accelerating to `HOLD_FAST_INTERVAL_MS` after `HOLD_ACCELERATE_AFTER_MS`
|
|
29739
|
+
* of continuous holding. Pointer up / leave / cancel stops the repeat.
|
|
29740
|
+
*/
|
|
29741
|
+
startHold(unit, direction, event) {
|
|
29742
|
+
if (this.isDisabled() || this.readonly())
|
|
29743
|
+
return;
|
|
29744
|
+
event.preventDefault();
|
|
29745
|
+
this.stopHold();
|
|
29746
|
+
this.step(unit, direction);
|
|
29747
|
+
this.holdStartedAt = performance.now();
|
|
29748
|
+
this.holdDelayTimer = setTimeout(() => {
|
|
29749
|
+
this.holdIntervalTimer = setInterval(() => {
|
|
29750
|
+
this.step(unit, direction);
|
|
29751
|
+
const elapsed = performance.now() - this.holdStartedAt;
|
|
29752
|
+
if (elapsed > HOLD_ACCELERATE_AFTER_MS && this.holdIntervalTimer !== null) {
|
|
29753
|
+
clearInterval(this.holdIntervalTimer);
|
|
29754
|
+
this.holdIntervalTimer = setInterval(() => this.step(unit, direction), HOLD_FAST_INTERVAL_MS);
|
|
29755
|
+
}
|
|
29756
|
+
}, HOLD_INTERVAL_MS);
|
|
29757
|
+
}, HOLD_INITIAL_DELAY);
|
|
29758
|
+
}
|
|
29759
|
+
/** End any in-flight long-press repeat. Idempotent. */
|
|
29760
|
+
stopHold() {
|
|
29761
|
+
if (this.holdDelayTimer !== null) {
|
|
29762
|
+
clearTimeout(this.holdDelayTimer);
|
|
29763
|
+
this.holdDelayTimer = null;
|
|
29764
|
+
}
|
|
29765
|
+
if (this.holdIntervalTimer !== null) {
|
|
29766
|
+
clearInterval(this.holdIntervalTimer);
|
|
29767
|
+
this.holdIntervalTimer = null;
|
|
29768
|
+
}
|
|
29769
|
+
}
|
|
29770
|
+
/** Switches the AM/PM period in 12h mode by toggling the 12-hour offset. */
|
|
29771
|
+
togglePeriod() {
|
|
29772
|
+
if (this.isDisabled() || this.readonly() || this.format() === '24h')
|
|
29773
|
+
return;
|
|
29774
|
+
const { hours, minutes, seconds } = this.parsed();
|
|
29775
|
+
const flipped = (hours + 12) % 24;
|
|
29776
|
+
this.commit({ hours: flipped, minutes, seconds });
|
|
29777
|
+
}
|
|
29778
|
+
handlePopoverKeydown(event, unit) {
|
|
29779
|
+
if (this.isDisabled() || this.readonly())
|
|
29780
|
+
return;
|
|
29781
|
+
// Digits, Backspace, and Delete pass through to the native `<input>`.
|
|
29782
|
+
// The `(input)` handler picks them up via `onSpinnerInput`.
|
|
29783
|
+
if (event.key === 'ArrowUp') {
|
|
29784
|
+
event.preventDefault();
|
|
29785
|
+
this.flushBuffer();
|
|
29786
|
+
this.step(unit, 1);
|
|
29787
|
+
}
|
|
29788
|
+
else if (event.key === 'ArrowDown') {
|
|
29789
|
+
event.preventDefault();
|
|
29790
|
+
this.flushBuffer();
|
|
29791
|
+
this.step(unit, -1);
|
|
29792
|
+
}
|
|
29793
|
+
else if (event.key === 'PageUp') {
|
|
29794
|
+
event.preventDefault();
|
|
29795
|
+
this.flushBuffer();
|
|
29796
|
+
// Coarse step: 5× the configured step (or 10 for hours).
|
|
29797
|
+
const coarse = unit === 'hours' ? 10 : 5;
|
|
29798
|
+
for (let i = 0; i < coarse; i++)
|
|
29799
|
+
this.step(unit, 1);
|
|
29800
|
+
}
|
|
29801
|
+
else if (event.key === 'PageDown') {
|
|
29802
|
+
event.preventDefault();
|
|
29803
|
+
this.flushBuffer();
|
|
29804
|
+
const coarse = unit === 'hours' ? 10 : 5;
|
|
29805
|
+
for (let i = 0; i < coarse; i++)
|
|
29806
|
+
this.step(unit, -1);
|
|
29807
|
+
}
|
|
29808
|
+
else if (event.key === 'Enter') {
|
|
29809
|
+
event.preventDefault();
|
|
29810
|
+
this.flushBuffer();
|
|
29811
|
+
this.close();
|
|
29812
|
+
this.triggerEl()?.nativeElement.focus();
|
|
29813
|
+
}
|
|
29814
|
+
else if (event.key === 'Escape') {
|
|
29815
|
+
event.preventDefault();
|
|
29816
|
+
this.editBuffer.set(null);
|
|
29817
|
+
this.close();
|
|
29818
|
+
this.triggerEl()?.nativeElement.focus();
|
|
29819
|
+
}
|
|
29820
|
+
// Tab is handled by the browser; (blur) on the leaving input flushes.
|
|
29821
|
+
}
|
|
29822
|
+
/** Select-all on focus so the first keystroke replaces the current value. */
|
|
29823
|
+
onSpinnerFocus(event) {
|
|
29824
|
+
const el = event.currentTarget;
|
|
29825
|
+
// afterNextRender-ish: wait one tick so iOS / Safari accept the select().
|
|
29826
|
+
queueMicrotask(() => el.select());
|
|
29827
|
+
}
|
|
29828
|
+
/**
|
|
29829
|
+
* Native `(input)` event: the typed value is already in `el.value`. Strip
|
|
29830
|
+
* non-digits, update the buffer (which drives the displayed text), and
|
|
29831
|
+
* commit + auto-advance once the column is full or a third digit would
|
|
29832
|
+
* overflow.
|
|
29833
|
+
*/
|
|
29834
|
+
onSpinnerInput(unit, event) {
|
|
29835
|
+
if (this.isDisabled() || this.readonly())
|
|
29836
|
+
return;
|
|
29837
|
+
const el = event.currentTarget;
|
|
29838
|
+
const raw = el.value;
|
|
29839
|
+
const digits = raw.replace(/\D/g, '').slice(0, 2);
|
|
29840
|
+
if (digits !== raw)
|
|
29841
|
+
el.value = digits;
|
|
29842
|
+
this.editBuffer.set({ unit, digits });
|
|
29843
|
+
if (digits.length === 2) {
|
|
29844
|
+
// Two digits committed — advance.
|
|
29845
|
+
this.commitDigits(unit, digits);
|
|
29846
|
+
this.advanceFocus(unit);
|
|
29847
|
+
return;
|
|
29848
|
+
}
|
|
29849
|
+
if (digits.length === 1 && this.cannotExtend(unit, digits)) {
|
|
29850
|
+
// A single digit already saturates the unit (e.g. `9` in minutes once
|
|
29851
|
+
// a second `0`–`5` would be required to stay ≤ 59 — but 9 + 0 = 90 > 59).
|
|
29852
|
+
// Commit and advance.
|
|
29853
|
+
this.commitDigits(unit, digits);
|
|
29854
|
+
this.advanceFocus(unit);
|
|
29855
|
+
}
|
|
29856
|
+
}
|
|
29857
|
+
/** Commits the current buffer if any. Wired to each input's `(blur)`. */
|
|
29858
|
+
onSpinnerBlur() {
|
|
29859
|
+
this.flushBuffer();
|
|
29860
|
+
}
|
|
29861
|
+
// ─── Typing internals ─────────────────────────────────────────────────
|
|
29862
|
+
/** True when no digit `0`–`9` can validly extend the current buffer. */
|
|
29863
|
+
cannotExtend(unit, digits) {
|
|
29864
|
+
const candidate = parseInt(digits + '0', 10);
|
|
29865
|
+
return candidate > this.maxFor(unit);
|
|
29866
|
+
}
|
|
29867
|
+
/** Commits any pending buffer. Called on blur, on arrow keys, on Tab. */
|
|
29868
|
+
flushBuffer() {
|
|
29869
|
+
const buf = this.editBuffer();
|
|
29870
|
+
if (!buf || buf.digits.length === 0) {
|
|
29871
|
+
this.editBuffer.set(null);
|
|
29872
|
+
return;
|
|
29873
|
+
}
|
|
29874
|
+
this.commitDigits(buf.unit, buf.digits);
|
|
29875
|
+
}
|
|
29876
|
+
/** Writes the buffered digits into the value and clears the buffer. */
|
|
29877
|
+
commitDigits(unit, digits) {
|
|
29878
|
+
const raw = parseInt(digits, 10);
|
|
29879
|
+
if (isNaN(raw)) {
|
|
29880
|
+
this.editBuffer.set(null);
|
|
29881
|
+
return;
|
|
29882
|
+
}
|
|
29883
|
+
const max = this.maxFor(unit);
|
|
29884
|
+
const clamped = Math.min(max, Math.max(this.minFor(unit), raw));
|
|
29885
|
+
const { hours, minutes, seconds } = this.parsed();
|
|
29886
|
+
let next;
|
|
29887
|
+
if (unit === 'hours') {
|
|
29888
|
+
next = { hours: this.hoursFromTyped(clamped), minutes, seconds };
|
|
29889
|
+
}
|
|
29890
|
+
else if (unit === 'minutes') {
|
|
29891
|
+
next = { hours, minutes: clamped, seconds };
|
|
29892
|
+
}
|
|
29893
|
+
else {
|
|
29894
|
+
next = { hours, minutes, seconds: clamped };
|
|
29895
|
+
}
|
|
29896
|
+
this.editBuffer.set(null);
|
|
29897
|
+
this.commit(next);
|
|
29898
|
+
}
|
|
29899
|
+
/**
|
|
29900
|
+
* Map a typed hours value back to 24h. In 24h mode the typed value is the
|
|
29901
|
+
* hour. In 12h mode the typed value is interpreted in the current period
|
|
29902
|
+
* (AM → 12 maps to 0, others stay; PM → 12 stays, others add 12).
|
|
29903
|
+
*/
|
|
29904
|
+
hoursFromTyped(typed) {
|
|
29905
|
+
if (this.format() === '24h')
|
|
29906
|
+
return typed;
|
|
29907
|
+
const isPm = this.period() === 'PM';
|
|
29908
|
+
if (typed === 12)
|
|
29909
|
+
return isPm ? 12 : 0;
|
|
29910
|
+
return isPm ? typed + 12 : typed;
|
|
29911
|
+
}
|
|
29912
|
+
minFor(unit) {
|
|
29913
|
+
if (unit !== 'hours')
|
|
29914
|
+
return 0;
|
|
29915
|
+
return this.format() === '24h' ? 0 : 1;
|
|
29916
|
+
}
|
|
29917
|
+
maxFor(unit) {
|
|
29918
|
+
if (unit === 'hours')
|
|
29919
|
+
return this.format() === '24h' ? 23 : 12;
|
|
29920
|
+
return 59;
|
|
29921
|
+
}
|
|
29922
|
+
/** Move focus to the next unit column, looping back to hours at the end. */
|
|
29923
|
+
advanceFocus(unit) {
|
|
29924
|
+
const next = this.nextUnit(unit);
|
|
29925
|
+
const el = next === 'hours'
|
|
29926
|
+
? this.hoursEl()?.nativeElement
|
|
29927
|
+
: next === 'minutes'
|
|
29928
|
+
? this.minutesEl()?.nativeElement
|
|
29929
|
+
: this.secondsEl()?.nativeElement;
|
|
29930
|
+
el?.focus();
|
|
29931
|
+
}
|
|
29932
|
+
nextUnit(unit) {
|
|
29933
|
+
if (unit === 'hours')
|
|
29934
|
+
return 'minutes';
|
|
29935
|
+
if (unit === 'minutes')
|
|
29936
|
+
return this.includeSeconds() ? 'seconds' : 'hours';
|
|
29937
|
+
return 'hours';
|
|
29938
|
+
}
|
|
29939
|
+
// ─── Internals ────────────────────────────────────────────────────────
|
|
29940
|
+
commit(time) {
|
|
29941
|
+
const str = formatTime(time, this.includeSeconds());
|
|
29942
|
+
if (str === this.value())
|
|
29943
|
+
return;
|
|
29944
|
+
this.value.set(str);
|
|
29945
|
+
this.onChange(str);
|
|
29946
|
+
this.changed.emit(str);
|
|
29947
|
+
}
|
|
29948
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: TimePickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
29949
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.13", type: TimePickerComponent, isStandalone: true, selector: "ea-time-picker", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, errorMsg: { classPropertyName: "errorMsg", publicName: "errorMsg", isSignal: true, isRequired: false, transformFunction: null }, format: { classPropertyName: "format", publicName: "format", isSignal: true, isRequired: false, transformFunction: null }, includeSeconds: { classPropertyName: "includeSeconds", publicName: "includeSeconds", isSignal: true, isRequired: false, transformFunction: null }, minuteStep: { classPropertyName: "minuteStep", publicName: "minuteStep", isSignal: true, isRequired: false, transformFunction: null }, secondStep: { classPropertyName: "secondStep", publicName: "secondStep", isSignal: true, isRequired: false, transformFunction: null }, id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", changed: "changed" }, providers: [
|
|
29950
|
+
{
|
|
29951
|
+
provide: NG_VALUE_ACCESSOR,
|
|
29952
|
+
useExisting: forwardRef(() => TimePickerComponent),
|
|
29953
|
+
multi: true,
|
|
29954
|
+
},
|
|
29955
|
+
], viewQueries: [{ propertyName: "triggerEl", first: true, predicate: ["triggerEl"], descendants: true, isSignal: true }, { propertyName: "hoursEl", first: true, predicate: ["hoursEl"], descendants: true, isSignal: true }, { propertyName: "minutesEl", first: true, predicate: ["minutesEl"], descendants: true, isSignal: true }, { propertyName: "secondsEl", first: true, predicate: ["secondsEl"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"ea-time-picker-field\">\n @if (label()) {\n <label\n class=\"ea-time-picker-field__label\"\n [for]=\"id()\"\n [class.ea-time-picker-field__label--required]=\"required()\">\n {{ label() }}\n </label>\n }\n\n <div class=\"ea-time-picker\">\n <div class=\"ea-time-picker__trigger-wrapper\">\n <button\n #triggerEl\n type=\"button\"\n class=\"ea-time-picker__trigger\"\n [ngClass]=\"triggerClasses()\"\n [id]=\"id()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-haspopup]=\"'dialog'\"\n [attr.aria-required]=\"required() || null\"\n [attr.aria-invalid]=\"hasError() || null\"\n [attr.aria-describedby]=\"\n showError() ? id() + '-error' : showHint() ? id() + '-hint' : null\n \"\n (click)=\"toggle()\"\n (keydown)=\"handleTriggerKeydown($event)\">\n <ea-icon-clock\n class=\"ea-time-picker__trigger-icon\"\n aria-hidden=\"true\" />\n <span class=\"ea-time-picker__trigger-value\">\n {{ displayValue() || resolvedPlaceholder() }}\n </span>\n </button>\n @if (hasValue() && !isDisabled() && !readonly()) {\n <button\n type=\"button\"\n class=\"ea-time-picker__clear\"\n [attr.aria-label]=\"i18n.messages().timePicker.clear\"\n (click)=\"clear($event)\">\n <span aria-hidden=\"true\">\u00D7</span>\n </button>\n }\n </div>\n\n <ea-popover\n [anchor]=\"triggerEl\"\n [open]=\"isOpen()\"\n placement=\"bottom-start\"\n role=\"dialog\"\n [closeOnEscape]=\"false\"\n scrollBehavior=\"close\"\n (closeRequested)=\"onPopoverCloseRequested()\">\n <div class=\"ea-time-picker__popover\">\n <!-- Hours column -->\n <div class=\"ea-time-picker__column\">\n <button\n type=\"button\"\n class=\"ea-time-picker__step\"\n [attr.aria-label]=\"i18n.messages().timePicker.incrementHours\"\n (mousedown)=\"startHold('hours', 1, $event)\"\n (touchstart)=\"startHold('hours', 1, $event)\"\n (mouseup)=\"stopHold()\"\n (mouseleave)=\"stopHold()\"\n (touchend)=\"stopHold()\"\n (touchcancel)=\"stopHold()\">\n <ea-icon-chevron-up aria-hidden=\"true\" />\n </button>\n <input\n #hoursEl\n type=\"text\"\n class=\"ea-time-picker__value\"\n inputmode=\"numeric\"\n autocomplete=\"off\"\n maxlength=\"2\"\n role=\"spinbutton\"\n [attr.aria-label]=\"i18n.messages().timePicker.hoursLabel\"\n [attr.aria-valuemin]=\"format() === '24h' ? 0 : 1\"\n [attr.aria-valuemax]=\"format() === '24h' ? 23 : 12\"\n [attr.aria-valuenow]=\"displayHours()\"\n [value]=\"hoursText()\"\n (focus)=\"onSpinnerFocus($event)\"\n (input)=\"onSpinnerInput('hours', $event)\"\n (keydown)=\"handlePopoverKeydown($event, 'hours')\"\n (blur)=\"onSpinnerBlur()\" />\n <button\n type=\"button\"\n class=\"ea-time-picker__step\"\n [attr.aria-label]=\"i18n.messages().timePicker.decrementHours\"\n (mousedown)=\"startHold('hours', -1, $event)\"\n (touchstart)=\"startHold('hours', -1, $event)\"\n (mouseup)=\"stopHold()\"\n (mouseleave)=\"stopHold()\"\n (touchend)=\"stopHold()\"\n (touchcancel)=\"stopHold()\">\n <ea-icon-chevron-down aria-hidden=\"true\" />\n </button>\n </div>\n\n <span\n class=\"ea-time-picker__separator\"\n aria-hidden=\"true\">\n :\n </span>\n\n <!-- Minutes column -->\n <div class=\"ea-time-picker__column\">\n <button\n type=\"button\"\n class=\"ea-time-picker__step\"\n [attr.aria-label]=\"i18n.messages().timePicker.incrementMinutes\"\n (mousedown)=\"startHold('minutes', 1, $event)\"\n (touchstart)=\"startHold('minutes', 1, $event)\"\n (mouseup)=\"stopHold()\"\n (mouseleave)=\"stopHold()\"\n (touchend)=\"stopHold()\"\n (touchcancel)=\"stopHold()\">\n <ea-icon-chevron-up aria-hidden=\"true\" />\n </button>\n <input\n #minutesEl\n type=\"text\"\n class=\"ea-time-picker__value\"\n inputmode=\"numeric\"\n autocomplete=\"off\"\n maxlength=\"2\"\n role=\"spinbutton\"\n [attr.aria-label]=\"i18n.messages().timePicker.minutesLabel\"\n [attr.aria-valuemin]=\"0\"\n [attr.aria-valuemax]=\"59\"\n [attr.aria-valuenow]=\"parsed().minutes\"\n [value]=\"minutesText()\"\n (focus)=\"onSpinnerFocus($event)\"\n (input)=\"onSpinnerInput('minutes', $event)\"\n (keydown)=\"handlePopoverKeydown($event, 'minutes')\"\n (blur)=\"onSpinnerBlur()\" />\n <button\n type=\"button\"\n class=\"ea-time-picker__step\"\n [attr.aria-label]=\"i18n.messages().timePicker.decrementMinutes\"\n (mousedown)=\"startHold('minutes', -1, $event)\"\n (touchstart)=\"startHold('minutes', -1, $event)\"\n (mouseup)=\"stopHold()\"\n (mouseleave)=\"stopHold()\"\n (touchend)=\"stopHold()\"\n (touchcancel)=\"stopHold()\">\n <ea-icon-chevron-down aria-hidden=\"true\" />\n </button>\n </div>\n\n <!-- Seconds column (optional) -->\n @if (includeSeconds()) {\n <span\n class=\"ea-time-picker__separator\"\n aria-hidden=\"true\">\n :\n </span>\n <div class=\"ea-time-picker__column\">\n <button\n type=\"button\"\n class=\"ea-time-picker__step\"\n [attr.aria-label]=\"i18n.messages().timePicker.incrementSeconds\"\n (mousedown)=\"startHold('seconds', 1, $event)\"\n (touchstart)=\"startHold('seconds', 1, $event)\"\n (mouseup)=\"stopHold()\"\n (mouseleave)=\"stopHold()\"\n (touchend)=\"stopHold()\"\n (touchcancel)=\"stopHold()\">\n <ea-icon-chevron-up aria-hidden=\"true\" />\n </button>\n <input\n #secondsEl\n type=\"text\"\n class=\"ea-time-picker__value\"\n inputmode=\"numeric\"\n autocomplete=\"off\"\n maxlength=\"2\"\n role=\"spinbutton\"\n [attr.aria-label]=\"i18n.messages().timePicker.secondsLabel\"\n [attr.aria-valuemin]=\"0\"\n [attr.aria-valuemax]=\"59\"\n [attr.aria-valuenow]=\"parsed().seconds\"\n [value]=\"secondsText()\"\n (focus)=\"onSpinnerFocus($event)\"\n (input)=\"onSpinnerInput('seconds', $event)\"\n (keydown)=\"handlePopoverKeydown($event, 'seconds')\"\n (blur)=\"onSpinnerBlur()\" />\n <button\n type=\"button\"\n class=\"ea-time-picker__step\"\n [attr.aria-label]=\"i18n.messages().timePicker.decrementSeconds\"\n (mousedown)=\"startHold('seconds', -1, $event)\"\n (touchstart)=\"startHold('seconds', -1, $event)\"\n (mouseup)=\"stopHold()\"\n (mouseleave)=\"stopHold()\"\n (touchend)=\"stopHold()\"\n (touchcancel)=\"stopHold()\">\n <ea-icon-chevron-down aria-hidden=\"true\" />\n </button>\n </div>\n }\n\n <!-- AM/PM toggle (12h only) -->\n @if (format() === '12h') {\n <div class=\"ea-time-picker__period\">\n <button\n type=\"button\"\n class=\"ea-time-picker__period-option\"\n [class.ea-time-picker__period-option--active]=\"period() === 'AM'\"\n (click)=\"period() === 'PM' && togglePeriod()\">\n {{ i18n.messages().timePicker.amLabel }}\n </button>\n <button\n type=\"button\"\n class=\"ea-time-picker__period-option\"\n [class.ea-time-picker__period-option--active]=\"period() === 'PM'\"\n (click)=\"period() === 'AM' && togglePeriod()\">\n {{ i18n.messages().timePicker.pmLabel }}\n </button>\n </div>\n }\n </div>\n </ea-popover>\n </div>\n\n @if (showError()) {\n <p\n class=\"ea-time-picker-field__message ea-time-picker-field__message--error\"\n [id]=\"id() + '-error'\"\n role=\"alert\">\n <ea-icon-alert-circle class=\"ea-time-picker-field__message-icon\" />\n {{ errorMsg() }}\n </p>\n }\n\n @if (showHint()) {\n <p\n class=\"ea-time-picker-field__message ea-time-picker-field__message--hint\"\n [id]=\"id() + '-hint'\">\n {{ hint() }}\n </p>\n }\n</div>\n", styles: [".ea-time-picker-field{display:flex;flex-direction:column;gap:var(--space-1-5)}.ea-time-picker-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-time-picker-field__label--required:after{content:\" *\";color:var(--color-error-default)}.ea-time-picker-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-time-picker-field__message--hint{color:var(--color-text-secondary)}.ea-time-picker-field__message--error{color:var(--color-error-default)}.ea-time-picker-field__message-icon{flex-shrink:0;width:.875em;height:.875em}.ea-time-picker,.ea-time-picker__trigger-wrapper{position:relative}.ea-time-picker__trigger{display:flex;align-items:center;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-time-picker__trigger:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-time-picker__trigger--sm{padding:var(--space-1-5) var(--space-2);font-size:var(--font-size-sm);min-height:2rem}.ea-time-picker__trigger--md{padding:var(--space-2) var(--space-3);font-size:var(--font-size-sm);min-height:2.5rem}.ea-time-picker__trigger--lg{padding:var(--space-2-5) var(--space-4);font-size:var(--font-size-md);min-height:3rem}.ea-time-picker__trigger--open{border-color:var(--color-border-focus);box-shadow:var(--shadow-focus-ring)}.ea-time-picker__trigger--error{border-color:var(--color-error-default)}.ea-time-picker__trigger--error.ea-time-picker__trigger--open{box-shadow:var(--shadow-focus-ring-error)}.ea-time-picker__trigger--disabled{background-color:var(--color-bg-muted);opacity:.6;cursor:not-allowed}.ea-time-picker__trigger--placeholder .ea-time-picker__trigger-value{color:var(--color-text-tertiary)}.ea-time-picker__trigger-icon{flex-shrink:0;width:1em;height:1em;color:var(--color-text-secondary)}.ea-time-picker__trigger-value{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-variant-numeric:tabular-nums}.ea-time-picker__clear{position:absolute;top:50%;right:var(--space-2);z-index:1;display:flex;align-items:center;justify-content:center;flex-shrink:0;width:1.25rem;height:1.25rem;padding:0;border:none;border-radius:var(--radius-sm);background:none;color:var(--color-text-secondary);font-size:1rem;line-height:1;cursor:pointer;transition:var(--transition-colors);transform:translateY(-50%)}.ea-time-picker__clear:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-time-picker__clear:hover{background-color:var(--color-bg-muted);color:var(--color-text-primary)}.ea-time-picker__popover{display:flex;align-items:center;gap:var(--space-2);padding:var(--space-3);border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-md);box-shadow:var(--shadow-lg);background-color:var(--color-bg-base)}.ea-time-picker__column{display:flex;flex-direction:column;align-items:stretch;gap:var(--space-1)}.ea-time-picker__step{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:2.25rem;height:1.75rem;padding:0;border:none;border-radius:var(--radius-sm);background:none;color:var(--color-text-secondary);cursor:pointer;transition:var(--transition-colors)}.ea-time-picker__step:hover{background-color:var(--color-bg-muted);color:var(--color-text-primary)}.ea-time-picker__step:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-time-picker__step ea-icon-chevron-up,.ea-time-picker__step ea-icon-chevron-down{width:.875em;height:.875em}.ea-time-picker__value{width:2.25rem;height:2.25rem;padding:0;border:var(--border-width-thin) solid transparent;border-radius:var(--radius-sm);background-color:var(--color-bg-muted);font-family:var(--font-family-mono);font-size:var(--font-size-md);font-weight:var(--font-weight-medium);text-align:center;color:var(--color-text-primary);font-variant-numeric:tabular-nums;appearance:none;cursor:text}.ea-time-picker__value::selection{background-color:var(--color-brand-default);color:var(--color-text-inverse)}.ea-time-picker__value:hover{border-color:var(--color-border-default)}.ea-time-picker__value:focus{outline:none;border-color:var(--color-border-focus);box-shadow:var(--shadow-focus-ring);background-color:var(--color-bg-base)}.ea-time-picker__separator{font-family:var(--font-family-mono);font-size:var(--font-size-md);font-weight:var(--font-weight-medium);color:var(--color-text-secondary);-webkit-user-select:none;user-select:none}.ea-time-picker__period{display:flex;flex-direction:column;gap:var(--space-1);margin-left:var(--space-1)}.ea-time-picker__period-option{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:2.5rem;padding:var(--space-1) var(--space-2);border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-sm);background-color:var(--color-bg-base);font-family:var(--font-family-sans);font-size:var(--font-size-xs);font-weight:var(--font-weight-medium);color:var(--color-text-secondary);cursor:pointer;transition:var(--transition-colors)}.ea-time-picker__period-option:hover{background-color:var(--color-bg-muted);color:var(--color-text-primary)}.ea-time-picker__period-option:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-time-picker__period-option--active{background-color:var(--color-brand-default);border-color:var(--color-brand-default);color:var(--color-text-inverse)}.ea-time-picker__period-option--active:hover{background-color:var(--color-brand-hover);border-color:var(--color-brand-hover);color:var(--color-text-inverse)}\n"], dependencies: [{ kind: "component", type: AlertCircleIconComponent, selector: "ea-icon-alert-circle" }, { kind: "component", type: ChevronDownIconComponent, selector: "ea-icon-chevron-down" }, { kind: "component", type: ChevronUpIconComponent, selector: "ea-icon-chevron-up" }, { kind: "component", type: ClockIconComponent, selector: "ea-icon-clock" }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: PopoverComponent, selector: "ea-popover", inputs: ["anchor", "open", "placement", "role", "aria-label", "surfaceId", "offset", "flip", "clamp", "matchAnchorWidth", "closeOnOutsideClick", "closeOnEscape", "scrollBehavior"], outputs: ["closeRequested"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
29956
|
+
}
|
|
29957
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImport: i0, type: TimePickerComponent, decorators: [{
|
|
29958
|
+
type: Component,
|
|
29959
|
+
args: [{ selector: 'ea-time-picker', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
29960
|
+
AlertCircleIconComponent,
|
|
29961
|
+
ChevronDownIconComponent,
|
|
29962
|
+
ChevronUpIconComponent,
|
|
29963
|
+
ClockIconComponent,
|
|
29964
|
+
NgClass,
|
|
29965
|
+
PopoverComponent,
|
|
29966
|
+
], providers: [
|
|
29967
|
+
{
|
|
29968
|
+
provide: NG_VALUE_ACCESSOR,
|
|
29969
|
+
useExisting: forwardRef(() => TimePickerComponent),
|
|
29970
|
+
multi: true,
|
|
29971
|
+
},
|
|
29972
|
+
], template: "<div class=\"ea-time-picker-field\">\n @if (label()) {\n <label\n class=\"ea-time-picker-field__label\"\n [for]=\"id()\"\n [class.ea-time-picker-field__label--required]=\"required()\">\n {{ label() }}\n </label>\n }\n\n <div class=\"ea-time-picker\">\n <div class=\"ea-time-picker__trigger-wrapper\">\n <button\n #triggerEl\n type=\"button\"\n class=\"ea-time-picker__trigger\"\n [ngClass]=\"triggerClasses()\"\n [id]=\"id()\"\n [disabled]=\"isDisabled()\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-haspopup]=\"'dialog'\"\n [attr.aria-required]=\"required() || null\"\n [attr.aria-invalid]=\"hasError() || null\"\n [attr.aria-describedby]=\"\n showError() ? id() + '-error' : showHint() ? id() + '-hint' : null\n \"\n (click)=\"toggle()\"\n (keydown)=\"handleTriggerKeydown($event)\">\n <ea-icon-clock\n class=\"ea-time-picker__trigger-icon\"\n aria-hidden=\"true\" />\n <span class=\"ea-time-picker__trigger-value\">\n {{ displayValue() || resolvedPlaceholder() }}\n </span>\n </button>\n @if (hasValue() && !isDisabled() && !readonly()) {\n <button\n type=\"button\"\n class=\"ea-time-picker__clear\"\n [attr.aria-label]=\"i18n.messages().timePicker.clear\"\n (click)=\"clear($event)\">\n <span aria-hidden=\"true\">\u00D7</span>\n </button>\n }\n </div>\n\n <ea-popover\n [anchor]=\"triggerEl\"\n [open]=\"isOpen()\"\n placement=\"bottom-start\"\n role=\"dialog\"\n [closeOnEscape]=\"false\"\n scrollBehavior=\"close\"\n (closeRequested)=\"onPopoverCloseRequested()\">\n <div class=\"ea-time-picker__popover\">\n <!-- Hours column -->\n <div class=\"ea-time-picker__column\">\n <button\n type=\"button\"\n class=\"ea-time-picker__step\"\n [attr.aria-label]=\"i18n.messages().timePicker.incrementHours\"\n (mousedown)=\"startHold('hours', 1, $event)\"\n (touchstart)=\"startHold('hours', 1, $event)\"\n (mouseup)=\"stopHold()\"\n (mouseleave)=\"stopHold()\"\n (touchend)=\"stopHold()\"\n (touchcancel)=\"stopHold()\">\n <ea-icon-chevron-up aria-hidden=\"true\" />\n </button>\n <input\n #hoursEl\n type=\"text\"\n class=\"ea-time-picker__value\"\n inputmode=\"numeric\"\n autocomplete=\"off\"\n maxlength=\"2\"\n role=\"spinbutton\"\n [attr.aria-label]=\"i18n.messages().timePicker.hoursLabel\"\n [attr.aria-valuemin]=\"format() === '24h' ? 0 : 1\"\n [attr.aria-valuemax]=\"format() === '24h' ? 23 : 12\"\n [attr.aria-valuenow]=\"displayHours()\"\n [value]=\"hoursText()\"\n (focus)=\"onSpinnerFocus($event)\"\n (input)=\"onSpinnerInput('hours', $event)\"\n (keydown)=\"handlePopoverKeydown($event, 'hours')\"\n (blur)=\"onSpinnerBlur()\" />\n <button\n type=\"button\"\n class=\"ea-time-picker__step\"\n [attr.aria-label]=\"i18n.messages().timePicker.decrementHours\"\n (mousedown)=\"startHold('hours', -1, $event)\"\n (touchstart)=\"startHold('hours', -1, $event)\"\n (mouseup)=\"stopHold()\"\n (mouseleave)=\"stopHold()\"\n (touchend)=\"stopHold()\"\n (touchcancel)=\"stopHold()\">\n <ea-icon-chevron-down aria-hidden=\"true\" />\n </button>\n </div>\n\n <span\n class=\"ea-time-picker__separator\"\n aria-hidden=\"true\">\n :\n </span>\n\n <!-- Minutes column -->\n <div class=\"ea-time-picker__column\">\n <button\n type=\"button\"\n class=\"ea-time-picker__step\"\n [attr.aria-label]=\"i18n.messages().timePicker.incrementMinutes\"\n (mousedown)=\"startHold('minutes', 1, $event)\"\n (touchstart)=\"startHold('minutes', 1, $event)\"\n (mouseup)=\"stopHold()\"\n (mouseleave)=\"stopHold()\"\n (touchend)=\"stopHold()\"\n (touchcancel)=\"stopHold()\">\n <ea-icon-chevron-up aria-hidden=\"true\" />\n </button>\n <input\n #minutesEl\n type=\"text\"\n class=\"ea-time-picker__value\"\n inputmode=\"numeric\"\n autocomplete=\"off\"\n maxlength=\"2\"\n role=\"spinbutton\"\n [attr.aria-label]=\"i18n.messages().timePicker.minutesLabel\"\n [attr.aria-valuemin]=\"0\"\n [attr.aria-valuemax]=\"59\"\n [attr.aria-valuenow]=\"parsed().minutes\"\n [value]=\"minutesText()\"\n (focus)=\"onSpinnerFocus($event)\"\n (input)=\"onSpinnerInput('minutes', $event)\"\n (keydown)=\"handlePopoverKeydown($event, 'minutes')\"\n (blur)=\"onSpinnerBlur()\" />\n <button\n type=\"button\"\n class=\"ea-time-picker__step\"\n [attr.aria-label]=\"i18n.messages().timePicker.decrementMinutes\"\n (mousedown)=\"startHold('minutes', -1, $event)\"\n (touchstart)=\"startHold('minutes', -1, $event)\"\n (mouseup)=\"stopHold()\"\n (mouseleave)=\"stopHold()\"\n (touchend)=\"stopHold()\"\n (touchcancel)=\"stopHold()\">\n <ea-icon-chevron-down aria-hidden=\"true\" />\n </button>\n </div>\n\n <!-- Seconds column (optional) -->\n @if (includeSeconds()) {\n <span\n class=\"ea-time-picker__separator\"\n aria-hidden=\"true\">\n :\n </span>\n <div class=\"ea-time-picker__column\">\n <button\n type=\"button\"\n class=\"ea-time-picker__step\"\n [attr.aria-label]=\"i18n.messages().timePicker.incrementSeconds\"\n (mousedown)=\"startHold('seconds', 1, $event)\"\n (touchstart)=\"startHold('seconds', 1, $event)\"\n (mouseup)=\"stopHold()\"\n (mouseleave)=\"stopHold()\"\n (touchend)=\"stopHold()\"\n (touchcancel)=\"stopHold()\">\n <ea-icon-chevron-up aria-hidden=\"true\" />\n </button>\n <input\n #secondsEl\n type=\"text\"\n class=\"ea-time-picker__value\"\n inputmode=\"numeric\"\n autocomplete=\"off\"\n maxlength=\"2\"\n role=\"spinbutton\"\n [attr.aria-label]=\"i18n.messages().timePicker.secondsLabel\"\n [attr.aria-valuemin]=\"0\"\n [attr.aria-valuemax]=\"59\"\n [attr.aria-valuenow]=\"parsed().seconds\"\n [value]=\"secondsText()\"\n (focus)=\"onSpinnerFocus($event)\"\n (input)=\"onSpinnerInput('seconds', $event)\"\n (keydown)=\"handlePopoverKeydown($event, 'seconds')\"\n (blur)=\"onSpinnerBlur()\" />\n <button\n type=\"button\"\n class=\"ea-time-picker__step\"\n [attr.aria-label]=\"i18n.messages().timePicker.decrementSeconds\"\n (mousedown)=\"startHold('seconds', -1, $event)\"\n (touchstart)=\"startHold('seconds', -1, $event)\"\n (mouseup)=\"stopHold()\"\n (mouseleave)=\"stopHold()\"\n (touchend)=\"stopHold()\"\n (touchcancel)=\"stopHold()\">\n <ea-icon-chevron-down aria-hidden=\"true\" />\n </button>\n </div>\n }\n\n <!-- AM/PM toggle (12h only) -->\n @if (format() === '12h') {\n <div class=\"ea-time-picker__period\">\n <button\n type=\"button\"\n class=\"ea-time-picker__period-option\"\n [class.ea-time-picker__period-option--active]=\"period() === 'AM'\"\n (click)=\"period() === 'PM' && togglePeriod()\">\n {{ i18n.messages().timePicker.amLabel }}\n </button>\n <button\n type=\"button\"\n class=\"ea-time-picker__period-option\"\n [class.ea-time-picker__period-option--active]=\"period() === 'PM'\"\n (click)=\"period() === 'AM' && togglePeriod()\">\n {{ i18n.messages().timePicker.pmLabel }}\n </button>\n </div>\n }\n </div>\n </ea-popover>\n </div>\n\n @if (showError()) {\n <p\n class=\"ea-time-picker-field__message ea-time-picker-field__message--error\"\n [id]=\"id() + '-error'\"\n role=\"alert\">\n <ea-icon-alert-circle class=\"ea-time-picker-field__message-icon\" />\n {{ errorMsg() }}\n </p>\n }\n\n @if (showHint()) {\n <p\n class=\"ea-time-picker-field__message ea-time-picker-field__message--hint\"\n [id]=\"id() + '-hint'\">\n {{ hint() }}\n </p>\n }\n</div>\n", styles: [".ea-time-picker-field{display:flex;flex-direction:column;gap:var(--space-1-5)}.ea-time-picker-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-time-picker-field__label--required:after{content:\" *\";color:var(--color-error-default)}.ea-time-picker-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-time-picker-field__message--hint{color:var(--color-text-secondary)}.ea-time-picker-field__message--error{color:var(--color-error-default)}.ea-time-picker-field__message-icon{flex-shrink:0;width:.875em;height:.875em}.ea-time-picker,.ea-time-picker__trigger-wrapper{position:relative}.ea-time-picker__trigger{display:flex;align-items:center;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-time-picker__trigger:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-time-picker__trigger--sm{padding:var(--space-1-5) var(--space-2);font-size:var(--font-size-sm);min-height:2rem}.ea-time-picker__trigger--md{padding:var(--space-2) var(--space-3);font-size:var(--font-size-sm);min-height:2.5rem}.ea-time-picker__trigger--lg{padding:var(--space-2-5) var(--space-4);font-size:var(--font-size-md);min-height:3rem}.ea-time-picker__trigger--open{border-color:var(--color-border-focus);box-shadow:var(--shadow-focus-ring)}.ea-time-picker__trigger--error{border-color:var(--color-error-default)}.ea-time-picker__trigger--error.ea-time-picker__trigger--open{box-shadow:var(--shadow-focus-ring-error)}.ea-time-picker__trigger--disabled{background-color:var(--color-bg-muted);opacity:.6;cursor:not-allowed}.ea-time-picker__trigger--placeholder .ea-time-picker__trigger-value{color:var(--color-text-tertiary)}.ea-time-picker__trigger-icon{flex-shrink:0;width:1em;height:1em;color:var(--color-text-secondary)}.ea-time-picker__trigger-value{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-variant-numeric:tabular-nums}.ea-time-picker__clear{position:absolute;top:50%;right:var(--space-2);z-index:1;display:flex;align-items:center;justify-content:center;flex-shrink:0;width:1.25rem;height:1.25rem;padding:0;border:none;border-radius:var(--radius-sm);background:none;color:var(--color-text-secondary);font-size:1rem;line-height:1;cursor:pointer;transition:var(--transition-colors);transform:translateY(-50%)}.ea-time-picker__clear:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-time-picker__clear:hover{background-color:var(--color-bg-muted);color:var(--color-text-primary)}.ea-time-picker__popover{display:flex;align-items:center;gap:var(--space-2);padding:var(--space-3);border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-md);box-shadow:var(--shadow-lg);background-color:var(--color-bg-base)}.ea-time-picker__column{display:flex;flex-direction:column;align-items:stretch;gap:var(--space-1)}.ea-time-picker__step{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:2.25rem;height:1.75rem;padding:0;border:none;border-radius:var(--radius-sm);background:none;color:var(--color-text-secondary);cursor:pointer;transition:var(--transition-colors)}.ea-time-picker__step:hover{background-color:var(--color-bg-muted);color:var(--color-text-primary)}.ea-time-picker__step:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-time-picker__step ea-icon-chevron-up,.ea-time-picker__step ea-icon-chevron-down{width:.875em;height:.875em}.ea-time-picker__value{width:2.25rem;height:2.25rem;padding:0;border:var(--border-width-thin) solid transparent;border-radius:var(--radius-sm);background-color:var(--color-bg-muted);font-family:var(--font-family-mono);font-size:var(--font-size-md);font-weight:var(--font-weight-medium);text-align:center;color:var(--color-text-primary);font-variant-numeric:tabular-nums;appearance:none;cursor:text}.ea-time-picker__value::selection{background-color:var(--color-brand-default);color:var(--color-text-inverse)}.ea-time-picker__value:hover{border-color:var(--color-border-default)}.ea-time-picker__value:focus{outline:none;border-color:var(--color-border-focus);box-shadow:var(--shadow-focus-ring);background-color:var(--color-bg-base)}.ea-time-picker__separator{font-family:var(--font-family-mono);font-size:var(--font-size-md);font-weight:var(--font-weight-medium);color:var(--color-text-secondary);-webkit-user-select:none;user-select:none}.ea-time-picker__period{display:flex;flex-direction:column;gap:var(--space-1);margin-left:var(--space-1)}.ea-time-picker__period-option{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:2.5rem;padding:var(--space-1) var(--space-2);border:var(--border-width-thin) solid var(--color-border-default);border-radius:var(--radius-sm);background-color:var(--color-bg-base);font-family:var(--font-family-sans);font-size:var(--font-size-xs);font-weight:var(--font-weight-medium);color:var(--color-text-secondary);cursor:pointer;transition:var(--transition-colors)}.ea-time-picker__period-option:hover{background-color:var(--color-bg-muted);color:var(--color-text-primary)}.ea-time-picker__period-option:focus-visible{outline:none;box-shadow:var(--shadow-focus-ring)}.ea-time-picker__period-option--active{background-color:var(--color-brand-default);border-color:var(--color-brand-default);color:var(--color-text-inverse)}.ea-time-picker__period-option--active:hover{background-color:var(--color-brand-hover);border-color:var(--color-brand-hover);color:var(--color-text-inverse)}\n"] }]
|
|
29973
|
+
}], ctorParameters: () => [], propDecorators: { triggerEl: [{ type: i0.ViewChild, args: ['triggerEl', { isSignal: true }] }], hoursEl: [{ type: i0.ViewChild, args: ['hoursEl', { isSignal: true }] }], minutesEl: [{ type: i0.ViewChild, args: ['minutesEl', { isSignal: true }] }], secondsEl: [{ type: i0.ViewChild, args: ['secondsEl', { 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 }] }], 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 }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], errorMsg: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMsg", required: false }] }], format: [{ type: i0.Input, args: [{ isSignal: true, alias: "format", required: false }] }], includeSeconds: [{ type: i0.Input, args: [{ isSignal: true, alias: "includeSeconds", required: false }] }], minuteStep: [{ type: i0.Input, args: [{ isSignal: true, alias: "minuteStep", required: false }] }], secondStep: [{ type: i0.Input, args: [{ isSignal: true, alias: "secondStep", 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"] }] } });
|
|
29974
|
+
// ─── Constants ──────────────────────────────────────────────────────────
|
|
29975
|
+
/** Delay before a held chevron button starts repeating, in ms. */
|
|
29976
|
+
const HOLD_INITIAL_DELAY = 400;
|
|
29977
|
+
/** Repeat interval while a chevron button is held, in ms. */
|
|
29978
|
+
const HOLD_INTERVAL_MS = 90;
|
|
29979
|
+
/** After this many ms of continuous hold, the repeat accelerates. */
|
|
29980
|
+
const HOLD_ACCELERATE_AFTER_MS = 1500;
|
|
29981
|
+
/** Repeat interval once the long-press has accelerated, in ms. */
|
|
29982
|
+
const HOLD_FAST_INTERVAL_MS = 35;
|
|
29983
|
+
// ─── Pure helpers ───────────────────────────────────────────────────────
|
|
29984
|
+
/** Pad a 0–59 unit to two digits. */
|
|
29985
|
+
function pad2(n) {
|
|
29986
|
+
return n < 10 ? `0${n}` : `${n}`;
|
|
29987
|
+
}
|
|
29988
|
+
/** Parse `"HH:MM"` / `"HH:MM:SS"`; returns `null` for any malformed input. */
|
|
29989
|
+
function parseTime(input) {
|
|
29990
|
+
if (!input)
|
|
29991
|
+
return null;
|
|
29992
|
+
const match = /^(\d{1,2}):(\d{1,2})(?::(\d{1,2}))?$/.exec(input.trim());
|
|
29993
|
+
if (!match)
|
|
29994
|
+
return null;
|
|
29995
|
+
const hours = clamp(parseInt(match[1], 10), 0, 23);
|
|
29996
|
+
const minutes = clamp(parseInt(match[2], 10), 0, 59);
|
|
29997
|
+
const seconds = match[3] !== undefined ? clamp(parseInt(match[3], 10), 0, 59) : 0;
|
|
29998
|
+
if (isNaN(hours) || isNaN(minutes) || isNaN(seconds))
|
|
29999
|
+
return null;
|
|
30000
|
+
return { hours, minutes, seconds };
|
|
30001
|
+
}
|
|
30002
|
+
function clamp(n, lo, hi) {
|
|
30003
|
+
return Math.min(hi, Math.max(lo, n));
|
|
30004
|
+
}
|
|
30005
|
+
function formatTime(time, includeSeconds) {
|
|
30006
|
+
const base = `${pad2(time.hours)}:${pad2(time.minutes)}`;
|
|
30007
|
+
return includeSeconds ? `${base}:${pad2(time.seconds)}` : base;
|
|
30008
|
+
}
|
|
30009
|
+
/** Wrap-around step for a unit. Hours wrap at 24, minutes/seconds at 60. */
|
|
30010
|
+
function nextTime(current, unit, direction, minuteStep, secondStep) {
|
|
30011
|
+
const { hours, minutes, seconds } = current;
|
|
30012
|
+
if (unit === 'hours') {
|
|
30013
|
+
const nextHours = (hours + direction + 24) % 24;
|
|
30014
|
+
return { hours: nextHours, minutes, seconds };
|
|
30015
|
+
}
|
|
30016
|
+
if (unit === 'minutes') {
|
|
30017
|
+
const nextMinutes = (minutes + direction * minuteStep + 60) % 60;
|
|
30018
|
+
return { hours, minutes: nextMinutes, seconds };
|
|
30019
|
+
}
|
|
30020
|
+
const nextSeconds = (seconds + direction * secondStep + 60) % 60;
|
|
30021
|
+
return { hours, minutes, seconds: nextSeconds };
|
|
30022
|
+
}
|
|
30023
|
+
|
|
28438
30024
|
/**
|
|
28439
30025
|
* Application-wide notification service. Use the convenience methods
|
|
28440
30026
|
* (`success`, `error`, `warning`, `info`) to push a toast, or call
|
|
@@ -28519,5 +30105,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.13", ngImpo
|
|
|
28519
30105
|
* Generated bundle index. Do not edit.
|
|
28520
30106
|
*/
|
|
28521
30107
|
|
|
28522
|
-
export { AccordionComponent, AccordionItemComponent, ActivityIconComponent, AirplayIconComponent, AlertCircleIconComponent, AlertComponent, AlertOctagonIconComponent, AlertTriangleIconComponent, AlignCenterIconComponent, AlignJustifyIconComponent, AlignLeftIconComponent, AlignRightIconComponent, AnchorIconComponent, ApertureIconComponent,
|
|
30108
|
+
export { AccordionComponent, AccordionItemComponent, ActivityIconComponent, AirplayIconComponent, AlertCircleIconComponent, AlertComponent, AlertOctagonIconComponent, AlertTriangleIconComponent, AlignCenterIconComponent, AlignJustifyIconComponent, AlignLeftIconComponent, AlignRightIconComponent, AnchorIconComponent, ApertureIconComponent, ArchiveIconComponent, ArrowDownCircleIconComponent, ArrowDownIconComponent, ArrowDownLeftIconComponent, ArrowDownRightIconComponent, ArrowLeftCircleIconComponent, ArrowLeftIconComponent, ArrowRightCircleIconComponent, ArrowRightIconComponent, ArrowUpCircleIconComponent, ArrowUpIconComponent, ArrowUpLeftIconComponent, ArrowUpRightIconComponent, AtSignIconComponent, AutocompleteComponent, AvatarComponent, AvatarEditorComponent, AwardIconComponent, BadgeComponent, BarChart2IconComponent, BarChartIconComponent, BatteryChargingIconComponent, BatteryIconComponent, BellIconComponent, BellOffIconComponent, BluetoothIconComponent, BoldIconComponent, BookIconComponent, BookOpenIconComponent, BookmarkIconComponent, BottleIconComponent, BoxIconComponent, BreadcrumbsComponent, BriefcaseIconComponent, ButtonComponent, CalendarIconComponent, CameraIconComponent, CameraOffIconComponent, CandleIconComponent, CardComponent, CastIconComponent, CheckCircleIconComponent, CheckIconComponent, CheckSquareIconComponent, CheckboxComponent, ChevronDownIconComponent, ChevronLeftIconComponent, ChevronRightIconComponent, ChevronUpIconComponent, ChevronsDownIconComponent, ChevronsLeftIconComponent, ChevronsRightIconComponent, ChevronsUpDownIconComponent, ChevronsUpIconComponent, ChromeIconComponent, CircleIconComponent, ClipboardIconComponent, ClockIconComponent, CloudDrizzleIconComponent, CloudIconComponent, CloudLightningIconComponent, CloudOffIconComponent, CloudRainIconComponent, CloudSnowIconComponent, CloudflareIconComponent, CodeIconComponent, CodeInputComponent, CodepenIconComponent, CodesandboxIconComponent, CoffeeIconComponent, ColorPickerComponent, ColumnsIconComponent, CommandIconComponent, CompassIconComponent, CopyIconComponent, CornerDownLeftIconComponent, CornerDownRightIconComponent, CornerLeftDownIconComponent, CornerLeftUpIconComponent, CornerRightDownIconComponent, CornerRightUpIconComponent, CornerUpLeftIconComponent, CornerUpRightIconComponent, CpuIconComponent, CreditCardIconComponent, CropIconComponent, CrosshairIconComponent, DataTableComponent, DatabaseIconComponent, DatePickerComponent, DeleteIconComponent, DialogComponent, DiscIconComponent, DiscordIconComponent, DivideCircleIconComponent, DivideIconComponent, DivideSquareIconComponent, DividerComponent, DockerIconComponent, DollarSignIconComponent, DownloadCloudIconComponent, DownloadIconComponent, DrawerComponent, DribbbleIconComponent, DropboxIconComponent, DropdownComponent, DropletIconComponent, EAGAMI_I18N_CONFIG, EAGAMI_LOCALES, EAGAMI_MESSAGES, EagamiI18nService, EagamiIconComponent, EagamiWordmarkComponent, Edit2IconComponent, Edit3IconComponent, EditIconComponent, EmptyStateComponent, ExternalLinkIconComponent, EyeIconComponent, EyeOffIconComponent, Facebook2IconComponent, FacebookIconComponent, FastForwardIconComponent, FeatherIconComponent, Figma2IconComponent, FigmaIconComponent, FileIconComponent, FileMinusIconComponent, FilePlusIconComponent, FileTextIconComponent, FilmIconComponent, FilterIconComponent, FlagIconComponent, FolderIconComponent, FolderMinusIconComponent, FolderPlusIconComponent, FramerIconComponent, FrownIconComponent, GiftIconComponent, GitBranchIconComponent, GitCommitIconComponent, GitMergeIconComponent, GitPullRequestIconComponent, Github2IconComponent, GithubIconComponent, GitlabIconComponent, GlobeIconComponent, GoogleIconComponent, GridIconComponent, HardDriveIconComponent, HashIconComponent, HeadphonesIconComponent, HeartIconComponent, HelpCircleIconComponent, HeptagonIconComponent, HexagonIconComponent, HomeIconComponent, ICONS, IconComponentBase, ImageIconComponent, InboxIconComponent, InfoIconComponent, InputComponent, InstagramIconComponent, ItalicIconComponent, KeyIconComponent, KubernetesIconComponent, LampIconComponent, LayersIconComponent, LayoutIconComponent, LeftHalfStarIconComponent, LifeBuoyIconComponent, Link2IconComponent, LinkIconComponent, Linkedin2IconComponent, LinkedinIconComponent, ListIconComponent, LoaderIconComponent, LockIconComponent, LogInIconComponent, LogOutIconComponent, MailIconComponent, MapIconComponent, MapPinIconComponent, MastercardIconComponent, Maximize2IconComponent, MaximizeIconComponent, MehIconComponent, MenuComponent, MenuIconComponent, MenuItemComponent, MenuTriggerDirective, MessageCircleIconComponent, MessageSquareIconComponent, MicIconComponent, MicOffIconComponent, MicrosoftIconComponent, Minimize2IconComponent, MinimizeIconComponent, MinusCircleIconComponent, MinusIconComponent, MinusSquareIconComponent, MongodbIconComponent, MonitorIconComponent, MoonIconComponent, MoreHorizontalIconComponent, MoreVerticalIconComponent, MousePointerIconComponent, MoveIconComponent, MultiSelectComponent, MusicIconComponent, Navigation2IconComponent, NavigationIconComponent, NetlifyIconComponent, NotionIconComponent, NpmIconComponent, OctagonIconComponent, PackageIconComponent, PaginatorComponent, PaperclipIconComponent, PauseCircleIconComponent, PauseIconComponent, PaypalIconComponent, PenToolIconComponent, PentagonIconComponent, PercentIconComponent, PhoneCallIconComponent, PhoneForwardedIconComponent, PhoneIconComponent, PhoneIncomingIconComponent, PhoneMissedIconComponent, PhoneOffIconComponent, PhoneOutgoingIconComponent, PieChartIconComponent, PlayCircleIconComponent, PlayIconComponent, PlusCircleIconComponent, PlusIconComponent, PlusSquareIconComponent, PocketIconComponent, PopoverComponent, PowerIconComponent, PrinterIconComponent, ProgressBarComponent, RadioComponent, RadioGroupComponent, RadioIconComponent, RangeSliderComponent, RectangleHorizontalIconComponent, RectangleVerticalIconComponent, RedditIconComponent, RefreshCcwIconComponent, RefreshCwIconComponent, RepeatIconComponent, RewindIconComponent, RightHalfStarIconComponent, RotateCcwIconComponent, RotateCwIconComponent, RssIconComponent, SaveIconComponent, ScissorsIconComponent, SearchIconComponent, SegmentedComponent, SendIconComponent, ServerIconComponent, SettingsIconComponent, Share2IconComponent, ShareIconComponent, ShieldIconComponent, ShieldOffIconComponent, ShoppingBagIconComponent, ShoppingCartIconComponent, ShuffleIconComponent, SidebarIconComponent, SkeletonComponent, SkipBackIconComponent, SkipForwardIconComponent, Slack2IconComponent, SlackIconComponent, SlashIconComponent, SliderComponent, SlidersIconComponent, SmartphoneIconComponent, SmileIconComponent, SoccerBallIconComponent, SpeakerIconComponent, SpinnerComponent, SpotifyIconComponent, SquareIconComponent, StarIconComponent, StepComponent, StepperComponent, StopCircleIconComponent, StripeIconComponent, SunIconComponent, SunriseIconComponent, SunsetIconComponent, SwitchComponent, TabComponent, TableIconComponent, TabletIconComponent, TabsComponent, TagComponent, TagIconComponent, TargetIconComponent, TerminalIconComponent, TextareaComponent, ThermometerIconComponent, ThumbsDownIconComponent, ThumbsUpIconComponent, TimePickerComponent, ToastComponent, ToastService, ToggleLeftIconComponent, ToggleRightIconComponent, ToolIconComponent, TooltipDirective, Trash2IconComponent, TrashIconComponent, TrelloIconComponent, TrendingDownIconComponent, TrendingUpIconComponent, TriangleIconComponent, TrophyIconComponent, TruckIconComponent, TvIconComponent, Twitch2IconComponent, TwitchIconComponent, TwitterIconComponent, TypeIconComponent, UmbrellaIconComponent, UnderlineIconComponent, UnlockIconComponent, UploadCloudIconComponent, UploadIconComponent, UserCheckIconComponent, UserIconComponent, UserMinusIconComponent, UserPlusIconComponent, UserXIconComponent, UsersIconComponent, VercelIconComponent, VideoIconComponent, VideoOffIconComponent, VoicemailIconComponent, Volume1IconComponent, Volume2IconComponent, VolumeIconComponent, VolumeXIconComponent, WatchIconComponent, WifiIconComponent, WifiOffIconComponent, WindIconComponent, XCircleIconComponent, XIconComponent, XOctagonIconComponent, XSquareIconComponent, XTwitterIconComponent, Youtube2IconComponent, YoutubeIconComponent, ZapIconComponent, ZapOffIconComponent, ZoomInIconComponent, ZoomOutIconComponent, computePopoverPosition, el, en, esES, frFR, frenchSpacing, iconDisplayName, pl, provideEagamiUi };
|
|
28523
30109
|
//# sourceMappingURL=eagami-ui.mjs.map
|