@foxeltech/angular-ui 0.2.0 → 0.3.1

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.
Files changed (41) hide show
  1. package/components.css +2 -17
  2. package/fesm2022/foxeltech-angular-ui.mjs +509 -243
  3. package/fesm2022/foxeltech-angular-ui.mjs.map +1 -1
  4. package/package.json +15 -15
  5. package/src/lib/styles/components.css +2 -17
  6. package/src/lib/styles/tailwind.css +11 -8
  7. package/src/lib/styles/tokens.css +131 -0
  8. package/src/lib/styles/utilities.css +24 -0
  9. package/src/lib/ui/components/button/button.component.html +4 -1
  10. package/src/lib/ui/components/checkbox/checkbox.component.html +3 -2
  11. package/src/lib/ui/components/datetime-picker/datetime-picker.component.html +10 -5
  12. package/src/lib/ui/components/datetime-picker/datetime-picker.component.scss +3 -0
  13. package/src/lib/ui/components/drawer/drawer.component.html +78 -61
  14. package/src/lib/ui/components/drawer/drawer.component.scss +3 -0
  15. package/src/lib/ui/components/input/input.component.html +15 -3
  16. package/src/lib/ui/components/kanban-board/kanban-board.component.scss +3 -0
  17. package/src/lib/ui/components/loading-panel/loading-panel.component.html +53 -53
  18. package/src/lib/ui/components/master-detail/master-detail.component.css +11 -0
  19. package/src/lib/ui/components/master-detail/master-detail.component.html +70 -0
  20. package/src/lib/ui/components/meter/meter.component.html +8 -1
  21. package/src/lib/ui/components/radio-button/radio-button.component.html +33 -27
  22. package/src/lib/ui/components/radio-button-toggle/radio-button-toggle.component.html +8 -3
  23. package/src/lib/ui/components/rich-text-area/rich-text-area.component.scss +3 -0
  24. package/src/lib/ui/components/search-bar/search-bar.component.html +11 -10
  25. package/src/lib/ui/components/select/select.component.html +17 -10
  26. package/src/lib/ui/components/severity-badges/severity-badges.component.html +5 -4
  27. package/src/lib/ui/components/skeleton-list/skeleton-list.component.html +2 -2
  28. package/src/lib/ui/components/slider/slider.component.html +20 -15
  29. package/src/lib/ui/components/switch/switch.component.html +11 -6
  30. package/src/lib/ui/components/tab-group/tab-group.component.html +44 -27
  31. package/src/lib/ui/components/tab-group/tab-group.component.scss +3 -0
  32. package/src/lib/ui/components/tag/tag.component.html +6 -1
  33. package/src/lib/ui/components/toast/toast.component.html +38 -35
  34. package/src/lib/ui/components/tree-diagram/tree-diagram.component.html +21 -19
  35. package/src/lib/ui/dialogs/confirmation/confirmation.component.html +1 -1
  36. package/tailwind.css +11 -8
  37. package/tokens.css +131 -0
  38. package/{index.d.ts → types/foxeltech-angular-ui.d.ts} +123 -34
  39. package/utilities.css +24 -0
  40. package/tailwind-config.d.ts +0 -4
  41. package/tailwind.config.js +0 -113
@@ -1,8 +1,8 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, DestroyRef, Injector, Directive, Input, Component, createComponent, Injectable, ViewChild, Inject, EventEmitter, NgModule, HostListener, PLATFORM_ID, Output, ChangeDetectionStrategy, TemplateRef, ContentChildren, ViewChildren, importProvidersFrom } from '@angular/core';
3
- import * as i44 from '@angular/material/paginator';
2
+ import { inject, DestroyRef, Injector, Directive, Input, Component, createComponent, Injectable, ViewChild, Inject, EventEmitter, NgModule, HostListener, PLATFORM_ID, Output, ChangeDetectionStrategy, TemplateRef, ContentChildren, ViewChildren, ContentChild, importProvidersFrom } from '@angular/core';
3
+ import * as i45 from '@angular/material/paginator';
4
4
  import { MatPaginator, MatPaginatorModule } from '@angular/material/paginator';
5
- import * as i45 from '@angular/material/table';
5
+ import * as i46 from '@angular/material/table';
6
6
  import { MatTableDataSource, MatTable, MatTableModule } from '@angular/material/table';
7
7
  import * as i1$1 from '@angular/common';
8
8
  import { isPlatformBrowser, CommonModule } from '@angular/common';
@@ -19,49 +19,49 @@ import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
19
19
  import * as i1$3 from '@ngx-translate/core';
20
20
  import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
21
21
  import { TranslateHttpLoader } from '@ngx-translate/http-loader';
22
- import * as i2$1 from '@angular/forms';
22
+ import * as i1$4 from '@angular/forms';
23
23
  import { NgControl, FormsModule, ReactiveFormsModule } from '@angular/forms';
24
- import * as i1$4 from '@angular/router';
24
+ import * as i1$5 from '@angular/router';
25
25
  import { NavigationEnd, RouterModule } from '@angular/router';
26
26
  import { catchError } from 'rxjs/operators';
27
27
  import * as signalR from '@microsoft/signalr';
28
- import * as i3 from '@angular/material/select';
28
+ import * as i2$1 from '@angular/material/select';
29
29
  import { MatSelectModule } from '@angular/material/select';
30
- import * as i41 from '@angular/material/radio';
30
+ import * as i42 from '@angular/material/radio';
31
31
  import { MatRadioModule } from '@angular/material/radio';
32
- import * as i42 from '@angular/material/button';
32
+ import * as i43 from '@angular/material/button';
33
33
  import { MatButtonModule } from '@angular/material/button';
34
- import * as i43 from '@angular/material/icon';
34
+ import * as i44 from '@angular/material/icon';
35
35
  import { MatIconModule } from '@angular/material/icon';
36
- import * as i46 from '@angular/material/snack-bar';
36
+ import * as i47 from '@angular/material/snack-bar';
37
37
  import { MatSnackBarModule } from '@angular/material/snack-bar';
38
- import * as i48 from '@angular/material/checkbox';
38
+ import * as i49 from '@angular/material/checkbox';
39
39
  import { MatCheckboxModule } from '@angular/material/checkbox';
40
- import * as i49 from '@angular/material/card';
40
+ import * as i50 from '@angular/material/card';
41
41
  import { MatCardModule } from '@angular/material/card';
42
- import * as i50 from '@angular/material/datepicker';
42
+ import * as i51 from '@angular/material/datepicker';
43
43
  import { MatDatepickerModule } from '@angular/material/datepicker';
44
- import * as i51 from '@angular/material/timepicker';
44
+ import * as i52 from '@angular/material/timepicker';
45
45
  import { MatTimepickerModule } from '@angular/material/timepicker';
46
- import * as i52 from '@angular/material/badge';
46
+ import * as i53 from '@angular/material/badge';
47
47
  import { MatBadgeModule } from '@angular/material/badge';
48
- import * as i53 from '@angular/material/expansion';
48
+ import * as i54 from '@angular/material/expansion';
49
49
  import { MatExpansionModule } from '@angular/material/expansion';
50
- import * as i54 from '@angular/material/form-field';
50
+ import * as i55 from '@angular/material/form-field';
51
51
  import { MatFormFieldModule } from '@angular/material/form-field';
52
- import * as i55 from '@angular/material/menu';
52
+ import * as i56 from '@angular/material/menu';
53
53
  import { MatMenuModule } from '@angular/material/menu';
54
- import * as i56 from '@angular/material/tooltip';
54
+ import * as i57 from '@angular/material/tooltip';
55
55
  import { MatTooltipModule } from '@angular/material/tooltip';
56
- import * as i2$3 from '@angular/cdk/drag-drop';
56
+ import * as i2$2 from '@angular/cdk/drag-drop';
57
57
  import { DragDropModule, moveItemInArray, transferArrayItem } from '@angular/cdk/drag-drop';
58
- import * as i2$2 from '@danielmoncada/angular-datetime-picker';
58
+ import * as i1$7 from '@danielmoncada/angular-datetime-picker';
59
59
  import { OwlDateTimeModule, OwlNativeDateTimeModule, OWL_DATE_TIME_FORMATS } from '@danielmoncada/angular-datetime-picker';
60
- import * as i1$5 from 'ngx-echarts';
60
+ import * as i1$6 from 'ngx-echarts';
61
61
  import { NgxEchartsModule } from 'ngx-echarts';
62
- import * as i38 from 'ngx-vflow';
62
+ import * as i39 from 'ngx-vflow';
63
63
  import { Vflow } from 'ngx-vflow';
64
- import { trigger, state, transition, style, animate } from '@angular/animations';
64
+ import { trigger, state, style, transition, animate } from '@angular/animations';
65
65
  import { OwlMomentDateTimeModule } from '@danielmoncada/angular-datetime-picker-moment-adapter';
66
66
 
67
67
  class BaseComponent {
@@ -76,10 +76,10 @@ class BaseComponent {
76
76
  }
77
77
  // eslint-disable-next-line @angular-eslint/no-empty-lifecycle-method -- subclasses across host apps call super.ngOnDestroy(); removing this breaks them at runtime
78
78
  ngOnDestroy() { }
79
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: BaseComponent, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.Directive });
80
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.4", type: BaseComponent, isStandalone: true, ngImport: i0 });
79
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: BaseComponent, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.Directive });
80
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.20", type: BaseComponent, isStandalone: true, ngImport: i0 });
81
81
  }
82
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: BaseComponent, decorators: [{
82
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: BaseComponent, decorators: [{
83
83
  type: Directive
84
84
  }], ctorParameters: () => [{ type: i0.Injector }] });
85
85
 
@@ -91,10 +91,10 @@ class HeroIconComponent {
91
91
  size;
92
92
  color;
93
93
  class;
94
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: HeroIconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
95
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.4", type: HeroIconComponent, isStandalone: false, selector: "fx-ui-hero-icon", inputs: { stroke: "stroke", icon: "icon", solid: "solid", outline: "outline", size: "size", color: "color", class: "class" }, ngImport: i0, template: "<ng-heroicons\n [stroke]=\"stroke\"\n [icon]=\"icon\"\n [size]=\"size\"\n [solid]=\"solid\"\n [outline]=\"outline\"\n [color]=\"color\"\n [class]=\"class\"\n/>\n", styles: [""], dependencies: [{ kind: "component", type: i1.DynamicComponent, selector: "ng-heroicons", inputs: ["icon", "size", "color", "stroke", "outline", "solid", "class", "style"] }] });
94
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: HeroIconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
95
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.20", type: HeroIconComponent, isStandalone: false, selector: "fx-ui-hero-icon", inputs: { stroke: "stroke", icon: "icon", solid: "solid", outline: "outline", size: "size", color: "color", class: "class" }, ngImport: i0, template: "<ng-heroicons\n [stroke]=\"stroke\"\n [icon]=\"icon\"\n [size]=\"size\"\n [solid]=\"solid\"\n [outline]=\"outline\"\n [color]=\"color\"\n [class]=\"class\"\n/>\n", styles: [""], dependencies: [{ kind: "component", type: i1.DynamicComponent, selector: "ng-heroicons", inputs: ["icon", "size", "color", "stroke", "outline", "solid", "class", "style"] }] });
96
96
  }
97
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: HeroIconComponent, decorators: [{
97
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: HeroIconComponent, decorators: [{
98
98
  type: Component,
99
99
  args: [{ selector: 'fx-ui-hero-icon', standalone: false, template: "<ng-heroicons\n [stroke]=\"stroke\"\n [icon]=\"icon\"\n [size]=\"size\"\n [solid]=\"solid\"\n [outline]=\"outline\"\n [color]=\"color\"\n [class]=\"class\"\n/>\n" }]
100
100
  }], propDecorators: { stroke: [{
@@ -118,12 +118,12 @@ class ToastComponent {
118
118
  title = '';
119
119
  message = '';
120
120
  type;
121
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: ToastComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
122
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: ToastComponent, isStandalone: false, selector: "fx-ui-toast", inputs: { toastId: "toastId", title: "title", message: "message", type: "type" }, ngImport: i0, template: "<div\n animate.enter=\"horizontal-fade-in-animation\"\n animate.leave=\"horizontal-fade-out-animation\"\n class=\"flex border-l-[3px] items-center bg-bg-primary gap-semi min-w-[250px] max-w-[400px] px-large py-semi rounded shadow-lg transition-all duration-300 ease-in-out transform opacity-100 translate-y-0\"\n [ngClass]=\"{\n 'border-success': type === 'success',\n 'border-critical': type === 'error',\n 'border-warning': type === 'warning',\n 'border-information': type === 'info'\n }\"\n>\n <div class=\"\">\n @switch (type) { @case('success') {\n <fx-ui-hero-icon\n icon=\"check-circle\"\n [solid]=\"true\"\n [size]=\"30\"\n class=\"text-success\"\n ></fx-ui-hero-icon>\n } @case('error') {\n <fx-ui-hero-icon\n icon=\"exclamation-circle\"\n [solid]=\"true\"\n [size]=\"30\"\n class=\"text-critical\"\n ></fx-ui-hero-icon>\n } @case('warning') {\n <fx-ui-hero-icon\n icon=\"exclamation-triangle\"\n [solid]=\"true\"\n [size]=\"30\"\n class=\"text-warning\"\n ></fx-ui-hero-icon>\n } @default {\n <fx-ui-hero-icon\n icon=\"information-circle\"\n [solid]=\"true\"\n [size]=\"30\"\n class=\"text-information\"\n ></fx-ui-hero-icon>\n } }\n </div>\n\n <div class=\"flex flex-col\">\n <strong *ngIf=\"title\" class=\"txt-field-label\">{{ title }}</strong>\n <p class=\"txt-default\">{{ message }}</p>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: HeroIconComponent, selector: "fx-ui-hero-icon", inputs: ["stroke", "icon", "solid", "outline", "size", "color", "class"] }] });
121
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: ToastComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
122
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: ToastComponent, isStandalone: false, selector: "fx-ui-toast", inputs: { toastId: "toastId", title: "title", message: "message", type: "type" }, ngImport: i0, template: "<div\n animate.enter=\"horizontal-fade-in-animation\"\n animate.leave=\"horizontal-fade-out-animation\"\n [attr.role]=\"type === 'error' ? 'alert' : 'status'\"\n class=\"flex border-l-[3px] items-center bg-bg-primary gap-semi min-w-[250px] max-w-[400px] px-large py-semi rounded shadow-lg transition-all duration-300 ease-in-out transform opacity-100 translate-y-0\"\n [ngClass]=\"{\n 'border-success': type === 'success',\n 'border-critical': type === 'error',\n 'border-warning': type === 'warning',\n 'border-information': type === 'info'\n }\"\n >\n <div class=\"\" aria-hidden=\"true\">\n @switch (type) { @case('success') {\n <fx-ui-hero-icon\n icon=\"check-circle\"\n [solid]=\"true\"\n [size]=\"30\"\n class=\"text-success\"\n ></fx-ui-hero-icon>\n } @case('error') {\n <fx-ui-hero-icon\n icon=\"exclamation-circle\"\n [solid]=\"true\"\n [size]=\"30\"\n class=\"text-critical\"\n ></fx-ui-hero-icon>\n } @case('warning') {\n <fx-ui-hero-icon\n icon=\"exclamation-triangle\"\n [solid]=\"true\"\n [size]=\"30\"\n class=\"text-warning\"\n ></fx-ui-hero-icon>\n } @default {\n <fx-ui-hero-icon\n icon=\"information-circle\"\n [solid]=\"true\"\n [size]=\"30\"\n class=\"text-information\"\n ></fx-ui-hero-icon>\n } }\n </div>\n\n <div class=\"flex flex-col\">\n @if (title) {\n <strong class=\"txt-field-label\">{{ title }}</strong>\n }\n <p class=\"txt-default\">{{ message }}</p>\n </div>\n </div>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: HeroIconComponent, selector: "fx-ui-hero-icon", inputs: ["stroke", "icon", "solid", "outline", "size", "color", "class"] }] });
123
123
  }
124
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: ToastComponent, decorators: [{
124
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: ToastComponent, decorators: [{
125
125
  type: Component,
126
- args: [{ selector: 'fx-ui-toast', standalone: false, template: "<div\n animate.enter=\"horizontal-fade-in-animation\"\n animate.leave=\"horizontal-fade-out-animation\"\n class=\"flex border-l-[3px] items-center bg-bg-primary gap-semi min-w-[250px] max-w-[400px] px-large py-semi rounded shadow-lg transition-all duration-300 ease-in-out transform opacity-100 translate-y-0\"\n [ngClass]=\"{\n 'border-success': type === 'success',\n 'border-critical': type === 'error',\n 'border-warning': type === 'warning',\n 'border-information': type === 'info'\n }\"\n>\n <div class=\"\">\n @switch (type) { @case('success') {\n <fx-ui-hero-icon\n icon=\"check-circle\"\n [solid]=\"true\"\n [size]=\"30\"\n class=\"text-success\"\n ></fx-ui-hero-icon>\n } @case('error') {\n <fx-ui-hero-icon\n icon=\"exclamation-circle\"\n [solid]=\"true\"\n [size]=\"30\"\n class=\"text-critical\"\n ></fx-ui-hero-icon>\n } @case('warning') {\n <fx-ui-hero-icon\n icon=\"exclamation-triangle\"\n [solid]=\"true\"\n [size]=\"30\"\n class=\"text-warning\"\n ></fx-ui-hero-icon>\n } @default {\n <fx-ui-hero-icon\n icon=\"information-circle\"\n [solid]=\"true\"\n [size]=\"30\"\n class=\"text-information\"\n ></fx-ui-hero-icon>\n } }\n </div>\n\n <div class=\"flex flex-col\">\n <strong *ngIf=\"title\" class=\"txt-field-label\">{{ title }}</strong>\n <p class=\"txt-default\">{{ message }}</p>\n </div>\n</div>\n" }]
126
+ args: [{ selector: 'fx-ui-toast', standalone: false, template: "<div\n animate.enter=\"horizontal-fade-in-animation\"\n animate.leave=\"horizontal-fade-out-animation\"\n [attr.role]=\"type === 'error' ? 'alert' : 'status'\"\n class=\"flex border-l-[3px] items-center bg-bg-primary gap-semi min-w-[250px] max-w-[400px] px-large py-semi rounded shadow-lg transition-all duration-300 ease-in-out transform opacity-100 translate-y-0\"\n [ngClass]=\"{\n 'border-success': type === 'success',\n 'border-critical': type === 'error',\n 'border-warning': type === 'warning',\n 'border-information': type === 'info'\n }\"\n >\n <div class=\"\" aria-hidden=\"true\">\n @switch (type) { @case('success') {\n <fx-ui-hero-icon\n icon=\"check-circle\"\n [solid]=\"true\"\n [size]=\"30\"\n class=\"text-success\"\n ></fx-ui-hero-icon>\n } @case('error') {\n <fx-ui-hero-icon\n icon=\"exclamation-circle\"\n [solid]=\"true\"\n [size]=\"30\"\n class=\"text-critical\"\n ></fx-ui-hero-icon>\n } @case('warning') {\n <fx-ui-hero-icon\n icon=\"exclamation-triangle\"\n [solid]=\"true\"\n [size]=\"30\"\n class=\"text-warning\"\n ></fx-ui-hero-icon>\n } @default {\n <fx-ui-hero-icon\n icon=\"information-circle\"\n [solid]=\"true\"\n [size]=\"30\"\n class=\"text-information\"\n ></fx-ui-hero-icon>\n } }\n </div>\n\n <div class=\"flex flex-col\">\n @if (title) {\n <strong class=\"txt-field-label\">{{ title }}</strong>\n }\n <p class=\"txt-default\">{{ message }}</p>\n </div>\n </div>\n" }]
127
127
  }], propDecorators: { toastId: [{
128
128
  type: Input
129
129
  }], title: [{
@@ -150,10 +150,10 @@ class ToastContainerComponent {
150
150
  this.toasts = this.toasts.filter(t => t.id !== id);
151
151
  this.ref.detectChanges();
152
152
  }
153
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: ToastContainerComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
154
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: ToastContainerComponent, isStandalone: false, selector: "fx-ui-toast-container", ngImport: i0, template: "<div\n class=\"fixed top-5 right-5 flex flex-col items-end gap-3 z-[10000] pointer-events-none\"\n>\n @for (toast of toasts; track toast) {\n <fx-ui-toast\n class=\"pointer-events-auto\"\n [message]=\"toast.message\"\n [title]=\"toast.title\"\n [type]=\"toast.type\"\n ></fx-ui-toast>\n }\n</div>", styles: [""], dependencies: [{ kind: "component", type: ToastComponent, selector: "fx-ui-toast", inputs: ["toastId", "title", "message", "type"] }] });
153
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: ToastContainerComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
154
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: ToastContainerComponent, isStandalone: false, selector: "fx-ui-toast-container", ngImport: i0, template: "<div\n class=\"fixed top-5 right-5 flex flex-col items-end gap-3 z-[10000] pointer-events-none\"\n>\n @for (toast of toasts; track toast) {\n <fx-ui-toast\n class=\"pointer-events-auto\"\n [message]=\"toast.message\"\n [title]=\"toast.title\"\n [type]=\"toast.type\"\n ></fx-ui-toast>\n }\n</div>", styles: [""], dependencies: [{ kind: "component", type: ToastComponent, selector: "fx-ui-toast", inputs: ["toastId", "title", "message", "type"] }] });
155
155
  }
156
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: ToastContainerComponent, decorators: [{
156
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: ToastContainerComponent, decorators: [{
157
157
  type: Component,
158
158
  args: [{ selector: 'fx-ui-toast-container', standalone: false, template: "<div\n class=\"fixed top-5 right-5 flex flex-col items-end gap-3 z-[10000] pointer-events-none\"\n>\n @for (toast of toasts; track toast) {\n <fx-ui-toast\n class=\"pointer-events-auto\"\n [message]=\"toast.message\"\n [title]=\"toast.title\"\n [type]=\"toast.type\"\n ></fx-ui-toast>\n }\n</div>" }]
159
159
  }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }] });
@@ -203,10 +203,10 @@ class FxToastrService {
203
203
  warning(message, title) {
204
204
  this.show(message, 'warning', title);
205
205
  }
206
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: FxToastrService, deps: [{ token: i0.ApplicationRef }], target: i0.ɵɵFactoryTarget.Injectable });
207
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: FxToastrService, providedIn: 'root' });
206
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: FxToastrService, deps: [{ token: i0.ApplicationRef }], target: i0.ɵɵFactoryTarget.Injectable });
207
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: FxToastrService, providedIn: 'root' });
208
208
  }
209
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: FxToastrService, decorators: [{
209
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: FxToastrService, decorators: [{
210
210
  type: Injectable,
211
211
  args: [{
212
212
  providedIn: 'root',
@@ -739,9 +739,9 @@ class BaseTableComponent extends BaseComponent {
739
739
  }
740
740
  const instance = this.modal.open(dialog, {
741
741
  panelClass: panelClass,
742
- autoFocus: false,
742
+ autoFocus: 'first-tabbable',
743
743
  width: size,
744
- disableClose: true,
744
+ disableClose: conf.disableClose ?? false,
745
745
  data: {
746
746
  method: 'create',
747
747
  data: this.empty(),
@@ -774,9 +774,9 @@ class BaseTableComponent extends BaseComponent {
774
774
  }
775
775
  const instance = this.modal.open(dialog, {
776
776
  panelClass: panelClass,
777
- autoFocus: false,
777
+ autoFocus: 'first-tabbable',
778
778
  width: size,
779
- disableClose: true,
779
+ disableClose: conf.disableClose ?? false,
780
780
  data: {
781
781
  method: 'update',
782
782
  data: model,
@@ -809,9 +809,9 @@ class BaseTableComponent extends BaseComponent {
809
809
  }
810
810
  const instance = this.modal.open(dialog, {
811
811
  panelClass: panelClass,
812
- autoFocus: false,
812
+ autoFocus: 'first-tabbable',
813
813
  width: size,
814
- disableClose: true,
814
+ disableClose: conf.disableClose ?? false,
815
815
  data: {
816
816
  data: model,
817
817
  title: conf.title,
@@ -838,7 +838,7 @@ class BaseTableComponent extends BaseComponent {
838
838
  try {
839
839
  const dialogRef = this.modal.open(dialog, {
840
840
  panelClass: 'fx-dialog',
841
- autoFocus: false,
841
+ autoFocus: 'first-tabbable',
842
842
  width: '400px',
843
843
  data: {
844
844
  title: _.get(conf, 'title'),
@@ -896,10 +896,10 @@ class BaseTableComponent extends BaseComponent {
896
896
  await this.refresh();
897
897
  }
898
898
  }
899
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: BaseTableComponent, deps: "invalid", target: i0.ɵɵFactoryTarget.Directive });
900
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.4", type: BaseTableComponent, isStandalone: true, viewQueries: [{ propertyName: "paginator", first: true, predicate: MatPaginator, descendants: true }, { propertyName: "table", first: true, predicate: MatTable, descendants: true }], usesInheritance: true, ngImport: i0 });
899
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: BaseTableComponent, deps: "invalid", target: i0.ɵɵFactoryTarget.Directive });
900
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.20", type: BaseTableComponent, isStandalone: true, viewQueries: [{ propertyName: "paginator", first: true, predicate: MatPaginator, descendants: true }, { propertyName: "table", first: true, predicate: MatTable, descendants: true }], usesInheritance: true, ngImport: i0 });
901
901
  }
902
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: BaseTableComponent, decorators: [{
902
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: BaseTableComponent, decorators: [{
903
903
  type: Directive
904
904
  }], ctorParameters: () => [{ type: i0.Injector }, { type: HttpWrapper }, { type: undefined }, { type: i0.ChangeDetectorRef }], propDecorators: { paginator: [{
905
905
  type: ViewChild,
@@ -909,6 +909,93 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
909
909
  args: [MatTable]
910
910
  }] } });
911
911
 
912
+ /**
913
+ * List + detail-pane counterpart of BaseTableComponent: the page keeps a
914
+ * selectable row list on one side and a lazily fetched, per-id-cached detail
915
+ * on the other. Pair it with `<fx-ui-master-detail>` which renders the
916
+ * two-column shell from this state.
917
+ *
918
+ * Subclasses declare where ids and details come from:
919
+ * protected override idKey = 'licenseId';
920
+ * protected override detailUrl(id: string) { return `/license/${id}`; }
921
+ * `detailUrl` returning null (the default) means the selected row itself is
922
+ * the detail and no request is made.
923
+ */
924
+ class BaseMasterDetailComponent extends BaseTableComponent {
925
+ selectedId = null;
926
+ selected = null;
927
+ detailMap = new Map();
928
+ detailLoading = new Set();
929
+ // Explicit ctor: Ivy refuses to inherit a constructor whose `modal: any`
930
+ // parameter is not DI-resolvable (NG2016).
931
+ constructor(injector, api, modal, ref) {
932
+ super(injector, api, modal, ref);
933
+ }
934
+ /** Key the row id is read from. Override idOf() instead for composite ids. */
935
+ idKey = 'id';
936
+ idOf(row) {
937
+ return this.value(row, this.idKey, null);
938
+ }
939
+ detailUrl(id) {
940
+ return null;
941
+ }
942
+ /** What the detail pane shows: the fetched detail when cached, else the row. */
943
+ get detail() {
944
+ return (this.selectedId != null && this.detailMap.get(this.selectedId)) || this.selected;
945
+ }
946
+ get detailBusy() {
947
+ return this.selectedId != null && this.detailLoading.has(this.selectedId);
948
+ }
949
+ setDataSource(result) {
950
+ super.setDataSource(result);
951
+ this.autoSelectFirst();
952
+ }
953
+ /** Keep the previous selection when it survived the new page, else pick row 0. */
954
+ autoSelectFirst() {
955
+ const list = this.dataSource.data || [];
956
+ if (!list.length) {
957
+ this.selectedId = null;
958
+ this.selected = null;
959
+ return;
960
+ }
961
+ const still = list.find((row) => this.idOf(row) === this.selectedId);
962
+ this.selectItem(still ?? list[0]);
963
+ }
964
+ selectItem(row) {
965
+ const id = this.idOf(row);
966
+ this.selectedId = id;
967
+ this.selected = row;
968
+ if (id != null && !this.detailMap.has(id)) {
969
+ this.fetchDetail(id);
970
+ }
971
+ }
972
+ fetchDetail(id) {
973
+ const url = this.detailUrl(id);
974
+ if (!url || this.detailLoading.has(id)) {
975
+ return;
976
+ }
977
+ this.detailLoading.add(id);
978
+ this.api
979
+ .get(url)
980
+ .then((res) => {
981
+ // New Map identity so OnPush consumers of the pane see the change.
982
+ this.detailMap = new Map(this.detailMap).set(id, res);
983
+ })
984
+ .catch((err) => {
985
+ this.toastr.error(FxUtils.parseError(err));
986
+ })
987
+ .finally(() => {
988
+ this.detailLoading.delete(id);
989
+ this.ref.detectChanges();
990
+ });
991
+ }
992
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: BaseMasterDetailComponent, deps: "invalid", target: i0.ɵɵFactoryTarget.Directive });
993
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.20", type: BaseMasterDetailComponent, isStandalone: true, usesInheritance: true, ngImport: i0 });
994
+ }
995
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: BaseMasterDetailComponent, decorators: [{
996
+ type: Directive
997
+ }], ctorParameters: () => [{ type: i0.Injector }, { type: HttpWrapper }, { type: undefined }, { type: i0.ChangeDetectorRef }] });
998
+
912
999
  class BaseDialogComponent extends BaseComponent {
913
1000
  ref;
914
1001
  bindings;
@@ -1021,10 +1108,10 @@ class BaseDialogComponent extends BaseComponent {
1021
1108
  validate() {
1022
1109
  return true;
1023
1110
  }
1024
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: BaseDialogComponent, deps: [{ token: i1$2.MatDialogRef }, { token: MAT_DIALOG_DATA }, { token: FxToastrService }, { token: HttpWrapper }, { token: i1$2.MatDialog }], target: i0.ɵɵFactoryTarget.Directive });
1025
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.4", type: BaseDialogComponent, isStandalone: true, viewQueries: [{ propertyName: "ngForm", first: true, predicate: ["f"], descendants: true, static: true }], usesInheritance: true, ngImport: i0 });
1111
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: BaseDialogComponent, deps: [{ token: i1$2.MatDialogRef }, { token: MAT_DIALOG_DATA }, { token: FxToastrService }, { token: HttpWrapper }, { token: i1$2.MatDialog }], target: i0.ɵɵFactoryTarget.Directive });
1112
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.20", type: BaseDialogComponent, isStandalone: true, viewQueries: [{ propertyName: "ngForm", first: true, predicate: ["f"], descendants: true, static: true }], usesInheritance: true, ngImport: i0 });
1026
1113
  }
1027
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: BaseDialogComponent, decorators: [{
1114
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: BaseDialogComponent, decorators: [{
1028
1115
  type: Directive
1029
1116
  }], ctorParameters: () => [{ type: i1$2.MatDialogRef }, { type: undefined, decorators: [{
1030
1117
  type: Inject,
@@ -1049,10 +1136,10 @@ class FxLoadingService {
1049
1136
  stopAction() {
1050
1137
  this.listenerAction.emit(false);
1051
1138
  }
1052
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: FxLoadingService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1053
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: FxLoadingService, providedIn: 'root' });
1139
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: FxLoadingService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1140
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: FxLoadingService, providedIn: 'root' });
1054
1141
  }
1055
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: FxLoadingService, decorators: [{
1142
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: FxLoadingService, decorators: [{
1056
1143
  type: Injectable,
1057
1144
  args: [{
1058
1145
  providedIn: 'root'
@@ -1082,10 +1169,10 @@ class FxStorageService {
1082
1169
  remove(key) {
1083
1170
  localStorage.removeItem(key);
1084
1171
  }
1085
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: FxStorageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1086
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: FxStorageService, providedIn: 'root' });
1172
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: FxStorageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1173
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: FxStorageService, providedIn: 'root' });
1087
1174
  }
1088
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: FxStorageService, decorators: [{
1175
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: FxStorageService, decorators: [{
1089
1176
  type: Injectable,
1090
1177
  args: [{
1091
1178
  providedIn: 'root',
@@ -1292,6 +1379,27 @@ class RealtimeTableSync {
1292
1379
 
1293
1380
  const NEUTRAL_TEXT = 'text-text-secondary';
1294
1381
  const NEUTRAL_BG = 'bg-bg-hover';
1382
+ const TONE_TEXT = {
1383
+ critical: 'text-critical',
1384
+ danger: 'text-danger',
1385
+ warning: 'text-warning',
1386
+ success: 'text-success',
1387
+ information: 'text-information',
1388
+ };
1389
+ const TONE_BG = {
1390
+ critical: 'bg-critical',
1391
+ danger: 'bg-danger',
1392
+ warning: 'bg-warning',
1393
+ success: 'bg-success',
1394
+ information: 'bg-information',
1395
+ };
1396
+ const TONE_BADGE = {
1397
+ critical: 'bg-critical/10 text-critical',
1398
+ danger: 'bg-danger/10 text-danger',
1399
+ warning: 'bg-warning/10 text-warning',
1400
+ success: 'bg-success/10 text-success',
1401
+ information: 'bg-information/10 text-information',
1402
+ };
1295
1403
  function hasVal(v) {
1296
1404
  if (_.isNil(v))
1297
1405
  return false;
@@ -1338,15 +1446,15 @@ function countTone(count, positiveTone = 'danger') {
1338
1446
  }
1339
1447
  /** Tone → text colour class, with a neutral fallback when there is no value. */
1340
1448
  function toneText(tone) {
1341
- return tone ? `text-${tone}` : NEUTRAL_TEXT;
1449
+ return tone ? TONE_TEXT[tone] : NEUTRAL_TEXT;
1342
1450
  }
1343
1451
  /** Tone → background colour class, with a neutral fallback when there is no value. */
1344
1452
  function toneBg(tone) {
1345
- return tone ? `bg-${tone}` : NEUTRAL_BG;
1453
+ return tone ? TONE_BG[tone] : NEUTRAL_BG;
1346
1454
  }
1347
1455
  /** Tone → soft pill/badge classes (tinted bg + matching text), neutral fallback. */
1348
1456
  function toneBadge(tone) {
1349
- return tone ? `bg-${tone}/10 text-${tone}` : `${NEUTRAL_BG} text-text-secondary`;
1457
+ return tone ? TONE_BADGE[tone] : 'bg-bg-hover text-text-secondary';
1350
1458
  }
1351
1459
  /**
1352
1460
  * Tone → resolved CSS colour string for ECharts / canvas where a Tailwind
@@ -1496,11 +1604,11 @@ class TranslationModule {
1496
1604
  providers: []
1497
1605
  };
1498
1606
  }
1499
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: TranslationModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1500
- static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.4", ngImport: i0, type: TranslationModule, imports: [TranslateModule], exports: [TranslateModule] });
1501
- static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: TranslationModule, imports: [TranslateModule, TranslateModule] });
1607
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: TranslationModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1608
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.20", ngImport: i0, type: TranslationModule, imports: [TranslateModule], exports: [TranslateModule] });
1609
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: TranslationModule, imports: [TranslateModule, TranslateModule] });
1502
1610
  }
1503
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: TranslationModule, decorators: [{
1611
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: TranslationModule, decorators: [{
1504
1612
  type: NgModule,
1505
1613
  args: [{
1506
1614
  imports: [TranslateModule],
@@ -1544,10 +1652,10 @@ class TranslationService {
1544
1652
  onLanguageChange(callback) {
1545
1653
  this.currentLang$.subscribe(callback);
1546
1654
  }
1547
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: TranslationService, deps: [{ token: i1$3.TranslateService }, { token: i2.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
1548
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: TranslationService, providedIn: 'root' });
1655
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: TranslationService, deps: [{ token: i1$3.TranslateService }, { token: i2.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
1656
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: TranslationService, providedIn: 'root' });
1549
1657
  }
1550
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: TranslationService, decorators: [{
1658
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: TranslationService, decorators: [{
1551
1659
  type: Injectable,
1552
1660
  args: [{ providedIn: 'root' }]
1553
1661
  }], ctorParameters: () => [{ type: i1$3.TranslateService }, { type: i2.HttpClient }] });
@@ -1563,10 +1671,10 @@ class PermissionService {
1563
1671
  getPermissions() {
1564
1672
  return [...this.permissions];
1565
1673
  }
1566
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: PermissionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1567
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: PermissionService, providedIn: 'root' });
1674
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: PermissionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1675
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: PermissionService, providedIn: 'root' });
1568
1676
  }
1569
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: PermissionService, decorators: [{
1677
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: PermissionService, decorators: [{
1570
1678
  type: Injectable,
1571
1679
  args: [{
1572
1680
  providedIn: 'root'
@@ -1589,10 +1697,10 @@ class HasPermissionDirective {
1589
1697
  this.viewContainerRef.createEmbeddedView(this.templateRef);
1590
1698
  }
1591
1699
  }
1592
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: HasPermissionDirective, deps: [{ token: i0.TemplateRef }, { token: i0.ViewContainerRef }, { token: PermissionService }], target: i0.ɵɵFactoryTarget.Directive });
1593
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.4", type: HasPermissionDirective, isStandalone: true, selector: "[hasPermission]", inputs: { hasPermission: "hasPermission" }, ngImport: i0 });
1700
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: HasPermissionDirective, deps: [{ token: i0.TemplateRef }, { token: i0.ViewContainerRef }, { token: PermissionService }], target: i0.ɵɵFactoryTarget.Directive });
1701
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.20", type: HasPermissionDirective, isStandalone: true, selector: "[hasPermission]", inputs: { hasPermission: "hasPermission" }, ngImport: i0 });
1594
1702
  }
1595
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: HasPermissionDirective, decorators: [{
1703
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: HasPermissionDirective, decorators: [{
1596
1704
  type: Directive,
1597
1705
  args: [{
1598
1706
  // eslint-disable-next-line @angular-eslint/directive-selector -- renaming is a breaking change for all host-app templates
@@ -1632,16 +1740,16 @@ class TrimOnBlurDirective {
1632
1740
  native.dispatchEvent(ev);
1633
1741
  }
1634
1742
  }
1635
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: TrimOnBlurDirective, deps: [{ token: i0.ElementRef }, { token: i2$1.NgControl }], target: i0.ɵɵFactoryTarget.Directive });
1636
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.4", type: TrimOnBlurDirective, isStandalone: true, selector: "[appTrimOnBlur]", inputs: { collapseWhitespace: ["appTrimOnBlurCollapse", "collapseWhitespace"] }, host: { listeners: { "blur": "onBlur()" } }, ngImport: i0 });
1743
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: TrimOnBlurDirective, deps: [{ token: i0.ElementRef }, { token: i1$4.NgControl }], target: i0.ɵɵFactoryTarget.Directive });
1744
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.20", type: TrimOnBlurDirective, isStandalone: true, selector: "[appTrimOnBlur]", inputs: { collapseWhitespace: ["appTrimOnBlurCollapse", "collapseWhitespace"] }, host: { listeners: { "blur": "onBlur()" } }, ngImport: i0 });
1637
1745
  }
1638
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: TrimOnBlurDirective, decorators: [{
1746
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: TrimOnBlurDirective, decorators: [{
1639
1747
  type: Directive,
1640
1748
  args: [{
1641
1749
  // eslint-disable-next-line @angular-eslint/directive-selector -- renaming is a breaking change for all host-app templates
1642
1750
  selector: '[appTrimOnBlur]'
1643
1751
  }]
1644
- }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i2$1.NgControl }], propDecorators: { collapseWhitespace: [{
1752
+ }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i1$4.NgControl }], propDecorators: { collapseWhitespace: [{
1645
1753
  type: Input,
1646
1754
  args: ['appTrimOnBlurCollapse']
1647
1755
  }], onBlur: [{
@@ -1664,15 +1772,15 @@ class PermissionGuard {
1664
1772
  this.router.navigate(['/unauthorized']);
1665
1773
  return false;
1666
1774
  }
1667
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: PermissionGuard, deps: [{ token: PermissionService }, { token: i1$4.Router }], target: i0.ɵɵFactoryTarget.Injectable });
1668
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: PermissionGuard, providedIn: 'root' });
1775
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: PermissionGuard, deps: [{ token: PermissionService }, { token: i1$5.Router }], target: i0.ɵɵFactoryTarget.Injectable });
1776
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: PermissionGuard, providedIn: 'root' });
1669
1777
  }
1670
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: PermissionGuard, decorators: [{
1778
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: PermissionGuard, decorators: [{
1671
1779
  type: Injectable,
1672
1780
  args: [{
1673
1781
  providedIn: 'root',
1674
1782
  }]
1675
- }], ctorParameters: () => [{ type: PermissionService }, { type: i1$4.Router }] });
1783
+ }], ctorParameters: () => [{ type: PermissionService }, { type: i1$5.Router }] });
1676
1784
 
1677
1785
  class AuthStateService {
1678
1786
  _isLoggedIn$ = new BehaviorSubject(null);
@@ -1689,10 +1797,10 @@ class AuthStateService {
1689
1797
  this.setLoggedIn(false);
1690
1798
  this.unauthorized$.next();
1691
1799
  }
1692
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: AuthStateService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1693
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: AuthStateService, providedIn: 'root' });
1800
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: AuthStateService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1801
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: AuthStateService, providedIn: 'root' });
1694
1802
  }
1695
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: AuthStateService, decorators: [{
1803
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: AuthStateService, decorators: [{
1696
1804
  type: Injectable,
1697
1805
  args: [{ providedIn: 'root' }]
1698
1806
  }], ctorParameters: () => [] });
@@ -1722,10 +1830,10 @@ class AuthInterceptor {
1722
1830
  return throwError(() => error);
1723
1831
  }));
1724
1832
  }
1725
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: AuthInterceptor, deps: [{ token: AuthStateService }], target: i0.ɵɵFactoryTarget.Injectable });
1726
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: AuthInterceptor });
1833
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: AuthInterceptor, deps: [{ token: AuthStateService }], target: i0.ɵɵFactoryTarget.Injectable });
1834
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: AuthInterceptor });
1727
1835
  }
1728
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: AuthInterceptor, decorators: [{
1836
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: AuthInterceptor, decorators: [{
1729
1837
  type: Injectable
1730
1838
  }], ctorParameters: () => [{ type: AuthStateService }] });
1731
1839
 
@@ -1740,10 +1848,10 @@ class BreadcrumbService {
1740
1848
  clear() {
1741
1849
  this.breadcrumbs$.next([]);
1742
1850
  }
1743
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: BreadcrumbService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1744
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: BreadcrumbService, providedIn: 'root' });
1851
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: BreadcrumbService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1852
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: BreadcrumbService, providedIn: 'root' });
1745
1853
  }
1746
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: BreadcrumbService, decorators: [{
1854
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: BreadcrumbService, decorators: [{
1747
1855
  type: Injectable,
1748
1856
  args: [{
1749
1857
  providedIn: 'root'
@@ -1804,10 +1912,10 @@ class QuillStyleLoaderService {
1804
1912
  });
1805
1913
  return this.loadingPromise;
1806
1914
  }
1807
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: QuillStyleLoaderService, deps: [{ token: PLATFORM_ID }], target: i0.ɵɵFactoryTarget.Injectable });
1808
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: QuillStyleLoaderService, providedIn: 'root' });
1915
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: QuillStyleLoaderService, deps: [{ token: PLATFORM_ID }], target: i0.ɵɵFactoryTarget.Injectable });
1916
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: QuillStyleLoaderService, providedIn: 'root' });
1809
1917
  }
1810
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: QuillStyleLoaderService, decorators: [{
1918
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: QuillStyleLoaderService, decorators: [{
1811
1919
  type: Injectable,
1812
1920
  args: [{ providedIn: 'root' }]
1813
1921
  }], ctorParameters: () => [{ type: undefined, decorators: [{
@@ -1859,10 +1967,10 @@ class ThemeService {
1859
1967
  getLogoPath() {
1860
1968
  return 'assets/images/logo.png';
1861
1969
  }
1862
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: ThemeService, deps: [{ token: i0.RendererFactory2 }], target: i0.ɵɵFactoryTarget.Injectable });
1863
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: ThemeService, providedIn: 'root' });
1970
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: ThemeService, deps: [{ token: i0.RendererFactory2 }], target: i0.ɵɵFactoryTarget.Injectable });
1971
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: ThemeService, providedIn: 'root' });
1864
1972
  }
1865
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: ThemeService, decorators: [{
1973
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: ThemeService, decorators: [{
1866
1974
  type: Injectable,
1867
1975
  args: [{ providedIn: 'root' }]
1868
1976
  }], ctorParameters: () => [{ type: i0.RendererFactory2 }] });
@@ -2084,10 +2192,10 @@ class NotificationService {
2084
2192
  getConnectionId() {
2085
2193
  return this.hubConnection?.connectionId ?? null;
2086
2194
  }
2087
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: NotificationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2088
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: NotificationService, providedIn: 'root' });
2195
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: NotificationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2196
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: NotificationService, providedIn: 'root' });
2089
2197
  }
2090
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: NotificationService, decorators: [{
2198
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: NotificationService, decorators: [{
2091
2199
  type: Injectable,
2092
2200
  args: [{
2093
2201
  providedIn: 'root'
@@ -2122,17 +2230,21 @@ class ButtonComponent {
2122
2230
  icon;
2123
2231
  class;
2124
2232
  loading = false;
2233
+ /** Native button type. Defaults to 'button' so it never implicitly submits a form. */
2234
+ type = 'button';
2235
+ /** Accessible name for icon-only usage (icon set, no label). */
2236
+ ariaLabel = '';
2125
2237
  clicked = new EventEmitter();
2126
2238
  onClick() {
2127
2239
  if (!this.disabled)
2128
2240
  this.clicked.emit();
2129
2241
  }
2130
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: ButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2131
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: ButtonComponent, isStandalone: false, selector: "fx-ui-button", inputs: { label: "label", disabled: "disabled", buttonVariant: "buttonVariant", icon: "icon", class: "class", loading: "loading" }, outputs: { clicked: "clicked" }, ngImport: i0, template: "<button\n [class]=\"class\"\n [ngClass]=\"{\n 'btn-default': buttonVariant === 'default',\n 'btn-primary': buttonVariant === 'primary',\n 'btn-success': buttonVariant === 'success',\n 'btn-alternative': buttonVariant === 'alternative',\n }\"\n [disabled]=\"disabled || loading\"\n (click)=\"onClick()\"\n>\n @if (loading) {\n <div class=\"flex w-full items-center justify-center\">\n <svg\n [attr.fill]=\"\n buttonVariant !== 'alternative' ? 'rgb(var(--text-primary))' : 'rgb(var(--primary))'\n \"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <circle cx=\"4\" cy=\"12\" r=\"0\">\n <animate\n begin=\"0;spinner_z0Or.end\"\n attributeName=\"r\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"0;3\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_OLMs.end\"\n attributeName=\"cx\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"4;12\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_UHR2.end\"\n attributeName=\"cx\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"12;20\"\n fill=\"freeze\"\n />\n <animate\n id=\"spinner_lo66\"\n begin=\"spinner_Aguh.end\"\n attributeName=\"r\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"3;0\"\n fill=\"freeze\"\n />\n <animate\n id=\"spinner_z0Or\"\n begin=\"spinner_lo66.end\"\n attributeName=\"cx\"\n dur=\"0.001s\"\n values=\"20;4\"\n fill=\"freeze\"\n />\n </circle>\n <circle cx=\"4\" cy=\"12\" r=\"3\">\n <animate\n begin=\"0;spinner_z0Or.end\"\n attributeName=\"cx\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"4;12\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_OLMs.end\"\n attributeName=\"cx\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"12;20\"\n fill=\"freeze\"\n />\n <animate\n id=\"spinner_JsnR\"\n begin=\"spinner_UHR2.end\"\n attributeName=\"r\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"3;0\"\n fill=\"freeze\"\n />\n <animate\n id=\"spinner_Aguh\"\n begin=\"spinner_JsnR.end\"\n attributeName=\"cx\"\n dur=\"0.001s\"\n values=\"20;4\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_Aguh.end\"\n attributeName=\"r\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"0;3\"\n fill=\"freeze\"\n />\n </circle>\n <circle cx=\"12\" cy=\"12\" r=\"3\">\n <animate\n begin=\"0;spinner_z0Or.end\"\n attributeName=\"cx\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"12;20\"\n fill=\"freeze\"\n />\n <animate\n id=\"spinner_hSjk\"\n begin=\"spinner_OLMs.end\"\n attributeName=\"r\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"3;0\"\n fill=\"freeze\"\n />\n <animate\n id=\"spinner_UHR2\"\n begin=\"spinner_hSjk.end\"\n attributeName=\"cx\"\n dur=\"0.001s\"\n values=\"20;4\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_UHR2.end\"\n attributeName=\"r\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"0;3\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_Aguh.end\"\n attributeName=\"cx\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"4;12\"\n fill=\"freeze\"\n />\n </circle>\n <circle cx=\"20\" cy=\"12\" r=\"3\">\n <animate\n id=\"spinner_4v5M\"\n begin=\"0;spinner_z0Or.end\"\n attributeName=\"r\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"3;0\"\n fill=\"freeze\"\n />\n <animate\n id=\"spinner_OLMs\"\n begin=\"spinner_4v5M.end\"\n attributeName=\"cx\"\n dur=\"0.001s\"\n values=\"20;4\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_OLMs.end\"\n attributeName=\"r\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"0;3\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_UHR2.end\"\n attributeName=\"cx\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"4;12\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_Aguh.end\"\n attributeName=\"cx\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"12;20\"\n fill=\"freeze\"\n />\n </circle>\n </svg>\n </div>\n } @else {\n <ng-container>\n <div class=\"flex items-center justify-center gap-small\">\n @if (icon) {\n <fx-ui-hero-icon\n [icon]=\"icon\"\n [size]=\"20\"\n class=\"flex\"\n [ngClass]=\"{\n 'text-text-inverse': buttonVariant === 'default',\n 'text-text-primary': buttonVariant === 'alternative',\n 'text-white': buttonVariant === 'primary' || buttonVariant === 'success',\n }\"\n ></fx-ui-hero-icon>\n }\n @if (label) {\n <div>{{ label }}</div>\n }\n </div>\n </ng-container>\n }\n</button>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: HeroIconComponent, selector: "fx-ui-hero-icon", inputs: ["stroke", "icon", "solid", "outline", "size", "color", "class"] }] });
2242
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: ButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2243
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: ButtonComponent, isStandalone: false, selector: "fx-ui-button", inputs: { label: "label", disabled: "disabled", buttonVariant: "buttonVariant", icon: "icon", class: "class", loading: "loading", type: "type", ariaLabel: "ariaLabel" }, outputs: { clicked: "clicked" }, ngImport: i0, template: "<button\n [attr.type]=\"type\"\n [attr.aria-label]=\"ariaLabel || null\"\n [attr.aria-busy]=\"loading || null\"\n [class]=\"class\"\n [ngClass]=\"{\n 'btn-default': buttonVariant === 'default',\n 'btn-primary': buttonVariant === 'primary',\n 'btn-success': buttonVariant === 'success',\n 'btn-alternative': buttonVariant === 'alternative',\n }\"\n [disabled]=\"disabled || loading\"\n (click)=\"onClick()\"\n>\n @if (loading) {\n <div class=\"flex w-full items-center justify-center\" aria-hidden=\"true\">\n <svg\n [attr.fill]=\"\n buttonVariant !== 'alternative' ? 'rgb(var(--text-primary))' : 'rgb(var(--primary))'\n \"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <circle cx=\"4\" cy=\"12\" r=\"0\">\n <animate\n begin=\"0;spinner_z0Or.end\"\n attributeName=\"r\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"0;3\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_OLMs.end\"\n attributeName=\"cx\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"4;12\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_UHR2.end\"\n attributeName=\"cx\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"12;20\"\n fill=\"freeze\"\n />\n <animate\n id=\"spinner_lo66\"\n begin=\"spinner_Aguh.end\"\n attributeName=\"r\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"3;0\"\n fill=\"freeze\"\n />\n <animate\n id=\"spinner_z0Or\"\n begin=\"spinner_lo66.end\"\n attributeName=\"cx\"\n dur=\"0.001s\"\n values=\"20;4\"\n fill=\"freeze\"\n />\n </circle>\n <circle cx=\"4\" cy=\"12\" r=\"3\">\n <animate\n begin=\"0;spinner_z0Or.end\"\n attributeName=\"cx\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"4;12\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_OLMs.end\"\n attributeName=\"cx\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"12;20\"\n fill=\"freeze\"\n />\n <animate\n id=\"spinner_JsnR\"\n begin=\"spinner_UHR2.end\"\n attributeName=\"r\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"3;0\"\n fill=\"freeze\"\n />\n <animate\n id=\"spinner_Aguh\"\n begin=\"spinner_JsnR.end\"\n attributeName=\"cx\"\n dur=\"0.001s\"\n values=\"20;4\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_Aguh.end\"\n attributeName=\"r\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"0;3\"\n fill=\"freeze\"\n />\n </circle>\n <circle cx=\"12\" cy=\"12\" r=\"3\">\n <animate\n begin=\"0;spinner_z0Or.end\"\n attributeName=\"cx\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"12;20\"\n fill=\"freeze\"\n />\n <animate\n id=\"spinner_hSjk\"\n begin=\"spinner_OLMs.end\"\n attributeName=\"r\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"3;0\"\n fill=\"freeze\"\n />\n <animate\n id=\"spinner_UHR2\"\n begin=\"spinner_hSjk.end\"\n attributeName=\"cx\"\n dur=\"0.001s\"\n values=\"20;4\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_UHR2.end\"\n attributeName=\"r\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"0;3\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_Aguh.end\"\n attributeName=\"cx\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"4;12\"\n fill=\"freeze\"\n />\n </circle>\n <circle cx=\"20\" cy=\"12\" r=\"3\">\n <animate\n id=\"spinner_4v5M\"\n begin=\"0;spinner_z0Or.end\"\n attributeName=\"r\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"3;0\"\n fill=\"freeze\"\n />\n <animate\n id=\"spinner_OLMs\"\n begin=\"spinner_4v5M.end\"\n attributeName=\"cx\"\n dur=\"0.001s\"\n values=\"20;4\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_OLMs.end\"\n attributeName=\"r\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"0;3\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_UHR2.end\"\n attributeName=\"cx\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"4;12\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_Aguh.end\"\n attributeName=\"cx\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"12;20\"\n fill=\"freeze\"\n />\n </circle>\n </svg>\n </div>\n } @else {\n <ng-container>\n <div class=\"flex items-center justify-center gap-small\">\n @if (icon) {\n <fx-ui-hero-icon\n [icon]=\"icon\"\n [size]=\"20\"\n class=\"flex\"\n [ngClass]=\"{\n 'text-text-inverse': buttonVariant === 'default',\n 'text-text-primary': buttonVariant === 'alternative',\n 'text-white': buttonVariant === 'primary' || buttonVariant === 'success',\n }\"\n ></fx-ui-hero-icon>\n }\n @if (label) {\n <div>{{ label }}</div>\n }\n </div>\n </ng-container>\n }\n</button>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: HeroIconComponent, selector: "fx-ui-hero-icon", inputs: ["stroke", "icon", "solid", "outline", "size", "color", "class"] }] });
2132
2244
  }
2133
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: ButtonComponent, decorators: [{
2245
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: ButtonComponent, decorators: [{
2134
2246
  type: Component,
2135
- args: [{ selector: 'fx-ui-button', standalone: false, template: "<button\n [class]=\"class\"\n [ngClass]=\"{\n 'btn-default': buttonVariant === 'default',\n 'btn-primary': buttonVariant === 'primary',\n 'btn-success': buttonVariant === 'success',\n 'btn-alternative': buttonVariant === 'alternative',\n }\"\n [disabled]=\"disabled || loading\"\n (click)=\"onClick()\"\n>\n @if (loading) {\n <div class=\"flex w-full items-center justify-center\">\n <svg\n [attr.fill]=\"\n buttonVariant !== 'alternative' ? 'rgb(var(--text-primary))' : 'rgb(var(--primary))'\n \"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <circle cx=\"4\" cy=\"12\" r=\"0\">\n <animate\n begin=\"0;spinner_z0Or.end\"\n attributeName=\"r\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"0;3\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_OLMs.end\"\n attributeName=\"cx\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"4;12\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_UHR2.end\"\n attributeName=\"cx\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"12;20\"\n fill=\"freeze\"\n />\n <animate\n id=\"spinner_lo66\"\n begin=\"spinner_Aguh.end\"\n attributeName=\"r\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"3;0\"\n fill=\"freeze\"\n />\n <animate\n id=\"spinner_z0Or\"\n begin=\"spinner_lo66.end\"\n attributeName=\"cx\"\n dur=\"0.001s\"\n values=\"20;4\"\n fill=\"freeze\"\n />\n </circle>\n <circle cx=\"4\" cy=\"12\" r=\"3\">\n <animate\n begin=\"0;spinner_z0Or.end\"\n attributeName=\"cx\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"4;12\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_OLMs.end\"\n attributeName=\"cx\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"12;20\"\n fill=\"freeze\"\n />\n <animate\n id=\"spinner_JsnR\"\n begin=\"spinner_UHR2.end\"\n attributeName=\"r\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"3;0\"\n fill=\"freeze\"\n />\n <animate\n id=\"spinner_Aguh\"\n begin=\"spinner_JsnR.end\"\n attributeName=\"cx\"\n dur=\"0.001s\"\n values=\"20;4\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_Aguh.end\"\n attributeName=\"r\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"0;3\"\n fill=\"freeze\"\n />\n </circle>\n <circle cx=\"12\" cy=\"12\" r=\"3\">\n <animate\n begin=\"0;spinner_z0Or.end\"\n attributeName=\"cx\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"12;20\"\n fill=\"freeze\"\n />\n <animate\n id=\"spinner_hSjk\"\n begin=\"spinner_OLMs.end\"\n attributeName=\"r\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"3;0\"\n fill=\"freeze\"\n />\n <animate\n id=\"spinner_UHR2\"\n begin=\"spinner_hSjk.end\"\n attributeName=\"cx\"\n dur=\"0.001s\"\n values=\"20;4\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_UHR2.end\"\n attributeName=\"r\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"0;3\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_Aguh.end\"\n attributeName=\"cx\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"4;12\"\n fill=\"freeze\"\n />\n </circle>\n <circle cx=\"20\" cy=\"12\" r=\"3\">\n <animate\n id=\"spinner_4v5M\"\n begin=\"0;spinner_z0Or.end\"\n attributeName=\"r\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"3;0\"\n fill=\"freeze\"\n />\n <animate\n id=\"spinner_OLMs\"\n begin=\"spinner_4v5M.end\"\n attributeName=\"cx\"\n dur=\"0.001s\"\n values=\"20;4\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_OLMs.end\"\n attributeName=\"r\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"0;3\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_UHR2.end\"\n attributeName=\"cx\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"4;12\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_Aguh.end\"\n attributeName=\"cx\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"12;20\"\n fill=\"freeze\"\n />\n </circle>\n </svg>\n </div>\n } @else {\n <ng-container>\n <div class=\"flex items-center justify-center gap-small\">\n @if (icon) {\n <fx-ui-hero-icon\n [icon]=\"icon\"\n [size]=\"20\"\n class=\"flex\"\n [ngClass]=\"{\n 'text-text-inverse': buttonVariant === 'default',\n 'text-text-primary': buttonVariant === 'alternative',\n 'text-white': buttonVariant === 'primary' || buttonVariant === 'success',\n }\"\n ></fx-ui-hero-icon>\n }\n @if (label) {\n <div>{{ label }}</div>\n }\n </div>\n </ng-container>\n }\n</button>\n" }]
2247
+ args: [{ selector: 'fx-ui-button', standalone: false, template: "<button\n [attr.type]=\"type\"\n [attr.aria-label]=\"ariaLabel || null\"\n [attr.aria-busy]=\"loading || null\"\n [class]=\"class\"\n [ngClass]=\"{\n 'btn-default': buttonVariant === 'default',\n 'btn-primary': buttonVariant === 'primary',\n 'btn-success': buttonVariant === 'success',\n 'btn-alternative': buttonVariant === 'alternative',\n }\"\n [disabled]=\"disabled || loading\"\n (click)=\"onClick()\"\n>\n @if (loading) {\n <div class=\"flex w-full items-center justify-center\" aria-hidden=\"true\">\n <svg\n [attr.fill]=\"\n buttonVariant !== 'alternative' ? 'rgb(var(--text-primary))' : 'rgb(var(--primary))'\n \"\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <circle cx=\"4\" cy=\"12\" r=\"0\">\n <animate\n begin=\"0;spinner_z0Or.end\"\n attributeName=\"r\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"0;3\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_OLMs.end\"\n attributeName=\"cx\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"4;12\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_UHR2.end\"\n attributeName=\"cx\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"12;20\"\n fill=\"freeze\"\n />\n <animate\n id=\"spinner_lo66\"\n begin=\"spinner_Aguh.end\"\n attributeName=\"r\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"3;0\"\n fill=\"freeze\"\n />\n <animate\n id=\"spinner_z0Or\"\n begin=\"spinner_lo66.end\"\n attributeName=\"cx\"\n dur=\"0.001s\"\n values=\"20;4\"\n fill=\"freeze\"\n />\n </circle>\n <circle cx=\"4\" cy=\"12\" r=\"3\">\n <animate\n begin=\"0;spinner_z0Or.end\"\n attributeName=\"cx\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"4;12\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_OLMs.end\"\n attributeName=\"cx\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"12;20\"\n fill=\"freeze\"\n />\n <animate\n id=\"spinner_JsnR\"\n begin=\"spinner_UHR2.end\"\n attributeName=\"r\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"3;0\"\n fill=\"freeze\"\n />\n <animate\n id=\"spinner_Aguh\"\n begin=\"spinner_JsnR.end\"\n attributeName=\"cx\"\n dur=\"0.001s\"\n values=\"20;4\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_Aguh.end\"\n attributeName=\"r\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"0;3\"\n fill=\"freeze\"\n />\n </circle>\n <circle cx=\"12\" cy=\"12\" r=\"3\">\n <animate\n begin=\"0;spinner_z0Or.end\"\n attributeName=\"cx\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"12;20\"\n fill=\"freeze\"\n />\n <animate\n id=\"spinner_hSjk\"\n begin=\"spinner_OLMs.end\"\n attributeName=\"r\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"3;0\"\n fill=\"freeze\"\n />\n <animate\n id=\"spinner_UHR2\"\n begin=\"spinner_hSjk.end\"\n attributeName=\"cx\"\n dur=\"0.001s\"\n values=\"20;4\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_UHR2.end\"\n attributeName=\"r\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"0;3\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_Aguh.end\"\n attributeName=\"cx\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"4;12\"\n fill=\"freeze\"\n />\n </circle>\n <circle cx=\"20\" cy=\"12\" r=\"3\">\n <animate\n id=\"spinner_4v5M\"\n begin=\"0;spinner_z0Or.end\"\n attributeName=\"r\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"3;0\"\n fill=\"freeze\"\n />\n <animate\n id=\"spinner_OLMs\"\n begin=\"spinner_4v5M.end\"\n attributeName=\"cx\"\n dur=\"0.001s\"\n values=\"20;4\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_OLMs.end\"\n attributeName=\"r\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"0;3\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_UHR2.end\"\n attributeName=\"cx\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"4;12\"\n fill=\"freeze\"\n />\n <animate\n begin=\"spinner_Aguh.end\"\n attributeName=\"cx\"\n calcMode=\"spline\"\n dur=\"0.5s\"\n keySplines=\".36,.6,.31,1\"\n values=\"12;20\"\n fill=\"freeze\"\n />\n </circle>\n </svg>\n </div>\n } @else {\n <ng-container>\n <div class=\"flex items-center justify-center gap-small\">\n @if (icon) {\n <fx-ui-hero-icon\n [icon]=\"icon\"\n [size]=\"20\"\n class=\"flex\"\n [ngClass]=\"{\n 'text-text-inverse': buttonVariant === 'default',\n 'text-text-primary': buttonVariant === 'alternative',\n 'text-white': buttonVariant === 'primary' || buttonVariant === 'success',\n }\"\n ></fx-ui-hero-icon>\n }\n @if (label) {\n <div>{{ label }}</div>\n }\n </div>\n </ng-container>\n }\n</button>\n" }]
2136
2248
  }], propDecorators: { label: [{
2137
2249
  type: Input
2138
2250
  }], disabled: [{
@@ -2145,6 +2257,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
2145
2257
  type: Input
2146
2258
  }], loading: [{
2147
2259
  type: Input
2260
+ }], type: [{
2261
+ type: Input
2262
+ }], ariaLabel: [{
2263
+ type: Input
2148
2264
  }], clicked: [{
2149
2265
  type: Output
2150
2266
  }] } });
@@ -2514,10 +2630,10 @@ class ChartComponent {
2514
2630
  return `rgba(${rgb},1)`;
2515
2631
  });
2516
2632
  }
2517
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: ChartComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
2518
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: ChartComponent, isStandalone: false, selector: "fx-ui-chart", inputs: { type: "type", data: "data", options: "options", palette: "palette", height: "height", loading: "loading", pieLegendAlign: "pieLegendAlign", pieLegendPosition: "pieLegendPosition", showPieLabel: "showPieLabel", mobileWidth: "mobileWidth", labelFontFamily: "labelFontFamily", emptyText: "emptyText" }, outputs: { chartClick: "chartClick", chartInit: "chartInit" }, host: { listeners: { "window:theme-changed": "onThemeChange()" } }, usesOnChanges: true, ngImport: i0, template: "<div class=\"chart-wrapper\" [style.height]=\"height\">\n @if (isEmpty) {\n <div class=\"chart-empty\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" class=\"chart-empty-icon\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M3 13.125C3 12.504 3.504 12 4.125 12h2.25c.621 0 1.125.504 1.125 1.125v6.75C7.5 20.496 6.996 21 6.375 21h-2.25A1.125 1.125 0 0 1 3 19.875v-6.75ZM9.75 8.625c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125v11.25c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 0 1-1.125-1.125V8.625ZM16.5 4.125c0-.621.504-1.125 1.125-1.125h2.25C20.496 3 21 3.504 21 4.125v15.75c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 0 1-1.125-1.125V4.125Z\" />\n </svg>\n <span class=\"chart-empty-text\">{{ emptyText }}</span>\n </div>\n } @else {\n <div\n echarts\n [options]=\"chartOptions\"\n [loading]=\"loading\"\n (chartInit)=\"onChartInit($event)\"\n (chartClick)=\"onChartClick($event)\"\n class=\"fx-chart\"\n [style.height]=\"height\"\n ></div>\n }\n</div>\n", styles: [":host{display:block;width:100%}.chart-wrapper{position:relative;width:100%;height:100%}.chart-container{width:100%;height:100%}.chart-loader{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:rgba(var(--bg-primary-hover)/.6);font-weight:500;font-size:1.1rem;z-index:2;border-radius:4px}.chart-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;gap:12px;color:rgba(var(--text-secondary)/1)}.chart-empty-icon{width:48px;height:48px;opacity:.4}.chart-empty-text{font-size:14px;font-weight:500}\n"], dependencies: [{ kind: "directive", type: i1$5.NgxEchartsDirective, selector: "echarts, [echarts]", inputs: ["options", "theme", "initOpts", "merge", "autoResize", "loading", "loadingType", "loadingOpts"], outputs: ["chartInit", "optionsError", "chartClick", "chartDblClick", "chartMouseDown", "chartMouseMove", "chartMouseUp", "chartMouseOver", "chartMouseOut", "chartGlobalOut", "chartContextMenu", "chartHighlight", "chartDownplay", "chartSelectChanged", "chartLegendSelectChanged", "chartLegendSelected", "chartLegendUnselected", "chartLegendLegendSelectAll", "chartLegendLegendInverseSelect", "chartLegendScroll", "chartDataZoom", "chartDataRangeSelected", "chartGraphRoam", "chartGeoRoam", "chartTreeRoam", "chartTimelineChanged", "chartTimelinePlayChanged", "chartRestore", "chartDataViewChanged", "chartMagicTypeChanged", "chartGeoSelectChanged", "chartGeoSelected", "chartGeoUnselected", "chartAxisAreaSelected", "chartBrush", "chartBrushEnd", "chartBrushSelected", "chartGlobalCursorTaken", "chartRendered", "chartFinished"], exportAs: ["echarts"] }] });
2633
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: ChartComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
2634
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: ChartComponent, isStandalone: false, selector: "fx-ui-chart", inputs: { type: "type", data: "data", options: "options", palette: "palette", height: "height", loading: "loading", pieLegendAlign: "pieLegendAlign", pieLegendPosition: "pieLegendPosition", showPieLabel: "showPieLabel", mobileWidth: "mobileWidth", labelFontFamily: "labelFontFamily", emptyText: "emptyText" }, outputs: { chartClick: "chartClick", chartInit: "chartInit" }, host: { listeners: { "window:theme-changed": "onThemeChange()" } }, usesOnChanges: true, ngImport: i0, template: "<div class=\"chart-wrapper\" [style.height]=\"height\">\n @if (isEmpty) {\n <div class=\"chart-empty\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" class=\"chart-empty-icon\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M3 13.125C3 12.504 3.504 12 4.125 12h2.25c.621 0 1.125.504 1.125 1.125v6.75C7.5 20.496 6.996 21 6.375 21h-2.25A1.125 1.125 0 0 1 3 19.875v-6.75ZM9.75 8.625c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125v11.25c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 0 1-1.125-1.125V8.625ZM16.5 4.125c0-.621.504-1.125 1.125-1.125h2.25C20.496 3 21 3.504 21 4.125v15.75c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 0 1-1.125-1.125V4.125Z\" />\n </svg>\n <span class=\"chart-empty-text\">{{ emptyText }}</span>\n </div>\n } @else {\n <div\n echarts\n [options]=\"chartOptions\"\n [loading]=\"loading\"\n (chartInit)=\"onChartInit($event)\"\n (chartClick)=\"onChartClick($event)\"\n class=\"fx-chart\"\n [style.height]=\"height\"\n ></div>\n }\n</div>\n", styles: [":host{display:block;width:100%}.chart-wrapper{position:relative;width:100%;height:100%}.chart-container{width:100%;height:100%}.chart-loader{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:rgba(var(--bg-primary-hover)/.6);font-weight:500;font-size:1.1rem;z-index:2;border-radius:4px}.chart-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;gap:12px;color:rgba(var(--text-secondary)/1)}.chart-empty-icon{width:48px;height:48px;opacity:.4}.chart-empty-text{font-size:14px;font-weight:500}\n"], dependencies: [{ kind: "directive", type: i1$6.NgxEchartsDirective, selector: "echarts, [echarts]", inputs: ["options", "theme", "initOpts", "merge", "autoResize", "loading", "loadingType", "loadingOpts"], outputs: ["chartInit", "optionsError", "chartClick", "chartDblClick", "chartMouseDown", "chartMouseMove", "chartMouseUp", "chartMouseOver", "chartMouseOut", "chartGlobalOut", "chartContextMenu", "chartHighlight", "chartDownplay", "chartSelectChanged", "chartLegendSelectChanged", "chartLegendSelected", "chartLegendUnselected", "chartLegendLegendSelectAll", "chartLegendLegendInverseSelect", "chartLegendScroll", "chartDataZoom", "chartDataRangeSelected", "chartGraphRoam", "chartGeoRoam", "chartTreeRoam", "chartTimelineChanged", "chartTimelinePlayChanged", "chartRestore", "chartDataViewChanged", "chartMagicTypeChanged", "chartGeoSelectChanged", "chartGeoSelected", "chartGeoUnselected", "chartAxisAreaSelected", "chartBrush", "chartBrushEnd", "chartBrushSelected", "chartGlobalCursorTaken", "chartRendered", "chartFinished"], exportAs: ["echarts"] }] });
2519
2635
  }
2520
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: ChartComponent, decorators: [{
2636
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: ChartComponent, decorators: [{
2521
2637
  type: Component,
2522
2638
  args: [{ selector: 'fx-ui-chart', standalone: false, template: "<div class=\"chart-wrapper\" [style.height]=\"height\">\n @if (isEmpty) {\n <div class=\"chart-empty\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" stroke-width=\"1.5\" stroke=\"currentColor\" class=\"chart-empty-icon\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M3 13.125C3 12.504 3.504 12 4.125 12h2.25c.621 0 1.125.504 1.125 1.125v6.75C7.5 20.496 6.996 21 6.375 21h-2.25A1.125 1.125 0 0 1 3 19.875v-6.75ZM9.75 8.625c0-.621.504-1.125 1.125-1.125h2.25c.621 0 1.125.504 1.125 1.125v11.25c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 0 1-1.125-1.125V8.625ZM16.5 4.125c0-.621.504-1.125 1.125-1.125h2.25C20.496 3 21 3.504 21 4.125v15.75c0 .621-.504 1.125-1.125 1.125h-2.25a1.125 1.125 0 0 1-1.125-1.125V4.125Z\" />\n </svg>\n <span class=\"chart-empty-text\">{{ emptyText }}</span>\n </div>\n } @else {\n <div\n echarts\n [options]=\"chartOptions\"\n [loading]=\"loading\"\n (chartInit)=\"onChartInit($event)\"\n (chartClick)=\"onChartClick($event)\"\n class=\"fx-chart\"\n [style.height]=\"height\"\n ></div>\n }\n</div>\n", styles: [":host{display:block;width:100%}.chart-wrapper{position:relative;width:100%;height:100%}.chart-container{width:100%;height:100%}.chart-loader{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:rgba(var(--bg-primary-hover)/.6);font-weight:500;font-size:1.1rem;z-index:2;border-radius:4px}.chart-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;gap:12px;color:rgba(var(--text-secondary)/1)}.chart-empty-icon{width:48px;height:48px;opacity:.4}.chart-empty-text{font-size:14px;font-weight:500}\n"] }]
2523
2639
  }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }], propDecorators: { type: [{
@@ -2647,10 +2763,10 @@ class FxComponent {
2647
2763
  const firstKey = Object.keys(this.errors)[0];
2648
2764
  return messages[firstKey] || `Invalid ${label ?? 'value'}`;
2649
2765
  }
2650
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: FxComponent, deps: [], target: i0.ɵɵFactoryTarget.Directive });
2651
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.4", type: FxComponent, isStandalone: true, inputs: { disabled: "disabled" }, ngImport: i0 });
2766
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: FxComponent, deps: [], target: i0.ɵɵFactoryTarget.Directive });
2767
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.20", type: FxComponent, isStandalone: true, inputs: { disabled: "disabled" }, ngImport: i0 });
2652
2768
  }
2653
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: FxComponent, decorators: [{
2769
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: FxComponent, decorators: [{
2654
2770
  type: Directive
2655
2771
  }], ctorParameters: () => [], propDecorators: { disabled: [{
2656
2772
  type: Input
@@ -2680,12 +2796,12 @@ class CheckboxComponent extends FxComponent {
2680
2796
  markTouched() {
2681
2797
  this.onTouched();
2682
2798
  }
2683
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: CheckboxComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
2684
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: CheckboxComponent, isStandalone: false, selector: "fx-ui-checkbox", inputs: { label: "label", rounded: "rounded" }, outputs: { valueChange: "valueChange" }, usesInheritance: true, ngImport: i0, template: "<label\n class=\"flex items-center gap-normal cursor-pointer select-none\"\n [class.opacity-50]=\"disabled\"\n [class.cursor-not-allowed]=\"disabled\"\n>\n <input\n type=\"checkbox\"\n class=\"hidden\"\n [checked]=\"value\"\n [disabled]=\"disabled\"\n (change)=\"onInputChange($event)\"\n (blur)=\"onTouched()\"\n />\n <span\n class=\"relative w-4 h-4 border rounded-full transition-colors duration-150 shrink-0\"\n [ngClass]=\"{\n 'rounded-full': rounded,\n 'rounded-sm': !rounded,\n 'border-border-strong bg-transparent': !value,\n 'border-transparent bg-gradient-primary': value,\n }\"\n >\n <!-- Keep SVG space reserved always -->\n <span class=\"absolute inset-0 flex items-center justify-center\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n class=\"text-white w-4 h-4 transition-opacity duration-150\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n [style.opacity]=\"value ? 1 : 0\"\n >\n <path d=\"M5 13l4 4L19 7\" />\n </svg>\n </span>\n </span>\n\n @if (label) {\n <span class=\"mb-0 txt-field-label\">{{ label }}</span>\n }\n</label>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
2799
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: CheckboxComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
2800
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: CheckboxComponent, isStandalone: false, selector: "fx-ui-checkbox", inputs: { label: "label", rounded: "rounded" }, outputs: { valueChange: "valueChange" }, usesInheritance: true, ngImport: i0, template: "<label\n class=\"flex items-center gap-normal cursor-pointer select-none\"\n [class.opacity-50]=\"disabled\"\n [class.cursor-not-allowed]=\"disabled\"\n>\n <!-- sr-only (not `hidden`): keeps the input focusable and in the a11y tree -->\n <input\n type=\"checkbox\"\n class=\"peer sr-only\"\n [checked]=\"value\"\n [disabled]=\"disabled\"\n (change)=\"onInputChange($event)\"\n (blur)=\"onTouched()\"\n />\n <span\n class=\"relative w-4 h-4 border rounded-full transition-colors duration-150 shrink-0 peer-focus-visible:ring-2 peer-focus-visible:ring-primary/50\"\n [ngClass]=\"{\n 'rounded-full': rounded,\n 'rounded-sm': !rounded,\n 'border-border-strong bg-transparent': !value,\n 'border-transparent bg-gradient-primary': value,\n }\"\n >\n <!-- Keep SVG space reserved always -->\n <span class=\"absolute inset-0 flex items-center justify-center\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n class=\"text-white w-4 h-4 transition-opacity duration-150\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n [style.opacity]=\"value ? 1 : 0\"\n >\n <path d=\"M5 13l4 4L19 7\" />\n </svg>\n </span>\n </span>\n\n @if (label) {\n <span class=\"mb-0 txt-field-label\">{{ label }}</span>\n }\n</label>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
2685
2801
  }
2686
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: CheckboxComponent, decorators: [{
2802
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: CheckboxComponent, decorators: [{
2687
2803
  type: Component,
2688
- args: [{ selector: 'fx-ui-checkbox', standalone: false, template: "<label\n class=\"flex items-center gap-normal cursor-pointer select-none\"\n [class.opacity-50]=\"disabled\"\n [class.cursor-not-allowed]=\"disabled\"\n>\n <input\n type=\"checkbox\"\n class=\"hidden\"\n [checked]=\"value\"\n [disabled]=\"disabled\"\n (change)=\"onInputChange($event)\"\n (blur)=\"onTouched()\"\n />\n <span\n class=\"relative w-4 h-4 border rounded-full transition-colors duration-150 shrink-0\"\n [ngClass]=\"{\n 'rounded-full': rounded,\n 'rounded-sm': !rounded,\n 'border-border-strong bg-transparent': !value,\n 'border-transparent bg-gradient-primary': value,\n }\"\n >\n <!-- Keep SVG space reserved always -->\n <span class=\"absolute inset-0 flex items-center justify-center\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n class=\"text-white w-4 h-4 transition-opacity duration-150\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n [style.opacity]=\"value ? 1 : 0\"\n >\n <path d=\"M5 13l4 4L19 7\" />\n </svg>\n </span>\n </span>\n\n @if (label) {\n <span class=\"mb-0 txt-field-label\">{{ label }}</span>\n }\n</label>\n" }]
2804
+ args: [{ selector: 'fx-ui-checkbox', standalone: false, template: "<label\n class=\"flex items-center gap-normal cursor-pointer select-none\"\n [class.opacity-50]=\"disabled\"\n [class.cursor-not-allowed]=\"disabled\"\n>\n <!-- sr-only (not `hidden`): keeps the input focusable and in the a11y tree -->\n <input\n type=\"checkbox\"\n class=\"peer sr-only\"\n [checked]=\"value\"\n [disabled]=\"disabled\"\n (change)=\"onInputChange($event)\"\n (blur)=\"onTouched()\"\n />\n <span\n class=\"relative w-4 h-4 border rounded-full transition-colors duration-150 shrink-0 peer-focus-visible:ring-2 peer-focus-visible:ring-primary/50\"\n [ngClass]=\"{\n 'rounded-full': rounded,\n 'rounded-sm': !rounded,\n 'border-border-strong bg-transparent': !value,\n 'border-transparent bg-gradient-primary': value,\n }\"\n >\n <!-- Keep SVG space reserved always -->\n <span class=\"absolute inset-0 flex items-center justify-center\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n class=\"text-white w-4 h-4 transition-opacity duration-150\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"3\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n [style.opacity]=\"value ? 1 : 0\"\n >\n <path d=\"M5 13l4 4L19 7\" />\n </svg>\n </span>\n </span>\n\n @if (label) {\n <span class=\"mb-0 txt-field-label\">{{ label }}</span>\n }\n</label>\n" }]
2689
2805
  }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { label: [{
2690
2806
  type: Input
2691
2807
  }], rounded: [{
@@ -2708,10 +2824,10 @@ class CircleProgressBar {
2708
2824
  get ariaLabel() {
2709
2825
  return `${Math.round(this.percent)}%`;
2710
2826
  }
2711
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: CircleProgressBar, deps: [], target: i0.ɵɵFactoryTarget.Component });
2712
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: CircleProgressBar, isStandalone: false, selector: "fx-ui-circle-progress-bar", inputs: { percent: "percent", showPercent: "showPercent" }, ngImport: i0, template: "<div class=\"flex items-center justify-center w-full h-full\">\n <svg\n class=\"transform -rotate-90 block\"\n [attr.viewBox]=\"'0 0 ' + radius * 2 + ' ' + radius * 2\"\n width=\"100%\"\n height=\"100%\"\n >\n <circle\n class=\"opacity-20\"\n [attr.cx]=\"radius\"\n [attr.cy]=\"radius\"\n [attr.r]=\"normalizedRadius\"\n [attr.stroke-width]=\"stroke\"\n fill=\"transparent\"\n stroke=\"currentColor\"\n ></circle>\n\n <circle\n class=\"stroke-current\"\n [attr.cx]=\"radius\"\n [attr.cy]=\"radius\"\n [attr.r]=\"normalizedRadius\"\n [attr.stroke-width]=\"stroke\"\n fill=\"transparent\"\n stroke-linecap=\"round\"\n [attr.stroke-dasharray]=\"circumference\"\n [attr.stroke-dashoffset]=\"dashOffset\"\n style=\"transition: stroke-dashoffset 300ms linear\"\n ></circle>\n\n @if(showPercent){\n <text\n [attr.x]=\"radius\"\n [attr.y]=\"radius\"\n dominant-baseline=\"central\"\n text-anchor=\"middle\"\n class=\"text-xs font-medium\"\n fill=\"currentColor\"\n >\n {{ percent }}%\n </text>\n }\n </svg>\n</div>\n", styles: [""] });
2827
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: CircleProgressBar, deps: [], target: i0.ɵɵFactoryTarget.Component });
2828
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: CircleProgressBar, isStandalone: false, selector: "fx-ui-circle-progress-bar", inputs: { percent: "percent", showPercent: "showPercent" }, ngImport: i0, template: "<div class=\"flex items-center justify-center w-full h-full\">\n <svg\n class=\"transform -rotate-90 block\"\n [attr.viewBox]=\"'0 0 ' + radius * 2 + ' ' + radius * 2\"\n width=\"100%\"\n height=\"100%\"\n >\n <circle\n class=\"opacity-20\"\n [attr.cx]=\"radius\"\n [attr.cy]=\"radius\"\n [attr.r]=\"normalizedRadius\"\n [attr.stroke-width]=\"stroke\"\n fill=\"transparent\"\n stroke=\"currentColor\"\n ></circle>\n\n <circle\n class=\"stroke-current\"\n [attr.cx]=\"radius\"\n [attr.cy]=\"radius\"\n [attr.r]=\"normalizedRadius\"\n [attr.stroke-width]=\"stroke\"\n fill=\"transparent\"\n stroke-linecap=\"round\"\n [attr.stroke-dasharray]=\"circumference\"\n [attr.stroke-dashoffset]=\"dashOffset\"\n style=\"transition: stroke-dashoffset 300ms linear\"\n ></circle>\n\n @if(showPercent){\n <text\n [attr.x]=\"radius\"\n [attr.y]=\"radius\"\n dominant-baseline=\"central\"\n text-anchor=\"middle\"\n class=\"text-xs font-medium\"\n fill=\"currentColor\"\n >\n {{ percent }}%\n </text>\n }\n </svg>\n</div>\n", styles: [""] });
2713
2829
  }
2714
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: CircleProgressBar, decorators: [{
2830
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: CircleProgressBar, decorators: [{
2715
2831
  type: Component,
2716
2832
  args: [{ selector: 'fx-ui-circle-progress-bar', standalone: false, template: "<div class=\"flex items-center justify-center w-full h-full\">\n <svg\n class=\"transform -rotate-90 block\"\n [attr.viewBox]=\"'0 0 ' + radius * 2 + ' ' + radius * 2\"\n width=\"100%\"\n height=\"100%\"\n >\n <circle\n class=\"opacity-20\"\n [attr.cx]=\"radius\"\n [attr.cy]=\"radius\"\n [attr.r]=\"normalizedRadius\"\n [attr.stroke-width]=\"stroke\"\n fill=\"transparent\"\n stroke=\"currentColor\"\n ></circle>\n\n <circle\n class=\"stroke-current\"\n [attr.cx]=\"radius\"\n [attr.cy]=\"radius\"\n [attr.r]=\"normalizedRadius\"\n [attr.stroke-width]=\"stroke\"\n fill=\"transparent\"\n stroke-linecap=\"round\"\n [attr.stroke-dasharray]=\"circumference\"\n [attr.stroke-dashoffset]=\"dashOffset\"\n style=\"transition: stroke-dashoffset 300ms linear\"\n ></circle>\n\n @if(showPercent){\n <text\n [attr.x]=\"radius\"\n [attr.y]=\"radius\"\n dominant-baseline=\"central\"\n text-anchor=\"middle\"\n class=\"text-xs font-medium\"\n fill=\"currentColor\"\n >\n {{ percent }}%\n </text>\n }\n </svg>\n</div>\n" }]
2717
2833
  }], propDecorators: { percent: [{
@@ -2720,6 +2836,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
2720
2836
  type: Input
2721
2837
  }] } });
2722
2838
 
2839
+ let nextPickerId = 0;
2723
2840
  class DatetimePicker extends FxComponent {
2724
2841
  ref;
2725
2842
  label;
@@ -2730,6 +2847,7 @@ class DatetimePicker extends FxComponent {
2730
2847
  maxDate;
2731
2848
  errorMessages = {};
2732
2849
  validateFn;
2850
+ fieldId = `fx-datetime-${nextPickerId++}`;
2733
2851
  startAt;
2734
2852
  constructor(ref) {
2735
2853
  super();
@@ -2756,12 +2874,12 @@ class DatetimePicker extends FxComponent {
2756
2874
  this.onChange(date);
2757
2875
  this.onTouched();
2758
2876
  }
2759
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: DatetimePicker, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
2760
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: DatetimePicker, isStandalone: false, selector: "fx-ui-datetime-picker", inputs: { label: "label", placeholder: "placeholder", required: "required", type: "type", minDate: "minDate", maxDate: "maxDate", errorMessages: "errorMessages", validateFn: "validateFn" }, usesInheritance: true, ngImport: i0, template: "<div class=\"flex flex-col mb-4 w-full text-left\">\n @if (label) {\n <label class=\"txt-field-label\">\n {{ label }}\n <span *ngIf=\"required\" class=\"txt-required\">*</span>\n </label>\n }\n\n <div class=\"relative\">\n <input\n [owlDateTimeTrigger]=\"picker\"\n [owlDateTime]=\"picker\"\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n [min]=\"minDate\"\n [max]=\"maxDate\"\n (blur)=\"onBlur()\"\n [value]=\"value\"\n readonly\n class=\"input-default pr-9\"\n />\n <span\n [owlDateTimeTrigger]=\"picker\"\n class=\"absolute inset-y-0 right-0 flex items-center pr-2.5 cursor-pointer text-text-placeholder hover:text-text-primary transition-colors\"\n >\n <fx-ui-hero-icon icon=\"calendar\" [size]=\"20\" class=\"text-text-primary\"></fx-ui-hero-icon>\n </span>\n </div>\n <owl-date-time\n #picker\n [startAt]=\"startAt\"\n [pickerType]=\"type\"\n (afterPickerClosed)=\"onValueChange($event)\"\n ></owl-date-time>\n <div *ngIf=\"invalid\" class=\"txt-invalid\">{{ getErrorMessage(label) }}</div>\n</div>\n", styles: ["::ng-deep .owl-dt-container{border-radius:.75rem;border-width:1px;--tw-border-opacity: 1;border-color:rgb(var(--border-default) / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(var(--bg-primary) / var(--tw-bg-opacity, 1));--tw-shadow: 0 20px 25px -5px rgb(var(--shadow-color) / .1), 0 10px 10px -5px rgb(var(--shadow-color) / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 10px 10px -5px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow);width:320px!important}::ng-deep .owl-dt-calendar-table{width:100%;border-collapse:collapse}::ng-deep .owl-dt-calendar-table :not(.owl-dt-calendar-cell-disabled):hover>.owl-dt-calendar-cell-content:not(.owl-dt-calendar-cell-selected){--tw-bg-opacity: 1;background-color:rgb(var(--bg-primary-hover) / var(--tw-bg-opacity, 1))}::ng-deep .owl-dt-calendar-table .owl-dt-calendar-cell-content{color:rgb(var(--text-primary))}::ng-deep .owl-dt-calendar-table .owl-dt-calendar-cell-selected{background-color:rgb(var(--primary))!important;color:#fff!important}::ng-deep .owl-dt-calendar-table .owl-dt-calendar-cell-today:not(.owl-dt-calendar-cell-selected){border-color:rgb(var(--primary))!important}::ng-deep .owl-dt-calendar-table .owl-dt-calendar-cell-disabled>.owl-dt-calendar-cell-content{color:rgb(var(--text-placeholder))!important;opacity:.6!important;cursor:not-allowed;pointer-events:none}::ng-deep .owl-dt-calendar-table .owl-dt-calendar-cell-content.owl-dt-calendar-cell-out{color:rgb(var(--text-secondary))!important;opacity:.6!important}::ng-deep .owl-dt-timer-content .owl-dt-timer-input{border-radius:.5rem;border-width:1px;--tw-border-opacity: 1;border-color:rgb(var(--border-strong) / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(var(--bg-primary) / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(var(--text-primary) / var(--tw-text-opacity, 1))}::ng-deep .owl-dt-control-period-button .owl-dt-control-button-arrow{display:none}::ng-deep .owl-dt-container-buttons{height:auto!important;color:rgb(var(--text-primary))!important;display:flex!important;align-items:center!important;justify-content:flex-end!important;gap:8px;padding:8px 12px;border-top:1px solid rgb(var(--border-default))}::ng-deep .owl-dt-container-buttons .owl-dt-container-control-button{width:auto!important;height:32px!important;border-radius:6px!important;width:60px!important;padding-top:4px!important;padding-bottom:4px!important;font-size:13px!important;font-weight:600!important;border:1px solid rgb(var(--border-default))!important;background-color:rgb(var(--bg-primary))!important;color:rgb(var(--text-primary))!important;cursor:pointer;transition:opacity .15s ease}::ng-deep .owl-dt-container-buttons .owl-dt-container-control-button:hover{background-color:rgb(var(--bg-hover))!important}::ng-deep .owl-dt-container-buttons .owl-dt-container-control-button:last-child{background-color:rgb(var(--primary))!important;border-color:rgb(var(--primary))!important;color:#fff!important}::ng-deep .owl-dt-container-buttons .owl-dt-container-control-button:last-child:hover{opacity:.85}::ng-deep .owl-dt-container-buttons .owl-dt-container-control-button .owl-dt-control-button-content{height:100%!important;width:100%!important;padding:0!important;background-color:transparent!important;color:inherit!important;display:flex!important;align-items:center!important;justify-content:center!important}::ng-deep .owl-dt-calendar-control-content .owl-dt-control-button-content{font-weight:500;--tw-text-opacity: 1;color:rgb(var(--text-primary) / var(--tw-text-opacity, 1))}::ng-deep .owl-dt-control-arrow-button .owl-dt-control-button-content{--tw-text-opacity: 1;color:rgb(var(--text-primary) / var(--tw-text-opacity, 1))}::ng-deep .owl-dt-calendar-table .owl-dt-calendar-header{--tw-text-opacity: 1;color:rgb(var(--text-secondary) / var(--tw-text-opacity, 1))}::ng-deep .owl-dt-calendar-table .owl-dt-calendar-header .owl-dt-weekdays th{font-weight:500;--tw-text-opacity: 1;color:rgb(var(--text-secondary) / var(--tw-text-opacity, 1))}::ng-deep .owl-dt-inline-container,::ng-deep .owl-dt-popup-container{border-radius:.75rem;border-width:1px;--tw-border-opacity: 1;border-color:rgb(var(--border-strong) / var(--tw-border-opacity, 1));--tw-shadow: 0 10px 15px -3px rgb(var(--shadow-color) / .1), 0 4px 6px -4px rgb(var(--shadow-color) / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}\n"], dependencies: [{ kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2$2.OwlDateTimeTriggerDirective, selector: "[owlDateTimeTrigger]", inputs: ["owlDateTimeTrigger", "disabled"] }, { kind: "directive", type: i2$2.OwlDateTimeInputDirective, selector: "input[owlDateTime]", inputs: ["required", "owlDateTime", "owlDateTimeFilter", "_disabled", "min", "max", "selectMode", "rangeSeparator", "value", "values"], outputs: ["dateTimeChange", "dateTimeInput"], exportAs: ["owlDateTimeInput"] }, { kind: "component", type: i2$2.OwlDateTimeComponent, selector: "owl-date-time", inputs: ["backdropClass", "panelClass", "startAt", "endAt", "pickerType", "pickerMode", "disabled", "opened", "scrollStrategy"], outputs: ["afterPickerClosed", "beforePickerOpen", "afterPickerOpen", "yearSelected", "monthSelected", "dateSelected"], exportAs: ["owlDateTime"] }, { kind: "component", type: HeroIconComponent, selector: "fx-ui-hero-icon", inputs: ["stroke", "icon", "solid", "outline", "size", "color", "class"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2877
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: DatetimePicker, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
2878
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: DatetimePicker, isStandalone: false, selector: "fx-ui-datetime-picker", inputs: { label: "label", placeholder: "placeholder", required: "required", type: "type", minDate: "minDate", maxDate: "maxDate", errorMessages: "errorMessages", validateFn: "validateFn" }, usesInheritance: true, ngImport: i0, template: "<div class=\"flex flex-col mb-4 w-full text-left\">\n @if (label) {\n <label class=\"txt-field-label\" [attr.for]=\"fieldId\">\n {{ label }}\n @if (required) {\n <span class=\"txt-required\" aria-hidden=\"true\">*</span>\n }\n </label>\n }\n\n <div class=\"relative\">\n <input\n [id]=\"fieldId\"\n [owlDateTimeTrigger]=\"picker\"\n [owlDateTime]=\"picker\"\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n [min]=\"minDate\"\n [max]=\"maxDate\"\n (blur)=\"onBlur()\"\n [value]=\"value\"\n readonly\n class=\"input-default pr-9\"\n />\n <span\n [owlDateTimeTrigger]=\"picker\"\n class=\"absolute inset-y-0 right-0 flex items-center pr-2.5 cursor-pointer text-text-placeholder hover:text-text-primary transition-colors\"\n >\n <fx-ui-hero-icon icon=\"calendar\" [size]=\"20\" class=\"text-text-primary\"></fx-ui-hero-icon>\n </span>\n </div>\n <owl-date-time\n #picker\n [startAt]=\"startAt\"\n [pickerType]=\"type\"\n (afterPickerClosed)=\"onValueChange($event)\"\n ></owl-date-time>\n @if (invalid) {\n <div class=\"txt-invalid\">{{ getErrorMessage(label) }}</div>\n }\n</div>\n", styles: ["@charset \"UTF-8\";@layer properties;::ng-deep .owl-dt-container{border-radius:.75rem;border-style:var(--tw-border-style);border-width:1px;border-color:rgb(var(--border-default));background-color:rgb(var(--bg-primary));--tw-shadow: 0 20px 25px -5px var(--tw-shadow-color, rgb(var(--shadow-color) / .1)), 0 10px 10px -5px var(--tw-shadow-color, rgb(var(--shadow-color) / .1));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);width:320px!important}::ng-deep .owl-dt-calendar-table{width:100%;border-collapse:collapse}::ng-deep .owl-dt-calendar-table :not(.owl-dt-calendar-cell-disabled):hover>.owl-dt-calendar-cell-content:not(.owl-dt-calendar-cell-selected){background-color:rgb(var(--bg-primary-hover))}::ng-deep .owl-dt-calendar-table .owl-dt-calendar-cell-content{color:rgb(var(--text-primary))}::ng-deep .owl-dt-calendar-table .owl-dt-calendar-cell-selected{background-color:rgb(var(--primary))!important;color:#fff!important}::ng-deep .owl-dt-calendar-table .owl-dt-calendar-cell-today:not(.owl-dt-calendar-cell-selected){border-color:rgb(var(--primary))!important}::ng-deep .owl-dt-calendar-table .owl-dt-calendar-cell-disabled>.owl-dt-calendar-cell-content{color:rgb(var(--text-placeholder))!important;opacity:.6!important;cursor:not-allowed;pointer-events:none}::ng-deep .owl-dt-calendar-table .owl-dt-calendar-cell-content.owl-dt-calendar-cell-out{color:rgb(var(--text-secondary))!important;opacity:.6!important}::ng-deep .owl-dt-timer-content .owl-dt-timer-input{border-radius:.5rem;border-style:var(--tw-border-style);border-width:1px;border-color:rgb(var(--border-strong));background-color:rgb(var(--bg-primary));color:rgb(var(--text-primary))}::ng-deep .owl-dt-control-period-button .owl-dt-control-button-arrow{display:none}::ng-deep .owl-dt-container-buttons{height:auto!important;color:rgb(var(--text-primary))!important;display:flex!important;align-items:center!important;justify-content:flex-end!important;gap:8px;padding:8px 12px;border-top:1px solid rgb(var(--border-default))}::ng-deep .owl-dt-container-buttons .owl-dt-container-control-button{width:auto!important;height:32px!important;border-radius:6px!important;width:60px!important;padding-top:4px!important;padding-bottom:4px!important;font-size:13px!important;font-weight:600!important;border:1px solid rgb(var(--border-default))!important;background-color:rgb(var(--bg-primary))!important;color:rgb(var(--text-primary))!important;cursor:pointer;transition:opacity .15s ease}::ng-deep .owl-dt-container-buttons .owl-dt-container-control-button:hover{background-color:rgb(var(--bg-hover))!important}::ng-deep .owl-dt-container-buttons .owl-dt-container-control-button:last-child{background-color:rgb(var(--primary))!important;border-color:rgb(var(--primary))!important;color:#fff!important}::ng-deep .owl-dt-container-buttons .owl-dt-container-control-button:last-child:hover{opacity:.85}::ng-deep .owl-dt-container-buttons .owl-dt-container-control-button .owl-dt-control-button-content{height:100%!important;width:100%!important;padding:0!important;background-color:transparent!important;color:inherit!important;display:flex!important;align-items:center!important;justify-content:center!important}::ng-deep .owl-dt-calendar-control-content .owl-dt-control-button-content{--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:rgb(var(--text-primary))}::ng-deep .owl-dt-control-arrow-button .owl-dt-control-button-content{color:rgb(var(--text-primary))}::ng-deep .owl-dt-calendar-table .owl-dt-calendar-header{color:rgb(var(--text-secondary))}::ng-deep .owl-dt-calendar-table .owl-dt-calendar-header .owl-dt-weekdays th{--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:rgb(var(--text-secondary))}::ng-deep .owl-dt-inline-container,::ng-deep .owl-dt-popup-container{border-radius:.75rem;border-style:var(--tw-border-style);border-width:1px;border-color:rgb(var(--border-strong));--tw-shadow: 0 10px 15px -3px var(--tw-shadow-color, rgb(var(--shadow-color) / .1)), 0 4px 6px -4px var(--tw-shadow-color, rgb(var(--shadow-color) / .1));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000;--tw-font-weight: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "directive", type: i1$7.OwlDateTimeTriggerDirective, selector: "[owlDateTimeTrigger]", inputs: ["owlDateTimeTrigger", "disabled"] }, { kind: "directive", type: i1$7.OwlDateTimeInputDirective, selector: "input[owlDateTime]", inputs: ["required", "owlDateTime", "owlDateTimeFilter", "_disabled", "min", "max", "selectMode", "rangeSeparator", "value", "values"], outputs: ["dateTimeChange", "dateTimeInput"], exportAs: ["owlDateTimeInput"] }, { kind: "component", type: i1$7.OwlDateTimeComponent, selector: "owl-date-time", inputs: ["backdropClass", "panelClass", "startAt", "endAt", "pickerType", "pickerMode", "disabled", "opened", "scrollStrategy"], outputs: ["afterPickerClosed", "beforePickerOpen", "afterPickerOpen", "yearSelected", "monthSelected", "dateSelected"], exportAs: ["owlDateTime"] }, { kind: "component", type: HeroIconComponent, selector: "fx-ui-hero-icon", inputs: ["stroke", "icon", "solid", "outline", "size", "color", "class"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2761
2879
  }
2762
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: DatetimePicker, decorators: [{
2880
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: DatetimePicker, decorators: [{
2763
2881
  type: Component,
2764
- args: [{ selector: 'fx-ui-datetime-picker', standalone: false, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"flex flex-col mb-4 w-full text-left\">\n @if (label) {\n <label class=\"txt-field-label\">\n {{ label }}\n <span *ngIf=\"required\" class=\"txt-required\">*</span>\n </label>\n }\n\n <div class=\"relative\">\n <input\n [owlDateTimeTrigger]=\"picker\"\n [owlDateTime]=\"picker\"\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n [min]=\"minDate\"\n [max]=\"maxDate\"\n (blur)=\"onBlur()\"\n [value]=\"value\"\n readonly\n class=\"input-default pr-9\"\n />\n <span\n [owlDateTimeTrigger]=\"picker\"\n class=\"absolute inset-y-0 right-0 flex items-center pr-2.5 cursor-pointer text-text-placeholder hover:text-text-primary transition-colors\"\n >\n <fx-ui-hero-icon icon=\"calendar\" [size]=\"20\" class=\"text-text-primary\"></fx-ui-hero-icon>\n </span>\n </div>\n <owl-date-time\n #picker\n [startAt]=\"startAt\"\n [pickerType]=\"type\"\n (afterPickerClosed)=\"onValueChange($event)\"\n ></owl-date-time>\n <div *ngIf=\"invalid\" class=\"txt-invalid\">{{ getErrorMessage(label) }}</div>\n</div>\n", styles: ["::ng-deep .owl-dt-container{border-radius:.75rem;border-width:1px;--tw-border-opacity: 1;border-color:rgb(var(--border-default) / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(var(--bg-primary) / var(--tw-bg-opacity, 1));--tw-shadow: 0 20px 25px -5px rgb(var(--shadow-color) / .1), 0 10px 10px -5px rgb(var(--shadow-color) / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 10px 10px -5px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow);width:320px!important}::ng-deep .owl-dt-calendar-table{width:100%;border-collapse:collapse}::ng-deep .owl-dt-calendar-table :not(.owl-dt-calendar-cell-disabled):hover>.owl-dt-calendar-cell-content:not(.owl-dt-calendar-cell-selected){--tw-bg-opacity: 1;background-color:rgb(var(--bg-primary-hover) / var(--tw-bg-opacity, 1))}::ng-deep .owl-dt-calendar-table .owl-dt-calendar-cell-content{color:rgb(var(--text-primary))}::ng-deep .owl-dt-calendar-table .owl-dt-calendar-cell-selected{background-color:rgb(var(--primary))!important;color:#fff!important}::ng-deep .owl-dt-calendar-table .owl-dt-calendar-cell-today:not(.owl-dt-calendar-cell-selected){border-color:rgb(var(--primary))!important}::ng-deep .owl-dt-calendar-table .owl-dt-calendar-cell-disabled>.owl-dt-calendar-cell-content{color:rgb(var(--text-placeholder))!important;opacity:.6!important;cursor:not-allowed;pointer-events:none}::ng-deep .owl-dt-calendar-table .owl-dt-calendar-cell-content.owl-dt-calendar-cell-out{color:rgb(var(--text-secondary))!important;opacity:.6!important}::ng-deep .owl-dt-timer-content .owl-dt-timer-input{border-radius:.5rem;border-width:1px;--tw-border-opacity: 1;border-color:rgb(var(--border-strong) / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(var(--bg-primary) / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(var(--text-primary) / var(--tw-text-opacity, 1))}::ng-deep .owl-dt-control-period-button .owl-dt-control-button-arrow{display:none}::ng-deep .owl-dt-container-buttons{height:auto!important;color:rgb(var(--text-primary))!important;display:flex!important;align-items:center!important;justify-content:flex-end!important;gap:8px;padding:8px 12px;border-top:1px solid rgb(var(--border-default))}::ng-deep .owl-dt-container-buttons .owl-dt-container-control-button{width:auto!important;height:32px!important;border-radius:6px!important;width:60px!important;padding-top:4px!important;padding-bottom:4px!important;font-size:13px!important;font-weight:600!important;border:1px solid rgb(var(--border-default))!important;background-color:rgb(var(--bg-primary))!important;color:rgb(var(--text-primary))!important;cursor:pointer;transition:opacity .15s ease}::ng-deep .owl-dt-container-buttons .owl-dt-container-control-button:hover{background-color:rgb(var(--bg-hover))!important}::ng-deep .owl-dt-container-buttons .owl-dt-container-control-button:last-child{background-color:rgb(var(--primary))!important;border-color:rgb(var(--primary))!important;color:#fff!important}::ng-deep .owl-dt-container-buttons .owl-dt-container-control-button:last-child:hover{opacity:.85}::ng-deep .owl-dt-container-buttons .owl-dt-container-control-button .owl-dt-control-button-content{height:100%!important;width:100%!important;padding:0!important;background-color:transparent!important;color:inherit!important;display:flex!important;align-items:center!important;justify-content:center!important}::ng-deep .owl-dt-calendar-control-content .owl-dt-control-button-content{font-weight:500;--tw-text-opacity: 1;color:rgb(var(--text-primary) / var(--tw-text-opacity, 1))}::ng-deep .owl-dt-control-arrow-button .owl-dt-control-button-content{--tw-text-opacity: 1;color:rgb(var(--text-primary) / var(--tw-text-opacity, 1))}::ng-deep .owl-dt-calendar-table .owl-dt-calendar-header{--tw-text-opacity: 1;color:rgb(var(--text-secondary) / var(--tw-text-opacity, 1))}::ng-deep .owl-dt-calendar-table .owl-dt-calendar-header .owl-dt-weekdays th{font-weight:500;--tw-text-opacity: 1;color:rgb(var(--text-secondary) / var(--tw-text-opacity, 1))}::ng-deep .owl-dt-inline-container,::ng-deep .owl-dt-popup-container{border-radius:.75rem;border-width:1px;--tw-border-opacity: 1;border-color:rgb(var(--border-strong) / var(--tw-border-opacity, 1));--tw-shadow: 0 10px 15px -3px rgb(var(--shadow-color) / .1), 0 4px 6px -4px rgb(var(--shadow-color) / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}\n"] }]
2882
+ args: [{ selector: 'fx-ui-datetime-picker', standalone: false, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"flex flex-col mb-4 w-full text-left\">\n @if (label) {\n <label class=\"txt-field-label\" [attr.for]=\"fieldId\">\n {{ label }}\n @if (required) {\n <span class=\"txt-required\" aria-hidden=\"true\">*</span>\n }\n </label>\n }\n\n <div class=\"relative\">\n <input\n [id]=\"fieldId\"\n [owlDateTimeTrigger]=\"picker\"\n [owlDateTime]=\"picker\"\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n [min]=\"minDate\"\n [max]=\"maxDate\"\n (blur)=\"onBlur()\"\n [value]=\"value\"\n readonly\n class=\"input-default pr-9\"\n />\n <span\n [owlDateTimeTrigger]=\"picker\"\n class=\"absolute inset-y-0 right-0 flex items-center pr-2.5 cursor-pointer text-text-placeholder hover:text-text-primary transition-colors\"\n >\n <fx-ui-hero-icon icon=\"calendar\" [size]=\"20\" class=\"text-text-primary\"></fx-ui-hero-icon>\n </span>\n </div>\n <owl-date-time\n #picker\n [startAt]=\"startAt\"\n [pickerType]=\"type\"\n (afterPickerClosed)=\"onValueChange($event)\"\n ></owl-date-time>\n @if (invalid) {\n <div class=\"txt-invalid\">{{ getErrorMessage(label) }}</div>\n }\n</div>\n", styles: ["@charset \"UTF-8\";@layer properties;::ng-deep .owl-dt-container{border-radius:.75rem;border-style:var(--tw-border-style);border-width:1px;border-color:rgb(var(--border-default));background-color:rgb(var(--bg-primary));--tw-shadow: 0 20px 25px -5px var(--tw-shadow-color, rgb(var(--shadow-color) / .1)), 0 10px 10px -5px var(--tw-shadow-color, rgb(var(--shadow-color) / .1));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);width:320px!important}::ng-deep .owl-dt-calendar-table{width:100%;border-collapse:collapse}::ng-deep .owl-dt-calendar-table :not(.owl-dt-calendar-cell-disabled):hover>.owl-dt-calendar-cell-content:not(.owl-dt-calendar-cell-selected){background-color:rgb(var(--bg-primary-hover))}::ng-deep .owl-dt-calendar-table .owl-dt-calendar-cell-content{color:rgb(var(--text-primary))}::ng-deep .owl-dt-calendar-table .owl-dt-calendar-cell-selected{background-color:rgb(var(--primary))!important;color:#fff!important}::ng-deep .owl-dt-calendar-table .owl-dt-calendar-cell-today:not(.owl-dt-calendar-cell-selected){border-color:rgb(var(--primary))!important}::ng-deep .owl-dt-calendar-table .owl-dt-calendar-cell-disabled>.owl-dt-calendar-cell-content{color:rgb(var(--text-placeholder))!important;opacity:.6!important;cursor:not-allowed;pointer-events:none}::ng-deep .owl-dt-calendar-table .owl-dt-calendar-cell-content.owl-dt-calendar-cell-out{color:rgb(var(--text-secondary))!important;opacity:.6!important}::ng-deep .owl-dt-timer-content .owl-dt-timer-input{border-radius:.5rem;border-style:var(--tw-border-style);border-width:1px;border-color:rgb(var(--border-strong));background-color:rgb(var(--bg-primary));color:rgb(var(--text-primary))}::ng-deep .owl-dt-control-period-button .owl-dt-control-button-arrow{display:none}::ng-deep .owl-dt-container-buttons{height:auto!important;color:rgb(var(--text-primary))!important;display:flex!important;align-items:center!important;justify-content:flex-end!important;gap:8px;padding:8px 12px;border-top:1px solid rgb(var(--border-default))}::ng-deep .owl-dt-container-buttons .owl-dt-container-control-button{width:auto!important;height:32px!important;border-radius:6px!important;width:60px!important;padding-top:4px!important;padding-bottom:4px!important;font-size:13px!important;font-weight:600!important;border:1px solid rgb(var(--border-default))!important;background-color:rgb(var(--bg-primary))!important;color:rgb(var(--text-primary))!important;cursor:pointer;transition:opacity .15s ease}::ng-deep .owl-dt-container-buttons .owl-dt-container-control-button:hover{background-color:rgb(var(--bg-hover))!important}::ng-deep .owl-dt-container-buttons .owl-dt-container-control-button:last-child{background-color:rgb(var(--primary))!important;border-color:rgb(var(--primary))!important;color:#fff!important}::ng-deep .owl-dt-container-buttons .owl-dt-container-control-button:last-child:hover{opacity:.85}::ng-deep .owl-dt-container-buttons .owl-dt-container-control-button .owl-dt-control-button-content{height:100%!important;width:100%!important;padding:0!important;background-color:transparent!important;color:inherit!important;display:flex!important;align-items:center!important;justify-content:center!important}::ng-deep .owl-dt-calendar-control-content .owl-dt-control-button-content{--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:rgb(var(--text-primary))}::ng-deep .owl-dt-control-arrow-button .owl-dt-control-button-content{color:rgb(var(--text-primary))}::ng-deep .owl-dt-calendar-table .owl-dt-calendar-header{color:rgb(var(--text-secondary))}::ng-deep .owl-dt-calendar-table .owl-dt-calendar-header .owl-dt-weekdays th{--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:rgb(var(--text-secondary))}::ng-deep .owl-dt-inline-container,::ng-deep .owl-dt-popup-container{border-radius:.75rem;border-style:var(--tw-border-style);border-width:1px;border-color:rgb(var(--border-strong));--tw-shadow: 0 10px 15px -3px var(--tw-shadow-color, rgb(var(--shadow-color) / .1)), 0 4px 6px -4px var(--tw-shadow-color, rgb(var(--shadow-color) / .1));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000;--tw-font-weight: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
2765
2883
  }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { label: [{
2766
2884
  type: Input
2767
2885
  }], placeholder: [{
@@ -2880,12 +2998,12 @@ class DndUploadComponent {
2880
2998
  return a === fileType;
2881
2999
  });
2882
3000
  }
2883
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: DndUploadComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2884
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: DndUploadComponent, isStandalone: false, selector: "fx-ui-dnd-upload", inputs: { multiple: "multiple", accept: "accept", maxSizeMB: "maxSizeMB", strictSize: "strictSize", icon: "icon", accentColor: "accentColor" }, outputs: { fileDrop: "fileDrop", fileClick: "fileClick", uploadComplete: "uploadComplete", uploadError: "uploadError" }, ngImport: i0, template: "<div\n class=\"dnd-wrapper\"\n [ngStyle]=\"accentStyle\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\"\n>\n <div\n role=\"button\"\n tabindex=\"0\"\n class=\"dnd-area\"\n [class.drag-over]=\"isDragOver\"\n (click)=\"onAreaClick(fileInput, $event)\"\n (keydown.enter)=\"onAreaClick(fileInput, $event)\"\n >\n <fx-ui-hero-icon\n [icon]=\"icon\"\n [size]=\"40\"\n class=\"flex dnd-icon\"\n ></fx-ui-hero-icon>\n <div class=\"dnd-text\">\n <span class=\"dnd-link\">Click to upload</span>\n <span class=\"dnd-or\">or drag and drop</span>\n </div>\n <div class=\"dnd-hint\">\n @if (accept) {\n Accepted: {{ accept }}\n } @else {\n Any file type\n }\n \u2014 Max {{ maxSizeMB }} MB\n </div>\n\n <input\n #fileInput\n type=\"file\"\n class=\"dnd-input\"\n [attr.multiple]=\"multiple ? '' : null\"\n [attr.accept]=\"accept\"\n (change)=\"onFileSelected($event)\"\n />\n </div>\n</div>\n", styles: [":host{--dnd-accent: rgba(var(--gradient-primary-start) / 1)}.dnd-wrapper{display:block;width:100%}.dnd-area{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;min-height:160px;padding:32px 24px;border:2px dashed color-mix(in srgb,var(--dnd-accent) 40%,transparent);border-radius:12px;background:color-mix(in srgb,var(--dnd-accent) 4%,transparent);cursor:pointer;outline:none;transition:all .2s ease;position:relative}.dnd-area:hover{border-color:color-mix(in srgb,var(--dnd-accent) 70%,transparent);background:color-mix(in srgb,var(--dnd-accent) 8%,transparent)}.dnd-area:focus-visible{box-shadow:0 0 0 3px color-mix(in srgb,var(--dnd-accent) 20%,transparent)}.dnd-area.drag-over{border-color:var(--dnd-accent);background:color-mix(in srgb,var(--dnd-accent) 10%,transparent)}.dnd-icon{color:var(--dnd-accent)}.dnd-text{display:flex;align-items:center;gap:4px;font-size:14px;flex-wrap:wrap;justify-content:center}.dnd-link{color:var(--dnd-accent);font-weight:600;text-decoration:underline}.dnd-or{color:rgba(var(--text-secondary)/1)}.dnd-hint{font-size:12px;color:rgba(var(--text-secondary)/.7)}.dnd-input{position:absolute;width:0;height:0;overflow:hidden;opacity:0}@media (max-width: 640px){.dnd-area{min-height:120px;padding:24px 16px}.dnd-text{font-size:13px}}\n"], dependencies: [{ kind: "directive", type: i1$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: HeroIconComponent, selector: "fx-ui-hero-icon", inputs: ["stroke", "icon", "solid", "outline", "size", "color", "class"] }] });
3001
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: DndUploadComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3002
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: DndUploadComponent, isStandalone: false, selector: "fx-ui-dnd-upload", inputs: { multiple: "multiple", accept: "accept", maxSizeMB: "maxSizeMB", strictSize: "strictSize", icon: "icon", accentColor: "accentColor" }, outputs: { fileDrop: "fileDrop", fileClick: "fileClick", uploadComplete: "uploadComplete", uploadError: "uploadError" }, ngImport: i0, template: "<div\n class=\"dnd-wrapper\"\n [ngStyle]=\"accentStyle\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\"\n>\n <div\n role=\"button\"\n tabindex=\"0\"\n class=\"dnd-area\"\n [class.drag-over]=\"isDragOver\"\n (click)=\"onAreaClick(fileInput, $event)\"\n (keydown.enter)=\"onAreaClick(fileInput, $event)\"\n >\n <fx-ui-hero-icon\n [icon]=\"icon\"\n [size]=\"40\"\n class=\"flex dnd-icon\"\n ></fx-ui-hero-icon>\n <div class=\"dnd-text\">\n <span class=\"dnd-link\">Click to upload</span>\n <span class=\"dnd-or\">or drag and drop</span>\n </div>\n <div class=\"dnd-hint\">\n @if (accept) {\n Accepted: {{ accept }}\n } @else {\n Any file type\n }\n \u2014 Max {{ maxSizeMB }} MB\n </div>\n\n <input\n #fileInput\n type=\"file\"\n class=\"dnd-input\"\n [attr.multiple]=\"multiple ? '' : null\"\n [attr.accept]=\"accept\"\n (change)=\"onFileSelected($event)\"\n />\n </div>\n</div>\n", styles: [":host{--dnd-accent: rgba(var(--gradient-primary-start) / 1)}.dnd-wrapper{display:block;width:100%}.dnd-area{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;min-height:160px;padding:32px 24px;border:2px dashed color-mix(in srgb,var(--dnd-accent) 40%,transparent);border-radius:12px;background:color-mix(in srgb,var(--dnd-accent) 4%,transparent);cursor:pointer;outline:none;transition:all .2s ease;position:relative}.dnd-area:hover{border-color:color-mix(in srgb,var(--dnd-accent) 70%,transparent);background:color-mix(in srgb,var(--dnd-accent) 8%,transparent)}.dnd-area:focus-visible{box-shadow:0 0 0 3px color-mix(in srgb,var(--dnd-accent) 20%,transparent)}.dnd-area.drag-over{border-color:var(--dnd-accent);background:color-mix(in srgb,var(--dnd-accent) 10%,transparent)}.dnd-icon{color:var(--dnd-accent)}.dnd-text{display:flex;align-items:center;gap:4px;font-size:14px;flex-wrap:wrap;justify-content:center}.dnd-link{color:var(--dnd-accent);font-weight:600;text-decoration:underline}.dnd-or{color:rgba(var(--text-secondary)/1)}.dnd-hint{font-size:12px;color:rgba(var(--text-secondary)/.7)}.dnd-input{position:absolute;width:0;height:0;overflow:hidden;opacity:0}@media(max-width:640px){.dnd-area{min-height:120px;padding:24px 16px}.dnd-text{font-size:13px}}\n"], dependencies: [{ kind: "directive", type: i1$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: HeroIconComponent, selector: "fx-ui-hero-icon", inputs: ["stroke", "icon", "solid", "outline", "size", "color", "class"] }] });
2885
3003
  }
2886
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: DndUploadComponent, decorators: [{
3004
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: DndUploadComponent, decorators: [{
2887
3005
  type: Component,
2888
- args: [{ selector: 'fx-ui-dnd-upload', standalone: false, template: "<div\n class=\"dnd-wrapper\"\n [ngStyle]=\"accentStyle\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\"\n>\n <div\n role=\"button\"\n tabindex=\"0\"\n class=\"dnd-area\"\n [class.drag-over]=\"isDragOver\"\n (click)=\"onAreaClick(fileInput, $event)\"\n (keydown.enter)=\"onAreaClick(fileInput, $event)\"\n >\n <fx-ui-hero-icon\n [icon]=\"icon\"\n [size]=\"40\"\n class=\"flex dnd-icon\"\n ></fx-ui-hero-icon>\n <div class=\"dnd-text\">\n <span class=\"dnd-link\">Click to upload</span>\n <span class=\"dnd-or\">or drag and drop</span>\n </div>\n <div class=\"dnd-hint\">\n @if (accept) {\n Accepted: {{ accept }}\n } @else {\n Any file type\n }\n \u2014 Max {{ maxSizeMB }} MB\n </div>\n\n <input\n #fileInput\n type=\"file\"\n class=\"dnd-input\"\n [attr.multiple]=\"multiple ? '' : null\"\n [attr.accept]=\"accept\"\n (change)=\"onFileSelected($event)\"\n />\n </div>\n</div>\n", styles: [":host{--dnd-accent: rgba(var(--gradient-primary-start) / 1)}.dnd-wrapper{display:block;width:100%}.dnd-area{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;min-height:160px;padding:32px 24px;border:2px dashed color-mix(in srgb,var(--dnd-accent) 40%,transparent);border-radius:12px;background:color-mix(in srgb,var(--dnd-accent) 4%,transparent);cursor:pointer;outline:none;transition:all .2s ease;position:relative}.dnd-area:hover{border-color:color-mix(in srgb,var(--dnd-accent) 70%,transparent);background:color-mix(in srgb,var(--dnd-accent) 8%,transparent)}.dnd-area:focus-visible{box-shadow:0 0 0 3px color-mix(in srgb,var(--dnd-accent) 20%,transparent)}.dnd-area.drag-over{border-color:var(--dnd-accent);background:color-mix(in srgb,var(--dnd-accent) 10%,transparent)}.dnd-icon{color:var(--dnd-accent)}.dnd-text{display:flex;align-items:center;gap:4px;font-size:14px;flex-wrap:wrap;justify-content:center}.dnd-link{color:var(--dnd-accent);font-weight:600;text-decoration:underline}.dnd-or{color:rgba(var(--text-secondary)/1)}.dnd-hint{font-size:12px;color:rgba(var(--text-secondary)/.7)}.dnd-input{position:absolute;width:0;height:0;overflow:hidden;opacity:0}@media (max-width: 640px){.dnd-area{min-height:120px;padding:24px 16px}.dnd-text{font-size:13px}}\n"] }]
3006
+ args: [{ selector: 'fx-ui-dnd-upload', standalone: false, template: "<div\n class=\"dnd-wrapper\"\n [ngStyle]=\"accentStyle\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\"\n>\n <div\n role=\"button\"\n tabindex=\"0\"\n class=\"dnd-area\"\n [class.drag-over]=\"isDragOver\"\n (click)=\"onAreaClick(fileInput, $event)\"\n (keydown.enter)=\"onAreaClick(fileInput, $event)\"\n >\n <fx-ui-hero-icon\n [icon]=\"icon\"\n [size]=\"40\"\n class=\"flex dnd-icon\"\n ></fx-ui-hero-icon>\n <div class=\"dnd-text\">\n <span class=\"dnd-link\">Click to upload</span>\n <span class=\"dnd-or\">or drag and drop</span>\n </div>\n <div class=\"dnd-hint\">\n @if (accept) {\n Accepted: {{ accept }}\n } @else {\n Any file type\n }\n \u2014 Max {{ maxSizeMB }} MB\n </div>\n\n <input\n #fileInput\n type=\"file\"\n class=\"dnd-input\"\n [attr.multiple]=\"multiple ? '' : null\"\n [attr.accept]=\"accept\"\n (change)=\"onFileSelected($event)\"\n />\n </div>\n</div>\n", styles: [":host{--dnd-accent: rgba(var(--gradient-primary-start) / 1)}.dnd-wrapper{display:block;width:100%}.dnd-area{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;min-height:160px;padding:32px 24px;border:2px dashed color-mix(in srgb,var(--dnd-accent) 40%,transparent);border-radius:12px;background:color-mix(in srgb,var(--dnd-accent) 4%,transparent);cursor:pointer;outline:none;transition:all .2s ease;position:relative}.dnd-area:hover{border-color:color-mix(in srgb,var(--dnd-accent) 70%,transparent);background:color-mix(in srgb,var(--dnd-accent) 8%,transparent)}.dnd-area:focus-visible{box-shadow:0 0 0 3px color-mix(in srgb,var(--dnd-accent) 20%,transparent)}.dnd-area.drag-over{border-color:var(--dnd-accent);background:color-mix(in srgb,var(--dnd-accent) 10%,transparent)}.dnd-icon{color:var(--dnd-accent)}.dnd-text{display:flex;align-items:center;gap:4px;font-size:14px;flex-wrap:wrap;justify-content:center}.dnd-link{color:var(--dnd-accent);font-weight:600;text-decoration:underline}.dnd-or{color:rgba(var(--text-secondary)/1)}.dnd-hint{font-size:12px;color:rgba(var(--text-secondary)/.7)}.dnd-input{position:absolute;width:0;height:0;overflow:hidden;opacity:0}@media(max-width:640px){.dnd-area{min-height:120px;padding:24px 16px}.dnd-text{font-size:13px}}\n"] }]
2889
3007
  }], propDecorators: { multiple: [{
2890
3008
  type: Input
2891
3009
  }], accept: [{
@@ -2922,10 +3040,10 @@ class FlowConnection {
2922
3040
  },
2923
3041
  ];
2924
3042
  }
2925
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: FlowConnection, deps: [], target: i0.ɵɵFactoryTarget.Component });
2926
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.4", type: FlowConnection, isStandalone: false, selector: "fx-ui-flow-connection", inputs: { nodes: "nodes", edges: "edges", backgroundColor: "backgroundColor", view: "view" }, ngImport: i0, template: "<vflow\n [background]=\"{\n type: 'solid',\n color: `rgba(var(${backgroundColor})`\n}\"\n [nodes]=\"nodes\"\n [edges]=\"edges\"\n (onConnect)=\"handleConnection($event)\"\n [view]=\"view\"\n/>\n", styles: [""], dependencies: [{ kind: "component", type: i38.VflowComponent, selector: "vflow", inputs: ["view", "minZoom", "maxZoom", "background", "optimization", "entitiesSelectable", "keyboardShortcuts", "connection", "snapGrid", "elevateNodesOnSelect", "elevateEdgesOnSelect", "nodes", "alignmentHelper", "edges"], outputs: ["onComponentNodeEvent"] }, { kind: "directive", type: i38.ConnectionControllerDirective, selector: "[onConnect], [onReconnect], [connect], [reconnect]", outputs: ["onConnect", "connect", "onReconnect", "reconnect"] }] });
3043
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: FlowConnection, deps: [], target: i0.ɵɵFactoryTarget.Component });
3044
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.20", type: FlowConnection, isStandalone: false, selector: "fx-ui-flow-connection", inputs: { nodes: "nodes", edges: "edges", backgroundColor: "backgroundColor", view: "view" }, ngImport: i0, template: "<vflow\n [background]=\"{\n type: 'solid',\n color: `rgba(var(${backgroundColor})`\n}\"\n [nodes]=\"nodes\"\n [edges]=\"edges\"\n (onConnect)=\"handleConnection($event)\"\n [view]=\"view\"\n/>\n", styles: [""], dependencies: [{ kind: "component", type: i39.VflowComponent, selector: "vflow", inputs: ["view", "minZoom", "maxZoom", "background", "optimization", "entitiesSelectable", "keyboardShortcuts", "connection", "snapGrid", "elevateNodesOnSelect", "elevateEdgesOnSelect", "nodes", "alignmentHelper", "edges"], outputs: ["onComponentNodeEvent"] }, { kind: "directive", type: i39.ConnectionControllerDirective, selector: "[onConnect], [onReconnect], [connect], [reconnect]", outputs: ["onConnect", "connect", "onReconnect", "reconnect"] }] });
2927
3045
  }
2928
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: FlowConnection, decorators: [{
3046
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: FlowConnection, decorators: [{
2929
3047
  type: Component,
2930
3048
  args: [{ selector: 'fx-ui-flow-connection', standalone: false, template: "<vflow\n [background]=\"{\n type: 'solid',\n color: `rgba(var(${backgroundColor})`\n}\"\n [nodes]=\"nodes\"\n [edges]=\"edges\"\n (onConnect)=\"handleConnection($event)\"\n [view]=\"view\"\n/>\n" }]
2931
3049
  }], propDecorators: { nodes: [{
@@ -2938,6 +3056,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
2938
3056
  type: Input
2939
3057
  }] } });
2940
3058
 
3059
+ let nextInputId = 0;
2941
3060
  class InputComponent extends FxComponent {
2942
3061
  ref;
2943
3062
  label = '';
@@ -2953,6 +3072,9 @@ class InputComponent extends FxComponent {
2953
3072
  blurred = new EventEmitter();
2954
3073
  focused = new EventEmitter();
2955
3074
  suffixClick = new EventEmitter();
3075
+ /** Accessible name for the suffix icon button (it renders no text). */
3076
+ suffixAriaLabel = '';
3077
+ fieldId = `fx-input-${nextInputId++}`;
2956
3078
  showPassword = false;
2957
3079
  validateError = null;
2958
3080
  constructor(ref) {
@@ -3005,12 +3127,12 @@ class InputComponent extends FxComponent {
3005
3127
  return 'number';
3006
3128
  return this.type;
3007
3129
  }
3008
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: InputComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
3009
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: InputComponent, isStandalone: false, selector: "fx-ui-input", inputs: { label: "label", tooltip: "tooltip", type: "type", placeholder: "placeholder", errorMessages: "errorMessages", required: "required", suffixIcon: "suffixIcon", class: "class", maxlength: "maxlength", validateFn: "validateFn" }, outputs: { blurred: "blurred", focused: "focused", suffixClick: "suffixClick" }, usesInheritance: true, ngImport: i0, template: "<div class=\"mb-4 text-left w-full text-text-primary\" [class]=\"class\">\n @if (label) {\n <label class=\"block txt-field-label\">\n {{ label }}\n @if (required) {\n <span class=\"txt-required\">*</span>\n }\n @if (tooltip) {\n <fx-ui-hero-icon\n icon=\"information-circle\"\n [size]=\"16\"\n class=\"inline-block align-middle ml-0.5 text-text-secondary cursor-help relative -top-px\"\n [matTooltip]=\"tooltip\"\n matTooltipPosition=\"above\"\n matTooltipClass=\"text-text-primary text-xs font-semibold\"\n ></fx-ui-hero-icon>\n }\n </label>\n }\n\n <div class=\"relative\">\n <input\n appTrimOnBlur\n [appTrimOnBlurCollapse]=\"true\"\n [type]=\"displayType\"\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n [value]=\"value\"\n (input)=\"onInput($event)\"\n (blur)=\"onBlur()\"\n (focus)=\"onFocus()\"\n [attr.maxlength]=\"maxlength\"\n [class]=\"type === 'otp' ? 'input-otp' : 'input-default'\"\n [class.input-invalid]=\"invalid\"\n [class.pr-8]=\"type === 'password' || suffixIcon\"\n [class.txt-otp-input]=\"type === 'otp'\"\n />\n @if (type === 'password' || suffixIcon) {\n <button\n type=\"button\"\n class=\"absolute inset-y-0 right-2 flex items-center text-text-primary hover:text-text-secondary\"\n (click)=\"onSuffixClick()\"\n [disabled]=\"disabled\"\n >\n @if (type === 'password') {\n <fx-ui-hero-icon\n [icon]=\"showPassword ? 'eye-slash' : 'eye'\"\n [size]=\"18\"\n class=\"text-text-primary\"\n ></fx-ui-hero-icon>\n } @else if (suffixIcon) {\n <fx-ui-hero-icon\n [icon]=\"suffixIcon\"\n [size]=\"18\"\n class=\"text-text-primary\"\n ></fx-ui-hero-icon>\n }\n </button>\n }\n </div>\n\n @if (invalid) {\n <div class=\"txt-invalid\">\n {{ getErrorMessage(label) }}\n </div>\n }\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: TrimOnBlurDirective, selector: "[appTrimOnBlur]", inputs: ["appTrimOnBlurCollapse"] }, { kind: "directive", type: i56.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: HeroIconComponent, selector: "fx-ui-hero-icon", inputs: ["stroke", "icon", "solid", "outline", "size", "color", "class"] }] });
3130
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: InputComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
3131
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: InputComponent, isStandalone: false, selector: "fx-ui-input", inputs: { label: "label", tooltip: "tooltip", type: "type", placeholder: "placeholder", errorMessages: "errorMessages", required: "required", suffixIcon: "suffixIcon", class: "class", maxlength: "maxlength", validateFn: "validateFn", suffixAriaLabel: "suffixAriaLabel" }, outputs: { blurred: "blurred", focused: "focused", suffixClick: "suffixClick" }, usesInheritance: true, ngImport: i0, template: "<div class=\"mb-4 text-left w-full text-text-primary\" [class]=\"class\">\n @if (label) {\n <label class=\"block txt-field-label\" [attr.for]=\"fieldId\">\n {{ label }}\n @if (required) {\n <span class=\"txt-required\" aria-hidden=\"true\">*</span>\n }\n @if (tooltip) {\n <fx-ui-hero-icon\n icon=\"information-circle\"\n [size]=\"16\"\n class=\"inline-block align-middle ml-0.5 text-text-secondary cursor-help relative -top-px\"\n [matTooltip]=\"tooltip\"\n matTooltipPosition=\"above\"\n matTooltipClass=\"text-text-primary text-xs font-semibold\"\n ></fx-ui-hero-icon>\n }\n </label>\n }\n\n <div class=\"relative\">\n <input\n appTrimOnBlur\n [appTrimOnBlurCollapse]=\"true\"\n [id]=\"fieldId\"\n [type]=\"displayType\"\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n [value]=\"value\"\n (input)=\"onInput($event)\"\n (blur)=\"onBlur()\"\n (focus)=\"onFocus()\"\n [attr.maxlength]=\"maxlength\"\n [attr.aria-invalid]=\"invalid || null\"\n [attr.aria-describedby]=\"invalid ? fieldId + '-error' : null\"\n [attr.aria-required]=\"required ? true : null\"\n [class]=\"type === 'otp' ? 'input-otp' : 'input-default'\"\n [class.input-invalid]=\"invalid\"\n [class.pr-8]=\"type === 'password' || suffixIcon\"\n [class.txt-otp-input]=\"type === 'otp'\"\n />\n @if (type === 'password' || suffixIcon) {\n <button\n type=\"button\"\n class=\"absolute inset-y-0 right-2 flex items-center text-text-primary hover:text-text-secondary\"\n (click)=\"onSuffixClick()\"\n [disabled]=\"disabled\"\n [attr.aria-label]=\"\n type === 'password'\n ? (showPassword ? 'Hide password' : 'Show password')\n : (suffixAriaLabel || null)\n \"\n [attr.aria-pressed]=\"type === 'password' ? showPassword : null\"\n >\n @if (type === 'password') {\n <fx-ui-hero-icon\n [icon]=\"showPassword ? 'eye-slash' : 'eye'\"\n [size]=\"18\"\n class=\"text-text-primary\"\n aria-hidden=\"true\"\n ></fx-ui-hero-icon>\n } @else if (suffixIcon) {\n <fx-ui-hero-icon\n [icon]=\"suffixIcon\"\n [size]=\"18\"\n class=\"text-text-primary\"\n aria-hidden=\"true\"\n ></fx-ui-hero-icon>\n }\n </button>\n }\n </div>\n\n @if (invalid) {\n <div class=\"txt-invalid\" role=\"alert\" [id]=\"fieldId + '-error'\">\n {{ getErrorMessage(label) }}\n </div>\n }\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: TrimOnBlurDirective, selector: "[appTrimOnBlur]", inputs: ["appTrimOnBlurCollapse"] }, { kind: "directive", type: i57.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: HeroIconComponent, selector: "fx-ui-hero-icon", inputs: ["stroke", "icon", "solid", "outline", "size", "color", "class"] }] });
3010
3132
  }
3011
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: InputComponent, decorators: [{
3133
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: InputComponent, decorators: [{
3012
3134
  type: Component,
3013
- args: [{ selector: 'fx-ui-input', standalone: false, template: "<div class=\"mb-4 text-left w-full text-text-primary\" [class]=\"class\">\n @if (label) {\n <label class=\"block txt-field-label\">\n {{ label }}\n @if (required) {\n <span class=\"txt-required\">*</span>\n }\n @if (tooltip) {\n <fx-ui-hero-icon\n icon=\"information-circle\"\n [size]=\"16\"\n class=\"inline-block align-middle ml-0.5 text-text-secondary cursor-help relative -top-px\"\n [matTooltip]=\"tooltip\"\n matTooltipPosition=\"above\"\n matTooltipClass=\"text-text-primary text-xs font-semibold\"\n ></fx-ui-hero-icon>\n }\n </label>\n }\n\n <div class=\"relative\">\n <input\n appTrimOnBlur\n [appTrimOnBlurCollapse]=\"true\"\n [type]=\"displayType\"\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n [value]=\"value\"\n (input)=\"onInput($event)\"\n (blur)=\"onBlur()\"\n (focus)=\"onFocus()\"\n [attr.maxlength]=\"maxlength\"\n [class]=\"type === 'otp' ? 'input-otp' : 'input-default'\"\n [class.input-invalid]=\"invalid\"\n [class.pr-8]=\"type === 'password' || suffixIcon\"\n [class.txt-otp-input]=\"type === 'otp'\"\n />\n @if (type === 'password' || suffixIcon) {\n <button\n type=\"button\"\n class=\"absolute inset-y-0 right-2 flex items-center text-text-primary hover:text-text-secondary\"\n (click)=\"onSuffixClick()\"\n [disabled]=\"disabled\"\n >\n @if (type === 'password') {\n <fx-ui-hero-icon\n [icon]=\"showPassword ? 'eye-slash' : 'eye'\"\n [size]=\"18\"\n class=\"text-text-primary\"\n ></fx-ui-hero-icon>\n } @else if (suffixIcon) {\n <fx-ui-hero-icon\n [icon]=\"suffixIcon\"\n [size]=\"18\"\n class=\"text-text-primary\"\n ></fx-ui-hero-icon>\n }\n </button>\n }\n </div>\n\n @if (invalid) {\n <div class=\"txt-invalid\">\n {{ getErrorMessage(label) }}\n </div>\n }\n</div>\n" }]
3135
+ args: [{ selector: 'fx-ui-input', standalone: false, template: "<div class=\"mb-4 text-left w-full text-text-primary\" [class]=\"class\">\n @if (label) {\n <label class=\"block txt-field-label\" [attr.for]=\"fieldId\">\n {{ label }}\n @if (required) {\n <span class=\"txt-required\" aria-hidden=\"true\">*</span>\n }\n @if (tooltip) {\n <fx-ui-hero-icon\n icon=\"information-circle\"\n [size]=\"16\"\n class=\"inline-block align-middle ml-0.5 text-text-secondary cursor-help relative -top-px\"\n [matTooltip]=\"tooltip\"\n matTooltipPosition=\"above\"\n matTooltipClass=\"text-text-primary text-xs font-semibold\"\n ></fx-ui-hero-icon>\n }\n </label>\n }\n\n <div class=\"relative\">\n <input\n appTrimOnBlur\n [appTrimOnBlurCollapse]=\"true\"\n [id]=\"fieldId\"\n [type]=\"displayType\"\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n [value]=\"value\"\n (input)=\"onInput($event)\"\n (blur)=\"onBlur()\"\n (focus)=\"onFocus()\"\n [attr.maxlength]=\"maxlength\"\n [attr.aria-invalid]=\"invalid || null\"\n [attr.aria-describedby]=\"invalid ? fieldId + '-error' : null\"\n [attr.aria-required]=\"required ? true : null\"\n [class]=\"type === 'otp' ? 'input-otp' : 'input-default'\"\n [class.input-invalid]=\"invalid\"\n [class.pr-8]=\"type === 'password' || suffixIcon\"\n [class.txt-otp-input]=\"type === 'otp'\"\n />\n @if (type === 'password' || suffixIcon) {\n <button\n type=\"button\"\n class=\"absolute inset-y-0 right-2 flex items-center text-text-primary hover:text-text-secondary\"\n (click)=\"onSuffixClick()\"\n [disabled]=\"disabled\"\n [attr.aria-label]=\"\n type === 'password'\n ? (showPassword ? 'Hide password' : 'Show password')\n : (suffixAriaLabel || null)\n \"\n [attr.aria-pressed]=\"type === 'password' ? showPassword : null\"\n >\n @if (type === 'password') {\n <fx-ui-hero-icon\n [icon]=\"showPassword ? 'eye-slash' : 'eye'\"\n [size]=\"18\"\n class=\"text-text-primary\"\n aria-hidden=\"true\"\n ></fx-ui-hero-icon>\n } @else if (suffixIcon) {\n <fx-ui-hero-icon\n [icon]=\"suffixIcon\"\n [size]=\"18\"\n class=\"text-text-primary\"\n aria-hidden=\"true\"\n ></fx-ui-hero-icon>\n }\n </button>\n }\n </div>\n\n @if (invalid) {\n <div class=\"txt-invalid\" role=\"alert\" [id]=\"fieldId + '-error'\">\n {{ getErrorMessage(label) }}\n </div>\n }\n</div>\n" }]
3014
3136
  }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { label: [{
3015
3137
  type: Input
3016
3138
  }], tooltip: [{
@@ -3037,25 +3159,29 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
3037
3159
  type: Output
3038
3160
  }], suffixClick: [{
3039
3161
  type: Output
3162
+ }], suffixAriaLabel: [{
3163
+ type: Input
3040
3164
  }] } });
3041
3165
 
3042
3166
  class LoadingPanel {
3043
3167
  show = false;
3044
3168
  message = "Loading";
3045
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: LoadingPanel, deps: [], target: i0.ɵɵFactoryTarget.Component });
3046
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.4", type: LoadingPanel, isStandalone: false, selector: "fx-ui-loading-panel", inputs: { show: "show", message: "message" }, ngImport: i0, template: "<!-- Full-screen glass overlay -->\n<div\n *ngIf=\"show\"\n class=\"fixed inset-0 z-50 flex items-center justify-center\"\n aria-hidden=\"false\"\n role=\"alert\"\n aria-busy=\"true\"\n>\n <div class=\"absolute inset-0 bg-bg-primary/30 backdrop-blur-xl\" aria-hidden=\"true\"></div>\n\n <div\n class=\"relative z-10 flex flex-col items-center gap-4 p-6 rounded-2xl shadow-xl bg-bg-primary/70 border border-border-strong backdrop-bg-primary/70\"\n style=\"min-width: 220px; max-width: 90%\"\n >\n <svg fill=\"url(#spinner-gradient)\" width=\"50\" height=\"50\" viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <defs>\n <linearGradient id=\"spinner-gradient\" x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"0%\">\n <stop offset=\"0%\" style=\"stop-color: rgb(var(--gradient-primary-start)); stop-opacity: 1\" />\n <stop offset=\"100%\" style=\"stop-color: rgb(var(--gradient-primary-end)); stop-opacity: 1\" />\n </linearGradient>\n </defs>\n <circle cx=\"4\" cy=\"12\" r=\"0\">\n <animate begin=\"0;spinner_z0Or.end\" attributeName=\"r\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"0;3\" fill=\"freeze\"/>\n <animate begin=\"spinner_OLMs.end\" attributeName=\"cx\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"4;12\" fill=\"freeze\"/>\n <animate begin=\"spinner_UHR2.end\" attributeName=\"cx\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"12;20\" fill=\"freeze\"/>\n <animate id=\"spinner_lo66\" begin=\"spinner_Aguh.end\" attributeName=\"r\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"3;0\" fill=\"freeze\"/>\n <animate id=\"spinner_z0Or\" begin=\"spinner_lo66.end\" attributeName=\"cx\" dur=\"0.001s\" values=\"20;4\" fill=\"freeze\"/>\n </circle>\n <circle cx=\"4\" cy=\"12\" r=\"3\">\n <animate begin=\"0;spinner_z0Or.end\" attributeName=\"cx\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"4;12\" fill=\"freeze\"/>\n <animate begin=\"spinner_OLMs.end\" attributeName=\"cx\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"12;20\" fill=\"freeze\"/>\n <animate id=\"spinner_JsnR\" begin=\"spinner_UHR2.end\" attributeName=\"r\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"3;0\" fill=\"freeze\"/>\n <animate id=\"spinner_Aguh\" begin=\"spinner_JsnR.end\" attributeName=\"cx\" dur=\"0.001s\" values=\"20;4\" fill=\"freeze\"/>\n <animate begin=\"spinner_Aguh.end\" attributeName=\"r\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"0;3\" fill=\"freeze\"/>\n </circle>\n <circle cx=\"12\" cy=\"12\" r=\"3\">\n <animate begin=\"0;spinner_z0Or.end\" attributeName=\"cx\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"12;20\" fill=\"freeze\"/>\n <animate id=\"spinner_hSjk\" begin=\"spinner_OLMs.end\" attributeName=\"r\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"3;0\" fill=\"freeze\"/>\n <animate id=\"spinner_UHR2\" begin=\"spinner_hSjk.end\" attributeName=\"cx\" dur=\"0.001s\" values=\"20;4\" fill=\"freeze\"/>\n <animate begin=\"spinner_UHR2.end\" attributeName=\"r\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"0;3\" fill=\"freeze\"/>\n <animate begin=\"spinner_Aguh.end\" attributeName=\"cx\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"4;12\" fill=\"freeze\"/>\n </circle>\n <circle cx=\"20\" cy=\"12\" r=\"3\">\n <animate id=\"spinner_4v5M\" begin=\"0;spinner_z0Or.end\" attributeName=\"r\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"3;0\" fill=\"freeze\"/>\n <animate id=\"spinner_OLMs\" begin=\"spinner_4v5M.end\" attributeName=\"cx\" dur=\"0.001s\" values=\"20;4\" fill=\"freeze\"/>\n <animate begin=\"spinner_OLMs.end\" attributeName=\"r\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"0;3\" fill=\"freeze\"/>\n <animate begin=\"spinner_UHR2.end\" attributeName=\"cx\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"4;12\" fill=\"freeze\"/>\n <animate begin=\"spinner_Aguh.end\" attributeName=\"cx\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"12;20\" fill=\"freeze\"/>\n </circle>\n </svg>\n \n\n <div *ngIf=\"message\" class=\"text-sm text-text-primary text-center\">\n {{ message }}\n </div>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
3169
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: LoadingPanel, deps: [], target: i0.ɵɵFactoryTarget.Component });
3170
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: LoadingPanel, isStandalone: false, selector: "fx-ui-loading-panel", inputs: { show: "show", message: "message" }, ngImport: i0, template: "<!-- Full-screen glass overlay -->\n@if (show) {\n <div\n class=\"fixed inset-0 z-50 flex items-center justify-center\"\n aria-hidden=\"false\"\n role=\"alert\"\n aria-busy=\"true\"\n >\n <div class=\"absolute inset-0 bg-bg-primary/30 backdrop-blur-xl\" aria-hidden=\"true\"></div>\n <div\n class=\"relative z-10 flex flex-col items-center gap-4 p-6 rounded-2xl shadow-xl bg-bg-primary/70 border border-border-strong backdrop-bg-primary/70\"\n style=\"min-width: 220px; max-width: 90%\"\n >\n <svg fill=\"url(#spinner-gradient)\" width=\"50\" height=\"50\" viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <defs>\n <linearGradient id=\"spinner-gradient\" x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"0%\">\n <stop offset=\"0%\" style=\"stop-color: rgb(var(--gradient-primary-start)); stop-opacity: 1\" />\n <stop offset=\"100%\" style=\"stop-color: rgb(var(--gradient-primary-end)); stop-opacity: 1\" />\n </linearGradient>\n </defs>\n <circle cx=\"4\" cy=\"12\" r=\"0\">\n <animate begin=\"0;spinner_z0Or.end\" attributeName=\"r\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"0;3\" fill=\"freeze\"/>\n <animate begin=\"spinner_OLMs.end\" attributeName=\"cx\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"4;12\" fill=\"freeze\"/>\n <animate begin=\"spinner_UHR2.end\" attributeName=\"cx\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"12;20\" fill=\"freeze\"/>\n <animate id=\"spinner_lo66\" begin=\"spinner_Aguh.end\" attributeName=\"r\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"3;0\" fill=\"freeze\"/>\n <animate id=\"spinner_z0Or\" begin=\"spinner_lo66.end\" attributeName=\"cx\" dur=\"0.001s\" values=\"20;4\" fill=\"freeze\"/>\n </circle>\n <circle cx=\"4\" cy=\"12\" r=\"3\">\n <animate begin=\"0;spinner_z0Or.end\" attributeName=\"cx\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"4;12\" fill=\"freeze\"/>\n <animate begin=\"spinner_OLMs.end\" attributeName=\"cx\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"12;20\" fill=\"freeze\"/>\n <animate id=\"spinner_JsnR\" begin=\"spinner_UHR2.end\" attributeName=\"r\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"3;0\" fill=\"freeze\"/>\n <animate id=\"spinner_Aguh\" begin=\"spinner_JsnR.end\" attributeName=\"cx\" dur=\"0.001s\" values=\"20;4\" fill=\"freeze\"/>\n <animate begin=\"spinner_Aguh.end\" attributeName=\"r\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"0;3\" fill=\"freeze\"/>\n </circle>\n <circle cx=\"12\" cy=\"12\" r=\"3\">\n <animate begin=\"0;spinner_z0Or.end\" attributeName=\"cx\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"12;20\" fill=\"freeze\"/>\n <animate id=\"spinner_hSjk\" begin=\"spinner_OLMs.end\" attributeName=\"r\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"3;0\" fill=\"freeze\"/>\n <animate id=\"spinner_UHR2\" begin=\"spinner_hSjk.end\" attributeName=\"cx\" dur=\"0.001s\" values=\"20;4\" fill=\"freeze\"/>\n <animate begin=\"spinner_UHR2.end\" attributeName=\"r\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"0;3\" fill=\"freeze\"/>\n <animate begin=\"spinner_Aguh.end\" attributeName=\"cx\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"4;12\" fill=\"freeze\"/>\n </circle>\n <circle cx=\"20\" cy=\"12\" r=\"3\">\n <animate id=\"spinner_4v5M\" begin=\"0;spinner_z0Or.end\" attributeName=\"r\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"3;0\" fill=\"freeze\"/>\n <animate id=\"spinner_OLMs\" begin=\"spinner_4v5M.end\" attributeName=\"cx\" dur=\"0.001s\" values=\"20;4\" fill=\"freeze\"/>\n <animate begin=\"spinner_OLMs.end\" attributeName=\"r\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"0;3\" fill=\"freeze\"/>\n <animate begin=\"spinner_UHR2.end\" attributeName=\"cx\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"4;12\" fill=\"freeze\"/>\n <animate begin=\"spinner_Aguh.end\" attributeName=\"cx\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"12;20\" fill=\"freeze\"/>\n </circle>\n </svg>\n @if (message) {\n <div class=\"text-sm text-text-primary text-center\">\n {{ message }}\n </div>\n }\n </div>\n </div>\n}\n", styles: [""] });
3047
3171
  }
3048
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: LoadingPanel, decorators: [{
3172
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: LoadingPanel, decorators: [{
3049
3173
  type: Component,
3050
- args: [{ selector: 'fx-ui-loading-panel', standalone: false, template: "<!-- Full-screen glass overlay -->\n<div\n *ngIf=\"show\"\n class=\"fixed inset-0 z-50 flex items-center justify-center\"\n aria-hidden=\"false\"\n role=\"alert\"\n aria-busy=\"true\"\n>\n <div class=\"absolute inset-0 bg-bg-primary/30 backdrop-blur-xl\" aria-hidden=\"true\"></div>\n\n <div\n class=\"relative z-10 flex flex-col items-center gap-4 p-6 rounded-2xl shadow-xl bg-bg-primary/70 border border-border-strong backdrop-bg-primary/70\"\n style=\"min-width: 220px; max-width: 90%\"\n >\n <svg fill=\"url(#spinner-gradient)\" width=\"50\" height=\"50\" viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <defs>\n <linearGradient id=\"spinner-gradient\" x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"0%\">\n <stop offset=\"0%\" style=\"stop-color: rgb(var(--gradient-primary-start)); stop-opacity: 1\" />\n <stop offset=\"100%\" style=\"stop-color: rgb(var(--gradient-primary-end)); stop-opacity: 1\" />\n </linearGradient>\n </defs>\n <circle cx=\"4\" cy=\"12\" r=\"0\">\n <animate begin=\"0;spinner_z0Or.end\" attributeName=\"r\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"0;3\" fill=\"freeze\"/>\n <animate begin=\"spinner_OLMs.end\" attributeName=\"cx\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"4;12\" fill=\"freeze\"/>\n <animate begin=\"spinner_UHR2.end\" attributeName=\"cx\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"12;20\" fill=\"freeze\"/>\n <animate id=\"spinner_lo66\" begin=\"spinner_Aguh.end\" attributeName=\"r\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"3;0\" fill=\"freeze\"/>\n <animate id=\"spinner_z0Or\" begin=\"spinner_lo66.end\" attributeName=\"cx\" dur=\"0.001s\" values=\"20;4\" fill=\"freeze\"/>\n </circle>\n <circle cx=\"4\" cy=\"12\" r=\"3\">\n <animate begin=\"0;spinner_z0Or.end\" attributeName=\"cx\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"4;12\" fill=\"freeze\"/>\n <animate begin=\"spinner_OLMs.end\" attributeName=\"cx\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"12;20\" fill=\"freeze\"/>\n <animate id=\"spinner_JsnR\" begin=\"spinner_UHR2.end\" attributeName=\"r\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"3;0\" fill=\"freeze\"/>\n <animate id=\"spinner_Aguh\" begin=\"spinner_JsnR.end\" attributeName=\"cx\" dur=\"0.001s\" values=\"20;4\" fill=\"freeze\"/>\n <animate begin=\"spinner_Aguh.end\" attributeName=\"r\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"0;3\" fill=\"freeze\"/>\n </circle>\n <circle cx=\"12\" cy=\"12\" r=\"3\">\n <animate begin=\"0;spinner_z0Or.end\" attributeName=\"cx\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"12;20\" fill=\"freeze\"/>\n <animate id=\"spinner_hSjk\" begin=\"spinner_OLMs.end\" attributeName=\"r\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"3;0\" fill=\"freeze\"/>\n <animate id=\"spinner_UHR2\" begin=\"spinner_hSjk.end\" attributeName=\"cx\" dur=\"0.001s\" values=\"20;4\" fill=\"freeze\"/>\n <animate begin=\"spinner_UHR2.end\" attributeName=\"r\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"0;3\" fill=\"freeze\"/>\n <animate begin=\"spinner_Aguh.end\" attributeName=\"cx\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"4;12\" fill=\"freeze\"/>\n </circle>\n <circle cx=\"20\" cy=\"12\" r=\"3\">\n <animate id=\"spinner_4v5M\" begin=\"0;spinner_z0Or.end\" attributeName=\"r\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"3;0\" fill=\"freeze\"/>\n <animate id=\"spinner_OLMs\" begin=\"spinner_4v5M.end\" attributeName=\"cx\" dur=\"0.001s\" values=\"20;4\" fill=\"freeze\"/>\n <animate begin=\"spinner_OLMs.end\" attributeName=\"r\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"0;3\" fill=\"freeze\"/>\n <animate begin=\"spinner_UHR2.end\" attributeName=\"cx\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"4;12\" fill=\"freeze\"/>\n <animate begin=\"spinner_Aguh.end\" attributeName=\"cx\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"12;20\" fill=\"freeze\"/>\n </circle>\n </svg>\n \n\n <div *ngIf=\"message\" class=\"text-sm text-text-primary text-center\">\n {{ message }}\n </div>\n </div>\n</div>\n" }]
3174
+ args: [{ selector: 'fx-ui-loading-panel', standalone: false, template: "<!-- Full-screen glass overlay -->\n@if (show) {\n <div\n class=\"fixed inset-0 z-50 flex items-center justify-center\"\n aria-hidden=\"false\"\n role=\"alert\"\n aria-busy=\"true\"\n >\n <div class=\"absolute inset-0 bg-bg-primary/30 backdrop-blur-xl\" aria-hidden=\"true\"></div>\n <div\n class=\"relative z-10 flex flex-col items-center gap-4 p-6 rounded-2xl shadow-xl bg-bg-primary/70 border border-border-strong backdrop-bg-primary/70\"\n style=\"min-width: 220px; max-width: 90%\"\n >\n <svg fill=\"url(#spinner-gradient)\" width=\"50\" height=\"50\" viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <defs>\n <linearGradient id=\"spinner-gradient\" x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"0%\">\n <stop offset=\"0%\" style=\"stop-color: rgb(var(--gradient-primary-start)); stop-opacity: 1\" />\n <stop offset=\"100%\" style=\"stop-color: rgb(var(--gradient-primary-end)); stop-opacity: 1\" />\n </linearGradient>\n </defs>\n <circle cx=\"4\" cy=\"12\" r=\"0\">\n <animate begin=\"0;spinner_z0Or.end\" attributeName=\"r\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"0;3\" fill=\"freeze\"/>\n <animate begin=\"spinner_OLMs.end\" attributeName=\"cx\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"4;12\" fill=\"freeze\"/>\n <animate begin=\"spinner_UHR2.end\" attributeName=\"cx\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"12;20\" fill=\"freeze\"/>\n <animate id=\"spinner_lo66\" begin=\"spinner_Aguh.end\" attributeName=\"r\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"3;0\" fill=\"freeze\"/>\n <animate id=\"spinner_z0Or\" begin=\"spinner_lo66.end\" attributeName=\"cx\" dur=\"0.001s\" values=\"20;4\" fill=\"freeze\"/>\n </circle>\n <circle cx=\"4\" cy=\"12\" r=\"3\">\n <animate begin=\"0;spinner_z0Or.end\" attributeName=\"cx\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"4;12\" fill=\"freeze\"/>\n <animate begin=\"spinner_OLMs.end\" attributeName=\"cx\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"12;20\" fill=\"freeze\"/>\n <animate id=\"spinner_JsnR\" begin=\"spinner_UHR2.end\" attributeName=\"r\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"3;0\" fill=\"freeze\"/>\n <animate id=\"spinner_Aguh\" begin=\"spinner_JsnR.end\" attributeName=\"cx\" dur=\"0.001s\" values=\"20;4\" fill=\"freeze\"/>\n <animate begin=\"spinner_Aguh.end\" attributeName=\"r\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"0;3\" fill=\"freeze\"/>\n </circle>\n <circle cx=\"12\" cy=\"12\" r=\"3\">\n <animate begin=\"0;spinner_z0Or.end\" attributeName=\"cx\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"12;20\" fill=\"freeze\"/>\n <animate id=\"spinner_hSjk\" begin=\"spinner_OLMs.end\" attributeName=\"r\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"3;0\" fill=\"freeze\"/>\n <animate id=\"spinner_UHR2\" begin=\"spinner_hSjk.end\" attributeName=\"cx\" dur=\"0.001s\" values=\"20;4\" fill=\"freeze\"/>\n <animate begin=\"spinner_UHR2.end\" attributeName=\"r\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"0;3\" fill=\"freeze\"/>\n <animate begin=\"spinner_Aguh.end\" attributeName=\"cx\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"4;12\" fill=\"freeze\"/>\n </circle>\n <circle cx=\"20\" cy=\"12\" r=\"3\">\n <animate id=\"spinner_4v5M\" begin=\"0;spinner_z0Or.end\" attributeName=\"r\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"3;0\" fill=\"freeze\"/>\n <animate id=\"spinner_OLMs\" begin=\"spinner_4v5M.end\" attributeName=\"cx\" dur=\"0.001s\" values=\"20;4\" fill=\"freeze\"/>\n <animate begin=\"spinner_OLMs.end\" attributeName=\"r\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"0;3\" fill=\"freeze\"/>\n <animate begin=\"spinner_UHR2.end\" attributeName=\"cx\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"4;12\" fill=\"freeze\"/>\n <animate begin=\"spinner_Aguh.end\" attributeName=\"cx\" calcMode=\"spline\" dur=\"0.5s\" keySplines=\".36,.6,.31,1\" values=\"12;20\" fill=\"freeze\"/>\n </circle>\n </svg>\n @if (message) {\n <div class=\"text-sm text-text-primary text-center\">\n {{ message }}\n </div>\n }\n </div>\n </div>\n}\n" }]
3051
3175
  }], propDecorators: { show: [{
3052
3176
  type: Input
3053
3177
  }], message: [{
3054
3178
  type: Input
3055
3179
  }] } });
3056
3180
 
3181
+ let nextToggleGroupId = 0;
3057
3182
  class RadioButtonToggleComponent extends FxComponent {
3058
3183
  ref;
3184
+ groupId = `fx-radio-toggle-${nextToggleGroupId++}`;
3059
3185
  label;
3060
3186
  required = false;
3061
3187
  options = [];
@@ -3075,12 +3201,12 @@ class RadioButtonToggleComponent extends FxComponent {
3075
3201
  this.onChange(value);
3076
3202
  this.onTouched();
3077
3203
  }
3078
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: RadioButtonToggleComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
3079
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: RadioButtonToggleComponent, isStandalone: false, selector: "fx-ui-radio-toggle, [fx-ui-radio-toggle]", inputs: { label: "label", required: "required", options: "options", errorMessages: "errorMessages", class: "class" }, usesInheritance: true, ngImport: i0, template: "<div class=\"flex flex-col text-left mb-4 w-full\" [class]=\"class\">\n @if(label){<label class=\"txt-field-label\">\n {{ label }}\n @if(required) {<span class=\"txt-required\">*</span>} </label\n >}\n\n <div class=\"inline-flex w-full rounded-lg overflow-hidden\" role=\"radiogroup\">\n @for(opt of options; track opt){<button\n type=\"button\"\n role=\"radio\"\n [attr.aria-checked]=\"value === opt.value\"\n (click)=\"onSelectValue(opt.value)\"\n [disabled]=\"disabled\"\n [class.text-gray-900]=\"value !== opt.value\"\n class=\"flex-1 bg-bg-primary flex items-center pl-normal gap-normal h-10 rounded-md hover:bg-bg-hover transition-all duration-150 disabled:opacity-60 disabled:cursor-not-allowed\"\n >\n <span\n [ngClass]=\"{\n 'radio-checked': value === opt.value,\n 'radio-uncheck': value !== opt.value\n }\"\n class=\"radio-container\"\n >\n @if(value === opt.value) {<span class=\"radio-dot\"></span>}\n </span>\n\n <span class=\"txt-field-label mb-0\">{{ opt.label }}</span></button\n >}\n </div>\n\n @if(invalid){\n <div class=\"txt-invalid\">{{ getErrorMessage(label) }}</div>\n }\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
3204
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: RadioButtonToggleComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
3205
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: RadioButtonToggleComponent, isStandalone: false, selector: "fx-ui-radio-toggle, [fx-ui-radio-toggle]", inputs: { label: "label", required: "required", options: "options", errorMessages: "errorMessages", class: "class" }, usesInheritance: true, ngImport: i0, template: "<div class=\"flex flex-col text-left mb-4 w-full\" [class]=\"class\">\n <!-- A radiogroup has no single control a <label> could point at \u2014 name it via aria-labelledby. -->\n @if(label){<span class=\"txt-field-label\" [id]=\"groupId + '-label'\">\n {{ label }}\n @if(required) {<span class=\"txt-required\" aria-hidden=\"true\">*</span>} </span\n >}\n\n <div\n class=\"inline-flex w-full rounded-lg overflow-hidden\"\n role=\"radiogroup\"\n [attr.aria-labelledby]=\"label ? groupId + '-label' : null\"\n >\n @for(opt of options; track opt){<button\n type=\"button\"\n role=\"radio\"\n [attr.aria-checked]=\"value === opt.value\"\n (click)=\"onSelectValue(opt.value)\"\n [disabled]=\"disabled\"\n [class.text-gray-900]=\"value !== opt.value\"\n class=\"flex-1 bg-bg-primary flex items-center pl-normal gap-normal h-10 rounded-md hover:bg-bg-hover transition-all duration-150 disabled:opacity-60 disabled:cursor-not-allowed\"\n >\n <span\n [ngClass]=\"{\n 'radio-checked': value === opt.value,\n 'radio-uncheck': value !== opt.value\n }\"\n class=\"radio-container\"\n >\n @if(value === opt.value) {<span class=\"radio-dot\"></span>}\n </span>\n\n <span class=\"txt-field-label mb-0\">{{ opt.label }}</span></button\n >}\n </div>\n\n @if(invalid){\n <div class=\"txt-invalid\">{{ getErrorMessage(label) }}</div>\n }\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
3080
3206
  }
3081
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: RadioButtonToggleComponent, decorators: [{
3207
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: RadioButtonToggleComponent, decorators: [{
3082
3208
  type: Component,
3083
- args: [{ selector: 'fx-ui-radio-toggle, [fx-ui-radio-toggle]', standalone: false, template: "<div class=\"flex flex-col text-left mb-4 w-full\" [class]=\"class\">\n @if(label){<label class=\"txt-field-label\">\n {{ label }}\n @if(required) {<span class=\"txt-required\">*</span>} </label\n >}\n\n <div class=\"inline-flex w-full rounded-lg overflow-hidden\" role=\"radiogroup\">\n @for(opt of options; track opt){<button\n type=\"button\"\n role=\"radio\"\n [attr.aria-checked]=\"value === opt.value\"\n (click)=\"onSelectValue(opt.value)\"\n [disabled]=\"disabled\"\n [class.text-gray-900]=\"value !== opt.value\"\n class=\"flex-1 bg-bg-primary flex items-center pl-normal gap-normal h-10 rounded-md hover:bg-bg-hover transition-all duration-150 disabled:opacity-60 disabled:cursor-not-allowed\"\n >\n <span\n [ngClass]=\"{\n 'radio-checked': value === opt.value,\n 'radio-uncheck': value !== opt.value\n }\"\n class=\"radio-container\"\n >\n @if(value === opt.value) {<span class=\"radio-dot\"></span>}\n </span>\n\n <span class=\"txt-field-label mb-0\">{{ opt.label }}</span></button\n >}\n </div>\n\n @if(invalid){\n <div class=\"txt-invalid\">{{ getErrorMessage(label) }}</div>\n }\n</div>\n" }]
3209
+ args: [{ selector: 'fx-ui-radio-toggle, [fx-ui-radio-toggle]', standalone: false, template: "<div class=\"flex flex-col text-left mb-4 w-full\" [class]=\"class\">\n <!-- A radiogroup has no single control a <label> could point at \u2014 name it via aria-labelledby. -->\n @if(label){<span class=\"txt-field-label\" [id]=\"groupId + '-label'\">\n {{ label }}\n @if(required) {<span class=\"txt-required\" aria-hidden=\"true\">*</span>} </span\n >}\n\n <div\n class=\"inline-flex w-full rounded-lg overflow-hidden\"\n role=\"radiogroup\"\n [attr.aria-labelledby]=\"label ? groupId + '-label' : null\"\n >\n @for(opt of options; track opt){<button\n type=\"button\"\n role=\"radio\"\n [attr.aria-checked]=\"value === opt.value\"\n (click)=\"onSelectValue(opt.value)\"\n [disabled]=\"disabled\"\n [class.text-gray-900]=\"value !== opt.value\"\n class=\"flex-1 bg-bg-primary flex items-center pl-normal gap-normal h-10 rounded-md hover:bg-bg-hover transition-all duration-150 disabled:opacity-60 disabled:cursor-not-allowed\"\n >\n <span\n [ngClass]=\"{\n 'radio-checked': value === opt.value,\n 'radio-uncheck': value !== opt.value\n }\"\n class=\"radio-container\"\n >\n @if(value === opt.value) {<span class=\"radio-dot\"></span>}\n </span>\n\n <span class=\"txt-field-label mb-0\">{{ opt.label }}</span></button\n >}\n </div>\n\n @if(invalid){\n <div class=\"txt-invalid\">{{ getErrorMessage(label) }}</div>\n }\n</div>\n" }]
3084
3210
  }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { label: [{
3085
3211
  type: Input
3086
3212
  }], required: [{
@@ -3093,8 +3219,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
3093
3219
  type: Input
3094
3220
  }] } });
3095
3221
 
3222
+ let nextRadioGroupId = 0;
3096
3223
  class RadioButtonComponent extends FxComponent {
3097
3224
  ref;
3225
+ groupId = `fx-radio-${nextRadioGroupId++}`;
3098
3226
  label;
3099
3227
  tooltip = '';
3100
3228
  required = false;
@@ -3115,12 +3243,12 @@ class RadioButtonComponent extends FxComponent {
3115
3243
  this.onChange(value);
3116
3244
  this.onTouched();
3117
3245
  }
3118
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: RadioButtonComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
3119
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: RadioButtonComponent, isStandalone: false, selector: "fx-ui-radio", inputs: { label: "label", tooltip: "tooltip", required: "required", options: "options", errorMessages: "errorMessages", class: "class" }, usesInheritance: true, ngImport: i0, template: "<div class=\"w-full rounded-lg overflow-hidden\" [class]=\"class\" role=\"radiogroup\">\n @if (label) {\n <label class=\"txt-field-label\">\n {{ label }}\n @if (required) {\n <span class=\"txt-required\">*</span>\n }\n @if (tooltip) {\n <fx-ui-hero-icon\n icon=\"information-circle\"\n [size]=\"16\"\n class=\"inline-block align-middle ml-0.5 text-text-secondary cursor-help relative -top-px\"\n [matTooltip]=\"tooltip\"\n matTooltipPosition=\"above\"\n matTooltipClass=\"text-text-primary text-xs font-semibold\"\n ></fx-ui-hero-icon>\n }\n </label>\n }\n\n <button\n *ngFor=\"let opt of options\"\n type=\"button\"\n role=\"radio\"\n [attr.aria-checked]=\"value === opt.value\"\n (click)=\"onSelectValue(opt.value)\"\n [disabled]=\"disabled\"\n [class.text-gray-900]=\"value !== opt.value\"\n class=\"flex-1 px-normal w-full flex items-center gap-normal h-10 rounded-md hover:bg-bg-hover transition-all duration-150 disabled:opacity-60 disabled:cursor-not-allowed\"\n [matTooltip]=\"opt.tooltip || ''\"\n matTooltipPosition=\"right\"\n matTooltipClass=\"text-text-primary text-xs font-semibold\"\n >\n <span\n [ngClass]=\"{\n 'radio-checked': value === opt.value,\n 'radio-uncheck': value !== opt.value,\n }\"\n class=\"radio-container\"\n >\n @if (value === opt.value) {\n <span class=\"radio-dot\"></span>\n }\n </span>\n\n <span class=\"txt-default mb-0\">{{ opt.label }}</span>\n </button>\n @if (invalid) {\n <div class=\"txt-invalid\">\n {{ getErrorMessage(label) }}\n </div>\n }\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i56.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: HeroIconComponent, selector: "fx-ui-hero-icon", inputs: ["stroke", "icon", "solid", "outline", "size", "color", "class"] }] });
3246
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: RadioButtonComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
3247
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: RadioButtonComponent, isStandalone: false, selector: "fx-ui-radio", inputs: { label: "label", tooltip: "tooltip", required: "required", options: "options", errorMessages: "errorMessages", class: "class" }, usesInheritance: true, ngImport: i0, template: "<div\n class=\"w-full rounded-lg overflow-hidden\"\n [class]=\"class\"\n role=\"radiogroup\"\n [attr.aria-labelledby]=\"label ? groupId + '-label' : null\"\n >\n <!-- A radiogroup has no single control a <label> could point at \u2014 name it via aria-labelledby. -->\n @if (label) {\n <span class=\"txt-field-label block\" [id]=\"groupId + '-label'\">\n {{ label }}\n @if (required) {\n <span class=\"txt-required\" aria-hidden=\"true\">*</span>\n }\n @if (tooltip) {\n <fx-ui-hero-icon\n icon=\"information-circle\"\n [size]=\"16\"\n class=\"inline-block align-middle ml-0.5 text-text-secondary cursor-help relative -top-px\"\n [matTooltip]=\"tooltip\"\n matTooltipPosition=\"above\"\n matTooltipClass=\"text-text-primary text-xs font-semibold\"\n ></fx-ui-hero-icon>\n }\n </span>\n }\n\n @for (opt of options; track opt) {\n <button\n type=\"button\"\n role=\"radio\"\n [attr.aria-checked]=\"value === opt.value\"\n (click)=\"onSelectValue(opt.value)\"\n [disabled]=\"disabled\"\n [class.text-gray-900]=\"value !== opt.value\"\n class=\"flex-1 px-normal w-full flex items-center gap-normal h-10 rounded-md hover:bg-bg-hover transition-all duration-150 disabled:opacity-60 disabled:cursor-not-allowed\"\n [matTooltip]=\"opt.tooltip || ''\"\n matTooltipPosition=\"right\"\n matTooltipClass=\"text-text-primary text-xs font-semibold\"\n >\n <span\n [ngClass]=\"{\n 'radio-checked': value === opt.value,\n 'radio-uncheck': value !== opt.value,\n }\"\n class=\"radio-container\"\n >\n @if (value === opt.value) {\n <span class=\"radio-dot\"></span>\n }\n </span>\n <span class=\"txt-default mb-0\">{{ opt.label }}</span>\n </button>\n }\n @if (invalid) {\n <div class=\"txt-invalid\">\n {{ getErrorMessage(label) }}\n </div>\n }\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i57.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: HeroIconComponent, selector: "fx-ui-hero-icon", inputs: ["stroke", "icon", "solid", "outline", "size", "color", "class"] }] });
3120
3248
  }
3121
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: RadioButtonComponent, decorators: [{
3249
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: RadioButtonComponent, decorators: [{
3122
3250
  type: Component,
3123
- args: [{ selector: 'fx-ui-radio', standalone: false, template: "<div class=\"w-full rounded-lg overflow-hidden\" [class]=\"class\" role=\"radiogroup\">\n @if (label) {\n <label class=\"txt-field-label\">\n {{ label }}\n @if (required) {\n <span class=\"txt-required\">*</span>\n }\n @if (tooltip) {\n <fx-ui-hero-icon\n icon=\"information-circle\"\n [size]=\"16\"\n class=\"inline-block align-middle ml-0.5 text-text-secondary cursor-help relative -top-px\"\n [matTooltip]=\"tooltip\"\n matTooltipPosition=\"above\"\n matTooltipClass=\"text-text-primary text-xs font-semibold\"\n ></fx-ui-hero-icon>\n }\n </label>\n }\n\n <button\n *ngFor=\"let opt of options\"\n type=\"button\"\n role=\"radio\"\n [attr.aria-checked]=\"value === opt.value\"\n (click)=\"onSelectValue(opt.value)\"\n [disabled]=\"disabled\"\n [class.text-gray-900]=\"value !== opt.value\"\n class=\"flex-1 px-normal w-full flex items-center gap-normal h-10 rounded-md hover:bg-bg-hover transition-all duration-150 disabled:opacity-60 disabled:cursor-not-allowed\"\n [matTooltip]=\"opt.tooltip || ''\"\n matTooltipPosition=\"right\"\n matTooltipClass=\"text-text-primary text-xs font-semibold\"\n >\n <span\n [ngClass]=\"{\n 'radio-checked': value === opt.value,\n 'radio-uncheck': value !== opt.value,\n }\"\n class=\"radio-container\"\n >\n @if (value === opt.value) {\n <span class=\"radio-dot\"></span>\n }\n </span>\n\n <span class=\"txt-default mb-0\">{{ opt.label }}</span>\n </button>\n @if (invalid) {\n <div class=\"txt-invalid\">\n {{ getErrorMessage(label) }}\n </div>\n }\n</div>\n" }]
3251
+ args: [{ selector: 'fx-ui-radio', standalone: false, template: "<div\n class=\"w-full rounded-lg overflow-hidden\"\n [class]=\"class\"\n role=\"radiogroup\"\n [attr.aria-labelledby]=\"label ? groupId + '-label' : null\"\n >\n <!-- A radiogroup has no single control a <label> could point at \u2014 name it via aria-labelledby. -->\n @if (label) {\n <span class=\"txt-field-label block\" [id]=\"groupId + '-label'\">\n {{ label }}\n @if (required) {\n <span class=\"txt-required\" aria-hidden=\"true\">*</span>\n }\n @if (tooltip) {\n <fx-ui-hero-icon\n icon=\"information-circle\"\n [size]=\"16\"\n class=\"inline-block align-middle ml-0.5 text-text-secondary cursor-help relative -top-px\"\n [matTooltip]=\"tooltip\"\n matTooltipPosition=\"above\"\n matTooltipClass=\"text-text-primary text-xs font-semibold\"\n ></fx-ui-hero-icon>\n }\n </span>\n }\n\n @for (opt of options; track opt) {\n <button\n type=\"button\"\n role=\"radio\"\n [attr.aria-checked]=\"value === opt.value\"\n (click)=\"onSelectValue(opt.value)\"\n [disabled]=\"disabled\"\n [class.text-gray-900]=\"value !== opt.value\"\n class=\"flex-1 px-normal w-full flex items-center gap-normal h-10 rounded-md hover:bg-bg-hover transition-all duration-150 disabled:opacity-60 disabled:cursor-not-allowed\"\n [matTooltip]=\"opt.tooltip || ''\"\n matTooltipPosition=\"right\"\n matTooltipClass=\"text-text-primary text-xs font-semibold\"\n >\n <span\n [ngClass]=\"{\n 'radio-checked': value === opt.value,\n 'radio-uncheck': value !== opt.value,\n }\"\n class=\"radio-container\"\n >\n @if (value === opt.value) {\n <span class=\"radio-dot\"></span>\n }\n </span>\n <span class=\"txt-default mb-0\">{{ opt.label }}</span>\n </button>\n }\n @if (invalid) {\n <div class=\"txt-invalid\">\n {{ getErrorMessage(label) }}\n </div>\n }\n</div>\n" }]
3124
3252
  }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { label: [{
3125
3253
  type: Input
3126
3254
  }], tooltip: [{
@@ -3206,12 +3334,12 @@ class RichTextAreaComponent extends FxComponent {
3206
3334
  this.quillInstance.enable(!isDisabled);
3207
3335
  }
3208
3336
  }
3209
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: RichTextAreaComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: QuillStyleLoaderService }, { token: PLATFORM_ID }], target: i0.ɵɵFactoryTarget.Component });
3210
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.4", type: RichTextAreaComponent, isStandalone: false, selector: "fx-ui-rich-text-area", inputs: { placeholder: "placeholder", toolbarOptions: "toolbarOptions" }, outputs: { contentChange: "contentChange" }, viewQueries: [{ propertyName: "editorContainer", first: true, predicate: ["editorContainer"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"w-full rounded-2xl shadow-sm p-1 bg-bg-primary\">\n <div #editorContainer class=\"min-h-[200px] text-base\"></div>\n</div>", styles: [":host{display:block}.ql-toolbar{border-top-left-radius:.25rem;border-top-right-radius:.25rem;border-bottom-width:1px;--tw-border-opacity: 1;border-color:rgb(var(--border-default) / var(--tw-border-opacity, 1));padding:.5rem}.ql-container{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.ql-editor{min-height:200px;padding:.75rem;font-size:1rem}\n"] });
3337
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: RichTextAreaComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: QuillStyleLoaderService }, { token: PLATFORM_ID }], target: i0.ɵɵFactoryTarget.Component });
3338
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.20", type: RichTextAreaComponent, isStandalone: false, selector: "fx-ui-rich-text-area", inputs: { placeholder: "placeholder", toolbarOptions: "toolbarOptions" }, outputs: { contentChange: "contentChange" }, viewQueries: [{ propertyName: "editorContainer", first: true, predicate: ["editorContainer"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"w-full rounded-2xl shadow-sm p-1 bg-bg-primary\">\n <div #editorContainer class=\"min-h-[200px] text-base\"></div>\n</div>", styles: ["@charset \"UTF-8\";@layer properties;:host{display:block}.ql-toolbar{border-top-left-radius:.25rem;border-top-right-radius:.25rem;border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:rgb(var(--border-default));padding:calc(var(--spacing, .25rem) * 2)}.ql-container{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.ql-editor{min-height:200px;padding:calc(var(--spacing, .25rem) * 3);font-size:1rem;line-height:var(--tw-leading, var(--text-base--line-height, 1.5 ))}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] });
3211
3339
  }
3212
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: RichTextAreaComponent, decorators: [{
3340
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: RichTextAreaComponent, decorators: [{
3213
3341
  type: Component,
3214
- args: [{ selector: 'fx-ui-rich-text-area', standalone: false, template: "<div class=\"w-full rounded-2xl shadow-sm p-1 bg-bg-primary\">\n <div #editorContainer class=\"min-h-[200px] text-base\"></div>\n</div>", styles: [":host{display:block}.ql-toolbar{border-top-left-radius:.25rem;border-top-right-radius:.25rem;border-bottom-width:1px;--tw-border-opacity: 1;border-color:rgb(var(--border-default) / var(--tw-border-opacity, 1));padding:.5rem}.ql-container{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.ql-editor{min-height:200px;padding:.75rem;font-size:1rem}\n"] }]
3342
+ args: [{ selector: 'fx-ui-rich-text-area', standalone: false, template: "<div class=\"w-full rounded-2xl shadow-sm p-1 bg-bg-primary\">\n <div #editorContainer class=\"min-h-[200px] text-base\"></div>\n</div>", styles: ["@charset \"UTF-8\";@layer properties;:host{display:block}.ql-toolbar{border-top-left-radius:.25rem;border-top-right-radius:.25rem;border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:rgb(var(--border-default));padding:calc(var(--spacing, .25rem) * 2)}.ql-container{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.ql-editor{min-height:200px;padding:calc(var(--spacing, .25rem) * 3);font-size:1rem;line-height:var(--tw-leading, var(--text-base--line-height, 1.5 ))}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
3215
3343
  }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: QuillStyleLoaderService }, { type: undefined, decorators: [{
3216
3344
  type: Inject,
3217
3345
  args: [PLATFORM_ID]
@@ -3256,12 +3384,12 @@ class SearchBarComponent extends FxComponent {
3256
3384
  this.valueChange.emit('');
3257
3385
  this.search.emit('');
3258
3386
  }
3259
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: SearchBarComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
3260
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.4", type: SearchBarComponent, isStandalone: false, selector: "fx-ui-search-bar", inputs: { placeholder: "placeholder" }, outputs: { search: "search", valueChange: "valueChange" }, usesInheritance: true, ngImport: i0, template: "<div class=\"relative\">\n <fx-ui-hero-icon icon=\"magnifying-glass\" [size]=\"18\" class=\"absolute left-1 top-[3px] text-text-primary\"></fx-ui-hero-icon>\n <input\n type=\"text\"\n class=\"input-default px-9\"\n [attr.placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n [value]=\"value\"\n (input)=\"onValueChange($any($event.target).value)\"\n (keydown.enter)=\"onEnterKey()\"\n />\n\n <button\n *ngIf=\"value && !disabled\"\n type=\"button\"\n class=\"absolute inset-y-0 right-2 flex items-center text-text-primary hover:text-text-secondary\"\n (click)=\"clear()\"\n aria-label=\"Clear\"\n >\n <i class=\"material-symbols-outlined text-lg select-none\">close</i>\n </button>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: HeroIconComponent, selector: "fx-ui-hero-icon", inputs: ["stroke", "icon", "solid", "outline", "size", "color", "class"] }] });
3387
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: SearchBarComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
3388
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: SearchBarComponent, isStandalone: false, selector: "fx-ui-search-bar", inputs: { placeholder: "placeholder" }, outputs: { search: "search", valueChange: "valueChange" }, usesInheritance: true, ngImport: i0, template: "<div class=\"relative\">\n <fx-ui-hero-icon icon=\"magnifying-glass\" [size]=\"18\" class=\"absolute left-1 top-[3px] text-text-primary\"></fx-ui-hero-icon>\n <input\n type=\"text\"\n class=\"input-default px-9\"\n [attr.placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n [value]=\"value\"\n (input)=\"onValueChange($any($event.target).value)\"\n (keydown.enter)=\"onEnterKey()\"\n />\n\n @if (value && !disabled) {\n <button\n type=\"button\"\n class=\"absolute inset-y-0 right-2 flex items-center text-text-primary hover:text-text-secondary\"\n (click)=\"clear()\"\n aria-label=\"Clear\"\n >\n <i class=\"material-symbols-outlined text-lg select-none\">close</i>\n </button>\n }\n</div>\n", styles: [""], dependencies: [{ kind: "component", type: HeroIconComponent, selector: "fx-ui-hero-icon", inputs: ["stroke", "icon", "solid", "outline", "size", "color", "class"] }] });
3261
3389
  }
3262
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: SearchBarComponent, decorators: [{
3390
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: SearchBarComponent, decorators: [{
3263
3391
  type: Component,
3264
- args: [{ selector: 'fx-ui-search-bar', standalone: false, template: "<div class=\"relative\">\n <fx-ui-hero-icon icon=\"magnifying-glass\" [size]=\"18\" class=\"absolute left-1 top-[3px] text-text-primary\"></fx-ui-hero-icon>\n <input\n type=\"text\"\n class=\"input-default px-9\"\n [attr.placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n [value]=\"value\"\n (input)=\"onValueChange($any($event.target).value)\"\n (keydown.enter)=\"onEnterKey()\"\n />\n\n <button\n *ngIf=\"value && !disabled\"\n type=\"button\"\n class=\"absolute inset-y-0 right-2 flex items-center text-text-primary hover:text-text-secondary\"\n (click)=\"clear()\"\n aria-label=\"Clear\"\n >\n <i class=\"material-symbols-outlined text-lg select-none\">close</i>\n </button>\n</div>\n" }]
3392
+ args: [{ selector: 'fx-ui-search-bar', standalone: false, template: "<div class=\"relative\">\n <fx-ui-hero-icon icon=\"magnifying-glass\" [size]=\"18\" class=\"absolute left-1 top-[3px] text-text-primary\"></fx-ui-hero-icon>\n <input\n type=\"text\"\n class=\"input-default px-9\"\n [attr.placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n [value]=\"value\"\n (input)=\"onValueChange($any($event.target).value)\"\n (keydown.enter)=\"onEnterKey()\"\n />\n\n @if (value && !disabled) {\n <button\n type=\"button\"\n class=\"absolute inset-y-0 right-2 flex items-center text-text-primary hover:text-text-secondary\"\n (click)=\"clear()\"\n aria-label=\"Clear\"\n >\n <i class=\"material-symbols-outlined text-lg select-none\">close</i>\n </button>\n }\n</div>\n" }]
3265
3393
  }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { placeholder: [{
3266
3394
  type: Input
3267
3395
  }], search: [{
@@ -3270,6 +3398,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
3270
3398
  type: Output
3271
3399
  }] } });
3272
3400
 
3401
+ let nextSelectId = 0;
3273
3402
  class SelectComponent extends FxComponent {
3274
3403
  ref;
3275
3404
  label = '';
@@ -3284,6 +3413,7 @@ class SelectComponent extends FxComponent {
3284
3413
  searchFn;
3285
3414
  /** Emits the current value when the select panel closes (useful for multiple mode). */
3286
3415
  closed = new EventEmitter();
3416
+ fieldId = `fx-select-${nextSelectId++}`;
3287
3417
  searchTerm = '';
3288
3418
  filteredOptions = [];
3289
3419
  search$ = new Subject();
@@ -3350,12 +3480,12 @@ class SelectComponent extends FxComponent {
3350
3480
  }
3351
3481
  return this.value === value;
3352
3482
  }
3353
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: SelectComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
3354
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: SelectComponent, isStandalone: false, selector: "fx-ui-select", inputs: { label: "label", tooltip: "tooltip", placeholder: "placeholder", options: "options", multiple: "multiple", errorMessages: "errorMessages", required: "required", class: "class", enableSearch: "enableSearch", searchFn: "searchFn" }, outputs: { closed: "closed" }, usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<div class=\"mb-4 text-left w-full\" [class]=\"class\">\n @if (label) {\n <label class=\"block txt-field-label\">\n {{ label }}\n @if (required) {\n <span class=\"txt-required\">*</span>\n }\n @if (tooltip) {\n <fx-ui-hero-icon\n icon=\"information-circle\"\n [size]=\"16\"\n class=\"inline-block align-middle ml-0.5 text-text-secondary cursor-help relative -top-px\"\n [matTooltip]=\"tooltip\"\n matTooltipPosition=\"above\"\n matTooltipClass=\"text-text-primary text-xs font-semibold\"\n ></fx-ui-hero-icon>\n }\n </label>\n }\n\n <mat-form-field\n [attr.invalid]=\"invalid || null\"\n class=\"fx-select-field w-full shadow-sm\"\n appearance=\"fill\"\n >\n <mat-select\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n [multiple]=\"multiple\"\n [value]=\"value\"\n (selectionChange)=\"onSelectionChange($event.value)\"\n (openedChange)=\"onOpened($event)\"\n (blur)=\"onTouched()\"\n >\n @if (enableSearch) {\n <div class=\"px-semi w-full\">\n <input\n type=\"text\"\n [placeholder]=\"'Search'\"\n [(ngModel)]=\"searchTerm\"\n (ngModelChange)=\"onSearchChange($event)\"\n (click)=\"$event.stopPropagation()\"\n class=\"text-text-primary placeholder:text-text-placeholder w-full bg-bg-primary border-b px-semi py-normal border-border-default focus:outline-none focus:border-gradient-primary-start text-sm text-text-primary tracking-normal ring-0 transition-colors duration-500 ease-in-out\"\n />\n </div>\n }\n <mat-option *ngFor=\"let option of filteredOptions\" [value]=\"option.value\">\n <span class=\"txt-default\">{{ option.label }}</span>\n </mat-option>\n </mat-select>\n </mat-form-field>\n\n @if (invalid) {\n <div class=\"txt-invalid text-left\">\n {{ getErrorMessage(label) }}\n </div>\n }\n</div>\n", styles: ["::ng-deep .fx-select-field{display:block!important;width:100%!important;margin:0!important;padding:0!important;border-radius:.75rem;box-shadow:0 1px 1px rgb(var(--border-default))}::ng-deep .fx-select-field .mat-mdc-form-field-wrapper,::ng-deep .fx-select-field .mat-mdc-text-field-wrapper{padding:0!important;margin:0!important;width:100%!important}::ng-deep .fx-select-field .mdc-text-field{width:100%!important;margin:0!important;padding:0!important;--mdc-shape-small: 0 !important}::ng-deep .fx-select-field .mat-mdc-form-field-flex{width:100%!important;margin:0!important;padding:0 .75rem!important;border:1px solid rgb(var(--border-default));border-radius:.375rem;height:36px!important;align-items:center;background-color:rgb(var(--bg-primary))}::ng-deep .fx-select-field .mdc-notched-outline,::ng-deep .fx-select-field .mat-mdc-form-field-subscript-wrapper{display:none!important}::ng-deep .fx-select-field.mat-focused .mat-mdc-form-field-flex{border:2px solid rgb(var(--gradient-primary-start))!important;outline:none!important;border-radius:.375rem}::ng-deep .fx-select-field.mat-form-field-invalid .mat-mdc-form-field-flex{border:1px solid rgb(var(--bg-error-bold))!important;box-shadow:none!important}::ng-deep mat-form-field[invalid] .mat-mdc-form-field-flex{border:1px solid rgb(var(--bg-error-bold))!important;box-shadow:none!important}::ng-deep .fx-select-field .mat-mdc-select-trigger{padding:0!important;margin:0!important}::ng-deep .fx-select-field .mat-mdc-select-arrow-wrapper{margin-right:0!important}::ng-deep .fx-select-field .mat-mdc-select-arrow-wrapper .mat-mdc-select-arrow svg{display:none!important}::ng-deep .fx-select-field .mat-mdc-select-arrow-wrapper .mat-mdc-select-arrow{width:8px!important;height:8px!important;border-style:solid;border-color:currentColor;border-width:0 1.5px 1.5px 0;transform:rotate(45deg);margin-top:-3px;color:rgb(var(--text-secondary))!important}::ng-deep .mat-mdc-select-panel{background-color:rgb(var(--bg-primary))!important;border:1px solid rgb(var(--border-default))!important;border-radius:.375rem!important;box-shadow:0 2px 4px #0000001a!important}::ng-deep .fx-select-field .mat-mdc-select-placeholder{color:rgb(var(--text-placeholder))!important;font-size:14px}::ng-deep .fx-select-field .mat-mdc-select-value{color:rgb(var(--text-primary))!important;font-size:14px;font-weight:400}.mat-select-panel .search-option-full-width{padding-left:0!important;padding-right:0!important;display:block;pointer-events:none;line-height:initial;height:auto}.mat-select-panel .search-option-full-width .search-bar{width:100%;padding:8px 16px;border:none;border-bottom:1px solid #ddd;box-sizing:border-box}::ng-deep .fx-select-field.mat-form-field-disabled .mat-mdc-form-field-flex,::ng-deep .fx-select-field:has(.mat-mdc-select-disabled) .mat-mdc-form-field-flex{background-color:rgb(var(--bg-primary-hover))!important;border-color:rgb(var(--border-default))!important;cursor:not-allowed!important;opacity:.6;box-shadow:none!important}::ng-deep .fx-select-field.mat-form-field-disabled .mat-mdc-select-value,::ng-deep .fx-select-field.mat-form-field-disabled .mat-mdc-select-placeholder,::ng-deep .fx-select-field.mat-form-field-disabled .mat-mdc-select-arrow,::ng-deep .fx-select-field:has(.mat-mdc-select-disabled) .mat-mdc-select-value,::ng-deep .fx-select-field:has(.mat-mdc-select-disabled) .mat-mdc-select-placeholder,::ng-deep .fx-select-field:has(.mat-mdc-select-disabled) .mat-mdc-select-arrow{color:rgb(var(--text-placeholder))!important}::ng-deep .fx-select-field.mat-form-field-disabled .mat-mdc-select,::ng-deep .fx-select-field:has(.mat-mdc-select-disabled) .mat-mdc-select{cursor:not-allowed!important}\n"], dependencies: [{ kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "component", type: i3.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i3.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: i56.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: HeroIconComponent, selector: "fx-ui-hero-icon", inputs: ["stroke", "icon", "solid", "outline", "size", "color", "class"] }] });
3483
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: SelectComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
3484
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: SelectComponent, isStandalone: false, selector: "fx-ui-select", inputs: { label: "label", tooltip: "tooltip", placeholder: "placeholder", options: "options", multiple: "multiple", errorMessages: "errorMessages", required: "required", class: "class", enableSearch: "enableSearch", searchFn: "searchFn" }, outputs: { closed: "closed" }, usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<div class=\"mb-4 text-left w-full\" [class]=\"class\">\n @if (label) {\n <label class=\"block txt-field-label\" [attr.for]=\"fieldId\">\n {{ label }}\n @if (required) {\n <span class=\"txt-required\" aria-hidden=\"true\">*</span>\n }\n @if (tooltip) {\n <fx-ui-hero-icon\n icon=\"information-circle\"\n [size]=\"16\"\n class=\"inline-block align-middle ml-0.5 text-text-secondary cursor-help relative -top-px\"\n [matTooltip]=\"tooltip\"\n matTooltipPosition=\"above\"\n matTooltipClass=\"text-text-primary text-xs font-semibold\"\n ></fx-ui-hero-icon>\n }\n </label>\n }\n\n <mat-form-field\n [attr.invalid]=\"invalid || null\"\n class=\"fx-select-field w-full shadow-sm\"\n appearance=\"fill\"\n >\n <mat-select\n [id]=\"fieldId\"\n [required]=\"!!required\"\n [attr.aria-invalid]=\"invalid || null\"\n [attr.aria-describedby]=\"invalid ? fieldId + '-error' : null\"\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n [multiple]=\"multiple\"\n [value]=\"value\"\n (selectionChange)=\"onSelectionChange($event.value)\"\n (openedChange)=\"onOpened($event)\"\n (blur)=\"onTouched()\"\n >\n @if (enableSearch) {\n <div class=\"px-semi w-full\">\n <input\n type=\"text\"\n aria-label=\"Search\"\n [placeholder]=\"'Search'\"\n [(ngModel)]=\"searchTerm\"\n (ngModelChange)=\"onSearchChange($event)\"\n (click)=\"$event.stopPropagation()\"\n class=\"text-text-primary placeholder:text-text-placeholder w-full bg-bg-primary border-b px-semi py-normal border-border-default focus:outline-none focus:border-gradient-primary-start focus-visible:ring-2 focus-visible:ring-primary/50 text-sm text-text-primary tracking-normal ring-0 transition-colors duration-500 ease-in-out\"\n />\n </div>\n }\n @for (option of filteredOptions; track option) {\n <mat-option [value]=\"option.value\">\n <span class=\"txt-default\">{{ option.label }}</span>\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n\n @if (invalid) {\n <div class=\"txt-invalid text-left\" role=\"alert\" [id]=\"fieldId + '-error'\">\n {{ getErrorMessage(label) }}\n </div>\n }\n</div>\n", styles: ["::ng-deep .fx-select-field{display:block!important;width:100%!important;margin:0!important;padding:0!important;border-radius:.75rem;box-shadow:0 1px 1px rgb(var(--border-default))}::ng-deep .fx-select-field .mat-mdc-form-field-wrapper,::ng-deep .fx-select-field .mat-mdc-text-field-wrapper{padding:0!important;margin:0!important;width:100%!important}::ng-deep .fx-select-field .mdc-text-field{width:100%!important;margin:0!important;padding:0!important;--mdc-shape-small: 0 !important}::ng-deep .fx-select-field .mat-mdc-form-field-flex{width:100%!important;margin:0!important;padding:0 .75rem!important;border:1px solid rgb(var(--border-default));border-radius:.375rem;height:36px!important;align-items:center;background-color:rgb(var(--bg-primary))}::ng-deep .fx-select-field .mdc-notched-outline,::ng-deep .fx-select-field .mat-mdc-form-field-subscript-wrapper{display:none!important}::ng-deep .fx-select-field.mat-focused .mat-mdc-form-field-flex{border:2px solid rgb(var(--gradient-primary-start))!important;outline:none!important;border-radius:.375rem}::ng-deep .fx-select-field.mat-form-field-invalid .mat-mdc-form-field-flex{border:1px solid rgb(var(--bg-error-bold))!important;box-shadow:none!important}::ng-deep mat-form-field[invalid] .mat-mdc-form-field-flex{border:1px solid rgb(var(--bg-error-bold))!important;box-shadow:none!important}::ng-deep .fx-select-field .mat-mdc-select-trigger{padding:0!important;margin:0!important}::ng-deep .fx-select-field .mat-mdc-select-arrow-wrapper{margin-right:0!important}::ng-deep .fx-select-field .mat-mdc-select-arrow-wrapper .mat-mdc-select-arrow svg{display:none!important}::ng-deep .fx-select-field .mat-mdc-select-arrow-wrapper .mat-mdc-select-arrow{width:8px!important;height:8px!important;border-style:solid;border-color:currentColor;border-width:0 1.5px 1.5px 0;transform:rotate(45deg);margin-top:-3px;color:rgb(var(--text-secondary))!important}::ng-deep .mat-mdc-select-panel{background-color:rgb(var(--bg-primary))!important;border:1px solid rgb(var(--border-default))!important;border-radius:.375rem!important;box-shadow:0 2px 4px #0000001a!important}::ng-deep .fx-select-field .mat-mdc-select-placeholder{color:rgb(var(--text-placeholder))!important;font-size:14px}::ng-deep .fx-select-field .mat-mdc-select-value{color:rgb(var(--text-primary))!important;font-size:14px;font-weight:400}.mat-select-panel .search-option-full-width{padding-left:0!important;padding-right:0!important;display:block;pointer-events:none;line-height:initial;height:auto}.mat-select-panel .search-option-full-width .search-bar{width:100%;padding:8px 16px;border:none;border-bottom:1px solid #ddd;box-sizing:border-box}::ng-deep .fx-select-field.mat-form-field-disabled .mat-mdc-form-field-flex,::ng-deep .fx-select-field:has(.mat-mdc-select-disabled) .mat-mdc-form-field-flex{background-color:rgb(var(--bg-primary-hover))!important;border-color:rgb(var(--border-default))!important;cursor:not-allowed!important;opacity:.6;box-shadow:none!important}::ng-deep .fx-select-field.mat-form-field-disabled .mat-mdc-select-value,::ng-deep .fx-select-field.mat-form-field-disabled .mat-mdc-select-placeholder,::ng-deep .fx-select-field.mat-form-field-disabled .mat-mdc-select-arrow,::ng-deep .fx-select-field:has(.mat-mdc-select-disabled) .mat-mdc-select-value,::ng-deep .fx-select-field:has(.mat-mdc-select-disabled) .mat-mdc-select-placeholder,::ng-deep .fx-select-field:has(.mat-mdc-select-disabled) .mat-mdc-select-arrow{color:rgb(var(--text-placeholder))!important}::ng-deep .fx-select-field.mat-form-field-disabled .mat-mdc-select,::ng-deep .fx-select-field:has(.mat-mdc-select-disabled) .mat-mdc-select{cursor:not-allowed!important}\n"], dependencies: [{ kind: "directive", type: i1$4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i2$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "component", type: i2$1.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i2$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "directive", type: i57.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: HeroIconComponent, selector: "fx-ui-hero-icon", inputs: ["stroke", "icon", "solid", "outline", "size", "color", "class"] }] });
3355
3485
  }
3356
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: SelectComponent, decorators: [{
3486
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: SelectComponent, decorators: [{
3357
3487
  type: Component,
3358
- args: [{ selector: 'fx-ui-select', standalone: false, template: "<div class=\"mb-4 text-left w-full\" [class]=\"class\">\n @if (label) {\n <label class=\"block txt-field-label\">\n {{ label }}\n @if (required) {\n <span class=\"txt-required\">*</span>\n }\n @if (tooltip) {\n <fx-ui-hero-icon\n icon=\"information-circle\"\n [size]=\"16\"\n class=\"inline-block align-middle ml-0.5 text-text-secondary cursor-help relative -top-px\"\n [matTooltip]=\"tooltip\"\n matTooltipPosition=\"above\"\n matTooltipClass=\"text-text-primary text-xs font-semibold\"\n ></fx-ui-hero-icon>\n }\n </label>\n }\n\n <mat-form-field\n [attr.invalid]=\"invalid || null\"\n class=\"fx-select-field w-full shadow-sm\"\n appearance=\"fill\"\n >\n <mat-select\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n [multiple]=\"multiple\"\n [value]=\"value\"\n (selectionChange)=\"onSelectionChange($event.value)\"\n (openedChange)=\"onOpened($event)\"\n (blur)=\"onTouched()\"\n >\n @if (enableSearch) {\n <div class=\"px-semi w-full\">\n <input\n type=\"text\"\n [placeholder]=\"'Search'\"\n [(ngModel)]=\"searchTerm\"\n (ngModelChange)=\"onSearchChange($event)\"\n (click)=\"$event.stopPropagation()\"\n class=\"text-text-primary placeholder:text-text-placeholder w-full bg-bg-primary border-b px-semi py-normal border-border-default focus:outline-none focus:border-gradient-primary-start text-sm text-text-primary tracking-normal ring-0 transition-colors duration-500 ease-in-out\"\n />\n </div>\n }\n <mat-option *ngFor=\"let option of filteredOptions\" [value]=\"option.value\">\n <span class=\"txt-default\">{{ option.label }}</span>\n </mat-option>\n </mat-select>\n </mat-form-field>\n\n @if (invalid) {\n <div class=\"txt-invalid text-left\">\n {{ getErrorMessage(label) }}\n </div>\n }\n</div>\n", styles: ["::ng-deep .fx-select-field{display:block!important;width:100%!important;margin:0!important;padding:0!important;border-radius:.75rem;box-shadow:0 1px 1px rgb(var(--border-default))}::ng-deep .fx-select-field .mat-mdc-form-field-wrapper,::ng-deep .fx-select-field .mat-mdc-text-field-wrapper{padding:0!important;margin:0!important;width:100%!important}::ng-deep .fx-select-field .mdc-text-field{width:100%!important;margin:0!important;padding:0!important;--mdc-shape-small: 0 !important}::ng-deep .fx-select-field .mat-mdc-form-field-flex{width:100%!important;margin:0!important;padding:0 .75rem!important;border:1px solid rgb(var(--border-default));border-radius:.375rem;height:36px!important;align-items:center;background-color:rgb(var(--bg-primary))}::ng-deep .fx-select-field .mdc-notched-outline,::ng-deep .fx-select-field .mat-mdc-form-field-subscript-wrapper{display:none!important}::ng-deep .fx-select-field.mat-focused .mat-mdc-form-field-flex{border:2px solid rgb(var(--gradient-primary-start))!important;outline:none!important;border-radius:.375rem}::ng-deep .fx-select-field.mat-form-field-invalid .mat-mdc-form-field-flex{border:1px solid rgb(var(--bg-error-bold))!important;box-shadow:none!important}::ng-deep mat-form-field[invalid] .mat-mdc-form-field-flex{border:1px solid rgb(var(--bg-error-bold))!important;box-shadow:none!important}::ng-deep .fx-select-field .mat-mdc-select-trigger{padding:0!important;margin:0!important}::ng-deep .fx-select-field .mat-mdc-select-arrow-wrapper{margin-right:0!important}::ng-deep .fx-select-field .mat-mdc-select-arrow-wrapper .mat-mdc-select-arrow svg{display:none!important}::ng-deep .fx-select-field .mat-mdc-select-arrow-wrapper .mat-mdc-select-arrow{width:8px!important;height:8px!important;border-style:solid;border-color:currentColor;border-width:0 1.5px 1.5px 0;transform:rotate(45deg);margin-top:-3px;color:rgb(var(--text-secondary))!important}::ng-deep .mat-mdc-select-panel{background-color:rgb(var(--bg-primary))!important;border:1px solid rgb(var(--border-default))!important;border-radius:.375rem!important;box-shadow:0 2px 4px #0000001a!important}::ng-deep .fx-select-field .mat-mdc-select-placeholder{color:rgb(var(--text-placeholder))!important;font-size:14px}::ng-deep .fx-select-field .mat-mdc-select-value{color:rgb(var(--text-primary))!important;font-size:14px;font-weight:400}.mat-select-panel .search-option-full-width{padding-left:0!important;padding-right:0!important;display:block;pointer-events:none;line-height:initial;height:auto}.mat-select-panel .search-option-full-width .search-bar{width:100%;padding:8px 16px;border:none;border-bottom:1px solid #ddd;box-sizing:border-box}::ng-deep .fx-select-field.mat-form-field-disabled .mat-mdc-form-field-flex,::ng-deep .fx-select-field:has(.mat-mdc-select-disabled) .mat-mdc-form-field-flex{background-color:rgb(var(--bg-primary-hover))!important;border-color:rgb(var(--border-default))!important;cursor:not-allowed!important;opacity:.6;box-shadow:none!important}::ng-deep .fx-select-field.mat-form-field-disabled .mat-mdc-select-value,::ng-deep .fx-select-field.mat-form-field-disabled .mat-mdc-select-placeholder,::ng-deep .fx-select-field.mat-form-field-disabled .mat-mdc-select-arrow,::ng-deep .fx-select-field:has(.mat-mdc-select-disabled) .mat-mdc-select-value,::ng-deep .fx-select-field:has(.mat-mdc-select-disabled) .mat-mdc-select-placeholder,::ng-deep .fx-select-field:has(.mat-mdc-select-disabled) .mat-mdc-select-arrow{color:rgb(var(--text-placeholder))!important}::ng-deep .fx-select-field.mat-form-field-disabled .mat-mdc-select,::ng-deep .fx-select-field:has(.mat-mdc-select-disabled) .mat-mdc-select{cursor:not-allowed!important}\n"] }]
3488
+ args: [{ selector: 'fx-ui-select', standalone: false, template: "<div class=\"mb-4 text-left w-full\" [class]=\"class\">\n @if (label) {\n <label class=\"block txt-field-label\" [attr.for]=\"fieldId\">\n {{ label }}\n @if (required) {\n <span class=\"txt-required\" aria-hidden=\"true\">*</span>\n }\n @if (tooltip) {\n <fx-ui-hero-icon\n icon=\"information-circle\"\n [size]=\"16\"\n class=\"inline-block align-middle ml-0.5 text-text-secondary cursor-help relative -top-px\"\n [matTooltip]=\"tooltip\"\n matTooltipPosition=\"above\"\n matTooltipClass=\"text-text-primary text-xs font-semibold\"\n ></fx-ui-hero-icon>\n }\n </label>\n }\n\n <mat-form-field\n [attr.invalid]=\"invalid || null\"\n class=\"fx-select-field w-full shadow-sm\"\n appearance=\"fill\"\n >\n <mat-select\n [id]=\"fieldId\"\n [required]=\"!!required\"\n [attr.aria-invalid]=\"invalid || null\"\n [attr.aria-describedby]=\"invalid ? fieldId + '-error' : null\"\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n [multiple]=\"multiple\"\n [value]=\"value\"\n (selectionChange)=\"onSelectionChange($event.value)\"\n (openedChange)=\"onOpened($event)\"\n (blur)=\"onTouched()\"\n >\n @if (enableSearch) {\n <div class=\"px-semi w-full\">\n <input\n type=\"text\"\n aria-label=\"Search\"\n [placeholder]=\"'Search'\"\n [(ngModel)]=\"searchTerm\"\n (ngModelChange)=\"onSearchChange($event)\"\n (click)=\"$event.stopPropagation()\"\n class=\"text-text-primary placeholder:text-text-placeholder w-full bg-bg-primary border-b px-semi py-normal border-border-default focus:outline-none focus:border-gradient-primary-start focus-visible:ring-2 focus-visible:ring-primary/50 text-sm text-text-primary tracking-normal ring-0 transition-colors duration-500 ease-in-out\"\n />\n </div>\n }\n @for (option of filteredOptions; track option) {\n <mat-option [value]=\"option.value\">\n <span class=\"txt-default\">{{ option.label }}</span>\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n\n @if (invalid) {\n <div class=\"txt-invalid text-left\" role=\"alert\" [id]=\"fieldId + '-error'\">\n {{ getErrorMessage(label) }}\n </div>\n }\n</div>\n", styles: ["::ng-deep .fx-select-field{display:block!important;width:100%!important;margin:0!important;padding:0!important;border-radius:.75rem;box-shadow:0 1px 1px rgb(var(--border-default))}::ng-deep .fx-select-field .mat-mdc-form-field-wrapper,::ng-deep .fx-select-field .mat-mdc-text-field-wrapper{padding:0!important;margin:0!important;width:100%!important}::ng-deep .fx-select-field .mdc-text-field{width:100%!important;margin:0!important;padding:0!important;--mdc-shape-small: 0 !important}::ng-deep .fx-select-field .mat-mdc-form-field-flex{width:100%!important;margin:0!important;padding:0 .75rem!important;border:1px solid rgb(var(--border-default));border-radius:.375rem;height:36px!important;align-items:center;background-color:rgb(var(--bg-primary))}::ng-deep .fx-select-field .mdc-notched-outline,::ng-deep .fx-select-field .mat-mdc-form-field-subscript-wrapper{display:none!important}::ng-deep .fx-select-field.mat-focused .mat-mdc-form-field-flex{border:2px solid rgb(var(--gradient-primary-start))!important;outline:none!important;border-radius:.375rem}::ng-deep .fx-select-field.mat-form-field-invalid .mat-mdc-form-field-flex{border:1px solid rgb(var(--bg-error-bold))!important;box-shadow:none!important}::ng-deep mat-form-field[invalid] .mat-mdc-form-field-flex{border:1px solid rgb(var(--bg-error-bold))!important;box-shadow:none!important}::ng-deep .fx-select-field .mat-mdc-select-trigger{padding:0!important;margin:0!important}::ng-deep .fx-select-field .mat-mdc-select-arrow-wrapper{margin-right:0!important}::ng-deep .fx-select-field .mat-mdc-select-arrow-wrapper .mat-mdc-select-arrow svg{display:none!important}::ng-deep .fx-select-field .mat-mdc-select-arrow-wrapper .mat-mdc-select-arrow{width:8px!important;height:8px!important;border-style:solid;border-color:currentColor;border-width:0 1.5px 1.5px 0;transform:rotate(45deg);margin-top:-3px;color:rgb(var(--text-secondary))!important}::ng-deep .mat-mdc-select-panel{background-color:rgb(var(--bg-primary))!important;border:1px solid rgb(var(--border-default))!important;border-radius:.375rem!important;box-shadow:0 2px 4px #0000001a!important}::ng-deep .fx-select-field .mat-mdc-select-placeholder{color:rgb(var(--text-placeholder))!important;font-size:14px}::ng-deep .fx-select-field .mat-mdc-select-value{color:rgb(var(--text-primary))!important;font-size:14px;font-weight:400}.mat-select-panel .search-option-full-width{padding-left:0!important;padding-right:0!important;display:block;pointer-events:none;line-height:initial;height:auto}.mat-select-panel .search-option-full-width .search-bar{width:100%;padding:8px 16px;border:none;border-bottom:1px solid #ddd;box-sizing:border-box}::ng-deep .fx-select-field.mat-form-field-disabled .mat-mdc-form-field-flex,::ng-deep .fx-select-field:has(.mat-mdc-select-disabled) .mat-mdc-form-field-flex{background-color:rgb(var(--bg-primary-hover))!important;border-color:rgb(var(--border-default))!important;cursor:not-allowed!important;opacity:.6;box-shadow:none!important}::ng-deep .fx-select-field.mat-form-field-disabled .mat-mdc-select-value,::ng-deep .fx-select-field.mat-form-field-disabled .mat-mdc-select-placeholder,::ng-deep .fx-select-field.mat-form-field-disabled .mat-mdc-select-arrow,::ng-deep .fx-select-field:has(.mat-mdc-select-disabled) .mat-mdc-select-value,::ng-deep .fx-select-field:has(.mat-mdc-select-disabled) .mat-mdc-select-placeholder,::ng-deep .fx-select-field:has(.mat-mdc-select-disabled) .mat-mdc-select-arrow{color:rgb(var(--text-placeholder))!important}::ng-deep .fx-select-field.mat-form-field-disabled .mat-mdc-select,::ng-deep .fx-select-field:has(.mat-mdc-select-disabled) .mat-mdc-select{cursor:not-allowed!important}\n"] }]
3359
3489
  }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { label: [{
3360
3490
  type: Input
3361
3491
  }], tooltip: [{
@@ -3383,10 +3513,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
3383
3513
  class SkeletonTableLoadingComponent {
3384
3514
  columns = 5;
3385
3515
  rows = 5;
3386
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: SkeletonTableLoadingComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3387
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: SkeletonTableLoadingComponent, isStandalone: false, selector: "fx-ui-skeleton-table-loading", inputs: { columns: "columns", rows: "rows" }, ngImport: i0, template: "<div class=\"w-full animate-pulse space-y-normal\">\n <div\n class=\"grid gap-small\"\n [ngStyle]=\"{ 'grid-template-columns': 'repeat(' + columns + ', minmax(0, 1fr))' }\"\n >\n @for(col of [].constructor(columns); track col) {\n <div class=\"h-6 bg-bg-hover rounded\"></div>\n }\n </div>\n\n @for(row of [].constructor(rows); track row) {\n <div\n class=\"grid gap-small\"\n [ngStyle]=\"{ 'grid-template-columns': 'repeat(' + columns + ', minmax(0, 1fr))' }\"\n >\n @for(col of [].constructor(columns); track col) {\n <div class=\"h-7 bg-bg-hover rounded\"></div>\n }\n </div>\n }\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] });
3516
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: SkeletonTableLoadingComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3517
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: SkeletonTableLoadingComponent, isStandalone: false, selector: "fx-ui-skeleton-table-loading", inputs: { columns: "columns", rows: "rows" }, ngImport: i0, template: "<div class=\"w-full animate-pulse space-y-normal\">\n <div\n class=\"grid gap-small\"\n [ngStyle]=\"{ 'grid-template-columns': 'repeat(' + columns + ', minmax(0, 1fr))' }\"\n >\n @for(col of [].constructor(columns); track col) {\n <div class=\"h-6 bg-bg-hover rounded\"></div>\n }\n </div>\n\n @for(row of [].constructor(rows); track row) {\n <div\n class=\"grid gap-small\"\n [ngStyle]=\"{ 'grid-template-columns': 'repeat(' + columns + ', minmax(0, 1fr))' }\"\n >\n @for(col of [].constructor(columns); track col) {\n <div class=\"h-7 bg-bg-hover rounded\"></div>\n }\n </div>\n }\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] });
3388
3518
  }
3389
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: SkeletonTableLoadingComponent, decorators: [{
3519
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: SkeletonTableLoadingComponent, decorators: [{
3390
3520
  type: Component,
3391
3521
  args: [{ selector: 'fx-ui-skeleton-table-loading', standalone: false, template: "<div class=\"w-full animate-pulse space-y-normal\">\n <div\n class=\"grid gap-small\"\n [ngStyle]=\"{ 'grid-template-columns': 'repeat(' + columns + ', minmax(0, 1fr))' }\"\n >\n @for(col of [].constructor(columns); track col) {\n <div class=\"h-6 bg-bg-hover rounded\"></div>\n }\n </div>\n\n @for(row of [].constructor(rows); track row) {\n <div\n class=\"grid gap-small\"\n [ngStyle]=\"{ 'grid-template-columns': 'repeat(' + columns + ', minmax(0, 1fr))' }\"\n >\n @for(col of [].constructor(columns); track col) {\n <div class=\"h-7 bg-bg-hover rounded\"></div>\n }\n </div>\n }\n</div>\n" }]
3392
3522
  }], propDecorators: { columns: [{
@@ -3522,12 +3652,12 @@ class SliderComponent extends FxComponent {
3522
3652
  ? { bottom: `${this.percent}%`, transform: 'translateY(50%)' }
3523
3653
  : { left: `${this.percent}%`, transform: 'translateX(-50%)' };
3524
3654
  }
3525
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: SliderComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
3526
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.4", type: SliderComponent, isStandalone: false, selector: "fx-ui-slider", inputs: { min: "min", max: "max", step: "step", vertical: "vertical" }, outputs: { valueChange: "valueChange" }, host: { listeners: { "keydown": "onKeydown($event)" } }, viewQueries: [{ propertyName: "trackRef", first: true, predicate: ["track"], descendants: true, static: true }, { propertyName: "thumbRef", first: true, predicate: ["thumb"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<div\n class=\"w-full select-none\"\n [class.cursor-not-allowed]=\"disabled\"\n [class.opacity-60]=\"disabled\"\n role=\"group\"\n>\n <div\n #track\n class=\"relative touch-none py-4\"\n (click)=\"onTrackClick($event)\"\n [attr.aria-disabled]=\"disabled\"\n [attr.aria-orientation]=\"vertical ? 'vertical' : 'horizontal'\"\n >\n <div\n class=\"relative flex items-center\"\n [ngClass]=\"{ 'flex-col h-48': vertical }\"\n >\n <div\n class=\"relative flex-1 rounded-full bg-gray-600 h-2\"\n [ngClass]=\"{ 'w-1 rotate-0 h-full w-auto bg-border-gray-700': vertical }\"\n >\n <div\n class=\"absolute left-0 top-0 h-full rounded-full bg-primary\"\n *ngIf=\"!vertical\"\n [style.width.%]=\"percent\"\n ></div>\n\n <div\n class=\"absolute bottom-0 left-0 w-full rounded-full bg-primary\"\n *ngIf=\"vertical\"\n [style.height.%]=\"percent\"\n style=\"transform-origin: bottom;\"\n ></div>\n\n <button\n #thumb\n type=\"button\"\n class=\"absolute -mt-1 -ml-1.5 w-4 h-4 rounded-full shadow focus:ring-primary bg-primary border-2 border-text-primary\"\n [ngStyle]=\"thumbStyle()\"\n role=\"slider\"\n [attr.aria-valuemin]=\"min\"\n [attr.aria-valuemax]=\"max\"\n [attr.aria-valuenow]=\"value\"\n [attr.aria-disabled]=\"disabled\"\n tabindex=\"0\"\n (pointerdown)=\"onPointerDown($event)\"\n (pointermove)=\"onPointerMove($event)\"\n (pointerup)=\"onPointerUp($event)\"\n [disabled]=\"disabled\"\n ></button>\n </div>\n </div>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] });
3655
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: SliderComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
3656
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: SliderComponent, isStandalone: false, selector: "fx-ui-slider", inputs: { min: "min", max: "max", step: "step", vertical: "vertical" }, outputs: { valueChange: "valueChange" }, host: { listeners: { "keydown": "onKeydown($event)" } }, viewQueries: [{ propertyName: "trackRef", first: true, predicate: ["track"], descendants: true, static: true }, { propertyName: "thumbRef", first: true, predicate: ["thumb"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<div\n class=\"w-full select-none\"\n [class.cursor-not-allowed]=\"disabled\"\n [class.opacity-60]=\"disabled\"\n role=\"group\"\n >\n <!-- Track click is a pointer shortcut; the thumb button below owns keyboard/focus. -->\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <div\n #track\n class=\"relative touch-none py-4\"\n (click)=\"onTrackClick($event)\"\n [attr.aria-disabled]=\"disabled\"\n [attr.aria-orientation]=\"vertical ? 'vertical' : 'horizontal'\"\n >\n <div\n class=\"relative flex items-center\"\n [ngClass]=\"{ 'flex-col h-48': vertical }\"\n >\n <div\n class=\"relative flex-1 rounded-full bg-gray-600 h-2\"\n [ngClass]=\"{ 'w-1 rotate-0 h-full w-auto bg-border-gray-700': vertical }\"\n >\n @if (!vertical) {\n <div\n class=\"absolute left-0 top-0 h-full rounded-full bg-primary\"\n [style.width.%]=\"percent\"\n ></div>\n }\n\n @if (vertical) {\n <div\n class=\"absolute bottom-0 left-0 w-full rounded-full bg-primary\"\n [style.height.%]=\"percent\"\n style=\"transform-origin: bottom;\"\n ></div>\n }\n\n <button\n #thumb\n type=\"button\"\n class=\"absolute -mt-1 -ml-1.5 w-4 h-4 rounded-full shadow focus:ring-primary bg-primary border-2 border-text-primary\"\n [ngStyle]=\"thumbStyle()\"\n role=\"slider\"\n aria-label=\"Slider\"\n [attr.aria-valuemin]=\"min\"\n [attr.aria-valuemax]=\"max\"\n [attr.aria-valuenow]=\"value\"\n [attr.aria-disabled]=\"disabled\"\n tabindex=\"0\"\n (pointerdown)=\"onPointerDown($event)\"\n (pointermove)=\"onPointerMove($event)\"\n (pointerup)=\"onPointerUp($event)\"\n [disabled]=\"disabled\"\n ></button>\n </div>\n </div>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] });
3527
3657
  }
3528
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: SliderComponent, decorators: [{
3658
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: SliderComponent, decorators: [{
3529
3659
  type: Component,
3530
- args: [{ selector: 'fx-ui-slider', standalone: false, template: "<div\n class=\"w-full select-none\"\n [class.cursor-not-allowed]=\"disabled\"\n [class.opacity-60]=\"disabled\"\n role=\"group\"\n>\n <div\n #track\n class=\"relative touch-none py-4\"\n (click)=\"onTrackClick($event)\"\n [attr.aria-disabled]=\"disabled\"\n [attr.aria-orientation]=\"vertical ? 'vertical' : 'horizontal'\"\n >\n <div\n class=\"relative flex items-center\"\n [ngClass]=\"{ 'flex-col h-48': vertical }\"\n >\n <div\n class=\"relative flex-1 rounded-full bg-gray-600 h-2\"\n [ngClass]=\"{ 'w-1 rotate-0 h-full w-auto bg-border-gray-700': vertical }\"\n >\n <div\n class=\"absolute left-0 top-0 h-full rounded-full bg-primary\"\n *ngIf=\"!vertical\"\n [style.width.%]=\"percent\"\n ></div>\n\n <div\n class=\"absolute bottom-0 left-0 w-full rounded-full bg-primary\"\n *ngIf=\"vertical\"\n [style.height.%]=\"percent\"\n style=\"transform-origin: bottom;\"\n ></div>\n\n <button\n #thumb\n type=\"button\"\n class=\"absolute -mt-1 -ml-1.5 w-4 h-4 rounded-full shadow focus:ring-primary bg-primary border-2 border-text-primary\"\n [ngStyle]=\"thumbStyle()\"\n role=\"slider\"\n [attr.aria-valuemin]=\"min\"\n [attr.aria-valuemax]=\"max\"\n [attr.aria-valuenow]=\"value\"\n [attr.aria-disabled]=\"disabled\"\n tabindex=\"0\"\n (pointerdown)=\"onPointerDown($event)\"\n (pointermove)=\"onPointerMove($event)\"\n (pointerup)=\"onPointerUp($event)\"\n [disabled]=\"disabled\"\n ></button>\n </div>\n </div>\n </div>\n</div>\n" }]
3660
+ args: [{ selector: 'fx-ui-slider', standalone: false, template: "<div\n class=\"w-full select-none\"\n [class.cursor-not-allowed]=\"disabled\"\n [class.opacity-60]=\"disabled\"\n role=\"group\"\n >\n <!-- Track click is a pointer shortcut; the thumb button below owns keyboard/focus. -->\n <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->\n <div\n #track\n class=\"relative touch-none py-4\"\n (click)=\"onTrackClick($event)\"\n [attr.aria-disabled]=\"disabled\"\n [attr.aria-orientation]=\"vertical ? 'vertical' : 'horizontal'\"\n >\n <div\n class=\"relative flex items-center\"\n [ngClass]=\"{ 'flex-col h-48': vertical }\"\n >\n <div\n class=\"relative flex-1 rounded-full bg-gray-600 h-2\"\n [ngClass]=\"{ 'w-1 rotate-0 h-full w-auto bg-border-gray-700': vertical }\"\n >\n @if (!vertical) {\n <div\n class=\"absolute left-0 top-0 h-full rounded-full bg-primary\"\n [style.width.%]=\"percent\"\n ></div>\n }\n\n @if (vertical) {\n <div\n class=\"absolute bottom-0 left-0 w-full rounded-full bg-primary\"\n [style.height.%]=\"percent\"\n style=\"transform-origin: bottom;\"\n ></div>\n }\n\n <button\n #thumb\n type=\"button\"\n class=\"absolute -mt-1 -ml-1.5 w-4 h-4 rounded-full shadow focus:ring-primary bg-primary border-2 border-text-primary\"\n [ngStyle]=\"thumbStyle()\"\n role=\"slider\"\n aria-label=\"Slider\"\n [attr.aria-valuemin]=\"min\"\n [attr.aria-valuemax]=\"max\"\n [attr.aria-valuenow]=\"value\"\n [attr.aria-disabled]=\"disabled\"\n tabindex=\"0\"\n (pointerdown)=\"onPointerDown($event)\"\n (pointermove)=\"onPointerMove($event)\"\n (pointerup)=\"onPointerUp($event)\"\n [disabled]=\"disabled\"\n ></button>\n </div>\n </div>\n </div>\n</div>\n" }]
3531
3661
  }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { trackRef: [{
3532
3662
  type: ViewChild,
3533
3663
  args: ['track', { static: true }]
@@ -3552,6 +3682,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
3552
3682
  class SwitchComponent extends FxComponent {
3553
3683
  cdr;
3554
3684
  onSwitch = new EventEmitter();
3685
+ /** Accessible name — the switch renders no visible text of its own. */
3686
+ ariaLabel = '';
3555
3687
  ngAfterViewInit() {
3556
3688
  this.cdr.detectChanges();
3557
3689
  }
@@ -3570,24 +3702,26 @@ class SwitchComponent extends FxComponent {
3570
3702
  this.onChange(this.value);
3571
3703
  this.onTouched();
3572
3704
  }
3573
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: SwitchComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
3574
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: SwitchComponent, isStandalone: false, selector: "fx-ui-switch", outputs: { onSwitch: "onSwitch" }, usesInheritance: true, ngImport: i0, template: "<div\n class=\"relative flex items-center w-10 h-5 rounded-full transition-colors duration-300 cursor-pointer\"\n [ngClass]=\"{\n 'bg-success': value && !disabled,\n 'bg-button-default': !value && !disabled,\n 'bg-bg-hover': disabled\n }\"\n (click)=\"toggle()\"\n>\n @if(value) {\n <i style=\"font-size: 20px;\" class=\"material-symbols-outlined absolute left-0.5 top-0 text-text-inverse\">check</i>\n \n }\n @if(!value) {\n <i style=\"font-size: 20px;\" class=\"material-symbols-outlined absolute right-0.5 top-0 text-text-inverse\">close</i>\n }\n <div\n class=\"absolute top-0.5 left-0.5 w-4 h-4 bg-text-inverse rounded-full shadow-md transform transition-transform duration-300\"\n [ngClass]=\"{ 'translate-x-5': value }\"\n ></div>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
3705
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: SwitchComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
3706
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: SwitchComponent, isStandalone: false, selector: "fx-ui-switch", inputs: { ariaLabel: "ariaLabel" }, outputs: { onSwitch: "onSwitch" }, usesInheritance: true, ngImport: i0, template: "<button\n type=\"button\"\n role=\"switch\"\n [attr.aria-checked]=\"!!value\"\n [attr.aria-label]=\"ariaLabel || null\"\n [disabled]=\"disabled\"\n class=\"relative flex items-center w-10 h-5 rounded-full transition-colors duration-300 cursor-pointer disabled:cursor-not-allowed focus-visible:ring-2 focus-visible:ring-primary/50\"\n [ngClass]=\"{\n 'bg-success': value && !disabled,\n 'bg-button-default': !value && !disabled,\n 'bg-bg-hover': disabled\n }\"\n (click)=\"toggle()\"\n>\n @if(value) {\n <i style=\"font-size: 20px;\" class=\"material-symbols-outlined absolute left-0.5 top-0 text-text-inverse\" aria-hidden=\"true\">check</i>\n\n }\n @if(!value) {\n <i style=\"font-size: 20px;\" class=\"material-symbols-outlined absolute right-0.5 top-0 text-text-inverse\" aria-hidden=\"true\">close</i>\n }\n <div\n class=\"absolute top-0.5 left-0.5 w-4 h-4 bg-text-inverse rounded-full shadow-md transform transition-transform duration-300\"\n [ngClass]=\"{ 'translate-x-5': value }\"\n ></div>\n</button>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
3575
3707
  }
3576
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: SwitchComponent, decorators: [{
3708
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: SwitchComponent, decorators: [{
3577
3709
  type: Component,
3578
- args: [{ selector: 'fx-ui-switch', standalone: false, template: "<div\n class=\"relative flex items-center w-10 h-5 rounded-full transition-colors duration-300 cursor-pointer\"\n [ngClass]=\"{\n 'bg-success': value && !disabled,\n 'bg-button-default': !value && !disabled,\n 'bg-bg-hover': disabled\n }\"\n (click)=\"toggle()\"\n>\n @if(value) {\n <i style=\"font-size: 20px;\" class=\"material-symbols-outlined absolute left-0.5 top-0 text-text-inverse\">check</i>\n \n }\n @if(!value) {\n <i style=\"font-size: 20px;\" class=\"material-symbols-outlined absolute right-0.5 top-0 text-text-inverse\">close</i>\n }\n <div\n class=\"absolute top-0.5 left-0.5 w-4 h-4 bg-text-inverse rounded-full shadow-md transform transition-transform duration-300\"\n [ngClass]=\"{ 'translate-x-5': value }\"\n ></div>\n</div>\n" }]
3710
+ args: [{ selector: 'fx-ui-switch', standalone: false, template: "<button\n type=\"button\"\n role=\"switch\"\n [attr.aria-checked]=\"!!value\"\n [attr.aria-label]=\"ariaLabel || null\"\n [disabled]=\"disabled\"\n class=\"relative flex items-center w-10 h-5 rounded-full transition-colors duration-300 cursor-pointer disabled:cursor-not-allowed focus-visible:ring-2 focus-visible:ring-primary/50\"\n [ngClass]=\"{\n 'bg-success': value && !disabled,\n 'bg-button-default': !value && !disabled,\n 'bg-bg-hover': disabled\n }\"\n (click)=\"toggle()\"\n>\n @if(value) {\n <i style=\"font-size: 20px;\" class=\"material-symbols-outlined absolute left-0.5 top-0 text-text-inverse\" aria-hidden=\"true\">check</i>\n\n }\n @if(!value) {\n <i style=\"font-size: 20px;\" class=\"material-symbols-outlined absolute right-0.5 top-0 text-text-inverse\" aria-hidden=\"true\">close</i>\n }\n <div\n class=\"absolute top-0.5 left-0.5 w-4 h-4 bg-text-inverse rounded-full shadow-md transform transition-transform duration-300\"\n [ngClass]=\"{ 'translate-x-5': value }\"\n ></div>\n</button>\n" }]
3579
3711
  }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }], propDecorators: { onSwitch: [{
3580
3712
  type: Output
3713
+ }], ariaLabel: [{
3714
+ type: Input
3581
3715
  }] } });
3582
3716
 
3583
3717
  class TabComponent {
3584
3718
  label;
3585
3719
  icon;
3586
3720
  content;
3587
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: TabComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3588
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.4", type: TabComponent, isStandalone: false, selector: "fx-ui-tab", inputs: { label: "label", icon: "icon" }, viewQueries: [{ propertyName: "content", first: true, predicate: TemplateRef, descendants: true, static: true }], ngImport: i0, template: "<ng-template><ng-content></ng-content></ng-template>\n" });
3721
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: TabComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3722
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.20", type: TabComponent, isStandalone: false, selector: "fx-ui-tab", inputs: { label: "label", icon: "icon" }, viewQueries: [{ propertyName: "content", first: true, predicate: TemplateRef, descendants: true, static: true }], ngImport: i0, template: "<ng-template><ng-content></ng-content></ng-template>\n" });
3589
3723
  }
3590
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: TabComponent, decorators: [{
3724
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: TabComponent, decorators: [{
3591
3725
  type: Component,
3592
3726
  args: [{ selector: 'fx-ui-tab', standalone: false, template: "<ng-template><ng-content></ng-content></ng-template>\n" }]
3593
3727
  }], propDecorators: { label: [{
@@ -3624,6 +3758,33 @@ class TabGroupComponent {
3624
3758
  this.activeIndex = index;
3625
3759
  this.scrollToActiveTab(true);
3626
3760
  }
3761
+ /** Roving tablist keyboard nav: arrows move AND activate (selection follows focus). */
3762
+ onTabKeydown(event, index) {
3763
+ const count = this.tabs.length;
3764
+ if (!count)
3765
+ return;
3766
+ let next;
3767
+ switch (event.key) {
3768
+ case 'ArrowRight':
3769
+ next = (index + 1) % count;
3770
+ break;
3771
+ case 'ArrowLeft':
3772
+ next = (index - 1 + count) % count;
3773
+ break;
3774
+ case 'Home':
3775
+ next = 0;
3776
+ break;
3777
+ case 'End':
3778
+ next = count - 1;
3779
+ break;
3780
+ default:
3781
+ return;
3782
+ }
3783
+ event.preventDefault();
3784
+ this.selectTab(next);
3785
+ const buttons = this.tabListRef.nativeElement.querySelectorAll('.tab-btn');
3786
+ buttons[next]?.focus();
3787
+ }
3627
3788
  updateUnderlinePosition() {
3628
3789
  const tabListEl = this.tabListRef.nativeElement;
3629
3790
  const underlineEl = this.underlineRef.nativeElement;
@@ -3683,12 +3844,12 @@ class TabGroupComponent {
3683
3844
  onResize() {
3684
3845
  this.updateUnderlinePosition();
3685
3846
  }
3686
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: TabGroupComponent, deps: [{ token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
3687
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: TabGroupComponent, isStandalone: false, selector: "fx-ui-tab-group", inputs: { activeIndex: "activeIndex" }, host: { listeners: { "window:resize": "onResize()" } }, queries: [{ propertyName: "tabs", predicate: TabComponent }], viewQueries: [{ propertyName: "tabListRef", first: true, predicate: ["tabList"], descendants: true, static: true }, { propertyName: "underlineRef", first: true, predicate: ["underline"], descendants: true, static: true }], ngImport: i0, template: "<div class=\"relative\">\n <!-- Left scroll button -->\n <button\n class=\"left-scroll-button\"\n type=\"button\"\n (click)=\"scroll('left')\"\n [style.opacity]=\"canScrollLeft ? 1 : 0\"\n [style.pointerEvents]=\"canScrollLeft ? 'auto' : 'none'\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n class=\"h-5 w-5 text-text-primary\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15 19l-7-7 7-7\" />\n </svg>\n </button>\n\n <div\n #tabList\n class=\"relative flex overflow-x-auto no-scrollbar scroll-smooth\"\n (scroll)=\"onScroll()\"\n >\n <button\n *ngFor=\"let tab of tabs.toArray(); let i = index\"\n (click)=\"selectTab(i)\"\n class=\"tab-btn tab-bar-btn\"\n >\n <div class=\"flex flex-row items-center justify-center\">\n @if (tab.icon) {\n <fx-ui-hero-icon\n [icon]=\"tab.icon\"\n [size]=\"20\"\n class=\"flex mr-[2px]\"\n [ngClass]=\"{\n 'text-gradient-primary-start mb-small': i === activeIndex,\n 'text-text-placeholder': i !== activeIndex,\n }\"\n ></fx-ui-hero-icon>\n }\n <div\n [ngClass]=\"\n i === activeIndex ? 'txt-field-label text-gradient-primary-start' : 'txt-placeholder'\n \"\n >\n {{ tab.label }}\n </div>\n </div>\n </button>\n\n <span #underline class=\"underline\" style=\"width: 0; transform: translateX(0)\"></span>\n </div>\n\n <button\n class=\"right-scroll-button\"\n type=\"button\"\n (click)=\"scroll('right')\"\n [style.opacity]=\"canScrollRight ? 1 : 0\"\n [style.pointerEvents]=\"canScrollRight ? 'auto' : 'none'\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n class=\"h-5 w-5 text-text-primary\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 5l7 7-7 7\" />\n </svg>\n </button>\n</div>\n\n<!-- Tab content -->\n<div class=\"transition-all duration-300 ease-in-out mt-4\">\n <ng-container *ngFor=\"let tab of tabs.toArray(); let i = index\">\n <div *ngIf=\"i === activeIndex\" class=\"animate-fadeIn\">\n <ng-container *ngTemplateOutlet=\"tab.content\"></ng-container>\n </div>\n </ng-container>\n</div>\n", styles: ["@keyframes fadeIn{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}.animate-fadeIn{animation:fadeIn .28s ease-in-out}.no-scrollbar::-webkit-scrollbar{display:none}.no-scrollbar{-ms-overflow-style:none;scrollbar-width:none}.underline{position:absolute;bottom:0;height:2px;background-color:rgb(var(--gradient-primary-start));transition:transform .25s cubic-bezier(.2,.9,.2,1),width .25s cubic-bezier(.2,.9,.2,1);will-change:transform,width;transform:translate(0);width:0;margin-left:32px;margin-right:32px}.left-scroll-button{position:absolute;left:0;top:0;z-index:10;display:flex;height:100%;align-items:center;--tw-bg-opacity: 1;background-color:rgb(var(--bg-primary) / var(--tw-bg-opacity, 1));padding-left:.5rem;padding-right:.5rem;transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s}.right-scroll-button{position:absolute;right:0;top:0;z-index:10;display:flex;height:100%;align-items:center;--tw-bg-opacity: 1;background-color:rgb(var(--bg-primary) / var(--tw-bg-opacity, 1));padding-left:.5rem;padding-right:.5rem;transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s}.tab-bar-btn{position:relative;white-space:nowrap;padding:.5rem 1rem;font-size:.875rem;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s}\n"], dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: HeroIconComponent, selector: "fx-ui-hero-icon", inputs: ["stroke", "icon", "solid", "outline", "size", "color", "class"] }] });
3847
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: TabGroupComponent, deps: [{ token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
3848
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: TabGroupComponent, isStandalone: false, selector: "fx-ui-tab-group", inputs: { activeIndex: "activeIndex" }, host: { listeners: { "window:resize": "onResize()" } }, queries: [{ propertyName: "tabs", predicate: TabComponent }], viewQueries: [{ propertyName: "tabListRef", first: true, predicate: ["tabList"], descendants: true, static: true }, { propertyName: "underlineRef", first: true, predicate: ["underline"], descendants: true, static: true }], ngImport: i0, template: "<div class=\"relative\">\n <!-- Left scroll button -->\n <button\n class=\"left-scroll-button\"\n type=\"button\"\n aria-label=\"Scroll tabs left\"\n (click)=\"scroll('left')\"\n [style.opacity]=\"canScrollLeft ? 1 : 0\"\n [style.pointerEvents]=\"canScrollLeft ? 'auto' : 'none'\"\n [attr.tabindex]=\"canScrollLeft ? null : -1\"\n [attr.aria-hidden]=\"!canScrollLeft\"\n >\n <svg\n aria-hidden=\"true\"\n xmlns=\"http://www.w3.org/2000/svg\"\n class=\"h-5 w-5 text-text-primary\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15 19l-7-7 7-7\" />\n </svg>\n </button>\n\n <div\n #tabList\n role=\"tablist\"\n class=\"relative flex overflow-x-auto no-scrollbar scroll-smooth\"\n (scroll)=\"onScroll()\"\n >\n @for (tab of tabs.toArray(); track tab; let i = $index) {\n <button\n type=\"button\"\n role=\"tab\"\n [attr.aria-selected]=\"i === activeIndex\"\n [tabindex]=\"i === activeIndex ? 0 : -1\"\n (click)=\"selectTab(i)\"\n (keydown)=\"onTabKeydown($event, i)\"\n class=\"tab-btn tab-bar-btn\"\n >\n <div class=\"flex flex-row items-center justify-center\">\n @if (tab.icon) {\n <fx-ui-hero-icon\n [icon]=\"tab.icon\"\n [size]=\"20\"\n class=\"flex mr-[2px]\"\n [ngClass]=\"{\n 'text-gradient-primary-start mb-small': i === activeIndex,\n 'text-text-placeholder': i !== activeIndex,\n }\"\n ></fx-ui-hero-icon>\n }\n <div\n [ngClass]=\"\n i === activeIndex ? 'txt-field-label text-gradient-primary-start' : 'txt-placeholder'\n \"\n >\n {{ tab.label }}\n </div>\n </div>\n </button>\n }\n\n <span #underline class=\"underline\" style=\"width: 0; transform: translateX(0)\"></span>\n </div>\n\n <button\n class=\"right-scroll-button\"\n type=\"button\"\n aria-label=\"Scroll tabs right\"\n (click)=\"scroll('right')\"\n [style.opacity]=\"canScrollRight ? 1 : 0\"\n [style.pointerEvents]=\"canScrollRight ? 'auto' : 'none'\"\n [attr.tabindex]=\"canScrollRight ? null : -1\"\n [attr.aria-hidden]=\"!canScrollRight\"\n >\n <svg\n aria-hidden=\"true\"\n xmlns=\"http://www.w3.org/2000/svg\"\n class=\"h-5 w-5 text-text-primary\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 5l7 7-7 7\" />\n </svg>\n </button>\n</div>\n\n<!-- Tab content -->\n<div class=\"transition-all duration-300 ease-in-out mt-4\">\n @for (tab of tabs.toArray(); track tab; let i = $index) {\n @if (i === activeIndex) {\n <div role=\"tabpanel\" class=\"animate-fadeIn\">\n <ng-container *ngTemplateOutlet=\"tab.content\"></ng-container>\n </div>\n }\n }\n</div>\n", styles: ["@charset \"UTF-8\";@layer properties;@keyframes fadeIn{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}.animate-fadeIn{animation:fadeIn .28s ease-in-out}.no-scrollbar::-webkit-scrollbar{display:none}.no-scrollbar{-ms-overflow-style:none;scrollbar-width:none}.underline{position:absolute;bottom:0;height:2px;background-color:rgb(var(--gradient-primary-start));transition:transform .25s cubic-bezier(.2,.9,.2,1),width .25s cubic-bezier(.2,.9,.2,1);will-change:transform,width;transform:translate(0);width:0;margin-left:32px;margin-right:32px}.left-scroll-button{position:absolute;top:0;left:0;z-index:10;display:flex;height:100%;align-items:center;background-color:rgb(var(--bg-primary));padding-inline:.5rem;transition-property:opacity;transition-timing-function:var(--tw-ease, var(--default-transition-timing-function, cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration, var(--default-transition-duration, .15s));--tw-duration: .2s;transition-duration:.2s}.right-scroll-button{position:absolute;top:0;right:0;z-index:10;display:flex;height:100%;align-items:center;background-color:rgb(var(--bg-primary));padding-inline:.5rem;transition-property:opacity;transition-timing-function:var(--tw-ease, var(--default-transition-timing-function, cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration, var(--default-transition-duration, .15s));--tw-duration: .2s;transition-duration:.2s}.tab-bar-btn{position:relative;padding-inline:1rem;padding-block:.5rem;font-size:.875rem;line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));white-space:nowrap;transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease, var(--default-transition-timing-function, cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration, var(--default-transition-duration, .15s));--tw-duration: .2s;transition-duration:.2s}@property --tw-duration{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-duration: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: HeroIconComponent, selector: "fx-ui-hero-icon", inputs: ["stroke", "icon", "solid", "outline", "size", "color", "class"] }] });
3688
3849
  }
3689
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: TabGroupComponent, decorators: [{
3850
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: TabGroupComponent, decorators: [{
3690
3851
  type: Component,
3691
- args: [{ selector: 'fx-ui-tab-group', standalone: false, template: "<div class=\"relative\">\n <!-- Left scroll button -->\n <button\n class=\"left-scroll-button\"\n type=\"button\"\n (click)=\"scroll('left')\"\n [style.opacity]=\"canScrollLeft ? 1 : 0\"\n [style.pointerEvents]=\"canScrollLeft ? 'auto' : 'none'\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n class=\"h-5 w-5 text-text-primary\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15 19l-7-7 7-7\" />\n </svg>\n </button>\n\n <div\n #tabList\n class=\"relative flex overflow-x-auto no-scrollbar scroll-smooth\"\n (scroll)=\"onScroll()\"\n >\n <button\n *ngFor=\"let tab of tabs.toArray(); let i = index\"\n (click)=\"selectTab(i)\"\n class=\"tab-btn tab-bar-btn\"\n >\n <div class=\"flex flex-row items-center justify-center\">\n @if (tab.icon) {\n <fx-ui-hero-icon\n [icon]=\"tab.icon\"\n [size]=\"20\"\n class=\"flex mr-[2px]\"\n [ngClass]=\"{\n 'text-gradient-primary-start mb-small': i === activeIndex,\n 'text-text-placeholder': i !== activeIndex,\n }\"\n ></fx-ui-hero-icon>\n }\n <div\n [ngClass]=\"\n i === activeIndex ? 'txt-field-label text-gradient-primary-start' : 'txt-placeholder'\n \"\n >\n {{ tab.label }}\n </div>\n </div>\n </button>\n\n <span #underline class=\"underline\" style=\"width: 0; transform: translateX(0)\"></span>\n </div>\n\n <button\n class=\"right-scroll-button\"\n type=\"button\"\n (click)=\"scroll('right')\"\n [style.opacity]=\"canScrollRight ? 1 : 0\"\n [style.pointerEvents]=\"canScrollRight ? 'auto' : 'none'\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n class=\"h-5 w-5 text-text-primary\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 5l7 7-7 7\" />\n </svg>\n </button>\n</div>\n\n<!-- Tab content -->\n<div class=\"transition-all duration-300 ease-in-out mt-4\">\n <ng-container *ngFor=\"let tab of tabs.toArray(); let i = index\">\n <div *ngIf=\"i === activeIndex\" class=\"animate-fadeIn\">\n <ng-container *ngTemplateOutlet=\"tab.content\"></ng-container>\n </div>\n </ng-container>\n</div>\n", styles: ["@keyframes fadeIn{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}.animate-fadeIn{animation:fadeIn .28s ease-in-out}.no-scrollbar::-webkit-scrollbar{display:none}.no-scrollbar{-ms-overflow-style:none;scrollbar-width:none}.underline{position:absolute;bottom:0;height:2px;background-color:rgb(var(--gradient-primary-start));transition:transform .25s cubic-bezier(.2,.9,.2,1),width .25s cubic-bezier(.2,.9,.2,1);will-change:transform,width;transform:translate(0);width:0;margin-left:32px;margin-right:32px}.left-scroll-button{position:absolute;left:0;top:0;z-index:10;display:flex;height:100%;align-items:center;--tw-bg-opacity: 1;background-color:rgb(var(--bg-primary) / var(--tw-bg-opacity, 1));padding-left:.5rem;padding-right:.5rem;transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s}.right-scroll-button{position:absolute;right:0;top:0;z-index:10;display:flex;height:100%;align-items:center;--tw-bg-opacity: 1;background-color:rgb(var(--bg-primary) / var(--tw-bg-opacity, 1));padding-left:.5rem;padding-right:.5rem;transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s}.tab-bar-btn{position:relative;white-space:nowrap;padding:.5rem 1rem;font-size:.875rem;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s}\n"] }]
3852
+ args: [{ selector: 'fx-ui-tab-group', standalone: false, template: "<div class=\"relative\">\n <!-- Left scroll button -->\n <button\n class=\"left-scroll-button\"\n type=\"button\"\n aria-label=\"Scroll tabs left\"\n (click)=\"scroll('left')\"\n [style.opacity]=\"canScrollLeft ? 1 : 0\"\n [style.pointerEvents]=\"canScrollLeft ? 'auto' : 'none'\"\n [attr.tabindex]=\"canScrollLeft ? null : -1\"\n [attr.aria-hidden]=\"!canScrollLeft\"\n >\n <svg\n aria-hidden=\"true\"\n xmlns=\"http://www.w3.org/2000/svg\"\n class=\"h-5 w-5 text-text-primary\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15 19l-7-7 7-7\" />\n </svg>\n </button>\n\n <div\n #tabList\n role=\"tablist\"\n class=\"relative flex overflow-x-auto no-scrollbar scroll-smooth\"\n (scroll)=\"onScroll()\"\n >\n @for (tab of tabs.toArray(); track tab; let i = $index) {\n <button\n type=\"button\"\n role=\"tab\"\n [attr.aria-selected]=\"i === activeIndex\"\n [tabindex]=\"i === activeIndex ? 0 : -1\"\n (click)=\"selectTab(i)\"\n (keydown)=\"onTabKeydown($event, i)\"\n class=\"tab-btn tab-bar-btn\"\n >\n <div class=\"flex flex-row items-center justify-center\">\n @if (tab.icon) {\n <fx-ui-hero-icon\n [icon]=\"tab.icon\"\n [size]=\"20\"\n class=\"flex mr-[2px]\"\n [ngClass]=\"{\n 'text-gradient-primary-start mb-small': i === activeIndex,\n 'text-text-placeholder': i !== activeIndex,\n }\"\n ></fx-ui-hero-icon>\n }\n <div\n [ngClass]=\"\n i === activeIndex ? 'txt-field-label text-gradient-primary-start' : 'txt-placeholder'\n \"\n >\n {{ tab.label }}\n </div>\n </div>\n </button>\n }\n\n <span #underline class=\"underline\" style=\"width: 0; transform: translateX(0)\"></span>\n </div>\n\n <button\n class=\"right-scroll-button\"\n type=\"button\"\n aria-label=\"Scroll tabs right\"\n (click)=\"scroll('right')\"\n [style.opacity]=\"canScrollRight ? 1 : 0\"\n [style.pointerEvents]=\"canScrollRight ? 'auto' : 'none'\"\n [attr.tabindex]=\"canScrollRight ? null : -1\"\n [attr.aria-hidden]=\"!canScrollRight\"\n >\n <svg\n aria-hidden=\"true\"\n xmlns=\"http://www.w3.org/2000/svg\"\n class=\"h-5 w-5 text-text-primary\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 5l7 7-7 7\" />\n </svg>\n </button>\n</div>\n\n<!-- Tab content -->\n<div class=\"transition-all duration-300 ease-in-out mt-4\">\n @for (tab of tabs.toArray(); track tab; let i = $index) {\n @if (i === activeIndex) {\n <div role=\"tabpanel\" class=\"animate-fadeIn\">\n <ng-container *ngTemplateOutlet=\"tab.content\"></ng-container>\n </div>\n }\n }\n</div>\n", styles: ["@charset \"UTF-8\";@layer properties;@keyframes fadeIn{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}.animate-fadeIn{animation:fadeIn .28s ease-in-out}.no-scrollbar::-webkit-scrollbar{display:none}.no-scrollbar{-ms-overflow-style:none;scrollbar-width:none}.underline{position:absolute;bottom:0;height:2px;background-color:rgb(var(--gradient-primary-start));transition:transform .25s cubic-bezier(.2,.9,.2,1),width .25s cubic-bezier(.2,.9,.2,1);will-change:transform,width;transform:translate(0);width:0;margin-left:32px;margin-right:32px}.left-scroll-button{position:absolute;top:0;left:0;z-index:10;display:flex;height:100%;align-items:center;background-color:rgb(var(--bg-primary));padding-inline:.5rem;transition-property:opacity;transition-timing-function:var(--tw-ease, var(--default-transition-timing-function, cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration, var(--default-transition-duration, .15s));--tw-duration: .2s;transition-duration:.2s}.right-scroll-button{position:absolute;top:0;right:0;z-index:10;display:flex;height:100%;align-items:center;background-color:rgb(var(--bg-primary));padding-inline:.5rem;transition-property:opacity;transition-timing-function:var(--tw-ease, var(--default-transition-timing-function, cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration, var(--default-transition-duration, .15s));--tw-duration: .2s;transition-duration:.2s}.tab-bar-btn{position:relative;padding-inline:1rem;padding-block:.5rem;font-size:.875rem;line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));white-space:nowrap;transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease, var(--default-transition-timing-function, cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration, var(--default-transition-duration, .15s));--tw-duration: .2s;transition-duration:.2s}@property --tw-duration{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-duration: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
3692
3853
  }], ctorParameters: () => [{ type: i0.Renderer2 }], propDecorators: { tabs: [{
3693
3854
  type: ContentChildren,
3694
3855
  args: [TabComponent]
@@ -3708,10 +3869,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
3708
3869
  class TableCell {
3709
3870
  loading;
3710
3871
  skeletonClass = 'h-4 w-full';
3711
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: TableCell, deps: [], target: i0.ɵɵFactoryTarget.Component });
3712
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: TableCell, isStandalone: false, selector: "fx-ui-table-cell", inputs: { loading: "loading", skeletonClass: "skeletonClass" }, ngImport: i0, template: "@if (!loading) {\n <div animate.enter=\"fade-in-animation\" class=\"inline-block my-normal\">\n <ng-content />\n </div>\n} @else {\n <div animate.enter=\"fade-in-animation\" class=\"skeleton-load my-semi\" [class]=\"skeletonClass\"></div>\n}\n", styles: [""] });
3872
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: TableCell, deps: [], target: i0.ɵɵFactoryTarget.Component });
3873
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: TableCell, isStandalone: false, selector: "fx-ui-table-cell", inputs: { loading: "loading", skeletonClass: "skeletonClass" }, ngImport: i0, template: "@if (!loading) {\n <div animate.enter=\"fade-in-animation\" class=\"inline-block my-normal\">\n <ng-content />\n </div>\n} @else {\n <div animate.enter=\"fade-in-animation\" class=\"skeleton-load my-semi\" [class]=\"skeletonClass\"></div>\n}\n", styles: [""] });
3713
3874
  }
3714
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: TableCell, decorators: [{
3875
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: TableCell, decorators: [{
3715
3876
  type: Component,
3716
3877
  args: [{ selector: 'fx-ui-table-cell', standalone: false, template: "@if (!loading) {\n <div animate.enter=\"fade-in-animation\" class=\"inline-block my-normal\">\n <ng-content />\n </div>\n} @else {\n <div animate.enter=\"fade-in-animation\" class=\"skeleton-load my-semi\" [class]=\"skeletonClass\"></div>\n}\n" }]
3717
3878
  }], propDecorators: { loading: [{
@@ -3731,12 +3892,12 @@ class TagComponent {
3731
3892
  onClick() {
3732
3893
  this.clicked.emit();
3733
3894
  }
3734
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: TagComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3735
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: TagComponent, isStandalone: false, selector: "fx-ui-tag", inputs: { label: "label", type: "type", rounded: "rounded", icon: "icon", solid: "solid" }, outputs: { clicked: "clicked" }, ngImport: i0, template: "<div\n (click)=\"onClick()\"\n [class]=\"\n `flex flex-row gap-small ${rounded ? 'tag-round' : 'tag-square'} tag-${type}${solid ? '-solid' : ''}`\n \"\n>\n @if (icon) {\n <fx-ui-hero-icon\n [class]=\"`flex txt-tag-${type} ${solid && type !== 'default' ? 'text-white' : ''}`\"\n [icon]=\"icon\"\n [size]=\"18\"\n ></fx-ui-hero-icon>\n }\n\n <div [class]=\"`txt-tag-${type} ${solid && type !== 'default' ? 'text-white font-medium' : ''}`\">\n {{ label }}\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "component", type: HeroIconComponent, selector: "fx-ui-hero-icon", inputs: ["stroke", "icon", "solid", "outline", "size", "color", "class"] }] });
3895
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: TagComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3896
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: TagComponent, isStandalone: false, selector: "fx-ui-tag", inputs: { label: "label", type: "type", rounded: "rounded", icon: "icon", solid: "solid" }, outputs: { clicked: "clicked" }, ngImport: i0, template: "<!-- Interactive semantics only when a (clicked) listener is attached. -->\n<div\n (click)=\"onClick()\"\n (keydown.enter)=\"onClick()\"\n (keydown.space)=\"$event.preventDefault(); onClick()\"\n [attr.role]=\"clicked.observed ? 'button' : null\"\n [attr.tabindex]=\"clicked.observed ? 0 : null\"\n [class]=\"\n `flex flex-row gap-small ${rounded ? 'tag-round' : 'tag-square'} tag-${type}${solid ? '-solid' : ''}${clicked.observed ? ' cursor-pointer focus-visible:ring-2 focus-visible:ring-primary/50' : ''}`\n \"\n>\n @if (icon) {\n <fx-ui-hero-icon\n [class]=\"`flex txt-tag-${type} ${solid && type !== 'default' ? 'text-white' : ''}`\"\n [icon]=\"icon\"\n [size]=\"18\"\n ></fx-ui-hero-icon>\n }\n\n <div [class]=\"`txt-tag-${type} ${solid && type !== 'default' ? 'text-white font-medium' : ''}`\">\n {{ label }}\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "component", type: HeroIconComponent, selector: "fx-ui-hero-icon", inputs: ["stroke", "icon", "solid", "outline", "size", "color", "class"] }] });
3736
3897
  }
3737
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: TagComponent, decorators: [{
3898
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: TagComponent, decorators: [{
3738
3899
  type: Component,
3739
- args: [{ selector: 'fx-ui-tag', standalone: false, template: "<div\n (click)=\"onClick()\"\n [class]=\"\n `flex flex-row gap-small ${rounded ? 'tag-round' : 'tag-square'} tag-${type}${solid ? '-solid' : ''}`\n \"\n>\n @if (icon) {\n <fx-ui-hero-icon\n [class]=\"`flex txt-tag-${type} ${solid && type !== 'default' ? 'text-white' : ''}`\"\n [icon]=\"icon\"\n [size]=\"18\"\n ></fx-ui-hero-icon>\n }\n\n <div [class]=\"`txt-tag-${type} ${solid && type !== 'default' ? 'text-white font-medium' : ''}`\">\n {{ label }}\n </div>\n</div>\n" }]
3900
+ args: [{ selector: 'fx-ui-tag', standalone: false, template: "<!-- Interactive semantics only when a (clicked) listener is attached. -->\n<div\n (click)=\"onClick()\"\n (keydown.enter)=\"onClick()\"\n (keydown.space)=\"$event.preventDefault(); onClick()\"\n [attr.role]=\"clicked.observed ? 'button' : null\"\n [attr.tabindex]=\"clicked.observed ? 0 : null\"\n [class]=\"\n `flex flex-row gap-small ${rounded ? 'tag-round' : 'tag-square'} tag-${type}${solid ? '-solid' : ''}${clicked.observed ? ' cursor-pointer focus-visible:ring-2 focus-visible:ring-primary/50' : ''}`\n \"\n>\n @if (icon) {\n <fx-ui-hero-icon\n [class]=\"`flex txt-tag-${type} ${solid && type !== 'default' ? 'text-white' : ''}`\"\n [icon]=\"icon\"\n [size]=\"18\"\n ></fx-ui-hero-icon>\n }\n\n <div [class]=\"`txt-tag-${type} ${solid && type !== 'default' ? 'text-white font-medium' : ''}`\">\n {{ label }}\n </div>\n</div>\n" }]
3740
3901
  }], propDecorators: { label: [{
3741
3902
  type: Input
3742
3903
  }], type: [{
@@ -3835,12 +3996,12 @@ class TreeDiagram {
3835
3996
  });
3836
3997
  this.cdr.detectChanges();
3837
3998
  }
3838
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: TreeDiagram, deps: [{ token: i0.NgZone }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
3839
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.4", type: TreeDiagram, isStandalone: false, selector: "fx-ui-tree-diagram", inputs: { data: "data" }, viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true }, { propertyName: "root", first: true, predicate: ["root"], descendants: true }, { propertyName: "children", predicate: ["child"], descendants: true }], ngImport: i0, template: "<div class=\"relative p-8\" #container>\n\n <!-- ROOT -->\n <div\n #root\n class=\"mx-auto w-fit bg-blue-600 text-white px-7 py-3 rounded-md font-semibold text-center\"\n >\n {{ data.label }}\n </div>\n\n <!-- CHILDREN -->\n <div class=\"mt-16 flex justify-center gap-16\">\n <div\n *ngFor=\"let child of data.children\"\n #child\n class=\"w-48 bg-rose-600 text-white px-4 py-4 rounded-lg text-center\"\n >\n <div class=\"font-semibold text-lg\">{{ child.label }}</div>\n <div class=\"mt-1 text-sm opacity-90\">{{ child.status }}</div>\n </div>\n </div>\n\n <!-- SVG CONNECTORS -->\n <svg\n class=\"absolute inset-0 pointer-events-none\"\n [attr.width]=\"svgWidth\"\n [attr.height]=\"svgHeight\"\n >\n <line\n *ngFor=\"let line of lines\"\n [attr.x1]=\"line.x1\"\n [attr.y1]=\"line.y1\"\n [attr.x2]=\"line.x2\"\n [attr.y2]=\"line.y2\"\n stroke=\"#1f2937\"\n stroke-width=\"2\"\n />\n </svg>\n\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] });
3999
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: TreeDiagram, deps: [{ token: i0.NgZone }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
4000
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: TreeDiagram, isStandalone: false, selector: "fx-ui-tree-diagram", inputs: { data: "data" }, viewQueries: [{ propertyName: "container", first: true, predicate: ["container"], descendants: true }, { propertyName: "root", first: true, predicate: ["root"], descendants: true }, { propertyName: "children", predicate: ["child"], descendants: true }], ngImport: i0, template: "<div class=\"relative p-8\" #container>\n\n <!-- ROOT -->\n <div\n #root\n class=\"mx-auto w-fit bg-blue-600 text-white px-7 py-3 rounded-md font-semibold text-center\"\n >\n {{ data.label }}\n </div>\n\n <!-- CHILDREN -->\n <div class=\"mt-16 flex justify-center gap-16\">\n @for (child of data.children; track child) {\n <div\n #child\n class=\"w-48 bg-rose-600 text-white px-4 py-4 rounded-lg text-center\"\n >\n <div class=\"font-semibold text-lg\">{{ child.label }}</div>\n <div class=\"mt-1 text-sm opacity-90\">{{ child.status }}</div>\n </div>\n }\n </div>\n\n <!-- SVG CONNECTORS -->\n <svg\n class=\"absolute inset-0 pointer-events-none\"\n [attr.width]=\"svgWidth\"\n [attr.height]=\"svgHeight\"\n >\n @for (line of lines; track line) {\n <line\n [attr.x1]=\"line.x1\"\n [attr.y1]=\"line.y1\"\n [attr.x2]=\"line.x2\"\n [attr.y2]=\"line.y2\"\n stroke=\"#1f2937\"\n stroke-width=\"2\"\n />\n }\n </svg>\n\n</div>\n", styles: [""] });
3840
4001
  }
3841
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: TreeDiagram, decorators: [{
4002
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: TreeDiagram, decorators: [{
3842
4003
  type: Component,
3843
- args: [{ selector: 'fx-ui-tree-diagram', standalone: false, template: "<div class=\"relative p-8\" #container>\n\n <!-- ROOT -->\n <div\n #root\n class=\"mx-auto w-fit bg-blue-600 text-white px-7 py-3 rounded-md font-semibold text-center\"\n >\n {{ data.label }}\n </div>\n\n <!-- CHILDREN -->\n <div class=\"mt-16 flex justify-center gap-16\">\n <div\n *ngFor=\"let child of data.children\"\n #child\n class=\"w-48 bg-rose-600 text-white px-4 py-4 rounded-lg text-center\"\n >\n <div class=\"font-semibold text-lg\">{{ child.label }}</div>\n <div class=\"mt-1 text-sm opacity-90\">{{ child.status }}</div>\n </div>\n </div>\n\n <!-- SVG CONNECTORS -->\n <svg\n class=\"absolute inset-0 pointer-events-none\"\n [attr.width]=\"svgWidth\"\n [attr.height]=\"svgHeight\"\n >\n <line\n *ngFor=\"let line of lines\"\n [attr.x1]=\"line.x1\"\n [attr.y1]=\"line.y1\"\n [attr.x2]=\"line.x2\"\n [attr.y2]=\"line.y2\"\n stroke=\"#1f2937\"\n stroke-width=\"2\"\n />\n </svg>\n\n</div>\n" }]
4004
+ args: [{ selector: 'fx-ui-tree-diagram', standalone: false, template: "<div class=\"relative p-8\" #container>\n\n <!-- ROOT -->\n <div\n #root\n class=\"mx-auto w-fit bg-blue-600 text-white px-7 py-3 rounded-md font-semibold text-center\"\n >\n {{ data.label }}\n </div>\n\n <!-- CHILDREN -->\n <div class=\"mt-16 flex justify-center gap-16\">\n @for (child of data.children; track child) {\n <div\n #child\n class=\"w-48 bg-rose-600 text-white px-4 py-4 rounded-lg text-center\"\n >\n <div class=\"font-semibold text-lg\">{{ child.label }}</div>\n <div class=\"mt-1 text-sm opacity-90\">{{ child.status }}</div>\n </div>\n }\n </div>\n\n <!-- SVG CONNECTORS -->\n <svg\n class=\"absolute inset-0 pointer-events-none\"\n [attr.width]=\"svgWidth\"\n [attr.height]=\"svgHeight\"\n >\n @for (line of lines; track line) {\n <line\n [attr.x1]=\"line.x1\"\n [attr.y1]=\"line.y1\"\n [attr.x2]=\"line.x2\"\n [attr.y2]=\"line.y2\"\n stroke=\"#1f2937\"\n stroke-width=\"2\"\n />\n }\n </svg>\n\n</div>\n" }]
3844
4005
  }], ctorParameters: () => [{ type: i0.NgZone }, { type: i0.ChangeDetectorRef }], propDecorators: { data: [{
3845
4006
  type: Input
3846
4007
  }], container: [{
@@ -3888,12 +4049,12 @@ class KanbanBoardComponent {
3888
4049
  currentIndex: event.currentIndex,
3889
4050
  });
3890
4051
  }
3891
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: KanbanBoardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
3892
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: KanbanBoardComponent, isStandalone: false, selector: "fx-ui-kanban-board", inputs: { columns: "columns", itemTemplate: "itemTemplate" }, outputs: { columnChanged: "columnChanged" }, ngImport: i0, template: "<div class=\"kanban-board\">\n <div class=\"kanban-columns\">\n @for (column of columns; track column.id) {\n <div class=\"kanban-column\">\n <div class=\"kanban-column-header\">\n <h3 class=\"kanban-column-title\">{{ column.title }}</h3>\n <span class=\"kanban-column-count\">{{ column.items.length }}</span>\n </div>\n \n <div\n class=\"kanban-column-content\"\n cdkDropList\n [id]=\"column.id\"\n [cdkDropListData]=\"column.items\"\n [cdkDropListConnectedTo]=\"getColumnIds()\"\n (cdkDropListDropped)=\"onDrop($event, column.id)\"\n >\n @for (item of column.items; track $index) {\n <div class=\"kanban-item\" cdkDrag>\n <div class=\"kanban-item-placeholder\" *cdkDragPlaceholder></div>\n \n @if (itemTemplate) {\n <ng-container\n *ngTemplateOutlet=\"itemTemplate; context: { $implicit: item, index: $index }\"\n ></ng-container>\n } @else {\n <div class=\"kanban-item-default\">\n {{ item }}\n </div>\n }\n </div>\n }\n \n @if (column.items.length === 0) {\n <div class=\"kanban-column-empty\">\n Drop items here\n </div>\n }\n </div>\n </div>\n }\n </div>\n</div>\n", styles: [".kanban-board{height:100%;width:100%;overflow-x:auto}.kanban-columns{display:flex;min-height:100%;gap:1rem;padding:1rem}.kanban-column{display:flex;min-width:300px;flex-direction:column;border-radius:.5rem;--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}@media (prefers-color-scheme: dark){.kanban-column{--tw-bg-opacity: 1;background-color:rgb(31 41 55 / var(--tw-bg-opacity, 1))}}.kanban-column{flex-shrink:0}.kanban-column-header{display:flex;align-items:center;justify-content:space-between;border-bottom-width:1px;--tw-border-opacity: 1;border-color:rgb(229 231 235 / var(--tw-border-opacity, 1));padding:1rem}@media (prefers-color-scheme: dark){.kanban-column-header{--tw-border-opacity: 1;border-color:rgb(55 65 81 / var(--tw-border-opacity, 1))}}.kanban-column-title{margin:0;font-size:1.125rem;line-height:1.75rem;font-weight:600;--tw-text-opacity: 1;color:rgb(17 24 39 / var(--tw-text-opacity, 1))}@media (prefers-color-scheme: dark){.kanban-column-title{--tw-text-opacity: 1;color:rgb(243 244 246 / var(--tw-text-opacity, 1))}}.kanban-column-count{border-radius:9999px;--tw-bg-opacity: 1;background-color:rgb(229 231 235 / var(--tw-bg-opacity, 1));padding:.25rem .5rem;font-size:.875rem;font-weight:500;--tw-text-opacity: 1;color:rgb(55 65 81 / var(--tw-text-opacity, 1))}@media (prefers-color-scheme: dark){.kanban-column-count{--tw-bg-opacity: 1;background-color:rgb(55 65 81 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(209 213 219 / var(--tw-text-opacity, 1))}}.kanban-column-content{flex:1 1 0%}.kanban-column-content>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.kanban-column-content{overflow-y:auto;padding:1rem;min-height:200px}.kanban-item{border-radius:.5rem;border-width:1px;--tw-border-opacity: 1;border-color:rgb(229 231 235 / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1));--tw-shadow: 0 1px 2px 0 rgb(var(--shadow-color) / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}@media (prefers-color-scheme: dark){.kanban-item{--tw-border-opacity: 1;border-color:rgb(75 85 99 / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(55 65 81 / var(--tw-bg-opacity, 1))}}.kanban-item{transition-property:box-shadow;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;cursor:move}.kanban-item:hover{--tw-shadow: 0 4px 6px -1px rgb(var(--shadow-color) / .1), 0 2px 4px -2px rgb(var(--shadow-color) / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.kanban-item-default{padding:1rem;--tw-text-opacity: 1;color:rgb(17 24 39 / var(--tw-text-opacity, 1))}@media (prefers-color-scheme: dark){.kanban-item-default{--tw-text-opacity: 1;color:rgb(243 244 246 / var(--tw-text-opacity, 1))}}.kanban-item-placeholder{border-radius:.5rem;border-width:2px;border-style:dashed;--tw-border-opacity: 1;border-color:rgb(156 163 175 / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(229 231 235 / var(--tw-bg-opacity, 1))}@media (prefers-color-scheme: dark){.kanban-item-placeholder{--tw-border-opacity: 1;border-color:rgb(107 114 128 / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(75 85 99 / var(--tw-bg-opacity, 1))}}.kanban-item-placeholder{opacity:.5;min-height:60px}.kanban-column-empty{display:flex;height:8rem;align-items:center;justify-content:center;font-size:.875rem;--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}@media (prefers-color-scheme: dark){.kanban-column-empty{--tw-text-opacity: 1;color:rgb(107 114 128 / var(--tw-text-opacity, 1))}}.kanban-column-empty{border-radius:.5rem;border-width:2px;border-style:dashed;--tw-border-opacity: 1;border-color:rgb(209 213 219 / var(--tw-border-opacity, 1))}@media (prefers-color-scheme: dark){.kanban-column-empty{--tw-border-opacity: 1;border-color:rgb(75 85 99 / var(--tw-border-opacity, 1))}}.cdk-drag-preview{border-radius:.5rem;opacity:.8;--tw-shadow: 0 10px 15px -3px rgb(var(--shadow-color) / .1), 0 4px 6px -4px rgb(var(--shadow-color) / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.kanban-column-content.cdk-drop-list-dragging .kanban-item:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}\n"], dependencies: [{ kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2$3.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i2$3.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i2$3.CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }] });
4052
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: KanbanBoardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4053
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: KanbanBoardComponent, isStandalone: false, selector: "fx-ui-kanban-board", inputs: { columns: "columns", itemTemplate: "itemTemplate" }, outputs: { columnChanged: "columnChanged" }, ngImport: i0, template: "<div class=\"kanban-board\">\n <div class=\"kanban-columns\">\n @for (column of columns; track column.id) {\n <div class=\"kanban-column\">\n <div class=\"kanban-column-header\">\n <h3 class=\"kanban-column-title\">{{ column.title }}</h3>\n <span class=\"kanban-column-count\">{{ column.items.length }}</span>\n </div>\n \n <div\n class=\"kanban-column-content\"\n cdkDropList\n [id]=\"column.id\"\n [cdkDropListData]=\"column.items\"\n [cdkDropListConnectedTo]=\"getColumnIds()\"\n (cdkDropListDropped)=\"onDrop($event, column.id)\"\n >\n @for (item of column.items; track $index) {\n <div class=\"kanban-item\" cdkDrag>\n <div class=\"kanban-item-placeholder\" *cdkDragPlaceholder></div>\n \n @if (itemTemplate) {\n <ng-container\n *ngTemplateOutlet=\"itemTemplate; context: { $implicit: item, index: $index }\"\n ></ng-container>\n } @else {\n <div class=\"kanban-item-default\">\n {{ item }}\n </div>\n }\n </div>\n }\n \n @if (column.items.length === 0) {\n <div class=\"kanban-column-empty\">\n Drop items here\n </div>\n }\n </div>\n </div>\n }\n </div>\n</div>\n", styles: ["@charset \"UTF-8\";@layer properties;.kanban-board{height:100%;width:100%;overflow-x:auto}.kanban-columns{display:flex;min-height:100%;gap:calc(var(--spacing, .25rem) * 4);padding:calc(var(--spacing, .25rem) * 4)}.kanban-column{display:flex;min-width:300px;flex-direction:column;border-radius:.5rem;background-color:var(--color-gray-50, oklch(98.5% .002 247.839));flex-shrink:0}@media(prefers-color-scheme:dark){.kanban-column{background-color:var(--color-gray-800, oklch(27.8% .033 256.848))}}.kanban-column-header{display:flex;align-items:center;justify-content:space-between;border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--color-gray-200, oklch(92.8% .006 264.531));padding:calc(var(--spacing, .25rem) * 4)}@media(prefers-color-scheme:dark){.kanban-column-header{border-color:var(--color-gray-700, oklch(37.3% .034 259.733))}}.kanban-column-title{margin:0;font-size:var(--text-lg, 1.125rem);line-height:var(--tw-leading, var(--text-lg--line-height, calc(1.75 / 1.125)));--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600);color:var(--color-gray-900, oklch(21% .034 264.665))}@media(prefers-color-scheme:dark){.kanban-column-title{color:var(--color-gray-100, oklch(96.7% .003 264.542))}}.kanban-column-count{border-radius:calc(infinity * 1px);background-color:var(--color-gray-200, oklch(92.8% .006 264.531));padding-inline:calc(var(--spacing, .25rem) * 2);padding-block:var(--spacing, .25rem);font-size:.875rem;line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:var(--color-gray-700, oklch(37.3% .034 259.733))}@media(prefers-color-scheme:dark){.kanban-column-count{background-color:var(--color-gray-700, oklch(37.3% .034 259.733))}}@media(prefers-color-scheme:dark){.kanban-column-count{color:var(--color-gray-300, oklch(87.2% .01 258.338))}}.kanban-column-content{flex:1;overflow-y:auto;padding:calc(var(--spacing, .25rem) * 4);min-height:200px}:where(.kanban-column-content>:not(:last-child)){--tw-space-y-reverse: 0;margin-block-start:calc(calc(var(--spacing, .25rem) * 3) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing, .25rem) * 3) * calc(1 - var(--tw-space-y-reverse)))}.kanban-item{border-radius:.5rem;border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-gray-200, oklch(92.8% .006 264.531));background-color:var(--color-white, #fff);--tw-shadow: 0 1px 2px 0 var(--tw-shadow-color, rgb(var(--shadow-color) / .05));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);transition-property:box-shadow;transition-timing-function:var(--tw-ease, var(--default-transition-timing-function, cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration, var(--default-transition-duration, .15s));--tw-duration: .2s;transition-duration:.2s;cursor:move}@media(prefers-color-scheme:dark){.kanban-item{border-color:var(--color-gray-600, oklch(44.6% .03 256.802))}}@media(prefers-color-scheme:dark){.kanban-item{background-color:var(--color-gray-700, oklch(37.3% .034 259.733))}}.kanban-item:hover{--tw-shadow: 0 4px 6px -1px var(--tw-shadow-color, rgb(var(--shadow-color) / .1)), 0 2px 4px -2px var(--tw-shadow-color, rgb(var(--shadow-color) / .1));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.kanban-item-default{padding:calc(var(--spacing, .25rem) * 4);color:var(--color-gray-900, oklch(21% .034 264.665))}@media(prefers-color-scheme:dark){.kanban-item-default{color:var(--color-gray-100, oklch(96.7% .003 264.542))}}.kanban-item-placeholder{border-radius:.5rem;border-style:var(--tw-border-style);border-width:2px;--tw-border-style: dashed;border-style:dashed;border-color:var(--color-gray-400, oklch(70.7% .022 261.325));background-color:var(--color-gray-200, oklch(92.8% .006 264.531));opacity:50%;min-height:60px}@media(prefers-color-scheme:dark){.kanban-item-placeholder{border-color:var(--color-gray-500, oklch(55.1% .027 264.364))}}@media(prefers-color-scheme:dark){.kanban-item-placeholder{background-color:var(--color-gray-600, oklch(44.6% .03 256.802))}}.kanban-column-empty{display:flex;height:calc(var(--spacing, .25rem) * 32);align-items:center;justify-content:center;font-size:.875rem;line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));color:var(--color-gray-400, oklch(70.7% .022 261.325));border-radius:.5rem;border-style:var(--tw-border-style);border-width:2px;--tw-border-style: dashed;border-style:dashed;border-color:var(--color-gray-300, oklch(87.2% .01 258.338))}@media(prefers-color-scheme:dark){.kanban-column-empty{color:var(--color-gray-500, oklch(55.1% .027 264.364))}}@media(prefers-color-scheme:dark){.kanban-column-empty{border-color:var(--color-gray-600, oklch(44.6% .03 256.802))}}.cdk-drag-preview{border-radius:.5rem;opacity:80%;--tw-shadow: 0 10px 15px -3px var(--tw-shadow-color, rgb(var(--shadow-color) / .1)), 0 4px 6px -4px var(--tw-shadow-color, rgb(var(--shadow-color) / .1));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.kanban-column-content.cdk-drop-list-dragging .kanban-item:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-space-y-reverse{syntax: \"*\"; inherits: false; initial-value: 0;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-duration{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-font-weight: initial;--tw-space-y-reverse: 0;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000;--tw-duration: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2$2.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i2$2.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i2$2.CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }] });
3893
4054
  }
3894
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: KanbanBoardComponent, decorators: [{
4055
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: KanbanBoardComponent, decorators: [{
3895
4056
  type: Component,
3896
- args: [{ selector: 'fx-ui-kanban-board', standalone: false, template: "<div class=\"kanban-board\">\n <div class=\"kanban-columns\">\n @for (column of columns; track column.id) {\n <div class=\"kanban-column\">\n <div class=\"kanban-column-header\">\n <h3 class=\"kanban-column-title\">{{ column.title }}</h3>\n <span class=\"kanban-column-count\">{{ column.items.length }}</span>\n </div>\n \n <div\n class=\"kanban-column-content\"\n cdkDropList\n [id]=\"column.id\"\n [cdkDropListData]=\"column.items\"\n [cdkDropListConnectedTo]=\"getColumnIds()\"\n (cdkDropListDropped)=\"onDrop($event, column.id)\"\n >\n @for (item of column.items; track $index) {\n <div class=\"kanban-item\" cdkDrag>\n <div class=\"kanban-item-placeholder\" *cdkDragPlaceholder></div>\n \n @if (itemTemplate) {\n <ng-container\n *ngTemplateOutlet=\"itemTemplate; context: { $implicit: item, index: $index }\"\n ></ng-container>\n } @else {\n <div class=\"kanban-item-default\">\n {{ item }}\n </div>\n }\n </div>\n }\n \n @if (column.items.length === 0) {\n <div class=\"kanban-column-empty\">\n Drop items here\n </div>\n }\n </div>\n </div>\n }\n </div>\n</div>\n", styles: [".kanban-board{height:100%;width:100%;overflow-x:auto}.kanban-columns{display:flex;min-height:100%;gap:1rem;padding:1rem}.kanban-column{display:flex;min-width:300px;flex-direction:column;border-radius:.5rem;--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}@media (prefers-color-scheme: dark){.kanban-column{--tw-bg-opacity: 1;background-color:rgb(31 41 55 / var(--tw-bg-opacity, 1))}}.kanban-column{flex-shrink:0}.kanban-column-header{display:flex;align-items:center;justify-content:space-between;border-bottom-width:1px;--tw-border-opacity: 1;border-color:rgb(229 231 235 / var(--tw-border-opacity, 1));padding:1rem}@media (prefers-color-scheme: dark){.kanban-column-header{--tw-border-opacity: 1;border-color:rgb(55 65 81 / var(--tw-border-opacity, 1))}}.kanban-column-title{margin:0;font-size:1.125rem;line-height:1.75rem;font-weight:600;--tw-text-opacity: 1;color:rgb(17 24 39 / var(--tw-text-opacity, 1))}@media (prefers-color-scheme: dark){.kanban-column-title{--tw-text-opacity: 1;color:rgb(243 244 246 / var(--tw-text-opacity, 1))}}.kanban-column-count{border-radius:9999px;--tw-bg-opacity: 1;background-color:rgb(229 231 235 / var(--tw-bg-opacity, 1));padding:.25rem .5rem;font-size:.875rem;font-weight:500;--tw-text-opacity: 1;color:rgb(55 65 81 / var(--tw-text-opacity, 1))}@media (prefers-color-scheme: dark){.kanban-column-count{--tw-bg-opacity: 1;background-color:rgb(55 65 81 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(209 213 219 / var(--tw-text-opacity, 1))}}.kanban-column-content{flex:1 1 0%}.kanban-column-content>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.kanban-column-content{overflow-y:auto;padding:1rem;min-height:200px}.kanban-item{border-radius:.5rem;border-width:1px;--tw-border-opacity: 1;border-color:rgb(229 231 235 / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1));--tw-shadow: 0 1px 2px 0 rgb(var(--shadow-color) / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}@media (prefers-color-scheme: dark){.kanban-item{--tw-border-opacity: 1;border-color:rgb(75 85 99 / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(55 65 81 / var(--tw-bg-opacity, 1))}}.kanban-item{transition-property:box-shadow;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.2s;cursor:move}.kanban-item:hover{--tw-shadow: 0 4px 6px -1px rgb(var(--shadow-color) / .1), 0 2px 4px -2px rgb(var(--shadow-color) / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.kanban-item-default{padding:1rem;--tw-text-opacity: 1;color:rgb(17 24 39 / var(--tw-text-opacity, 1))}@media (prefers-color-scheme: dark){.kanban-item-default{--tw-text-opacity: 1;color:rgb(243 244 246 / var(--tw-text-opacity, 1))}}.kanban-item-placeholder{border-radius:.5rem;border-width:2px;border-style:dashed;--tw-border-opacity: 1;border-color:rgb(156 163 175 / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(229 231 235 / var(--tw-bg-opacity, 1))}@media (prefers-color-scheme: dark){.kanban-item-placeholder{--tw-border-opacity: 1;border-color:rgb(107 114 128 / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(75 85 99 / var(--tw-bg-opacity, 1))}}.kanban-item-placeholder{opacity:.5;min-height:60px}.kanban-column-empty{display:flex;height:8rem;align-items:center;justify-content:center;font-size:.875rem;--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}@media (prefers-color-scheme: dark){.kanban-column-empty{--tw-text-opacity: 1;color:rgb(107 114 128 / var(--tw-text-opacity, 1))}}.kanban-column-empty{border-radius:.5rem;border-width:2px;border-style:dashed;--tw-border-opacity: 1;border-color:rgb(209 213 219 / var(--tw-border-opacity, 1))}@media (prefers-color-scheme: dark){.kanban-column-empty{--tw-border-opacity: 1;border-color:rgb(75 85 99 / var(--tw-border-opacity, 1))}}.cdk-drag-preview{border-radius:.5rem;opacity:.8;--tw-shadow: 0 10px 15px -3px rgb(var(--shadow-color) / .1), 0 4px 6px -4px rgb(var(--shadow-color) / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.kanban-column-content.cdk-drop-list-dragging .kanban-item:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}\n"] }]
4057
+ args: [{ selector: 'fx-ui-kanban-board', standalone: false, template: "<div class=\"kanban-board\">\n <div class=\"kanban-columns\">\n @for (column of columns; track column.id) {\n <div class=\"kanban-column\">\n <div class=\"kanban-column-header\">\n <h3 class=\"kanban-column-title\">{{ column.title }}</h3>\n <span class=\"kanban-column-count\">{{ column.items.length }}</span>\n </div>\n \n <div\n class=\"kanban-column-content\"\n cdkDropList\n [id]=\"column.id\"\n [cdkDropListData]=\"column.items\"\n [cdkDropListConnectedTo]=\"getColumnIds()\"\n (cdkDropListDropped)=\"onDrop($event, column.id)\"\n >\n @for (item of column.items; track $index) {\n <div class=\"kanban-item\" cdkDrag>\n <div class=\"kanban-item-placeholder\" *cdkDragPlaceholder></div>\n \n @if (itemTemplate) {\n <ng-container\n *ngTemplateOutlet=\"itemTemplate; context: { $implicit: item, index: $index }\"\n ></ng-container>\n } @else {\n <div class=\"kanban-item-default\">\n {{ item }}\n </div>\n }\n </div>\n }\n \n @if (column.items.length === 0) {\n <div class=\"kanban-column-empty\">\n Drop items here\n </div>\n }\n </div>\n </div>\n }\n </div>\n</div>\n", styles: ["@charset \"UTF-8\";@layer properties;.kanban-board{height:100%;width:100%;overflow-x:auto}.kanban-columns{display:flex;min-height:100%;gap:calc(var(--spacing, .25rem) * 4);padding:calc(var(--spacing, .25rem) * 4)}.kanban-column{display:flex;min-width:300px;flex-direction:column;border-radius:.5rem;background-color:var(--color-gray-50, oklch(98.5% .002 247.839));flex-shrink:0}@media(prefers-color-scheme:dark){.kanban-column{background-color:var(--color-gray-800, oklch(27.8% .033 256.848))}}.kanban-column-header{display:flex;align-items:center;justify-content:space-between;border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--color-gray-200, oklch(92.8% .006 264.531));padding:calc(var(--spacing, .25rem) * 4)}@media(prefers-color-scheme:dark){.kanban-column-header{border-color:var(--color-gray-700, oklch(37.3% .034 259.733))}}.kanban-column-title{margin:0;font-size:var(--text-lg, 1.125rem);line-height:var(--tw-leading, var(--text-lg--line-height, calc(1.75 / 1.125)));--tw-font-weight: var(--font-weight-semibold, 600);font-weight:var(--font-weight-semibold, 600);color:var(--color-gray-900, oklch(21% .034 264.665))}@media(prefers-color-scheme:dark){.kanban-column-title{color:var(--color-gray-100, oklch(96.7% .003 264.542))}}.kanban-column-count{border-radius:calc(infinity * 1px);background-color:var(--color-gray-200, oklch(92.8% .006 264.531));padding-inline:calc(var(--spacing, .25rem) * 2);padding-block:var(--spacing, .25rem);font-size:.875rem;line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:var(--color-gray-700, oklch(37.3% .034 259.733))}@media(prefers-color-scheme:dark){.kanban-column-count{background-color:var(--color-gray-700, oklch(37.3% .034 259.733))}}@media(prefers-color-scheme:dark){.kanban-column-count{color:var(--color-gray-300, oklch(87.2% .01 258.338))}}.kanban-column-content{flex:1;overflow-y:auto;padding:calc(var(--spacing, .25rem) * 4);min-height:200px}:where(.kanban-column-content>:not(:last-child)){--tw-space-y-reverse: 0;margin-block-start:calc(calc(var(--spacing, .25rem) * 3) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing, .25rem) * 3) * calc(1 - var(--tw-space-y-reverse)))}.kanban-item{border-radius:.5rem;border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-gray-200, oklch(92.8% .006 264.531));background-color:var(--color-white, #fff);--tw-shadow: 0 1px 2px 0 var(--tw-shadow-color, rgb(var(--shadow-color) / .05));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);transition-property:box-shadow;transition-timing-function:var(--tw-ease, var(--default-transition-timing-function, cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration, var(--default-transition-duration, .15s));--tw-duration: .2s;transition-duration:.2s;cursor:move}@media(prefers-color-scheme:dark){.kanban-item{border-color:var(--color-gray-600, oklch(44.6% .03 256.802))}}@media(prefers-color-scheme:dark){.kanban-item{background-color:var(--color-gray-700, oklch(37.3% .034 259.733))}}.kanban-item:hover{--tw-shadow: 0 4px 6px -1px var(--tw-shadow-color, rgb(var(--shadow-color) / .1)), 0 2px 4px -2px var(--tw-shadow-color, rgb(var(--shadow-color) / .1));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.kanban-item-default{padding:calc(var(--spacing, .25rem) * 4);color:var(--color-gray-900, oklch(21% .034 264.665))}@media(prefers-color-scheme:dark){.kanban-item-default{color:var(--color-gray-100, oklch(96.7% .003 264.542))}}.kanban-item-placeholder{border-radius:.5rem;border-style:var(--tw-border-style);border-width:2px;--tw-border-style: dashed;border-style:dashed;border-color:var(--color-gray-400, oklch(70.7% .022 261.325));background-color:var(--color-gray-200, oklch(92.8% .006 264.531));opacity:50%;min-height:60px}@media(prefers-color-scheme:dark){.kanban-item-placeholder{border-color:var(--color-gray-500, oklch(55.1% .027 264.364))}}@media(prefers-color-scheme:dark){.kanban-item-placeholder{background-color:var(--color-gray-600, oklch(44.6% .03 256.802))}}.kanban-column-empty{display:flex;height:calc(var(--spacing, .25rem) * 32);align-items:center;justify-content:center;font-size:.875rem;line-height:var(--tw-leading, var(--text-sm--line-height, calc(1.25 / .875)));color:var(--color-gray-400, oklch(70.7% .022 261.325));border-radius:.5rem;border-style:var(--tw-border-style);border-width:2px;--tw-border-style: dashed;border-style:dashed;border-color:var(--color-gray-300, oklch(87.2% .01 258.338))}@media(prefers-color-scheme:dark){.kanban-column-empty{color:var(--color-gray-500, oklch(55.1% .027 264.364))}}@media(prefers-color-scheme:dark){.kanban-column-empty{border-color:var(--color-gray-600, oklch(44.6% .03 256.802))}}.cdk-drag-preview{border-radius:.5rem;opacity:80%;--tw-shadow: 0 10px 15px -3px var(--tw-shadow-color, rgb(var(--shadow-color) / .1)), 0 4px 6px -4px var(--tw-shadow-color, rgb(var(--shadow-color) / .1));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.cdk-drag-animating{transition:transform .25s cubic-bezier(0,0,.2,1)}.kanban-column-content.cdk-drop-list-dragging .kanban-item:not(.cdk-drag-placeholder){transition:transform .25s cubic-bezier(0,0,.2,1)}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-space-y-reverse{syntax: \"*\"; inherits: false; initial-value: 0;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-duration{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-font-weight: initial;--tw-space-y-reverse: 0;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000;--tw-duration: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
3897
4058
  }], propDecorators: { columns: [{
3898
4059
  type: Input
3899
4060
  }], itemTemplate: [{
@@ -4004,8 +4165,8 @@ class DrawerComponent {
4004
4165
  getDrawerState() {
4005
4166
  return this.isExpanded ? 'expanded' : 'collapsed';
4006
4167
  }
4007
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: DrawerComponent, deps: [{ token: i1$4.Router }], target: i0.ɵɵFactoryTarget.Component });
4008
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: DrawerComponent, isStandalone: false, selector: "fx-ui-drawer", inputs: { items: "items", isExpanded: "isExpanded", logo: "logo", version: "version" }, outputs: { toggleExpanded: "toggleExpanded", itemClicked: "itemClicked" }, ngImport: i0, template: "<div class=\"drawer-host-wrapper\">\n <a\n href=\"/\"\n class=\"h-[60px]\"\n [ngClass]=\"{ 'flex items-center justify-center': !isExpanded, 'p-4': isExpanded }\"\n >\n @if (logo) {\n <img\n [src]=\"logo\"\n class=\"h-[20px] w-auto transition-all duration-300 ease-in-out\"\n [ngClass]=\"{ 'scale-90': !isExpanded, 'ml-5': isExpanded }\"\n />\n } @else {\n <div class=\"h-[30px] w-auto transition-all duration-300 ease-in-out\"></div>\n }\n </a>\n <div class=\"drawer-container\" [@drawerExpand]=\"getDrawerState()\">\n <!-- Navigation Items -->\n <nav class=\"drawer-nav\">\n <ng-container *ngFor=\"let item of items\">\n <ng-container\n *ngTemplateOutlet=\"drawerItem; context: { $implicit: item, level: 0 }\"\n ></ng-container>\n </ng-container>\n </nav>\n\n <!-- Version -->\n <div *ngIf=\"version\" class=\"drawer-version\" [matTooltip]=\"!isExpanded ? version : ''\" matTooltipPosition=\"right\">\n <span *ngIf=\"isExpanded\">{{ version }}</span>\n <span *ngIf=\"!isExpanded\" class=\"drawer-version-dot\"></span>\n </div>\n </div>\n\n <!-- Floating Toggle Button on right border -->\n <button\n type=\"button\"\n class=\"toggle-btn\"\n (click)=\"toggleDrawer()\"\n [matTooltip]=\"isExpanded ? 'Collapse' : 'Expand'\"\n matTooltipClass=\"text-text-primary text-xs font-semibold\"\n matTooltipPosition=\"right\"\n >\n <fx-ui-hero-icon\n [icon]=\"isExpanded ? 'chevron-left' : 'chevron-right'\"\n [size]=\"16\"\n class=\"text-text-primary\"\n ></fx-ui-hero-icon>\n </button>\n</div>\n\n<!-- Recursive Template for Drawer Items -->\n<ng-template #drawerItem let-item let-level=\"level\">\n <div class=\"drawer-item-wrapper\">\n <!-- Item Button/Link -->\n <a\n *ngIf=\"item.route && !item.children\"\n [routerLink]=\"item.route\"\n class=\"drawer-item\"\n [class.active]=\"isActiveRoute(item.route)\"\n [class.has-children]=\"item.children && item.children.length > 0\"\n [style.paddingLeft.px]=\"isExpanded ? 16 + level * 16 : 16\"\n [matTooltip]=\"!isExpanded ? item.label : ''\"\n matTooltipPosition=\"right\"\n matTooltipClass=\"text-text-primary text-xs font-semibold\"\n (click)=\"onItemClick(item, $event)\"\n >\n <div class=\"item-content\">\n <fx-ui-hero-icon [icon]=\"item.icon\" [size]=\"20\" class=\"item-icon\"></fx-ui-hero-icon>\n <span *ngIf=\"isExpanded\" class=\"item-label\">{{ item.label }}</span>\n </div>\n </a>\n\n <button\n *ngIf=\"!item.route || item.children\"\n type=\"button\"\n class=\"drawer-item\"\n [class.active]=\"isActiveRoute(item.route)\"\n [class.has-children]=\"item.children && item.children.length > 0\"\n [style.paddingLeft.px]=\"isExpanded ? 16 + level * 16 : 16\"\n [matTooltip]=\"!isExpanded ? item.label : ''\"\n matTooltipPosition=\"right\"\n matTooltipClass=\"text-text-primary text-sm font-semibold\"\n (click)=\"onItemClick(item, $event)\"\n >\n <div class=\"item-content\">\n <fx-ui-hero-icon [icon]=\"item.icon\" [size]=\"20\" class=\"item-icon\"></fx-ui-hero-icon>\n <span *ngIf=\"isExpanded\" class=\"item-label\">{{ item.label }}</span>\n <fx-ui-hero-icon\n *ngIf=\"isExpanded && item.children && item.children.length > 0\"\n [icon]=\"'chevron-down'\"\n [size]=\"16\"\n class=\"chevron-icon\"\n [class.rotated]=\"isAccordionExpanded(item.id)\"\n ></fx-ui-hero-icon>\n </div>\n </button>\n\n <!-- Accordion Children -->\n <div\n *ngIf=\"item.children && item.children.length > 0\"\n class=\"accordion-children\"\n [@accordionExpand]=\"getAccordionState(item.id)\"\n >\n <ng-container *ngFor=\"let child of item.children\">\n <ng-container\n *ngTemplateOutlet=\"drawerItem; context: { $implicit: child, level: level + 1 }\"\n ></ng-container>\n </ng-container>\n </div>\n </div>\n</ng-template>\n", styles: ["@charset \"UTF-8\";:host{display:block;height:100%}.drawer-host-wrapper{position:relative;height:100%;border-right-width:1px;--tw-border-opacity: 1;border-color:rgb(var(--border-default) / var(--tw-border-opacity, 1))}.drawer-container{display:flex;height:100%;flex-direction:column;overflow:auto;--tw-bg-opacity: 1;background-color:rgb(var(--bg-primary) / var(--tw-bg-opacity, 1));padding-left:.5rem;padding-right:.5rem;transition:width .3s cubic-bezier(.4,0,.2,1)}.toggle-btn{position:absolute;top:50%;z-index:50;display:flex;height:1.5rem;width:1.5rem;--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));cursor:pointer;align-items:center;justify-content:center;border-radius:9999px;border-width:1px;--tw-border-opacity: 1;border-color:rgb(var(--border-default) / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(var(--bg-primary) / var(--tw-bg-opacity, 1));--tw-shadow: 0 1px 2px 0 rgb(var(--shadow-color) / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow);right:-12px;transition:all .2s ease}.toggle-btn:hover{--tw-bg-opacity: 1;background-color:rgb(var(--bg-primary-hover) / var(--tw-bg-opacity, 1));--tw-shadow: 0 4px 6px -1px rgb(var(--shadow-color) / .1), 0 2px 4px -2px rgb(var(--shadow-color) / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.toggle-btn:active{transform:translateY(-50%) scale(.9)}.toggle-btn:focus-visible{outline-width:2px;outline-offset:2px;outline-color:rgb(var(--primary) / 1)}.drawer-nav{flex:1 1 0%;overflow-y:auto;overflow-x:hidden;padding-top:.5rem;padding-bottom:.5rem}.drawer-nav::-webkit-scrollbar{width:.375rem}.drawer-nav::-webkit-scrollbar-track{background-color:transparent}.drawer-nav::-webkit-scrollbar-thumb{border-radius:.125rem;--tw-bg-opacity: 1;background-color:rgb(var(--border-default) / var(--tw-bg-opacity, 1))}.drawer-nav::-webkit-scrollbar-thumb:hover{--tw-bg-opacity: 1;background-color:rgb(var(--text-placeholder) / var(--tw-bg-opacity, 1))}.drawer-item-wrapper{position:relative}.drawer-item{position:relative;margin-top:.25rem;display:flex;min-height:2rem;width:100%;cursor:pointer;align-items:center;border-radius:.25rem;border-style:none;background-color:transparent;padding:.5rem 1rem;--tw-text-opacity: 1;color:rgb(var(--text-primary) / var(--tw-text-opacity, 1));text-decoration-line:none;transition:all .2s ease;-webkit-tap-highlight-color:transparent;outline:2px solid transparent;outline-offset:2px}.drawer-item:hover{--tw-scale-x: .95;--tw-scale-y: .95;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));--tw-bg-opacity: 1;background-color:rgb(var(--bg-primary-hover) / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(var(--text-primary) / var(--tw-text-opacity, 1))}.drawer-item.active{background-image:linear-gradient(135deg,rgb(var(--gradient-primary-start)),rgb(var(--gradient-primary-end)));font-weight:500;--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.drawer-item.active .item-icon{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.drawer-item:active{transform:scale(.98)}.drawer-item:focus-visible{outline-width:2px;outline-offset:2px;outline-color:rgb(var(--primary) / 1)}.item-content{display:flex;width:100%;align-items:center;gap:.75rem;overflow:hidden}.item-icon{flex-shrink:0;color:inherit}.item-label{flex:1 1 0%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:left;font-size:13px;line-height:1.25rem}.chevron-icon{margin-left:auto;flex-shrink:0;--tw-text-opacity: 1;color:rgb(var(--text-primary) / var(--tw-text-opacity, 1));transition:transform .3s cubic-bezier(.4,0,.2,1)}.chevron-icon.rotated{transform:rotate(180deg)}.accordion-children{overflow:hidden}.drawer-version{display:flex;-webkit-user-select:none;user-select:none;align-items:center;justify-content:center;border-top-width:1px;--tw-border-opacity: 1;border-color:rgb(var(--border-default) / var(--tw-border-opacity, 1));padding:.75rem 1rem;font-size:11px;--tw-text-opacity: 1;color:rgb(var(--text-placeholder) / var(--tw-text-opacity, 1));font-family:Roboto,monospace}.drawer-version-dot{display:block;height:.375rem;width:.375rem;border-radius:9999px;--tw-bg-opacity: 1;background-color:rgb(var(--text-placeholder) / var(--tw-bg-opacity, 1))}.drawer-container[style*=\"width: 64px\"] .drawer-item{justify-content:center;padding-left:16px!important}.drawer-container[style*=\"width: 64px\"] .item-content{justify-content:center}\n"], dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1$4.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i56.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: HeroIconComponent, selector: "fx-ui-hero-icon", inputs: ["stroke", "icon", "solid", "outline", "size", "color", "class"] }], animations: [
4168
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: DrawerComponent, deps: [{ token: i1$5.Router }], target: i0.ɵɵFactoryTarget.Component });
4169
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: DrawerComponent, isStandalone: false, selector: "fx-ui-drawer", inputs: { items: "items", isExpanded: "isExpanded", logo: "logo", version: "version" }, outputs: { toggleExpanded: "toggleExpanded", itemClicked: "itemClicked" }, ngImport: i0, template: "<div class=\"drawer-host-wrapper\">\n <a\n href=\"/\"\n class=\"h-[60px]\"\n [ngClass]=\"{ 'flex items-center justify-center': !isExpanded, 'p-4': isExpanded }\"\n >\n @if (logo) {\n <img\n [src]=\"logo\"\n alt=\"Home\"\n class=\"h-[20px] w-auto transition-all duration-300 ease-in-out\"\n [ngClass]=\"{ 'scale-90': !isExpanded, 'ml-5': isExpanded }\"\n />\n } @else {\n <div class=\"h-[30px] w-auto transition-all duration-300 ease-in-out\"></div>\n }\n </a>\n <div class=\"drawer-container\" [@drawerExpand]=\"getDrawerState()\">\n <!-- Navigation Items -->\n <nav class=\"drawer-nav\">\n @for (item of items; track item) {\n <ng-container\n *ngTemplateOutlet=\"drawerItem; context: { $implicit: item, level: 0 }\"\n ></ng-container>\n }\n </nav>\n\n <!-- Version -->\n @if (version) {\n <div class=\"drawer-version\" [matTooltip]=\"!isExpanded ? version : ''\" matTooltipPosition=\"right\">\n @if (isExpanded) {\n <span>{{ version }}</span>\n }\n @if (!isExpanded) {\n <span class=\"drawer-version-dot\"></span>\n }\n </div>\n }\n </div>\n\n <!-- Floating Toggle Button on right border -->\n <button\n type=\"button\"\n class=\"toggle-btn\"\n [attr.aria-label]=\"isExpanded ? 'Collapse navigation' : 'Expand navigation'\"\n [attr.aria-expanded]=\"isExpanded\"\n (click)=\"toggleDrawer()\"\n [matTooltip]=\"isExpanded ? 'Collapse' : 'Expand'\"\n matTooltipClass=\"text-text-primary text-xs font-semibold\"\n matTooltipPosition=\"right\"\n >\n <fx-ui-hero-icon\n [icon]=\"isExpanded ? 'chevron-left' : 'chevron-right'\"\n [size]=\"16\"\n class=\"text-text-primary\"\n ></fx-ui-hero-icon>\n </button>\n</div>\n\n<!-- Recursive Template for Drawer Items -->\n<ng-template #drawerItem let-item let-level=\"level\">\n <div class=\"drawer-item-wrapper\">\n <!-- Item Button/Link -->\n @if (item.route && !item.children) {\n <a\n [routerLink]=\"item.route\"\n class=\"drawer-item\"\n [class.active]=\"isActiveRoute(item.route)\"\n [class.has-children]=\"item.children && item.children.length > 0\"\n [style.paddingLeft.px]=\"isExpanded ? 16 + level * 16 : 16\"\n [matTooltip]=\"!isExpanded ? item.label : ''\"\n matTooltipPosition=\"right\"\n matTooltipClass=\"text-text-primary text-xs font-semibold\"\n (click)=\"onItemClick(item, $event)\"\n >\n <div class=\"item-content\">\n <fx-ui-hero-icon [icon]=\"item.icon\" [size]=\"20\" class=\"item-icon\"></fx-ui-hero-icon>\n @if (isExpanded) {\n <span class=\"item-label\">{{ item.label }}</span>\n }\n </div>\n </a>\n }\n\n @if (!item.route || item.children) {\n <button\n type=\"button\"\n class=\"drawer-item\"\n [class.active]=\"isActiveRoute(item.route)\"\n [class.has-children]=\"item.children && item.children.length > 0\"\n [style.paddingLeft.px]=\"isExpanded ? 16 + level * 16 : 16\"\n [matTooltip]=\"!isExpanded ? item.label : ''\"\n matTooltipPosition=\"right\"\n matTooltipClass=\"text-text-primary text-sm font-semibold\"\n (click)=\"onItemClick(item, $event)\"\n >\n <div class=\"item-content\">\n <fx-ui-hero-icon [icon]=\"item.icon\" [size]=\"20\" class=\"item-icon\"></fx-ui-hero-icon>\n @if (isExpanded) {\n <span class=\"item-label\">{{ item.label }}</span>\n }\n @if (isExpanded && item.children && item.children.length > 0) {\n <fx-ui-hero-icon\n [icon]=\"'chevron-down'\"\n [size]=\"16\"\n class=\"chevron-icon\"\n [class.rotated]=\"isAccordionExpanded(item.id)\"\n ></fx-ui-hero-icon>\n }\n </div>\n </button>\n }\n\n <!-- Accordion Children -->\n @if (item.children && item.children.length > 0) {\n <div\n class=\"accordion-children\"\n [@accordionExpand]=\"getAccordionState(item.id)\"\n >\n @for (child of item.children; track child) {\n <ng-container\n *ngTemplateOutlet=\"drawerItem; context: { $implicit: child, level: level + 1 }\"\n ></ng-container>\n }\n </div>\n }\n </div>\n</ng-template>\n", styles: ["@charset \"UTF-8\";@layer properties;:host{display:block;height:100%}.drawer-host-wrapper{position:relative;height:100%;border-right-style:var(--tw-border-style);border-right-width:1px;border-color:rgb(var(--border-default))}.drawer-container{display:flex;height:100%;flex-direction:column;overflow:auto;background-color:rgb(var(--bg-primary));padding-inline:calc(var(--spacing, .25rem) * 2);transition:width .3s cubic-bezier(.4,0,.2,1)}.toggle-btn{position:absolute;top:50%;z-index:50;display:flex;height:calc(var(--spacing, .25rem) * 6);width:calc(var(--spacing, .25rem) * 6);--tw-translate-y: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y);cursor:pointer;align-items:center;justify-content:center;border-radius:calc(infinity * 1px);border-style:var(--tw-border-style);border-width:1px;border-color:rgb(var(--border-default));background-color:rgb(var(--bg-primary));--tw-shadow: 0 1px 2px 0 var(--tw-shadow-color, rgb(var(--shadow-color) / .05));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);right:-12px;transition:all .2s ease}.toggle-btn:hover{background-color:rgb(var(--bg-primary-hover));--tw-shadow: 0 4px 6px -1px var(--tw-shadow-color, rgb(var(--shadow-color) / .1)), 0 2px 4px -2px var(--tw-shadow-color, rgb(var(--shadow-color) / .1));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.toggle-btn:active{transform:translateY(-50%) scale(.9)}.toggle-btn:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px;outline-offset:2px;outline-color:rgb(var(--primary))}.drawer-nav{flex:1;overflow-x:hidden;overflow-y:auto;padding-block:calc(var(--spacing, .25rem) * 2)}.drawer-nav::-webkit-scrollbar{width:calc(var(--spacing, .25rem) * 1.5)}.drawer-nav::-webkit-scrollbar-track{background-color:transparent}.drawer-nav::-webkit-scrollbar-thumb{border-radius:.125rem;background-color:rgb(var(--border-default))}.drawer-nav::-webkit-scrollbar-thumb:hover{background-color:rgb(var(--text-placeholder))}.drawer-item-wrapper{position:relative}.drawer-item{position:relative;margin-top:var(--spacing, .25rem);display:flex;min-height:calc(var(--spacing, .25rem) * 8);width:100%;cursor:pointer;align-items:center;border-radius:.25rem;--tw-border-style: none;border-style:none;background-color:transparent;padding-inline:1rem;padding-block:calc(var(--spacing, .25rem) * 2);color:rgb(var(--text-primary));text-decoration-line:none;transition:all .2s ease}.drawer-item:hover{--tw-scale-x: 95%;--tw-scale-y: 95%;--tw-scale-z: 95%;scale:var(--tw-scale-x) var(--tw-scale-y);background-color:rgb(var(--bg-primary-hover));color:rgb(var(--text-primary))}.drawer-item.active{background-image:linear-gradient(135deg,rgb(var(--gradient-primary-start)),rgb(var(--gradient-primary-end)));--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:var(--color-white, #fff)}.drawer-item.active .item-icon{color:var(--color-white, #fff)}.drawer-item:active{transform:scale(.98)}.drawer-item:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px;outline-offset:2px;outline-color:rgb(var(--primary))}.drawer-item{-webkit-tap-highlight-color:transparent;--tw-outline-style: none;outline-style:none}.item-content{display:flex;width:100%;align-items:center;gap:calc(var(--spacing, .25rem) * 3);overflow:hidden}.item-icon{flex-shrink:0;color:inherit}.item-label{flex:1;overflow:hidden;text-align:left;font-size:13px;--tw-leading: calc(var(--spacing, .25rem) * 5);line-height:calc(var(--spacing, .25rem) * 5);text-overflow:ellipsis;white-space:nowrap}.chevron-icon{margin-left:auto;flex-shrink:0;color:rgb(var(--text-primary));transition:transform .3s cubic-bezier(.4,0,.2,1)}.chevron-icon.rotated{transform:rotate(180deg)}.accordion-children{overflow:hidden}.drawer-version{display:flex;align-items:center;justify-content:center;border-top-style:var(--tw-border-style);border-top-width:1px;border-color:rgb(var(--border-default));padding-inline:calc(var(--spacing, .25rem) * 4);padding-block:calc(var(--spacing, .25rem) * 3);font-size:11px;color:rgb(var(--text-placeholder));-webkit-user-select:none;user-select:none;font-family:Roboto,monospace}.drawer-version-dot{display:block;height:calc(var(--spacing, .25rem) * 1.5);width:calc(var(--spacing, .25rem) * 1.5);border-radius:calc(infinity * 1px);background-color:rgb(var(--text-placeholder))}.drawer-container[style*=\"width: 64px\"] .drawer-item{justify-content:center;padding-left:16px!important}.drawer-container[style*=\"width: 64px\"] .item-content{justify-content:center}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-translate-x{syntax: \"*\"; inherits: false; initial-value: 0;}@property --tw-translate-y{syntax: \"*\"; inherits: false; initial-value: 0;}@property --tw-translate-z{syntax: \"*\"; inherits: false; initial-value: 0;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-outline-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-scale-x{syntax: \"*\"; inherits: false; initial-value: 1;}@property --tw-scale-y{syntax: \"*\"; inherits: false; initial-value: 1;}@property --tw-scale-z{syntax: \"*\"; inherits: false; initial-value: 1;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-leading{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-translate-x: 0;--tw-translate-y: 0;--tw-translate-z: 0;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000;--tw-outline-style: solid;--tw-scale-x: 1;--tw-scale-y: 1;--tw-scale-z: 1;--tw-font-weight: initial;--tw-leading: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"], dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1$5.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i57.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: HeroIconComponent, selector: "fx-ui-hero-icon", inputs: ["stroke", "icon", "solid", "outline", "size", "color", "class"] }], animations: [
4009
4170
  trigger('drawerExpand', [
4010
4171
  state('collapsed', style({ width: '70px' })),
4011
4172
  state('expanded', style({ width: '260px' })),
@@ -4018,7 +4179,7 @@ class DrawerComponent {
4018
4179
  ]),
4019
4180
  ] });
4020
4181
  }
4021
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: DrawerComponent, decorators: [{
4182
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: DrawerComponent, decorators: [{
4022
4183
  type: Component,
4023
4184
  args: [{ selector: 'fx-ui-drawer', standalone: false, animations: [
4024
4185
  trigger('drawerExpand', [
@@ -4031,8 +4192,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
4031
4192
  state('expanded', style({ height: '*', overflow: 'visible', opacity: 1 })),
4032
4193
  transition('collapsed <=> expanded', animate('300ms cubic-bezier(0.4, 0, 0.2, 1)')),
4033
4194
  ]),
4034
- ], template: "<div class=\"drawer-host-wrapper\">\n <a\n href=\"/\"\n class=\"h-[60px]\"\n [ngClass]=\"{ 'flex items-center justify-center': !isExpanded, 'p-4': isExpanded }\"\n >\n @if (logo) {\n <img\n [src]=\"logo\"\n class=\"h-[20px] w-auto transition-all duration-300 ease-in-out\"\n [ngClass]=\"{ 'scale-90': !isExpanded, 'ml-5': isExpanded }\"\n />\n } @else {\n <div class=\"h-[30px] w-auto transition-all duration-300 ease-in-out\"></div>\n }\n </a>\n <div class=\"drawer-container\" [@drawerExpand]=\"getDrawerState()\">\n <!-- Navigation Items -->\n <nav class=\"drawer-nav\">\n <ng-container *ngFor=\"let item of items\">\n <ng-container\n *ngTemplateOutlet=\"drawerItem; context: { $implicit: item, level: 0 }\"\n ></ng-container>\n </ng-container>\n </nav>\n\n <!-- Version -->\n <div *ngIf=\"version\" class=\"drawer-version\" [matTooltip]=\"!isExpanded ? version : ''\" matTooltipPosition=\"right\">\n <span *ngIf=\"isExpanded\">{{ version }}</span>\n <span *ngIf=\"!isExpanded\" class=\"drawer-version-dot\"></span>\n </div>\n </div>\n\n <!-- Floating Toggle Button on right border -->\n <button\n type=\"button\"\n class=\"toggle-btn\"\n (click)=\"toggleDrawer()\"\n [matTooltip]=\"isExpanded ? 'Collapse' : 'Expand'\"\n matTooltipClass=\"text-text-primary text-xs font-semibold\"\n matTooltipPosition=\"right\"\n >\n <fx-ui-hero-icon\n [icon]=\"isExpanded ? 'chevron-left' : 'chevron-right'\"\n [size]=\"16\"\n class=\"text-text-primary\"\n ></fx-ui-hero-icon>\n </button>\n</div>\n\n<!-- Recursive Template for Drawer Items -->\n<ng-template #drawerItem let-item let-level=\"level\">\n <div class=\"drawer-item-wrapper\">\n <!-- Item Button/Link -->\n <a\n *ngIf=\"item.route && !item.children\"\n [routerLink]=\"item.route\"\n class=\"drawer-item\"\n [class.active]=\"isActiveRoute(item.route)\"\n [class.has-children]=\"item.children && item.children.length > 0\"\n [style.paddingLeft.px]=\"isExpanded ? 16 + level * 16 : 16\"\n [matTooltip]=\"!isExpanded ? item.label : ''\"\n matTooltipPosition=\"right\"\n matTooltipClass=\"text-text-primary text-xs font-semibold\"\n (click)=\"onItemClick(item, $event)\"\n >\n <div class=\"item-content\">\n <fx-ui-hero-icon [icon]=\"item.icon\" [size]=\"20\" class=\"item-icon\"></fx-ui-hero-icon>\n <span *ngIf=\"isExpanded\" class=\"item-label\">{{ item.label }}</span>\n </div>\n </a>\n\n <button\n *ngIf=\"!item.route || item.children\"\n type=\"button\"\n class=\"drawer-item\"\n [class.active]=\"isActiveRoute(item.route)\"\n [class.has-children]=\"item.children && item.children.length > 0\"\n [style.paddingLeft.px]=\"isExpanded ? 16 + level * 16 : 16\"\n [matTooltip]=\"!isExpanded ? item.label : ''\"\n matTooltipPosition=\"right\"\n matTooltipClass=\"text-text-primary text-sm font-semibold\"\n (click)=\"onItemClick(item, $event)\"\n >\n <div class=\"item-content\">\n <fx-ui-hero-icon [icon]=\"item.icon\" [size]=\"20\" class=\"item-icon\"></fx-ui-hero-icon>\n <span *ngIf=\"isExpanded\" class=\"item-label\">{{ item.label }}</span>\n <fx-ui-hero-icon\n *ngIf=\"isExpanded && item.children && item.children.length > 0\"\n [icon]=\"'chevron-down'\"\n [size]=\"16\"\n class=\"chevron-icon\"\n [class.rotated]=\"isAccordionExpanded(item.id)\"\n ></fx-ui-hero-icon>\n </div>\n </button>\n\n <!-- Accordion Children -->\n <div\n *ngIf=\"item.children && item.children.length > 0\"\n class=\"accordion-children\"\n [@accordionExpand]=\"getAccordionState(item.id)\"\n >\n <ng-container *ngFor=\"let child of item.children\">\n <ng-container\n *ngTemplateOutlet=\"drawerItem; context: { $implicit: child, level: level + 1 }\"\n ></ng-container>\n </ng-container>\n </div>\n </div>\n</ng-template>\n", styles: ["@charset \"UTF-8\";:host{display:block;height:100%}.drawer-host-wrapper{position:relative;height:100%;border-right-width:1px;--tw-border-opacity: 1;border-color:rgb(var(--border-default) / var(--tw-border-opacity, 1))}.drawer-container{display:flex;height:100%;flex-direction:column;overflow:auto;--tw-bg-opacity: 1;background-color:rgb(var(--bg-primary) / var(--tw-bg-opacity, 1));padding-left:.5rem;padding-right:.5rem;transition:width .3s cubic-bezier(.4,0,.2,1)}.toggle-btn{position:absolute;top:50%;z-index:50;display:flex;height:1.5rem;width:1.5rem;--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));cursor:pointer;align-items:center;justify-content:center;border-radius:9999px;border-width:1px;--tw-border-opacity: 1;border-color:rgb(var(--border-default) / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(var(--bg-primary) / var(--tw-bg-opacity, 1));--tw-shadow: 0 1px 2px 0 rgb(var(--shadow-color) / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow);right:-12px;transition:all .2s ease}.toggle-btn:hover{--tw-bg-opacity: 1;background-color:rgb(var(--bg-primary-hover) / var(--tw-bg-opacity, 1));--tw-shadow: 0 4px 6px -1px rgb(var(--shadow-color) / .1), 0 2px 4px -2px rgb(var(--shadow-color) / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.toggle-btn:active{transform:translateY(-50%) scale(.9)}.toggle-btn:focus-visible{outline-width:2px;outline-offset:2px;outline-color:rgb(var(--primary) / 1)}.drawer-nav{flex:1 1 0%;overflow-y:auto;overflow-x:hidden;padding-top:.5rem;padding-bottom:.5rem}.drawer-nav::-webkit-scrollbar{width:.375rem}.drawer-nav::-webkit-scrollbar-track{background-color:transparent}.drawer-nav::-webkit-scrollbar-thumb{border-radius:.125rem;--tw-bg-opacity: 1;background-color:rgb(var(--border-default) / var(--tw-bg-opacity, 1))}.drawer-nav::-webkit-scrollbar-thumb:hover{--tw-bg-opacity: 1;background-color:rgb(var(--text-placeholder) / var(--tw-bg-opacity, 1))}.drawer-item-wrapper{position:relative}.drawer-item{position:relative;margin-top:.25rem;display:flex;min-height:2rem;width:100%;cursor:pointer;align-items:center;border-radius:.25rem;border-style:none;background-color:transparent;padding:.5rem 1rem;--tw-text-opacity: 1;color:rgb(var(--text-primary) / var(--tw-text-opacity, 1));text-decoration-line:none;transition:all .2s ease;-webkit-tap-highlight-color:transparent;outline:2px solid transparent;outline-offset:2px}.drawer-item:hover{--tw-scale-x: .95;--tw-scale-y: .95;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));--tw-bg-opacity: 1;background-color:rgb(var(--bg-primary-hover) / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(var(--text-primary) / var(--tw-text-opacity, 1))}.drawer-item.active{background-image:linear-gradient(135deg,rgb(var(--gradient-primary-start)),rgb(var(--gradient-primary-end)));font-weight:500;--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.drawer-item.active .item-icon{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.drawer-item:active{transform:scale(.98)}.drawer-item:focus-visible{outline-width:2px;outline-offset:2px;outline-color:rgb(var(--primary) / 1)}.item-content{display:flex;width:100%;align-items:center;gap:.75rem;overflow:hidden}.item-icon{flex-shrink:0;color:inherit}.item-label{flex:1 1 0%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:left;font-size:13px;line-height:1.25rem}.chevron-icon{margin-left:auto;flex-shrink:0;--tw-text-opacity: 1;color:rgb(var(--text-primary) / var(--tw-text-opacity, 1));transition:transform .3s cubic-bezier(.4,0,.2,1)}.chevron-icon.rotated{transform:rotate(180deg)}.accordion-children{overflow:hidden}.drawer-version{display:flex;-webkit-user-select:none;user-select:none;align-items:center;justify-content:center;border-top-width:1px;--tw-border-opacity: 1;border-color:rgb(var(--border-default) / var(--tw-border-opacity, 1));padding:.75rem 1rem;font-size:11px;--tw-text-opacity: 1;color:rgb(var(--text-placeholder) / var(--tw-text-opacity, 1));font-family:Roboto,monospace}.drawer-version-dot{display:block;height:.375rem;width:.375rem;border-radius:9999px;--tw-bg-opacity: 1;background-color:rgb(var(--text-placeholder) / var(--tw-bg-opacity, 1))}.drawer-container[style*=\"width: 64px\"] .drawer-item{justify-content:center;padding-left:16px!important}.drawer-container[style*=\"width: 64px\"] .item-content{justify-content:center}\n"] }]
4035
- }], ctorParameters: () => [{ type: i1$4.Router }], propDecorators: { items: [{
4195
+ ], template: "<div class=\"drawer-host-wrapper\">\n <a\n href=\"/\"\n class=\"h-[60px]\"\n [ngClass]=\"{ 'flex items-center justify-center': !isExpanded, 'p-4': isExpanded }\"\n >\n @if (logo) {\n <img\n [src]=\"logo\"\n alt=\"Home\"\n class=\"h-[20px] w-auto transition-all duration-300 ease-in-out\"\n [ngClass]=\"{ 'scale-90': !isExpanded, 'ml-5': isExpanded }\"\n />\n } @else {\n <div class=\"h-[30px] w-auto transition-all duration-300 ease-in-out\"></div>\n }\n </a>\n <div class=\"drawer-container\" [@drawerExpand]=\"getDrawerState()\">\n <!-- Navigation Items -->\n <nav class=\"drawer-nav\">\n @for (item of items; track item) {\n <ng-container\n *ngTemplateOutlet=\"drawerItem; context: { $implicit: item, level: 0 }\"\n ></ng-container>\n }\n </nav>\n\n <!-- Version -->\n @if (version) {\n <div class=\"drawer-version\" [matTooltip]=\"!isExpanded ? version : ''\" matTooltipPosition=\"right\">\n @if (isExpanded) {\n <span>{{ version }}</span>\n }\n @if (!isExpanded) {\n <span class=\"drawer-version-dot\"></span>\n }\n </div>\n }\n </div>\n\n <!-- Floating Toggle Button on right border -->\n <button\n type=\"button\"\n class=\"toggle-btn\"\n [attr.aria-label]=\"isExpanded ? 'Collapse navigation' : 'Expand navigation'\"\n [attr.aria-expanded]=\"isExpanded\"\n (click)=\"toggleDrawer()\"\n [matTooltip]=\"isExpanded ? 'Collapse' : 'Expand'\"\n matTooltipClass=\"text-text-primary text-xs font-semibold\"\n matTooltipPosition=\"right\"\n >\n <fx-ui-hero-icon\n [icon]=\"isExpanded ? 'chevron-left' : 'chevron-right'\"\n [size]=\"16\"\n class=\"text-text-primary\"\n ></fx-ui-hero-icon>\n </button>\n</div>\n\n<!-- Recursive Template for Drawer Items -->\n<ng-template #drawerItem let-item let-level=\"level\">\n <div class=\"drawer-item-wrapper\">\n <!-- Item Button/Link -->\n @if (item.route && !item.children) {\n <a\n [routerLink]=\"item.route\"\n class=\"drawer-item\"\n [class.active]=\"isActiveRoute(item.route)\"\n [class.has-children]=\"item.children && item.children.length > 0\"\n [style.paddingLeft.px]=\"isExpanded ? 16 + level * 16 : 16\"\n [matTooltip]=\"!isExpanded ? item.label : ''\"\n matTooltipPosition=\"right\"\n matTooltipClass=\"text-text-primary text-xs font-semibold\"\n (click)=\"onItemClick(item, $event)\"\n >\n <div class=\"item-content\">\n <fx-ui-hero-icon [icon]=\"item.icon\" [size]=\"20\" class=\"item-icon\"></fx-ui-hero-icon>\n @if (isExpanded) {\n <span class=\"item-label\">{{ item.label }}</span>\n }\n </div>\n </a>\n }\n\n @if (!item.route || item.children) {\n <button\n type=\"button\"\n class=\"drawer-item\"\n [class.active]=\"isActiveRoute(item.route)\"\n [class.has-children]=\"item.children && item.children.length > 0\"\n [style.paddingLeft.px]=\"isExpanded ? 16 + level * 16 : 16\"\n [matTooltip]=\"!isExpanded ? item.label : ''\"\n matTooltipPosition=\"right\"\n matTooltipClass=\"text-text-primary text-sm font-semibold\"\n (click)=\"onItemClick(item, $event)\"\n >\n <div class=\"item-content\">\n <fx-ui-hero-icon [icon]=\"item.icon\" [size]=\"20\" class=\"item-icon\"></fx-ui-hero-icon>\n @if (isExpanded) {\n <span class=\"item-label\">{{ item.label }}</span>\n }\n @if (isExpanded && item.children && item.children.length > 0) {\n <fx-ui-hero-icon\n [icon]=\"'chevron-down'\"\n [size]=\"16\"\n class=\"chevron-icon\"\n [class.rotated]=\"isAccordionExpanded(item.id)\"\n ></fx-ui-hero-icon>\n }\n </div>\n </button>\n }\n\n <!-- Accordion Children -->\n @if (item.children && item.children.length > 0) {\n <div\n class=\"accordion-children\"\n [@accordionExpand]=\"getAccordionState(item.id)\"\n >\n @for (child of item.children; track child) {\n <ng-container\n *ngTemplateOutlet=\"drawerItem; context: { $implicit: child, level: level + 1 }\"\n ></ng-container>\n }\n </div>\n }\n </div>\n</ng-template>\n", styles: ["@charset \"UTF-8\";@layer properties;:host{display:block;height:100%}.drawer-host-wrapper{position:relative;height:100%;border-right-style:var(--tw-border-style);border-right-width:1px;border-color:rgb(var(--border-default))}.drawer-container{display:flex;height:100%;flex-direction:column;overflow:auto;background-color:rgb(var(--bg-primary));padding-inline:calc(var(--spacing, .25rem) * 2);transition:width .3s cubic-bezier(.4,0,.2,1)}.toggle-btn{position:absolute;top:50%;z-index:50;display:flex;height:calc(var(--spacing, .25rem) * 6);width:calc(var(--spacing, .25rem) * 6);--tw-translate-y: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y);cursor:pointer;align-items:center;justify-content:center;border-radius:calc(infinity * 1px);border-style:var(--tw-border-style);border-width:1px;border-color:rgb(var(--border-default));background-color:rgb(var(--bg-primary));--tw-shadow: 0 1px 2px 0 var(--tw-shadow-color, rgb(var(--shadow-color) / .05));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);right:-12px;transition:all .2s ease}.toggle-btn:hover{background-color:rgb(var(--bg-primary-hover));--tw-shadow: 0 4px 6px -1px var(--tw-shadow-color, rgb(var(--shadow-color) / .1)), 0 2px 4px -2px var(--tw-shadow-color, rgb(var(--shadow-color) / .1));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.toggle-btn:active{transform:translateY(-50%) scale(.9)}.toggle-btn:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px;outline-offset:2px;outline-color:rgb(var(--primary))}.drawer-nav{flex:1;overflow-x:hidden;overflow-y:auto;padding-block:calc(var(--spacing, .25rem) * 2)}.drawer-nav::-webkit-scrollbar{width:calc(var(--spacing, .25rem) * 1.5)}.drawer-nav::-webkit-scrollbar-track{background-color:transparent}.drawer-nav::-webkit-scrollbar-thumb{border-radius:.125rem;background-color:rgb(var(--border-default))}.drawer-nav::-webkit-scrollbar-thumb:hover{background-color:rgb(var(--text-placeholder))}.drawer-item-wrapper{position:relative}.drawer-item{position:relative;margin-top:var(--spacing, .25rem);display:flex;min-height:calc(var(--spacing, .25rem) * 8);width:100%;cursor:pointer;align-items:center;border-radius:.25rem;--tw-border-style: none;border-style:none;background-color:transparent;padding-inline:1rem;padding-block:calc(var(--spacing, .25rem) * 2);color:rgb(var(--text-primary));text-decoration-line:none;transition:all .2s ease}.drawer-item:hover{--tw-scale-x: 95%;--tw-scale-y: 95%;--tw-scale-z: 95%;scale:var(--tw-scale-x) var(--tw-scale-y);background-color:rgb(var(--bg-primary-hover));color:rgb(var(--text-primary))}.drawer-item.active{background-image:linear-gradient(135deg,rgb(var(--gradient-primary-start)),rgb(var(--gradient-primary-end)));--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:var(--color-white, #fff)}.drawer-item.active .item-icon{color:var(--color-white, #fff)}.drawer-item:active{transform:scale(.98)}.drawer-item:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px;outline-offset:2px;outline-color:rgb(var(--primary))}.drawer-item{-webkit-tap-highlight-color:transparent;--tw-outline-style: none;outline-style:none}.item-content{display:flex;width:100%;align-items:center;gap:calc(var(--spacing, .25rem) * 3);overflow:hidden}.item-icon{flex-shrink:0;color:inherit}.item-label{flex:1;overflow:hidden;text-align:left;font-size:13px;--tw-leading: calc(var(--spacing, .25rem) * 5);line-height:calc(var(--spacing, .25rem) * 5);text-overflow:ellipsis;white-space:nowrap}.chevron-icon{margin-left:auto;flex-shrink:0;color:rgb(var(--text-primary));transition:transform .3s cubic-bezier(.4,0,.2,1)}.chevron-icon.rotated{transform:rotate(180deg)}.accordion-children{overflow:hidden}.drawer-version{display:flex;align-items:center;justify-content:center;border-top-style:var(--tw-border-style);border-top-width:1px;border-color:rgb(var(--border-default));padding-inline:calc(var(--spacing, .25rem) * 4);padding-block:calc(var(--spacing, .25rem) * 3);font-size:11px;color:rgb(var(--text-placeholder));-webkit-user-select:none;user-select:none;font-family:Roboto,monospace}.drawer-version-dot{display:block;height:calc(var(--spacing, .25rem) * 1.5);width:calc(var(--spacing, .25rem) * 1.5);border-radius:calc(infinity * 1px);background-color:rgb(var(--text-placeholder))}.drawer-container[style*=\"width: 64px\"] .drawer-item{justify-content:center;padding-left:16px!important}.drawer-container[style*=\"width: 64px\"] .item-content{justify-content:center}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-translate-x{syntax: \"*\"; inherits: false; initial-value: 0;}@property --tw-translate-y{syntax: \"*\"; inherits: false; initial-value: 0;}@property --tw-translate-z{syntax: \"*\"; inherits: false; initial-value: 0;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-outline-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-scale-x{syntax: \"*\"; inherits: false; initial-value: 1;}@property --tw-scale-y{syntax: \"*\"; inherits: false; initial-value: 1;}@property --tw-scale-z{syntax: \"*\"; inherits: false; initial-value: 1;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-leading{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-translate-x: 0;--tw-translate-y: 0;--tw-translate-z: 0;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000;--tw-outline-style: solid;--tw-scale-x: 1;--tw-scale-y: 1;--tw-scale-z: 1;--tw-font-weight: initial;--tw-leading: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"] }]
4196
+ }], ctorParameters: () => [{ type: i1$5.Router }], propDecorators: { items: [{
4036
4197
  type: Input
4037
4198
  }], isExpanded: [{
4038
4199
  type: Input
@@ -4052,12 +4213,12 @@ class SkeletonListComponent {
4052
4213
  range(n) {
4053
4214
  return Array.from({ length: Number(n) || 0 }, (_, i) => i);
4054
4215
  }
4055
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: SkeletonListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4056
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: SkeletonListComponent, isStandalone: false, selector: "fx-ui-skeleton-list", inputs: { rows: "rows" }, ngImport: i0, template: "<div class=\"flex flex-col gap-normal animate-pulse\">\n @for (r of range(rows); track r) {\n <div class=\"rounded-normal border border-border-default p-semi\">\n <div class=\"flex items-center gap-normal mb-small\">\n <div class=\"w-8 h-8 rounded-normal bg-bg-hover shrink-0\"></div>\n <div class=\"h-4 flex-1 rounded bg-bg-hover\"></div>\n <div class=\"h-5 w-12 rounded-full bg-bg-hover shrink-0\"></div>\n </div>\n <div class=\"h-3 w-3/4 rounded bg-bg-hover\"></div>\n </div>\n }\n</div>\n" });
4216
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: SkeletonListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4217
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: SkeletonListComponent, isStandalone: false, selector: "fx-ui-skeleton-list", inputs: { rows: "rows" }, ngImport: i0, template: "<div class=\"flex flex-col gap-normal animate-pulse\">\n @for (r of range(rows); track r) {\n <div class=\"rounded-lg border border-border-default p-semi\">\n <div class=\"flex items-center gap-normal mb-small\">\n <div class=\"w-8 h-8 rounded-lg bg-bg-hover shrink-0\"></div>\n <div class=\"h-4 flex-1 rounded bg-bg-hover\"></div>\n <div class=\"h-5 w-12 rounded-full bg-bg-hover shrink-0\"></div>\n </div>\n <div class=\"h-3 w-3/4 rounded bg-bg-hover\"></div>\n </div>\n }\n</div>\n" });
4057
4218
  }
4058
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: SkeletonListComponent, decorators: [{
4219
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: SkeletonListComponent, decorators: [{
4059
4220
  type: Component,
4060
- args: [{ selector: 'fx-ui-skeleton-list', standalone: false, template: "<div class=\"flex flex-col gap-normal animate-pulse\">\n @for (r of range(rows); track r) {\n <div class=\"rounded-normal border border-border-default p-semi\">\n <div class=\"flex items-center gap-normal mb-small\">\n <div class=\"w-8 h-8 rounded-normal bg-bg-hover shrink-0\"></div>\n <div class=\"h-4 flex-1 rounded bg-bg-hover\"></div>\n <div class=\"h-5 w-12 rounded-full bg-bg-hover shrink-0\"></div>\n </div>\n <div class=\"h-3 w-3/4 rounded bg-bg-hover\"></div>\n </div>\n }\n</div>\n" }]
4221
+ args: [{ selector: 'fx-ui-skeleton-list', standalone: false, template: "<div class=\"flex flex-col gap-normal animate-pulse\">\n @for (r of range(rows); track r) {\n <div class=\"rounded-lg border border-border-default p-semi\">\n <div class=\"flex items-center gap-normal mb-small\">\n <div class=\"w-8 h-8 rounded-lg bg-bg-hover shrink-0\"></div>\n <div class=\"h-4 flex-1 rounded bg-bg-hover\"></div>\n <div class=\"h-5 w-12 rounded-full bg-bg-hover shrink-0\"></div>\n </div>\n <div class=\"h-3 w-3/4 rounded bg-bg-hover\"></div>\n </div>\n }\n</div>\n" }]
4061
4222
  }], propDecorators: { rows: [{
4062
4223
  type: Input
4063
4224
  }] } });
@@ -4074,10 +4235,10 @@ class SkeletonDetailComponent {
4074
4235
  rowWidth(i) {
4075
4236
  return [90, 70, 80, 60][i % 4];
4076
4237
  }
4077
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: SkeletonDetailComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4078
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: SkeletonDetailComponent, isStandalone: false, selector: "fx-ui-skeleton-detail", inputs: { cards: "cards", rows: "rows" }, ngImport: i0, template: "<div class=\"flex flex-col gap-xl animate-pulse\">\n <div class=\"card-common\">\n <div class=\"flex items-start gap-normal\">\n <div class=\"w-10 h-10 rounded-lg bg-bg-hover shrink-0\"></div>\n <div class=\"flex-1 min-w-0 flex flex-col gap-normal\">\n <div class=\"h-5 w-1/2 rounded bg-bg-hover\"></div>\n <div class=\"h-3 w-3/4 rounded bg-bg-hover\"></div>\n </div>\n </div>\n </div>\n\n @for (c of range(cards); track c) {\n <div class=\"card-common flex flex-col gap-large\">\n <div class=\"h-4 w-1/3 rounded bg-bg-hover\"></div>\n <div class=\"flex flex-col gap-normal\">\n @for (r of range(rows); track r) {\n <div class=\"h-3 rounded bg-bg-hover\" [style.width.%]=\"rowWidth(r)\"></div>\n }\n </div>\n </div>\n }\n</div>\n" });
4238
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: SkeletonDetailComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4239
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: SkeletonDetailComponent, isStandalone: false, selector: "fx-ui-skeleton-detail", inputs: { cards: "cards", rows: "rows" }, ngImport: i0, template: "<div class=\"flex flex-col gap-xl animate-pulse\">\n <div class=\"card-common\">\n <div class=\"flex items-start gap-normal\">\n <div class=\"w-10 h-10 rounded-lg bg-bg-hover shrink-0\"></div>\n <div class=\"flex-1 min-w-0 flex flex-col gap-normal\">\n <div class=\"h-5 w-1/2 rounded bg-bg-hover\"></div>\n <div class=\"h-3 w-3/4 rounded bg-bg-hover\"></div>\n </div>\n </div>\n </div>\n\n @for (c of range(cards); track c) {\n <div class=\"card-common flex flex-col gap-large\">\n <div class=\"h-4 w-1/3 rounded bg-bg-hover\"></div>\n <div class=\"flex flex-col gap-normal\">\n @for (r of range(rows); track r) {\n <div class=\"h-3 rounded bg-bg-hover\" [style.width.%]=\"rowWidth(r)\"></div>\n }\n </div>\n </div>\n }\n</div>\n" });
4079
4240
  }
4080
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: SkeletonDetailComponent, decorators: [{
4241
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: SkeletonDetailComponent, decorators: [{
4081
4242
  type: Component,
4082
4243
  args: [{ selector: 'fx-ui-skeleton-detail', standalone: false, template: "<div class=\"flex flex-col gap-xl animate-pulse\">\n <div class=\"card-common\">\n <div class=\"flex items-start gap-normal\">\n <div class=\"w-10 h-10 rounded-lg bg-bg-hover shrink-0\"></div>\n <div class=\"flex-1 min-w-0 flex flex-col gap-normal\">\n <div class=\"h-5 w-1/2 rounded bg-bg-hover\"></div>\n <div class=\"h-3 w-3/4 rounded bg-bg-hover\"></div>\n </div>\n </div>\n </div>\n\n @for (c of range(cards); track c) {\n <div class=\"card-common flex flex-col gap-large\">\n <div class=\"h-4 w-1/3 rounded bg-bg-hover\"></div>\n <div class=\"flex flex-col gap-normal\">\n @for (r of range(rows); track r) {\n <div class=\"h-3 rounded bg-bg-hover\" [style.width.%]=\"rowWidth(r)\"></div>\n }\n </div>\n </div>\n }\n</div>\n" }]
4083
4244
  }], propDecorators: { cards: [{
@@ -4102,12 +4263,12 @@ class StatCardsComponent {
4102
4263
  return card.tone ? toneText(card.tone) : 'text-text-primary';
4103
4264
  }
4104
4265
  boxClass(card) {
4105
- return card.tone ? `bg-${card.tone}/10 ${toneText(card.tone)}` : 'bg-bg-hover text-text-secondary';
4266
+ return card.tone ? toneBadge(card.tone) : 'bg-bg-hover text-text-secondary';
4106
4267
  }
4107
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: StatCardsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4108
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: StatCardsComponent, isStandalone: false, selector: "fx-ui-stat-cards", inputs: { cards: "cards", cols: "cols" }, ngImport: i0, template: "<div class=\"grid gap-normal\" [ngStyle]=\"{ 'grid-template-columns': gridColumns }\">\n @for (card of cards; track card.label) {\n <div class=\"card-common flex items-center gap-normal\">\n @if (card.icon) {\n <div\n class=\"w-10 h-10 rounded-lg flex items-center justify-center shrink-0\"\n [ngClass]=\"boxClass(card)\"\n >\n <fx-ui-hero-icon [icon]=\"card.icon\" [size]=\"20\"></fx-ui-hero-icon>\n </div>\n }\n <div class=\"flex flex-col min-w-0\">\n <span class=\"txt-heading-04\" [ngClass]=\"numClass(card)\">{{ card.value }}</span>\n <span class=\"txt-utility-caption text-text-secondary truncate\">{{ card.label }}</span>\n </div>\n </div>\n }\n</div>\n", dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: HeroIconComponent, selector: "fx-ui-hero-icon", inputs: ["stroke", "icon", "solid", "outline", "size", "color", "class"] }] });
4268
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: StatCardsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4269
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: StatCardsComponent, isStandalone: false, selector: "fx-ui-stat-cards", inputs: { cards: "cards", cols: "cols" }, ngImport: i0, template: "<div class=\"grid gap-normal\" [ngStyle]=\"{ 'grid-template-columns': gridColumns }\">\n @for (card of cards; track card.label) {\n <div class=\"card-common flex items-center gap-normal\">\n @if (card.icon) {\n <div\n class=\"w-10 h-10 rounded-lg flex items-center justify-center shrink-0\"\n [ngClass]=\"boxClass(card)\"\n >\n <fx-ui-hero-icon [icon]=\"card.icon\" [size]=\"20\"></fx-ui-hero-icon>\n </div>\n }\n <div class=\"flex flex-col min-w-0\">\n <span class=\"txt-heading-04\" [ngClass]=\"numClass(card)\">{{ card.value }}</span>\n <span class=\"txt-utility-caption text-text-secondary truncate\">{{ card.label }}</span>\n </div>\n </div>\n }\n</div>\n", dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: HeroIconComponent, selector: "fx-ui-hero-icon", inputs: ["stroke", "icon", "solid", "outline", "size", "color", "class"] }] });
4109
4270
  }
4110
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: StatCardsComponent, decorators: [{
4271
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: StatCardsComponent, decorators: [{
4111
4272
  type: Component,
4112
4273
  args: [{ selector: 'fx-ui-stat-cards', standalone: false, template: "<div class=\"grid gap-normal\" [ngStyle]=\"{ 'grid-template-columns': gridColumns }\">\n @for (card of cards; track card.label) {\n <div class=\"card-common flex items-center gap-normal\">\n @if (card.icon) {\n <div\n class=\"w-10 h-10 rounded-lg flex items-center justify-center shrink-0\"\n [ngClass]=\"boxClass(card)\"\n >\n <fx-ui-hero-icon [icon]=\"card.icon\" [size]=\"20\"></fx-ui-hero-icon>\n </div>\n }\n <div class=\"flex flex-col min-w-0\">\n <span class=\"txt-heading-04\" [ngClass]=\"numClass(card)\">{{ card.value }}</span>\n <span class=\"txt-utility-caption text-text-secondary truncate\">{{ card.label }}</span>\n </div>\n </div>\n }\n</div>\n" }]
4113
4274
  }], propDecorators: { cards: [{
@@ -4123,10 +4284,10 @@ class EmptyStateComponent {
4123
4284
  icon;
4124
4285
  /** Min height of the block, CSS length. */
4125
4286
  height = '120px';
4126
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: EmptyStateComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4127
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: EmptyStateComponent, isStandalone: false, selector: "fx-ui-empty-state", inputs: { message: "message", icon: "icon", height: "height" }, ngImport: i0, template: "<div\n class=\"flex flex-col items-center justify-center gap-small w-full\"\n [style.minHeight]=\"height\"\n>\n @if (icon) {\n <fx-ui-hero-icon class=\"text-text-placeholder\" [icon]=\"icon\" [size]=\"24\"></fx-ui-hero-icon>\n }\n <div class=\"txt-default text-text-placeholder\">{{ message }}</div>\n</div>\n", dependencies: [{ kind: "component", type: HeroIconComponent, selector: "fx-ui-hero-icon", inputs: ["stroke", "icon", "solid", "outline", "size", "color", "class"] }] });
4287
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: EmptyStateComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4288
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: EmptyStateComponent, isStandalone: false, selector: "fx-ui-empty-state", inputs: { message: "message", icon: "icon", height: "height" }, ngImport: i0, template: "<div\n class=\"flex flex-col items-center justify-center gap-small w-full\"\n [style.minHeight]=\"height\"\n>\n @if (icon) {\n <fx-ui-hero-icon class=\"text-text-placeholder\" [icon]=\"icon\" [size]=\"24\"></fx-ui-hero-icon>\n }\n <div class=\"txt-default text-text-placeholder\">{{ message }}</div>\n</div>\n", dependencies: [{ kind: "component", type: HeroIconComponent, selector: "fx-ui-hero-icon", inputs: ["stroke", "icon", "solid", "outline", "size", "color", "class"] }] });
4128
4289
  }
4129
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: EmptyStateComponent, decorators: [{
4290
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: EmptyStateComponent, decorators: [{
4130
4291
  type: Component,
4131
4292
  args: [{ selector: 'fx-ui-empty-state', standalone: false, template: "<div\n class=\"flex flex-col items-center justify-center gap-small w-full\"\n [style.minHeight]=\"height\"\n>\n @if (icon) {\n <fx-ui-hero-icon class=\"text-text-placeholder\" [icon]=\"icon\" [size]=\"24\"></fx-ui-hero-icon>\n }\n <div class=\"txt-default text-text-placeholder\">{{ message }}</div>\n</div>\n" }]
4132
4293
  }], propDecorators: { message: [{
@@ -4165,12 +4326,12 @@ class FilterChipsComponent {
4165
4326
  if (!tone) {
4166
4327
  return active ? 'bg-text-primary text-text-focus' : `${toneBadge(null)} hover:opacity-50`;
4167
4328
  }
4168
- return active ? `bg-${tone} text-text-focus` : `${toneBadge(tone)} hover:opacity-50`;
4329
+ return active ? `${toneBg(tone)} text-text-focus` : `${toneBadge(tone)} hover:opacity-50`;
4169
4330
  }
4170
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: FilterChipsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4171
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: FilterChipsComponent, isStandalone: false, selector: "fx-ui-filter-chips", inputs: { options: "options", value: "value", toneOverrides: "toneOverrides" }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: "<div class=\"flex flex-wrap items-center gap-small\">\n @for (option of options; track option.value) {\n <button\n type=\"button\"\n class=\"px-3 py-1 rounded-full txt-utility-caption font-medium transition-colors cursor-pointer\"\n [ngClass]=\"chipClass(option)\"\n (click)=\"select(option)\"\n >\n {{ option.label }}\n </button>\n }\n</div>\n", dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
4331
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: FilterChipsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4332
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: FilterChipsComponent, isStandalone: false, selector: "fx-ui-filter-chips", inputs: { options: "options", value: "value", toneOverrides: "toneOverrides" }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: "<div class=\"flex flex-wrap items-center gap-small\">\n @for (option of options; track option.value) {\n <button\n type=\"button\"\n class=\"px-3 py-1 rounded-full txt-utility-caption font-medium transition-colors cursor-pointer\"\n [ngClass]=\"chipClass(option)\"\n (click)=\"select(option)\"\n >\n {{ option.label }}\n </button>\n }\n</div>\n", dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
4172
4333
  }
4173
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: FilterChipsComponent, decorators: [{
4334
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: FilterChipsComponent, decorators: [{
4174
4335
  type: Component,
4175
4336
  args: [{ selector: 'fx-ui-filter-chips', standalone: false, template: "<div class=\"flex flex-wrap items-center gap-small\">\n @for (option of options; track option.value) {\n <button\n type=\"button\"\n class=\"px-3 py-1 rounded-full txt-utility-caption font-medium transition-colors cursor-pointer\"\n [ngClass]=\"chipClass(option)\"\n (click)=\"select(option)\"\n >\n {{ option.label }}\n </button>\n }\n</div>\n" }]
4176
4337
  }], propDecorators: { options: [{
@@ -4199,12 +4360,12 @@ class MeterComponent {
4199
4360
  get fillClass() {
4200
4361
  return toneBg(this.tone);
4201
4362
  }
4202
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: MeterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4203
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: MeterComponent, isStandalone: false, selector: "fx-ui-meter", inputs: { value: "value", max: "max", tone: "tone", label: "label", caption: "caption" }, ngImport: i0, template: "<div class=\"flex flex-col gap-small w-full\">\n @if (label || caption) {\n <div class=\"flex items-center justify-between gap-normal\">\n @if (label) {\n <span class=\"txt-field-label !mb-0\">{{ label }}</span>\n }\n @if (caption) {\n <span class=\"txt-utility-caption text-text-secondary\">{{ caption }}</span>\n }\n </div>\n }\n <div class=\"h-2 rounded-full bg-bg-hover overflow-hidden\">\n <div class=\"h-full rounded-full\" [ngClass]=\"fillClass\" [style.width.%]=\"percent\"></div>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
4363
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: MeterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4364
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: MeterComponent, isStandalone: false, selector: "fx-ui-meter", inputs: { value: "value", max: "max", tone: "tone", label: "label", caption: "caption" }, ngImport: i0, template: "<div class=\"flex flex-col gap-small w-full\">\n @if (label || caption) {\n <div class=\"flex items-center justify-between gap-normal\">\n @if (label) {\n <span class=\"txt-field-label !mb-0\">{{ label }}</span>\n }\n @if (caption) {\n <span class=\"txt-utility-caption text-text-secondary\">{{ caption }}</span>\n }\n </div>\n }\n <div\n class=\"h-2 rounded-full bg-bg-hover overflow-hidden\"\n role=\"progressbar\"\n [attr.aria-valuemin]=\"0\"\n [attr.aria-valuemax]=\"max\"\n [attr.aria-valuenow]=\"value\"\n [attr.aria-label]=\"label || null\"\n >\n <div class=\"h-full rounded-full\" [ngClass]=\"fillClass\" [style.width.%]=\"percent\"></div>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
4204
4365
  }
4205
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: MeterComponent, decorators: [{
4366
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: MeterComponent, decorators: [{
4206
4367
  type: Component,
4207
- args: [{ selector: 'fx-ui-meter', standalone: false, template: "<div class=\"flex flex-col gap-small w-full\">\n @if (label || caption) {\n <div class=\"flex items-center justify-between gap-normal\">\n @if (label) {\n <span class=\"txt-field-label !mb-0\">{{ label }}</span>\n }\n @if (caption) {\n <span class=\"txt-utility-caption text-text-secondary\">{{ caption }}</span>\n }\n </div>\n }\n <div class=\"h-2 rounded-full bg-bg-hover overflow-hidden\">\n <div class=\"h-full rounded-full\" [ngClass]=\"fillClass\" [style.width.%]=\"percent\"></div>\n </div>\n</div>\n" }]
4368
+ args: [{ selector: 'fx-ui-meter', standalone: false, template: "<div class=\"flex flex-col gap-small w-full\">\n @if (label || caption) {\n <div class=\"flex items-center justify-between gap-normal\">\n @if (label) {\n <span class=\"txt-field-label !mb-0\">{{ label }}</span>\n }\n @if (caption) {\n <span class=\"txt-utility-caption text-text-secondary\">{{ caption }}</span>\n }\n </div>\n }\n <div\n class=\"h-2 rounded-full bg-bg-hover overflow-hidden\"\n role=\"progressbar\"\n [attr.aria-valuemin]=\"0\"\n [attr.aria-valuemax]=\"max\"\n [attr.aria-valuenow]=\"value\"\n [attr.aria-label]=\"label || null\"\n >\n <div class=\"h-full rounded-full\" [ngClass]=\"fillClass\" [style.width.%]=\"percent\"></div>\n </div>\n</div>\n" }]
4208
4369
  }], propDecorators: { value: [{
4209
4370
  type: Input
4210
4371
  }], max: [{
@@ -4227,10 +4388,10 @@ class SectionCardComponent {
4227
4388
  get iconClass() {
4228
4389
  return this.iconTone ? toneText(this.iconTone) : 'text-text-secondary';
4229
4390
  }
4230
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: SectionCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4231
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: SectionCardComponent, isStandalone: false, selector: "fx-ui-section-card", inputs: { title: "title", icon: "icon", iconTone: "iconTone" }, ngImport: i0, template: "<div class=\"card-common\">\n <div class=\"flex items-center gap-normal mb-large\">\n @if (icon) {\n <fx-ui-hero-icon [ngClass]=\"iconClass\" [icon]=\"icon\" [size]=\"18\"></fx-ui-hero-icon>\n }\n <span class=\"txt-heading-06\">{{ title }}</span>\n </div>\n <ng-content></ng-content>\n</div>\n", dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: HeroIconComponent, selector: "fx-ui-hero-icon", inputs: ["stroke", "icon", "solid", "outline", "size", "color", "class"] }] });
4391
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: SectionCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4392
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: SectionCardComponent, isStandalone: false, selector: "fx-ui-section-card", inputs: { title: "title", icon: "icon", iconTone: "iconTone" }, ngImport: i0, template: "<div class=\"card-common\">\n <div class=\"flex items-center gap-normal mb-large\">\n @if (icon) {\n <fx-ui-hero-icon [ngClass]=\"iconClass\" [icon]=\"icon\" [size]=\"18\"></fx-ui-hero-icon>\n }\n <span class=\"txt-heading-06\">{{ title }}</span>\n </div>\n <ng-content></ng-content>\n</div>\n", dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: HeroIconComponent, selector: "fx-ui-hero-icon", inputs: ["stroke", "icon", "solid", "outline", "size", "color", "class"] }] });
4232
4393
  }
4233
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: SectionCardComponent, decorators: [{
4394
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: SectionCardComponent, decorators: [{
4234
4395
  type: Component,
4235
4396
  args: [{ selector: 'fx-ui-section-card', standalone: false, template: "<div class=\"card-common\">\n <div class=\"flex items-center gap-normal mb-large\">\n @if (icon) {\n <fx-ui-hero-icon [ngClass]=\"iconClass\" [icon]=\"icon\" [size]=\"18\"></fx-ui-hero-icon>\n }\n <span class=\"txt-heading-06\">{{ title }}</span>\n </div>\n <ng-content></ng-content>\n</div>\n" }]
4236
4397
  }], propDecorators: { title: [{
@@ -4266,10 +4427,10 @@ class InfoFieldComponent {
4266
4427
  const toneClass = this.tone ? toneText(this.tone) : 'text-text-primary';
4267
4428
  return this.mono ? `${toneClass} font-mono break-all` : toneClass;
4268
4429
  }
4269
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: InfoFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4270
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.4", type: InfoFieldComponent, isStandalone: false, selector: "fx-ui-info-field", inputs: { label: "label", value: "value", tone: "tone", mono: "mono", placeholder: "placeholder" }, ngImport: i0, template: "<div class=\"flex flex-col gap-small min-w-0\">\n <span class=\"txt-field-label !mb-0\">{{ label }}</span>\n <span class=\"txt-default\" [ngClass]=\"valueClass\">{{ displayValue }}</span>\n</div>\n", dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
4430
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: InfoFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4431
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.20", type: InfoFieldComponent, isStandalone: false, selector: "fx-ui-info-field", inputs: { label: "label", value: "value", tone: "tone", mono: "mono", placeholder: "placeholder" }, ngImport: i0, template: "<div class=\"flex flex-col gap-small min-w-0\">\n <span class=\"txt-field-label !mb-0\">{{ label }}</span>\n <span class=\"txt-default\" [ngClass]=\"valueClass\">{{ displayValue }}</span>\n</div>\n", dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
4271
4432
  }
4272
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: InfoFieldComponent, decorators: [{
4433
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: InfoFieldComponent, decorators: [{
4273
4434
  type: Component,
4274
4435
  args: [{ selector: 'fx-ui-info-field', standalone: false, template: "<div class=\"flex flex-col gap-small min-w-0\">\n <span class=\"txt-field-label !mb-0\">{{ label }}</span>\n <span class=\"txt-default\" [ngClass]=\"valueClass\">{{ displayValue }}</span>\n</div>\n" }]
4275
4436
  }], propDecorators: { label: [{
@@ -4314,16 +4475,14 @@ class SeverityBadgesComponent {
4314
4475
  });
4315
4476
  }
4316
4477
  badgeClass(badge) {
4317
- return badge.tone
4318
- ? `bg-${badge.tone}/10 text-${badge.tone}`
4319
- : 'bg-bg-hover text-text-primary';
4478
+ return badge.tone ? toneBadge(badge.tone) : 'bg-bg-hover text-text-primary';
4320
4479
  }
4321
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: SeverityBadgesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4322
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: SeverityBadgesComponent, isStandalone: false, selector: "fx-ui-severity-badges", inputs: { stats: "stats", showZero: "showZero", suffixed: "suffixed" }, outputs: { badgeClick: "badgeClick" }, ngImport: i0, template: "<div class=\"flex items-center gap-small\">\n @for (badge of badges; track badge.key) {\n <span\n class=\"px-2 py-0.5 rounded-full txt-utility-caption font-medium cursor-pointer\"\n [ngClass]=\"badgeClass(badge)\"\n (click)=\"badgeClick.emit(badge.key)\"\n >{{ badge.label }}</span\n >\n }\n</div>\n", dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
4480
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: SeverityBadgesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4481
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: SeverityBadgesComponent, isStandalone: false, selector: "fx-ui-severity-badges", inputs: { stats: "stats", showZero: "showZero", suffixed: "suffixed" }, outputs: { badgeClick: "badgeClick" }, ngImport: i0, template: "<div class=\"flex items-center gap-small\">\n @for (badge of badges; track badge.key) {\n <button\n type=\"button\"\n class=\"px-2 py-0.5 rounded-full txt-utility-caption font-medium cursor-pointer focus-visible:ring-2 focus-visible:ring-primary/50\"\n [ngClass]=\"badgeClass(badge)\"\n [attr.aria-label]=\"badge.key + ': ' + badge.label\"\n (click)=\"badgeClick.emit(badge.key)\"\n >{{ badge.label }}</button>\n }\n</div>\n", dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
4323
4482
  }
4324
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: SeverityBadgesComponent, decorators: [{
4483
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: SeverityBadgesComponent, decorators: [{
4325
4484
  type: Component,
4326
- args: [{ selector: 'fx-ui-severity-badges', standalone: false, template: "<div class=\"flex items-center gap-small\">\n @for (badge of badges; track badge.key) {\n <span\n class=\"px-2 py-0.5 rounded-full txt-utility-caption font-medium cursor-pointer\"\n [ngClass]=\"badgeClass(badge)\"\n (click)=\"badgeClick.emit(badge.key)\"\n >{{ badge.label }}</span\n >\n }\n</div>\n" }]
4485
+ args: [{ selector: 'fx-ui-severity-badges', standalone: false, template: "<div class=\"flex items-center gap-small\">\n @for (badge of badges; track badge.key) {\n <button\n type=\"button\"\n class=\"px-2 py-0.5 rounded-full txt-utility-caption font-medium cursor-pointer focus-visible:ring-2 focus-visible:ring-primary/50\"\n [ngClass]=\"badgeClass(badge)\"\n [attr.aria-label]=\"badge.key + ': ' + badge.label\"\n (click)=\"badgeClick.emit(badge.key)\"\n >{{ badge.label }}</button>\n }\n</div>\n" }]
4327
4486
  }], propDecorators: { stats: [{
4328
4487
  type: Input
4329
4488
  }], showZero: [{
@@ -4334,6 +4493,112 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
4334
4493
  type: Output
4335
4494
  }] } });
4336
4495
 
4496
+ let nextUid = 0;
4497
+ /**
4498
+ * Two-column master-detail shell driven by a BaseMasterDetailComponent.
4499
+ * The host page projects its own header/filters and supplies templates for
4500
+ * the parts that vary per entity:
4501
+ *
4502
+ * <fx-ui-master-detail [table]="this" [emptyMessage]="'noData' | translate">
4503
+ * <div mdHeader>…title / stat cards…</div>
4504
+ * <div mdFilters>…search bar / filter chips…</div>
4505
+ * <ng-template #row let-item let-selected="selected">…row body…</ng-template>
4506
+ * <ng-template #detail let-detail>…detail pane…</ng-template>
4507
+ * </fx-ui-master-detail>
4508
+ *
4509
+ * The list behaves as a single-select listbox: the selected option is the
4510
+ * tab stop, ArrowUp/Down/Home/End move the selection.
4511
+ */
4512
+ class MasterDetailComponent {
4513
+ table;
4514
+ /** Fixed list-pane width on lg+ viewports (stacked full-width below). */
4515
+ listWidth = '420px';
4516
+ maxListHeight = '640px';
4517
+ pageSizeOptions = [5, 10, 20, 50];
4518
+ /** Labels come in via inputs — the lib carries no i18n. */
4519
+ emptyMessage = 'No data';
4520
+ listLabel = '';
4521
+ skeletonCards = 3;
4522
+ rowTemplate;
4523
+ detailTemplate;
4524
+ paginator;
4525
+ uid = `fx-md-${nextUid++}`;
4526
+ ngAfterViewInit() {
4527
+ // The paginator lives in this view, not the host page's, so the host's
4528
+ // @ViewChild(MatPaginator) never finds it. Hand it to the table so
4529
+ // refresh() keeps resetting pageIndex.
4530
+ if (this.table) {
4531
+ this.table.paginator = this.paginator;
4532
+ }
4533
+ }
4534
+ isSelected(row) {
4535
+ return this.table.idOf(row) === this.table.selectedId;
4536
+ }
4537
+ optionId(index) {
4538
+ return `${this.uid}-opt-${index}`;
4539
+ }
4540
+ onKeydown(event, index) {
4541
+ const rows = this.table.dataSource.data || [];
4542
+ if (!rows.length) {
4543
+ return;
4544
+ }
4545
+ let next;
4546
+ switch (event.key) {
4547
+ case 'ArrowDown':
4548
+ next = Math.min(index + 1, rows.length - 1);
4549
+ break;
4550
+ case 'ArrowUp':
4551
+ next = Math.max(index - 1, 0);
4552
+ break;
4553
+ case 'Home':
4554
+ next = 0;
4555
+ break;
4556
+ case 'End':
4557
+ next = rows.length - 1;
4558
+ break;
4559
+ default:
4560
+ return;
4561
+ }
4562
+ event.preventDefault();
4563
+ if (next === index) {
4564
+ return;
4565
+ }
4566
+ this.table.selectItem(rows[next]);
4567
+ const el = document.getElementById(this.optionId(next));
4568
+ el?.focus();
4569
+ el?.scrollIntoView({ block: 'nearest' });
4570
+ }
4571
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: MasterDetailComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
4572
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.20", type: MasterDetailComponent, isStandalone: false, selector: "fx-ui-master-detail", inputs: { table: "table", listWidth: "listWidth", maxListHeight: "maxListHeight", pageSizeOptions: "pageSizeOptions", emptyMessage: "emptyMessage", listLabel: "listLabel", skeletonCards: "skeletonCards" }, queries: [{ propertyName: "rowTemplate", first: true, predicate: ["row"], descendants: true }, { propertyName: "detailTemplate", first: true, predicate: ["detail"], descendants: true }], viewQueries: [{ propertyName: "paginator", first: true, predicate: MatPaginator, descendants: true }], ngImport: i0, template: "<div class=\"flex flex-col lg:flex-row items-start gap-xl\" [style.--fx-md-list-width]=\"listWidth\">\n <!-- Master: list pane -->\n <div class=\"fx-md-list card-common\">\n <ng-content select=\"[mdHeader]\"></ng-content>\n <ng-content select=\"[mdFilters]\"></ng-content>\n <div\n class=\"flex flex-col gap-normal overflow-auto pr-xs\"\n [style.maxHeight]=\"maxListHeight\"\n role=\"listbox\"\n [attr.aria-label]=\"listLabel || null\"\n >\n @if (table.loading) {\n <fx-ui-skeleton-list [rows]=\"table.pageSize\"></fx-ui-skeleton-list>\n } @else {\n @for (row of table.dataSource.data; track table.idOf(row); let i = $index) {\n <button\n type=\"button\"\n role=\"option\"\n [id]=\"optionId(i)\"\n [attr.aria-selected]=\"isSelected(row)\"\n [tabindex]=\"isSelected(row) ? 0 : -1\"\n (click)=\"table.selectItem(row)\"\n (keydown)=\"onKeydown($event, i)\"\n class=\"text-left rounded-lg border p-semi transition-colors\"\n [ngClass]=\"\n isSelected(row)\n ? 'border-gradient-primary-start bg-gradient-primary-start/5'\n : 'border-border-default hover:border-border-interactive bg-bg-primary'\n \"\n >\n <ng-container\n [ngTemplateOutlet]=\"rowTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: row, selected: isSelected(row) }\"\n ></ng-container>\n </button>\n }\n @if (!table.dataSource.data.length) {\n <fx-ui-empty-state [message]=\"emptyMessage\"></fx-ui-empty-state>\n }\n }\n </div>\n <!-- No (page) binding: ngAfterViewInit hands this paginator to the table,\n whose own BaseTable subscription (running after this child's hook)\n wires page events \u2014 a binding here would double-fetch every change. -->\n <mat-paginator\n class=\"mt-normal\"\n [length]=\"table.total\"\n [pageSize]=\"table.pageSize\"\n [pageSizeOptions]=\"pageSizeOptions\"\n ></mat-paginator>\n </div>\n\n <!-- Detail pane -->\n <div class=\"w-full lg:flex-1 min-w-0\">\n @if (table.selected) {\n @if (table.detailBusy) {\n <fx-ui-skeleton-detail [cards]=\"skeletonCards\"></fx-ui-skeleton-detail>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"detailTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: table.detail, selected: table.selected }\"\n ></ng-container>\n }\n } @else {\n <div class=\"card-common flex items-center justify-center h-[300px]\">\n <fx-ui-empty-state [message]=\"emptyMessage\"></fx-ui-empty-state>\n </div>\n }\n </div>\n</div>\n", styles: [".fx-md-list{width:100%}@media(min-width:1080px){.fx-md-list{width:var(--fx-md-list-width, 420px);flex-shrink:0}}\n"], dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i45.MatPaginator, selector: "mat-paginator", inputs: ["color", "pageIndex", "length", "pageSize", "pageSizeOptions", "hidePageSize", "showFirstLastButtons", "selectConfig", "disabled"], outputs: ["page"], exportAs: ["matPaginator"] }, { kind: "component", type: SkeletonListComponent, selector: "fx-ui-skeleton-list", inputs: ["rows"] }, { kind: "component", type: SkeletonDetailComponent, selector: "fx-ui-skeleton-detail", inputs: ["cards", "rows"] }, { kind: "component", type: EmptyStateComponent, selector: "fx-ui-empty-state", inputs: ["message", "icon", "height"] }] });
4573
+ }
4574
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: MasterDetailComponent, decorators: [{
4575
+ type: Component,
4576
+ args: [{ selector: 'fx-ui-master-detail', standalone: false, template: "<div class=\"flex flex-col lg:flex-row items-start gap-xl\" [style.--fx-md-list-width]=\"listWidth\">\n <!-- Master: list pane -->\n <div class=\"fx-md-list card-common\">\n <ng-content select=\"[mdHeader]\"></ng-content>\n <ng-content select=\"[mdFilters]\"></ng-content>\n <div\n class=\"flex flex-col gap-normal overflow-auto pr-xs\"\n [style.maxHeight]=\"maxListHeight\"\n role=\"listbox\"\n [attr.aria-label]=\"listLabel || null\"\n >\n @if (table.loading) {\n <fx-ui-skeleton-list [rows]=\"table.pageSize\"></fx-ui-skeleton-list>\n } @else {\n @for (row of table.dataSource.data; track table.idOf(row); let i = $index) {\n <button\n type=\"button\"\n role=\"option\"\n [id]=\"optionId(i)\"\n [attr.aria-selected]=\"isSelected(row)\"\n [tabindex]=\"isSelected(row) ? 0 : -1\"\n (click)=\"table.selectItem(row)\"\n (keydown)=\"onKeydown($event, i)\"\n class=\"text-left rounded-lg border p-semi transition-colors\"\n [ngClass]=\"\n isSelected(row)\n ? 'border-gradient-primary-start bg-gradient-primary-start/5'\n : 'border-border-default hover:border-border-interactive bg-bg-primary'\n \"\n >\n <ng-container\n [ngTemplateOutlet]=\"rowTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: row, selected: isSelected(row) }\"\n ></ng-container>\n </button>\n }\n @if (!table.dataSource.data.length) {\n <fx-ui-empty-state [message]=\"emptyMessage\"></fx-ui-empty-state>\n }\n }\n </div>\n <!-- No (page) binding: ngAfterViewInit hands this paginator to the table,\n whose own BaseTable subscription (running after this child's hook)\n wires page events \u2014 a binding here would double-fetch every change. -->\n <mat-paginator\n class=\"mt-normal\"\n [length]=\"table.total\"\n [pageSize]=\"table.pageSize\"\n [pageSizeOptions]=\"pageSizeOptions\"\n ></mat-paginator>\n </div>\n\n <!-- Detail pane -->\n <div class=\"w-full lg:flex-1 min-w-0\">\n @if (table.selected) {\n @if (table.detailBusy) {\n <fx-ui-skeleton-detail [cards]=\"skeletonCards\"></fx-ui-skeleton-detail>\n } @else {\n <ng-container\n [ngTemplateOutlet]=\"detailTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: table.detail, selected: table.selected }\"\n ></ng-container>\n }\n } @else {\n <div class=\"card-common flex items-center justify-center h-[300px]\">\n <fx-ui-empty-state [message]=\"emptyMessage\"></fx-ui-empty-state>\n </div>\n }\n </div>\n</div>\n", styles: [".fx-md-list{width:100%}@media(min-width:1080px){.fx-md-list{width:var(--fx-md-list-width, 420px);flex-shrink:0}}\n"] }]
4577
+ }], propDecorators: { table: [{
4578
+ type: Input
4579
+ }], listWidth: [{
4580
+ type: Input
4581
+ }], maxListHeight: [{
4582
+ type: Input
4583
+ }], pageSizeOptions: [{
4584
+ type: Input
4585
+ }], emptyMessage: [{
4586
+ type: Input
4587
+ }], listLabel: [{
4588
+ type: Input
4589
+ }], skeletonCards: [{
4590
+ type: Input
4591
+ }], rowTemplate: [{
4592
+ type: ContentChild,
4593
+ args: ['row']
4594
+ }], detailTemplate: [{
4595
+ type: ContentChild,
4596
+ args: ['detail']
4597
+ }], paginator: [{
4598
+ type: ViewChild,
4599
+ args: [MatPaginator]
4600
+ }] } });
4601
+
4337
4602
  const FX_COMPONENTS = [
4338
4603
  InputComponent,
4339
4604
  SelectComponent,
@@ -4371,6 +4636,7 @@ const FX_COMPONENTS = [
4371
4636
  SectionCardComponent,
4372
4637
  InfoFieldComponent,
4373
4638
  SeverityBadgesComponent,
4639
+ MasterDetailComponent,
4374
4640
  ];
4375
4641
 
4376
4642
  class ConfirmationDialogComponent {
@@ -4400,12 +4666,12 @@ class ConfirmationDialogComponent {
4400
4666
  cancel() {
4401
4667
  this.ref.close(false);
4402
4668
  }
4403
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: ConfirmationDialogComponent, deps: [{ token: i1$2.MatDialogRef }, { token: MAT_DIALOG_DATA }], target: i0.ɵɵFactoryTarget.Component });
4404
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.4", type: ConfirmationDialogComponent, isStandalone: false, selector: "fx-ui-confirmation-dialog", ngImport: i0, template: "<div animate.enter=\"fade-in-animation\" class=\"dialog-container\">\n <h1 class=\"txt-heading-05 dialog-header\">{{ title }}</h1>\n <mat-dialog-content>\n <div class=\"txt-default\">{{ message }}</div>\n </mat-dialog-content>\n <mat-dialog-actions align=\"end\">\n <fx-ui-button class=\"mr-1\" [label]=\"cancelLabel\" (clicked)=\"cancel()\"></fx-ui-button>\n <fx-ui-button\n buttonVariant=\"primary\"\n class=\"mr-1\"\n [label]=\"confirmLabel\"\n (clicked)=\"accept()\"\n [loading]=\"loading\"\n class=\"min-w-[100px]\"\n ></fx-ui-button>\n </mat-dialog-actions>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$2.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1$2.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "component", type: ButtonComponent, selector: "fx-ui-button", inputs: ["label", "disabled", "buttonVariant", "icon", "class", "loading"], outputs: ["clicked"] }] });
4669
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: ConfirmationDialogComponent, deps: [{ token: i1$2.MatDialogRef }, { token: MAT_DIALOG_DATA }], target: i0.ɵɵFactoryTarget.Component });
4670
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.20", type: ConfirmationDialogComponent, isStandalone: false, selector: "fx-ui-confirmation-dialog", ngImport: i0, template: "<div animate.enter=\"fade-in-animation\" class=\"dialog-container\">\n <h1 mat-dialog-title class=\"txt-heading-05 dialog-header\">{{ title }}</h1>\n <mat-dialog-content>\n <div class=\"txt-default\">{{ message }}</div>\n </mat-dialog-content>\n <mat-dialog-actions align=\"end\">\n <fx-ui-button class=\"mr-1\" [label]=\"cancelLabel\" (clicked)=\"cancel()\"></fx-ui-button>\n <fx-ui-button\n buttonVariant=\"primary\"\n class=\"mr-1\"\n [label]=\"confirmLabel\"\n (clicked)=\"accept()\"\n [loading]=\"loading\"\n class=\"min-w-[100px]\"\n ></fx-ui-button>\n </mat-dialog-actions>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$2.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: i1$2.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1$2.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "component", type: ButtonComponent, selector: "fx-ui-button", inputs: ["label", "disabled", "buttonVariant", "icon", "class", "loading", "type", "ariaLabel"], outputs: ["clicked"] }] });
4405
4671
  }
4406
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: ConfirmationDialogComponent, decorators: [{
4672
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: ConfirmationDialogComponent, decorators: [{
4407
4673
  type: Component,
4408
- args: [{ selector: 'fx-ui-confirmation-dialog', standalone: false, template: "<div animate.enter=\"fade-in-animation\" class=\"dialog-container\">\n <h1 class=\"txt-heading-05 dialog-header\">{{ title }}</h1>\n <mat-dialog-content>\n <div class=\"txt-default\">{{ message }}</div>\n </mat-dialog-content>\n <mat-dialog-actions align=\"end\">\n <fx-ui-button class=\"mr-1\" [label]=\"cancelLabel\" (clicked)=\"cancel()\"></fx-ui-button>\n <fx-ui-button\n buttonVariant=\"primary\"\n class=\"mr-1\"\n [label]=\"confirmLabel\"\n (clicked)=\"accept()\"\n [loading]=\"loading\"\n class=\"min-w-[100px]\"\n ></fx-ui-button>\n </mat-dialog-actions>\n</div>\n" }]
4674
+ args: [{ selector: 'fx-ui-confirmation-dialog', standalone: false, template: "<div animate.enter=\"fade-in-animation\" class=\"dialog-container\">\n <h1 mat-dialog-title class=\"txt-heading-05 dialog-header\">{{ title }}</h1>\n <mat-dialog-content>\n <div class=\"txt-default\">{{ message }}</div>\n </mat-dialog-content>\n <mat-dialog-actions align=\"end\">\n <fx-ui-button class=\"mr-1\" [label]=\"cancelLabel\" (clicked)=\"cancel()\"></fx-ui-button>\n <fx-ui-button\n buttonVariant=\"primary\"\n class=\"mr-1\"\n [label]=\"confirmLabel\"\n (clicked)=\"accept()\"\n [loading]=\"loading\"\n class=\"min-w-[100px]\"\n ></fx-ui-button>\n </mat-dialog-actions>\n</div>\n" }]
4409
4675
  }], ctorParameters: () => [{ type: i1$2.MatDialogRef }, { type: undefined, decorators: [{
4410
4676
  type: Inject,
4411
4677
  args: [MAT_DIALOG_DATA]
@@ -4425,8 +4691,8 @@ const MY_MOMENT_FORMATS = {
4425
4691
  monthYearA11yLabel: 'MMMM YYYY',
4426
4692
  };
4427
4693
  class UiModule {
4428
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: UiModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
4429
- static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.3.4", ngImport: i0, type: UiModule, declarations: [InputComponent, SelectComponent, RadioButtonComponent, CheckboxComponent, DndUploadComponent, ButtonComponent, RadioButtonToggleComponent, DatetimePicker, LoadingPanel, SearchBarComponent, TabGroupComponent, TabComponent, HeroIconComponent, ToastComponent, ToastContainerComponent, TagComponent, ChartComponent, SliderComponent, SwitchComponent, RichTextAreaComponent, SkeletonTableLoadingComponent, FlowConnection, CircleProgressBar, TreeDiagram, TableCell, KanbanBoardComponent, DrawerComponent, SkeletonListComponent, SkeletonDetailComponent, StatCardsComponent, EmptyStateComponent, FilterChipsComponent, MeterComponent, SectionCardComponent, InfoFieldComponent, SeverityBadgesComponent, ConfirmationDialogComponent], imports: [CommonModule,
4694
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: UiModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
4695
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.20", ngImport: i0, type: UiModule, declarations: [InputComponent, SelectComponent, RadioButtonComponent, CheckboxComponent, DndUploadComponent, ButtonComponent, RadioButtonToggleComponent, DatetimePicker, LoadingPanel, SearchBarComponent, TabGroupComponent, TabComponent, HeroIconComponent, ToastComponent, ToastContainerComponent, TagComponent, ChartComponent, SliderComponent, SwitchComponent, RichTextAreaComponent, SkeletonTableLoadingComponent, FlowConnection, CircleProgressBar, TreeDiagram, TableCell, KanbanBoardComponent, DrawerComponent, SkeletonListComponent, SkeletonDetailComponent, StatCardsComponent, EmptyStateComponent, FilterChipsComponent, MeterComponent, SectionCardComponent, InfoFieldComponent, SeverityBadgesComponent, MasterDetailComponent, ConfirmationDialogComponent], imports: [CommonModule,
4430
4696
  FormsModule,
4431
4697
  ReactiveFormsModule,
4432
4698
  RouterModule,
@@ -4435,7 +4701,7 @@ class UiModule {
4435
4701
  OwlMomentDateTimeModule,
4436
4702
  HasPermissionDirective,
4437
4703
  TrimOnBlurDirective,
4438
- NgHeroiconsModule, i38.VflowComponent, i38.HandleComponent, i38.ResizableComponent, i38.SelectableDirective, i38.MiniMapComponent, i38.NodeToolbarComponent, i38.CustomTemplateEdgeComponent, i38.DragHandleDirective, i38.ConnectionControllerDirective, i38.NodeHtmlTemplateDirective, i38.NodeSvgTemplateDirective, i38.GroupNodeTemplateDirective, i38.EdgeLabelHtmlTemplateDirective, i38.EdgeTemplateDirective, i38.ConnectionTemplateDirective, i38.HandleTemplateDirective, i1$5.NgxEchartsModule, i3.MatSelectModule, i41.MatRadioModule, i42.MatButtonModule, i43.MatIconModule, i44.MatPaginatorModule, i45.MatTableModule, i46.MatSnackBarModule, i1$2.MatDialogModule, i48.MatCheckboxModule, i49.MatCardModule, i50.MatDatepickerModule, i51.MatTimepickerModule, i52.MatBadgeModule, i53.MatExpansionModule, i54.MatFormFieldModule, i55.MatMenuModule, i56.MatTooltipModule, i2$3.DragDropModule], exports: [InputComponent, SelectComponent, RadioButtonComponent, CheckboxComponent, DndUploadComponent, ButtonComponent, RadioButtonToggleComponent, DatetimePicker, LoadingPanel, SearchBarComponent, TabGroupComponent, TabComponent, HeroIconComponent, ToastComponent, ToastContainerComponent, TagComponent, ChartComponent, SliderComponent, SwitchComponent, RichTextAreaComponent, SkeletonTableLoadingComponent, FlowConnection, CircleProgressBar, TreeDiagram, TableCell, KanbanBoardComponent, DrawerComponent, SkeletonListComponent, SkeletonDetailComponent, StatCardsComponent, EmptyStateComponent, FilterChipsComponent, MeterComponent, SectionCardComponent, InfoFieldComponent, SeverityBadgesComponent, ConfirmationDialogComponent,
4704
+ NgHeroiconsModule, i39.VflowComponent, i39.HandleComponent, i39.ResizableComponent, i39.SelectableDirective, i39.MiniMapComponent, i39.NodeToolbarComponent, i39.CustomTemplateEdgeComponent, i39.DragHandleDirective, i39.ConnectionControllerDirective, i39.NodeHtmlTemplateDirective, i39.NodeSvgTemplateDirective, i39.GroupNodeTemplateDirective, i39.EdgeLabelHtmlTemplateDirective, i39.EdgeTemplateDirective, i39.ConnectionTemplateDirective, i39.HandleTemplateDirective, i1$6.NgxEchartsModule, i2$1.MatSelectModule, i42.MatRadioModule, i43.MatButtonModule, i44.MatIconModule, i45.MatPaginatorModule, i46.MatTableModule, i47.MatSnackBarModule, i1$2.MatDialogModule, i49.MatCheckboxModule, i50.MatCardModule, i51.MatDatepickerModule, i52.MatTimepickerModule, i53.MatBadgeModule, i54.MatExpansionModule, i55.MatFormFieldModule, i56.MatMenuModule, i57.MatTooltipModule, i2$2.DragDropModule], exports: [InputComponent, SelectComponent, RadioButtonComponent, CheckboxComponent, DndUploadComponent, ButtonComponent, RadioButtonToggleComponent, DatetimePicker, LoadingPanel, SearchBarComponent, TabGroupComponent, TabComponent, HeroIconComponent, ToastComponent, ToastContainerComponent, TagComponent, ChartComponent, SliderComponent, SwitchComponent, RichTextAreaComponent, SkeletonTableLoadingComponent, FlowConnection, CircleProgressBar, TreeDiagram, TableCell, KanbanBoardComponent, DrawerComponent, SkeletonListComponent, SkeletonDetailComponent, StatCardsComponent, EmptyStateComponent, FilterChipsComponent, MeterComponent, SectionCardComponent, InfoFieldComponent, SeverityBadgesComponent, MasterDetailComponent, ConfirmationDialogComponent,
4439
4705
  // Module
4440
4706
  FormsModule,
4441
4707
  ReactiveFormsModule,
@@ -4443,8 +4709,8 @@ class UiModule {
4443
4709
  OwlDateTimeModule,
4444
4710
  OwlNativeDateTimeModule,
4445
4711
  HasPermissionDirective,
4446
- NgHeroiconsModule, i3.MatSelectModule, i41.MatRadioModule, i42.MatButtonModule, i43.MatIconModule, i44.MatPaginatorModule, i45.MatTableModule, i46.MatSnackBarModule, i1$2.MatDialogModule, i48.MatCheckboxModule, i49.MatCardModule, i50.MatDatepickerModule, i51.MatTimepickerModule, i52.MatBadgeModule, i53.MatExpansionModule, i54.MatFormFieldModule, i55.MatMenuModule, i56.MatTooltipModule, i2$3.DragDropModule] });
4447
- static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: UiModule, providers: [
4712
+ NgHeroiconsModule, i2$1.MatSelectModule, i42.MatRadioModule, i43.MatButtonModule, i44.MatIconModule, i45.MatPaginatorModule, i46.MatTableModule, i47.MatSnackBarModule, i1$2.MatDialogModule, i49.MatCheckboxModule, i50.MatCardModule, i51.MatDatepickerModule, i52.MatTimepickerModule, i53.MatBadgeModule, i54.MatExpansionModule, i55.MatFormFieldModule, i56.MatMenuModule, i57.MatTooltipModule, i2$2.DragDropModule] });
4713
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: UiModule, providers: [
4448
4714
  importProvidersFrom(NgHeroiconsModule.forRoot()),
4449
4715
  { provide: OWL_DATE_TIME_FORMATS, useValue: MY_MOMENT_FORMATS },
4450
4716
  ], imports: [CommonModule,
@@ -4454,16 +4720,16 @@ class UiModule {
4454
4720
  OwlDateTimeModule,
4455
4721
  OwlNativeDateTimeModule,
4456
4722
  OwlMomentDateTimeModule,
4457
- NgHeroiconsModule, i38.VflowComponent, i38.HandleComponent, i38.ResizableComponent, i38.MiniMapComponent, i38.NodeToolbarComponent, i38.CustomTemplateEdgeComponent, NgxEchartsModule.forRoot({ echarts: () => import('echarts') }), MATERIAL_MODULE,
4723
+ NgHeroiconsModule, i39.VflowComponent, i39.HandleComponent, i39.ResizableComponent, i39.MiniMapComponent, i39.NodeToolbarComponent, i39.CustomTemplateEdgeComponent, NgxEchartsModule.forRoot({ echarts: () => import('echarts') }), MATERIAL_MODULE,
4458
4724
  // Module
4459
4725
  FormsModule,
4460
4726
  ReactiveFormsModule,
4461
4727
  RouterModule,
4462
4728
  OwlDateTimeModule,
4463
4729
  OwlNativeDateTimeModule,
4464
- NgHeroiconsModule, i3.MatSelectModule, i41.MatRadioModule, i42.MatButtonModule, i43.MatIconModule, i44.MatPaginatorModule, i45.MatTableModule, i46.MatSnackBarModule, i1$2.MatDialogModule, i48.MatCheckboxModule, i49.MatCardModule, i50.MatDatepickerModule, i51.MatTimepickerModule, i52.MatBadgeModule, i53.MatExpansionModule, i54.MatFormFieldModule, i55.MatMenuModule, i56.MatTooltipModule, i2$3.DragDropModule] });
4730
+ NgHeroiconsModule, i2$1.MatSelectModule, i42.MatRadioModule, i43.MatButtonModule, i44.MatIconModule, i45.MatPaginatorModule, i46.MatTableModule, i47.MatSnackBarModule, i1$2.MatDialogModule, i49.MatCheckboxModule, i50.MatCardModule, i51.MatDatepickerModule, i52.MatTimepickerModule, i53.MatBadgeModule, i54.MatExpansionModule, i55.MatFormFieldModule, i56.MatMenuModule, i57.MatTooltipModule, i2$2.DragDropModule] });
4465
4731
  }
4466
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: UiModule, decorators: [{
4732
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.20", ngImport: i0, type: UiModule, decorators: [{
4467
4733
  type: NgModule,
4468
4734
  args: [{
4469
4735
  declarations: [...FX_COMPONENTS, ...DIALOGS_COMPONENT],
@@ -4511,5 +4777,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
4511
4777
  * Generated bundle index. Do not edit.
4512
4778
  */
4513
4779
 
4514
- export { AuthInterceptor, AuthStateService, BaseComponent, BaseDialogComponent, BaseResolver, BaseTableComponent, BreadcrumbService, ButtonComponent, ChartComponent, CheckboxComponent, CircleProgressBar, ConfirmationDialogComponent, DatetimePicker, DndUploadComponent, DrawerComponent, EmptyStateComponent, FilterChipsComponent, FlowConnection, FxLoadingService, FxStorageService, FxToastrService, FxUtils, FxValidators, HasPermissionDirective, HeroIconComponent, HttpLoaderFactory, HttpWrapper, InfoFieldComponent, InputComponent, KanbanBoardComponent, LoadingPanel, MY_MOMENT_FORMATS, MeterComponent, NotificationService, PermissionGuard, PermissionService, QuillStyleLoaderService, RadioButtonComponent, RadioButtonToggleComponent, RealtimeTableSync, RichTextAreaComponent, SearchBarComponent, SectionCardComponent, SelectComponent, SeverityBadgesComponent, SkeletonDetailComponent, SkeletonListComponent, SkeletonTableLoadingComponent, SliderComponent, StatCardsComponent, SwitchComponent, TabComponent, TabGroupComponent, TableCell, TagComponent, ThemeService, ToastComponent, ToastContainerComponent, TranslationModule, TranslationService, TreeDiagram, TrimOnBlurDirective, UiModule, countTone, createApi, fxListResolver, scoreTone, severityTone, toneBadge, toneBg, toneColor, toneText };
4780
+ export { AuthInterceptor, AuthStateService, BaseComponent, BaseDialogComponent, BaseMasterDetailComponent, BaseResolver, BaseTableComponent, BreadcrumbService, ButtonComponent, ChartComponent, CheckboxComponent, CircleProgressBar, ConfirmationDialogComponent, DatetimePicker, DndUploadComponent, DrawerComponent, EmptyStateComponent, FilterChipsComponent, FlowConnection, FxLoadingService, FxStorageService, FxToastrService, FxUtils, FxValidators, HasPermissionDirective, HeroIconComponent, HttpLoaderFactory, HttpWrapper, InfoFieldComponent, InputComponent, KanbanBoardComponent, LoadingPanel, MY_MOMENT_FORMATS, MasterDetailComponent, MeterComponent, NotificationService, PermissionGuard, PermissionService, QuillStyleLoaderService, RadioButtonComponent, RadioButtonToggleComponent, RealtimeTableSync, RichTextAreaComponent, SearchBarComponent, SectionCardComponent, SelectComponent, SeverityBadgesComponent, SkeletonDetailComponent, SkeletonListComponent, SkeletonTableLoadingComponent, SliderComponent, StatCardsComponent, SwitchComponent, TabComponent, TabGroupComponent, TableCell, TagComponent, ThemeService, ToastComponent, ToastContainerComponent, TranslationModule, TranslationService, TreeDiagram, TrimOnBlurDirective, UiModule, countTone, createApi, fxListResolver, scoreTone, severityTone, toneBadge, toneBg, toneColor, toneText };
4515
4781
  //# sourceMappingURL=foxeltech-angular-ui.mjs.map