@fxlt/common-ui 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,15 +1,15 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Directive, Input, Component, createComponent, Injectable, ViewChild, Inject, EventEmitter, NgModule, Output, HostListener, Optional, Self, ChangeDetectionStrategy, TemplateRef, ContentChildren, importProvidersFrom } from '@angular/core';
3
- import * as i26 from '@angular/material/paginator';
2
+ import { Directive, Input, Component, createComponent, Injectable, ViewChild, Inject, EventEmitter, NgModule, HostListener, PLATFORM_ID, Output, Optional, Self, ChangeDetectionStrategy, TemplateRef, ContentChildren, importProvidersFrom } from '@angular/core';
3
+ import * as i28 from '@angular/material/paginator';
4
4
  import { MatPaginator, MatPaginatorModule } from '@angular/material/paginator';
5
- import * as i27 from '@angular/material/table';
5
+ import * as i29 from '@angular/material/table';
6
6
  import { MatTableDataSource, MatTable, MatTableModule } from '@angular/material/table';
7
7
  import * as i2 from '@angular/common';
8
- import { CommonModule } from '@angular/common';
8
+ import { isPlatformBrowser, CommonModule } from '@angular/common';
9
9
  import * as i1 from '@dimaslz/ng-heroicons';
10
10
  import { NgHeroiconsModule } from '@dimaslz/ng-heroicons';
11
11
  import _, { clamp } from 'lodash';
12
- import { Observable, firstValueFrom, BehaviorSubject, Subject, throwError } from 'rxjs';
12
+ import { Observable, firstValueFrom, Subject, debounceTime, BehaviorSubject, throwError, distinctUntilChanged } from 'rxjs';
13
13
  import * as i1$1 from '@angular/material/dialog';
14
14
  import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
15
15
  import * as i2$1 from '@angular/common/http';
@@ -17,33 +17,33 @@ import { HttpClient } from '@angular/common/http';
17
17
  import * as i1$2 from '@ngx-translate/core';
18
18
  import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
19
19
  import { TranslateHttpLoader } from '@ngx-translate/http-loader';
20
- import * as i2$2 from '@angular/router';
21
- import { catchError } from 'rxjs/operators';
22
20
  import * as i1$3 from '@angular/forms';
23
21
  import { FormsModule, ReactiveFormsModule } from '@angular/forms';
22
+ import * as i2$2 from '@angular/router';
23
+ import { catchError } from 'rxjs/operators';
24
24
  import * as i3$1 from '@angular/material/select';
25
25
  import { MatSelectModule } from '@angular/material/select';
26
- import * as i23 from '@angular/material/radio';
26
+ import * as i25 from '@angular/material/radio';
27
27
  import { MatRadioModule } from '@angular/material/radio';
28
- import * as i24 from '@angular/material/button';
28
+ import * as i26 from '@angular/material/button';
29
29
  import { MatButtonModule } from '@angular/material/button';
30
- import * as i25 from '@angular/material/icon';
30
+ import * as i27 from '@angular/material/icon';
31
31
  import { MatIconModule } from '@angular/material/icon';
32
- import * as i28 from '@angular/material/snack-bar';
32
+ import * as i30 from '@angular/material/snack-bar';
33
33
  import { MatSnackBarModule } from '@angular/material/snack-bar';
34
- import * as i30 from '@angular/material/checkbox';
34
+ import * as i32 from '@angular/material/checkbox';
35
35
  import { MatCheckboxModule } from '@angular/material/checkbox';
36
- import * as i31 from '@angular/material/card';
36
+ import * as i33 from '@angular/material/card';
37
37
  import { MatCardModule } from '@angular/material/card';
38
- import * as i32 from '@angular/material/datepicker';
38
+ import * as i34 from '@angular/material/datepicker';
39
39
  import { MatDatepickerModule } from '@angular/material/datepicker';
40
- import * as i33 from '@angular/material/timepicker';
40
+ import * as i35 from '@angular/material/timepicker';
41
41
  import { MatTimepickerModule } from '@angular/material/timepicker';
42
- import * as i34 from '@angular/material/badge';
42
+ import * as i36 from '@angular/material/badge';
43
43
  import { MatBadgeModule } from '@angular/material/badge';
44
- import * as i35 from '@angular/material/expansion';
44
+ import * as i37 from '@angular/material/expansion';
45
45
  import { MatExpansionModule } from '@angular/material/expansion';
46
- import * as i36 from '@angular/material/form-field';
46
+ import * as i38 from '@angular/material/form-field';
47
47
  import { MatFormFieldModule } from '@angular/material/form-field';
48
48
  import * as i3 from '@danielmoncada/angular-datetime-picker';
49
49
  import { OwlDateTimeModule, OwlNativeDateTimeModule } from '@danielmoncada/angular-datetime-picker';
@@ -99,11 +99,11 @@ class ToastComponent {
99
99
  message = '';
100
100
  type;
101
101
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: ToastComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
102
- 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-[320px] 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: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: HeroIconComponent, selector: "fx-ui-hero-icon", inputs: ["icon", "solid", "outline", "size", "color", "class"] }] });
102
+ 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: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: HeroIconComponent, selector: "fx-ui-hero-icon", inputs: ["icon", "solid", "outline", "size", "color", "class"] }] });
103
103
  }
104
104
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: ToastComponent, decorators: [{
105
105
  type: Component,
106
- 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-[320px] 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" }]
106
+ 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" }]
107
107
  }], propDecorators: { toastId: [{
108
108
  type: Input
109
109
  }], title: [{
@@ -427,12 +427,13 @@ class BaseTableComponent extends BaseComponent {
427
427
  cols = [];
428
428
  total = 0;
429
429
  page = 1;
430
- pageSize = 5;
430
+ pageSize = 10;
431
431
  filters = {};
432
432
  loading = false;
433
433
  expandedElement;
434
434
  toastr;
435
435
  _lock = false;
436
+ keywordChange$ = new Subject();
436
437
  config;
437
438
  paginator;
438
439
  table;
@@ -444,6 +445,9 @@ class BaseTableComponent extends BaseComponent {
444
445
  this.toastr = injector.get(FxToastrService);
445
446
  }
446
447
  ngOnInit() {
448
+ this.keywordChange$.pipe(debounceTime(300)).subscribe(async (keyword) => {
449
+ await this.refresh();
450
+ });
447
451
  this.init();
448
452
  }
449
453
  init() { }
@@ -465,13 +469,13 @@ class BaseTableComponent extends BaseComponent {
465
469
  const params = { page: this.page, pageSize: this.pageSize, ...this.filters };
466
470
  const result = await this.api.search(params);
467
471
  this.setDataSource(result);
468
- this.ref.detectChanges();
469
472
  }
470
473
  catch (err) {
471
- this.toastr.error(FxUtils.parseError(err), 'Error');
474
+ this.toastr.error(FxUtils.parseError(err));
472
475
  }
473
476
  finally {
474
477
  this.loading = false;
478
+ this.ref.detectChanges();
475
479
  }
476
480
  }
477
481
  async onPageChange(event) {
@@ -485,6 +489,9 @@ class BaseTableComponent extends BaseComponent {
485
489
  empty() {
486
490
  return {};
487
491
  }
492
+ onKeywordChange(keyword) {
493
+ this.keywordChange$.next(keyword);
494
+ }
488
495
  async create() {
489
496
  const conf = _.get(this.config, 'create');
490
497
  const dialog = _.get(conf, 'dialog');
@@ -506,6 +513,7 @@ class BaseTableComponent extends BaseComponent {
506
513
  width: size,
507
514
  disableClose: true,
508
515
  data: {
516
+ method: 'create',
509
517
  data: this.empty(),
510
518
  title: conf.title,
511
519
  message: conf.message,
@@ -540,6 +548,7 @@ class BaseTableComponent extends BaseComponent {
540
548
  width: size,
541
549
  disableClose: true,
542
550
  data: {
551
+ method: 'update',
543
552
  data: model,
544
553
  title: conf.title,
545
554
  message: conf.message,
@@ -590,32 +599,36 @@ class BaseTableComponent extends BaseComponent {
590
599
  return;
591
600
  }
592
601
  this._lock = true;
593
- const conf = _.get(this.config, 'delete');
594
- const dialog = _.get(conf, 'dialog');
595
- const dialogRef = this.modal.open(dialog, {
596
- panelClass: 'fx-dialog',
597
- autoFocus: false,
598
- width: '400px',
599
- data: {
600
- title: _.get(conf, 'title'),
601
- message: _.get(conf, 'message'),
602
- cancelTitle: _.get(conf, 'cancelTitle'),
603
- confirmTitle: _.get(conf, 'confirmTitle'),
604
- },
605
- });
606
- dialogRef.afterClosed().subscribe(async (state) => {
602
+ try {
603
+ const conf = _.get(this.config, 'delete');
604
+ const dialog = _.get(conf, 'dialog');
605
+ const dialogRef = this.modal.open(dialog, {
606
+ panelClass: 'fx-dialog',
607
+ autoFocus: false,
608
+ width: '400px',
609
+ data: {
610
+ title: _.get(conf, 'title'),
611
+ message: _.get(conf, 'message'),
612
+ cancelLabel: _.get(conf, 'cancelTitle'),
613
+ confirmLabel: _.get(conf, 'confirmTitle'),
614
+ callback: async () => {
615
+ await this.remove(model);
616
+ },
617
+ },
618
+ });
619
+ const state = await firstValueFrom(dialogRef.afterClosed());
607
620
  if (state) {
608
621
  try {
609
- await this.remove(model);
610
- this.refresh();
622
+ await this.refresh();
611
623
  }
612
624
  catch (err) {
613
- this.toastr.error(FxUtils.parseError(err), 'Error');
625
+ this.toastr.error(FxUtils.parseError(err));
614
626
  }
615
- return;
616
627
  }
628
+ }
629
+ finally {
617
630
  this._lock = false;
618
- });
631
+ }
619
632
  }
620
633
  async remove(model) {
621
634
  try {
@@ -631,6 +644,18 @@ class BaseTableComponent extends BaseComponent {
631
644
  toggleExpand(element) {
632
645
  this.expandedElement = this.expandedElement === element ? null : element;
633
646
  }
647
+ async updateStatus(params) {
648
+ try {
649
+ await this.api.updateStatus(params);
650
+ this.toastr.success(_.get(this.config, 'updateStatus.message', 'Update Success'));
651
+ }
652
+ catch (err) {
653
+ this.toastr.success(FxUtils.parseError(err));
654
+ }
655
+ finally {
656
+ await this.refresh();
657
+ }
658
+ }
634
659
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: BaseTableComponent, deps: "invalid", target: i0.ɵɵFactoryTarget.Directive });
635
660
  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 });
636
661
  }
@@ -651,6 +676,7 @@ class BaseDialogComponent extends BaseComponent {
651
676
  api;
652
677
  dialog;
653
678
  ngForm;
679
+ method;
654
680
  title;
655
681
  model;
656
682
  disabled;
@@ -667,6 +693,7 @@ class BaseDialogComponent extends BaseComponent {
667
693
  this.api = api;
668
694
  this.dialog = dialog;
669
695
  this.model = _.clone(_.get(bindings, 'data'));
696
+ this.method = _.get(bindings, 'method');
670
697
  this.title = _.get(bindings, 'title');
671
698
  this.disabled = _.get(bindings, 'disabled');
672
699
  this.message = _.get(bindings, 'message');
@@ -703,31 +730,13 @@ class BaseDialogComponent extends BaseComponent {
703
730
  this.toastr.success(this.message);
704
731
  this.ref.close(true);
705
732
  }, (error) => {
706
- this.toastr.error(error);
733
+ this.toastr.error(FxUtils.parseError(error));
707
734
  })
708
735
  .then(() => {
709
736
  this.loading = false;
710
737
  });
711
738
  }
712
739
  update(params = null) {
713
- if (this.loading) {
714
- return;
715
- }
716
- this.loading = true;
717
- let code = _.get(this.model, 'code');
718
- this.api
719
- .update(code, { ...this.model, ...params })
720
- .then(() => {
721
- this.toastr.success(this.message);
722
- this.ref.close(true);
723
- }, (error) => {
724
- this.toastr.error(error);
725
- })
726
- .then(() => {
727
- this.loading = false;
728
- });
729
- }
730
- updateData(params = null) {
731
740
  if (this.loading) {
732
741
  return;
733
742
  }
@@ -944,6 +953,52 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
944
953
  type: Input
945
954
  }] } });
946
955
 
956
+ class TrimOnBlurDirective {
957
+ el;
958
+ ngControl;
959
+ collapseWhitespace = false;
960
+ constructor(el, ngControl) {
961
+ this.el = el;
962
+ this.ngControl = ngControl;
963
+ }
964
+ onBlur() {
965
+ const native = this.el.nativeElement;
966
+ if (!native)
967
+ return;
968
+ let value = native.value ?? '';
969
+ if (this.collapseWhitespace) {
970
+ value = value.replace(/\s+/g, ' ').trim();
971
+ }
972
+ else {
973
+ value = value.trim();
974
+ }
975
+ if (native.value === value)
976
+ return;
977
+ native.value = value;
978
+ if (this.ngControl && this.ngControl.control) {
979
+ this.ngControl.control.setValue(value);
980
+ }
981
+ else {
982
+ const ev = new Event('input', { bubbles: true });
983
+ native.dispatchEvent(ev);
984
+ }
985
+ }
986
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: TrimOnBlurDirective, deps: [{ token: i0.ElementRef }, { token: i1$3.NgControl }], target: i0.ɵɵFactoryTarget.Directive });
987
+ 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 });
988
+ }
989
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: TrimOnBlurDirective, decorators: [{
990
+ type: Directive,
991
+ args: [{
992
+ selector: '[appTrimOnBlur]'
993
+ }]
994
+ }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i1$3.NgControl }], propDecorators: { collapseWhitespace: [{
995
+ type: Input,
996
+ args: ['appTrimOnBlurCollapse']
997
+ }], onBlur: [{
998
+ type: HostListener,
999
+ args: ['blur']
1000
+ }] } });
1001
+
947
1002
  class PermissionGuard {
948
1003
  permissionService;
949
1004
  router;
@@ -991,19 +1046,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
991
1046
  }] });
992
1047
 
993
1048
  class AuthStateService {
994
- _isLoggedIn$ = new BehaviorSubject(false);
1049
+ _isLoggedIn$ = new BehaviorSubject(null);
995
1050
  isLoggedIn$ = this._isLoggedIn$.asObservable();
996
1051
  unauthorized$ = new Subject();
997
- constructor() {
998
- const saved = localStorage.getItem('isLoggedIn') === 'true';
999
- this._isLoggedIn$.next(saved);
1000
- }
1052
+ constructor() { }
1001
1053
  setLoggedIn(value) {
1002
1054
  this._isLoggedIn$.next(value);
1003
- localStorage.setItem('isLoggedIn', String(value));
1004
1055
  }
1005
1056
  get isLoggedIn() {
1006
- return this._isLoggedIn$.value;
1057
+ return this._isLoggedIn$.value === true;
1007
1058
  }
1008
1059
  handleUnauthorized() {
1009
1060
  this.setLoggedIn(false);
@@ -1059,6 +1110,71 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
1059
1110
  }]
1060
1111
  }] });
1061
1112
 
1113
+ class QuillStyleLoaderService {
1114
+ platformId;
1115
+ loaded = false;
1116
+ loadingPromise = null;
1117
+ constructor(platformId) {
1118
+ this.platformId = platformId;
1119
+ }
1120
+ /**
1121
+ * Load Quill CSS (only in browser). Returns a promise that resolves when
1122
+ * the CSS links have been appended.
1123
+ */
1124
+ load() {
1125
+ if (!isPlatformBrowser(this.platformId)) {
1126
+ // Server: do nothing and resolve immediately.
1127
+ return Promise.resolve();
1128
+ }
1129
+ if (this.loaded)
1130
+ return Promise.resolve();
1131
+ if (this.loadingPromise)
1132
+ return this.loadingPromise;
1133
+ this.loadingPromise = new Promise((resolve) => {
1134
+ const cssUrls = [
1135
+ // Using CDN is simplest — no consumer angular.json edits needed.
1136
+ 'https://cdn.jsdelivr.net/npm/quill/dist/quill.core.css',
1137
+ 'https://cdn.jsdelivr.net/npm/quill/dist/quill.snow.css'
1138
+ ];
1139
+ let remaining = cssUrls.length;
1140
+ const onLoad = () => {
1141
+ remaining -= 1;
1142
+ if (remaining === 0) {
1143
+ this.loaded = true;
1144
+ resolve();
1145
+ }
1146
+ };
1147
+ cssUrls.forEach((href) => {
1148
+ // Do not add duplicate links
1149
+ if (document.querySelector(`link[href="${href}"]`)) {
1150
+ onLoad();
1151
+ return;
1152
+ }
1153
+ const link = document.createElement('link');
1154
+ link.rel = 'stylesheet';
1155
+ link.href = href;
1156
+ link.onload = () => onLoad();
1157
+ link.onerror = () => {
1158
+ // still count it as loaded to avoid hanging if CDN fails
1159
+ console.warn(`[QuillStyleLoader] failed to load: ${href}`);
1160
+ onLoad();
1161
+ };
1162
+ document.head.appendChild(link);
1163
+ });
1164
+ });
1165
+ return this.loadingPromise;
1166
+ }
1167
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: QuillStyleLoaderService, deps: [{ token: PLATFORM_ID }], target: i0.ɵɵFactoryTarget.Injectable });
1168
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: QuillStyleLoaderService, providedIn: 'root' });
1169
+ }
1170
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: QuillStyleLoaderService, decorators: [{
1171
+ type: Injectable,
1172
+ args: [{ providedIn: 'root' }]
1173
+ }], ctorParameters: () => [{ type: Object, decorators: [{
1174
+ type: Inject,
1175
+ args: [PLATFORM_ID]
1176
+ }] }] });
1177
+
1062
1178
  const MATERIAL_MODULE = [
1063
1179
  MatSelectModule,
1064
1180
  MatRadioModule,
@@ -1090,11 +1206,11 @@ class ButtonComponent {
1090
1206
  this.clicked.emit();
1091
1207
  }
1092
1208
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: ButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
1093
- 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-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) {<fx-ui-hero-icon [icon]=\"icon\" [size]=\"20\" class=\"flex\" [ngClass]=\"{\n 'text-text-inverse': buttonVariant !== 'default',\n 'text-text-primary': buttonVariant === 'alternative'\n }\"></fx-ui-hero-icon>}\n <div>{{ label }}</div>\n </div>\n </ng-container>\n }\n</button>\n", styles: [""], dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: HeroIconComponent, selector: "fx-ui-hero-icon", inputs: ["icon", "solid", "outline", "size", "color", "class"] }] });
1209
+ 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-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) {<fx-ui-hero-icon [icon]=\"icon\" [size]=\"20\" class=\"flex\" [ngClass]=\"{\n 'text-text-inverse': buttonVariant !== 'default',\n 'text-text-primary': buttonVariant === 'alternative'\n }\"></fx-ui-hero-icon>}\n @if(label){<div>{{ label }}</div>}\n </div>\n </ng-container>\n }\n</button>\n", styles: [""], dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: HeroIconComponent, selector: "fx-ui-hero-icon", inputs: ["icon", "solid", "outline", "size", "color", "class"] }] });
1094
1210
  }
1095
1211
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: ButtonComponent, decorators: [{
1096
1212
  type: Component,
1097
- 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-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) {<fx-ui-hero-icon [icon]=\"icon\" [size]=\"20\" class=\"flex\" [ngClass]=\"{\n 'text-text-inverse': buttonVariant !== 'default',\n 'text-text-primary': buttonVariant === 'alternative'\n }\"></fx-ui-hero-icon>}\n <div>{{ label }}</div>\n </div>\n </ng-container>\n }\n</button>\n" }]
1213
+ 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-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) {<fx-ui-hero-icon [icon]=\"icon\" [size]=\"20\" class=\"flex\" [ngClass]=\"{\n 'text-text-inverse': buttonVariant !== 'default',\n 'text-text-primary': buttonVariant === 'alternative'\n }\"></fx-ui-hero-icon>}\n @if(label){<div>{{ label }}</div>}\n </div>\n </ng-container>\n }\n</button>\n" }]
1098
1214
  }], propDecorators: { label: [{
1099
1215
  type: Input
1100
1216
  }], disabled: [{
@@ -1438,7 +1554,15 @@ let FxComponent = class FxComponent {
1438
1554
  const control = this.ngControl?.control;
1439
1555
  if (!control)
1440
1556
  return;
1441
- control.setErrors(null);
1557
+ const errors = control.errors || {};
1558
+ const builtInErrorKeys = ['required', 'minlength', 'maxlength', 'email', 'pattern'];
1559
+ const remaining = {};
1560
+ for (const key of builtInErrorKeys) {
1561
+ if (errors[key] !== undefined) {
1562
+ remaining[key] = errors[key];
1563
+ }
1564
+ }
1565
+ control.setErrors(Object.keys(remaining).length ? remaining : null);
1442
1566
  }
1443
1567
  getErrorMessage(label) {
1444
1568
  if (!this.errors)
@@ -1447,6 +1571,7 @@ let FxComponent = class FxComponent {
1447
1571
  const defaultMessages = {
1448
1572
  required: `${displayLabel} is required`,
1449
1573
  minlength: `${displayLabel} minimum length is ${this.errors['minlength']?.requiredLength}`,
1574
+ email: "Please enter a valid email"
1450
1575
  };
1451
1576
  const messages = { ...defaultMessages, ...this.validationError, ...this.errorMessages };
1452
1577
  const firstKey = Object.keys(this.errors)[0];
@@ -1462,8 +1587,7 @@ class CheckboxComponent extends FxComponent {
1462
1587
  ref;
1463
1588
  label = '';
1464
1589
  disabled = false;
1465
- rounded = true;
1466
- size = 'normal';
1590
+ rounded;
1467
1591
  valueChange = new EventEmitter();
1468
1592
  constructor(ngControl, ref) {
1469
1593
  super(ngControl);
@@ -1485,19 +1609,17 @@ class CheckboxComponent extends FxComponent {
1485
1609
  this.onTouched();
1486
1610
  }
1487
1611
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: CheckboxComponent, deps: [{ token: i1$3.NgControl }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
1488
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.4", type: CheckboxComponent, isStandalone: false, selector: "fx-ui-checkbox", inputs: { label: "label", disabled: "disabled", rounded: "rounded", size: "size" }, outputs: { valueChange: "valueChange" }, usesInheritance: true, ngImport: i0, template: "<label\n class=\"inline-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 flex items-center justify-center border rounded-full transition-colors duration-150 shrink-0\"\n [class]=\"rounded ? 'rounded-full' : 'rounded-sm'\"\n [class]=\"size === 'large' ? 'w-6 h-6' : 'w-4 h-4'\"\n [ngClass]=\"{\n 'border-border-strong bg-transparent': !value,\n 'border-border-selected bg-border-selected': 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-bg-primary transition-opacity duration-150\"\n [class]=\"size === 'large' ? 'w-4.5 h-4.5' : 'w-3 h-3'\"\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 <span class=\"mb-0 txt-field-label\">{{ label }}</span>\n</label>\n", styles: [""], dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
1612
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: CheckboxComponent, isStandalone: false, selector: "fx-ui-checkbox", inputs: { label: "label", disabled: "disabled", 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-border-selected bg-border-selected': 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-bg-primary 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){<span class=\"mb-0 txt-field-label\">{{ label }}</span>}\n</label>\n", styles: [""], dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
1489
1613
  }
1490
1614
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: CheckboxComponent, decorators: [{
1491
1615
  type: Component,
1492
- args: [{ selector: 'fx-ui-checkbox', standalone: false, template: "<label\n class=\"inline-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 flex items-center justify-center border rounded-full transition-colors duration-150 shrink-0\"\n [class]=\"rounded ? 'rounded-full' : 'rounded-sm'\"\n [class]=\"size === 'large' ? 'w-6 h-6' : 'w-4 h-4'\"\n [ngClass]=\"{\n 'border-border-strong bg-transparent': !value,\n 'border-border-selected bg-border-selected': 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-bg-primary transition-opacity duration-150\"\n [class]=\"size === 'large' ? 'w-4.5 h-4.5' : 'w-3 h-3'\"\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 <span class=\"mb-0 txt-field-label\">{{ label }}</span>\n</label>\n" }]
1616
+ 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-border-selected bg-border-selected': 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-bg-primary 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){<span class=\"mb-0 txt-field-label\">{{ label }}</span>}\n</label>\n" }]
1493
1617
  }], ctorParameters: () => [{ type: i1$3.NgControl }, { type: i0.ChangeDetectorRef }], propDecorators: { label: [{
1494
1618
  type: Input
1495
1619
  }], disabled: [{
1496
1620
  type: Input
1497
1621
  }], rounded: [{
1498
1622
  type: Input
1499
- }], size: [{
1500
- type: Input
1501
1623
  }], valueChange: [{
1502
1624
  type: Output
1503
1625
  }] } });
@@ -1724,11 +1846,11 @@ class InputComponent extends FxComponent {
1724
1846
  return this.type;
1725
1847
  }
1726
1848
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: InputComponent, deps: [{ token: i1$3.NgControl }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
1727
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: InputComponent, isStandalone: false, selector: "fx-ui-input", inputs: { label: "label", type: "type", placeholder: "placeholder", errorMessages: "errorMessages", required: "required", disabled: "disabled", iconClass: "iconClass", 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){<label class=\"block txt-field-label\">\n {{ label }}\n @if (required) {<span class=\"txt-required\">*</span>}\n </label>\n }\n\n <div class=\"relative\">\n <input\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 [ngClass]=\"{\n 'input-invalid': invalid,\n 'pr-8': type === 'password' || suffixIcon,\n 'txt-otp-input': type === 'otp'\n }\"\n />\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 <i class=\"material-symbols-outlined text-lg select-none\">{{\n showPassword ? 'visibility_off' : 'visibility'\n }}</i>\n } @else if (suffixIcon) {\n <i [class]=\"iconClass\" class=\"text-lg select-none\">{{ suffixIcon }}</i>\n }\n </button>\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: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
1849
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: InputComponent, isStandalone: false, selector: "fx-ui-input", inputs: { label: "label", type: "type", placeholder: "placeholder", errorMessages: "errorMessages", required: "required", disabled: "disabled", iconClass: "iconClass", 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){<label class=\"block txt-field-label\">\n {{ label }}\n @if (required) {<span class=\"txt-required\">*</span>}\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 [ngClass]=\"{\n 'input-invalid': invalid,\n 'pr-8': type === 'password' || suffixIcon,\n 'txt-otp-input': type === 'otp'\n }\"\n />\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 <i class=\"material-symbols-outlined text-lg select-none\">{{\n showPassword ? 'visibility_off' : 'visibility'\n }}</i>\n } @else if (suffixIcon) {\n <i [class]=\"iconClass\" class=\"text-lg select-none\">{{ suffixIcon }}</i>\n }\n </button>\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: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: TrimOnBlurDirective, selector: "[appTrimOnBlur]", inputs: ["appTrimOnBlurCollapse"] }] });
1728
1850
  }
1729
1851
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: InputComponent, decorators: [{
1730
1852
  type: Component,
1731
- args: [{ selector: 'fx-ui-input', standalone: false, template: "<div class=\"mb-4 text-left w-full text-text-primary\" [class]=\"class\">\n @if(label){<label class=\"block txt-field-label\">\n {{ label }}\n @if (required) {<span class=\"txt-required\">*</span>}\n </label>\n }\n\n <div class=\"relative\">\n <input\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 [ngClass]=\"{\n 'input-invalid': invalid,\n 'pr-8': type === 'password' || suffixIcon,\n 'txt-otp-input': type === 'otp'\n }\"\n />\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 <i class=\"material-symbols-outlined text-lg select-none\">{{\n showPassword ? 'visibility_off' : 'visibility'\n }}</i>\n } @else if (suffixIcon) {\n <i [class]=\"iconClass\" class=\"text-lg select-none\">{{ suffixIcon }}</i>\n }\n </button>\n </div>\n\n @if (invalid){\n <div class=\"txt-invalid\">\n {{ getErrorMessage(label) }}\n </div>\n }\n</div>\n" }]
1853
+ args: [{ selector: 'fx-ui-input', standalone: false, template: "<div class=\"mb-4 text-left w-full text-text-primary\" [class]=\"class\">\n @if(label){<label class=\"block txt-field-label\">\n {{ label }}\n @if (required) {<span class=\"txt-required\">*</span>}\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 [ngClass]=\"{\n 'input-invalid': invalid,\n 'pr-8': type === 'password' || suffixIcon,\n 'txt-otp-input': type === 'otp'\n }\"\n />\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 <i class=\"material-symbols-outlined text-lg select-none\">{{\n showPassword ? 'visibility_off' : 'visibility'\n }}</i>\n } @else if (suffixIcon) {\n <i [class]=\"iconClass\" class=\"text-lg select-none\">{{ suffixIcon }}</i>\n }\n </button>\n </div>\n\n @if (invalid){\n <div class=\"txt-invalid\">\n {{ getErrorMessage(label) }}\n </div>\n }\n</div>\n" }]
1732
1854
  }], ctorParameters: () => [{ type: i1$3.NgControl }, { type: i0.ChangeDetectorRef }], propDecorators: { label: [{
1733
1855
  type: Input
1734
1856
  }], type: [{
@@ -1864,6 +1986,96 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
1864
1986
  type: Input
1865
1987
  }] } });
1866
1988
 
1989
+ class RichTextAreaComponent extends FxComponent {
1990
+ cdr;
1991
+ styleLoader;
1992
+ platformId;
1993
+ editorContainer;
1994
+ placeholder = 'Write something...';
1995
+ toolbarOptions = [
1996
+ // ['undo', 'redo'],
1997
+ [{ 'header': [1, 2, 3, 4, 5, 6, false] }],
1998
+ [{ 'font': [] }],
1999
+ [{ 'size': ['small', false, 'large', 'huge'] }],
2000
+ [{ 'align': [] }],
2001
+ [{ 'color': [] }, { 'background': [] }],
2002
+ ['bold', 'italic', 'underline', 'strike'],
2003
+ ['blockquote', 'code-block'],
2004
+ [{ 'list': 'ordered' }, { 'list': 'bullet' }],
2005
+ [{ 'indent': '-1' }, { 'indent': '+1' }],
2006
+ ['link', 'image'],
2007
+ ['clean']
2008
+ ];
2009
+ contentChange = new EventEmitter();
2010
+ quillInstance;
2011
+ constructor(ngControl, cdr, styleLoader, platformId) {
2012
+ super(ngControl);
2013
+ this.cdr = cdr;
2014
+ this.styleLoader = styleLoader;
2015
+ this.platformId = platformId;
2016
+ }
2017
+ async ngAfterViewInit() {
2018
+ if (!isPlatformBrowser(this.platformId))
2019
+ return;
2020
+ await this.styleLoader.load();
2021
+ const QuillModule = await import('quill');
2022
+ const Quill = QuillModule.default || QuillModule;
2023
+ const icons = Quill.import('ui/icons');
2024
+ // icons['undo'] = `<svg viewBox="0 0 18 18"><path d="M6.4 5.2H3L6.8 1l3.8 4.2H7.9C10.2 5.4 12 7.4 12 9.8c0 2.7-2.2 4.9-4.9 4.9S2.2 12.5 2.2 9.8H0c0 3.8 3.1 6.9 6.9 6.9s6.9-3.1 6.9-6.9S10.7 3 7 3v2.2z"></path></svg>`;
2025
+ // icons['redo'] = `<svg viewBox="0 0 18 18"><path d="M11.6 5.2H15L11.2 1 7.4 5.2h2.7C7.8 5.4 6 7.4 6 9.8c0 2.7 2.2 4.9 4.9 4.9s4.9-2.2 4.9-4.9H18c0 3.8-3.1 6.9-6.9 6.9S4.2 13.6 4.2 9.8 7.3 3 11 3v2.2z"></path></svg>`;
2026
+ this.quillInstance = new Quill(this.editorContainer.nativeElement, {
2027
+ theme: 'snow',
2028
+ placeholder: this.placeholder,
2029
+ modules: {
2030
+ history: true,
2031
+ toolbar: this.toolbarOptions,
2032
+ }
2033
+ });
2034
+ this.quillInstance.root.style.color = FxUtils.convertColorFromVariable('--text-primary');
2035
+ const toolbar = this.quillInstance.getModule('toolbar');
2036
+ toolbar.addHandler('undo', () => this.quillInstance.history.undo());
2037
+ toolbar.addHandler('redo', () => this.quillInstance.history.redo());
2038
+ if (this.value) {
2039
+ this.quillInstance.root.innerHTML = this.value;
2040
+ }
2041
+ this.quillInstance.on('text-change', () => {
2042
+ const html = this.quillInstance.root.innerHTML || '';
2043
+ this.value = html;
2044
+ this.onChange(html);
2045
+ this.contentChange.emit(html);
2046
+ });
2047
+ }
2048
+ writeValue(value) {
2049
+ this.value = value || '';
2050
+ if (this.quillInstance) {
2051
+ this.quillInstance.root.innerHTML = this.value;
2052
+ }
2053
+ }
2054
+ setDisabledState(isDisabled) {
2055
+ if (this.quillInstance) {
2056
+ this.quillInstance.enable(!isDisabled);
2057
+ }
2058
+ }
2059
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: RichTextAreaComponent, deps: [{ token: i1$3.NgControl }, { token: i0.ChangeDetectorRef }, { token: QuillStyleLoaderService }, { token: PLATFORM_ID }], target: i0.ɵɵFactoryTarget.Component });
2060
+ 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;line-height:1.5rem}\n"] });
2061
+ }
2062
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: RichTextAreaComponent, decorators: [{
2063
+ type: Component,
2064
+ 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;line-height:1.5rem}\n"] }]
2065
+ }], ctorParameters: () => [{ type: i1$3.NgControl }, { type: i0.ChangeDetectorRef }, { type: QuillStyleLoaderService }, { type: Object, decorators: [{
2066
+ type: Inject,
2067
+ args: [PLATFORM_ID]
2068
+ }] }], propDecorators: { editorContainer: [{
2069
+ type: ViewChild,
2070
+ args: ['editorContainer', { static: true }]
2071
+ }], placeholder: [{
2072
+ type: Input
2073
+ }], toolbarOptions: [{
2074
+ type: Input
2075
+ }], contentChange: [{
2076
+ type: Output
2077
+ }] } });
2078
+
1867
2079
  class SearchBarComponent extends FxComponent {
1868
2080
  ref;
1869
2081
  placeholder = 'Search...';
@@ -1918,13 +2130,49 @@ class SelectComponent extends FxComponent {
1918
2130
  errorMessages = {};
1919
2131
  required = false;
1920
2132
  class;
2133
+ enableSearch = false;
2134
+ searchFn;
2135
+ searchTerm = '';
2136
+ filteredOptions = [];
2137
+ search$ = new Subject();
1921
2138
  constructor(ngControl, ref) {
1922
2139
  super(ngControl);
1923
2140
  this.ref = ref;
1924
2141
  }
2142
+ ngOnInit() {
2143
+ this.filteredOptions = this.options;
2144
+ this.search$
2145
+ .pipe(debounceTime(300), distinctUntilChanged())
2146
+ .subscribe((term) => this.performSearch(term));
2147
+ }
1925
2148
  ngAfterViewInit() {
1926
2149
  this.ref.detectChanges();
1927
2150
  }
2151
+ onOpened(open) {
2152
+ if (open) {
2153
+ this.filteredOptions = this.options;
2154
+ if (this.enableSearch)
2155
+ this.searchTerm = '';
2156
+ }
2157
+ }
2158
+ onSearchChange(value) {
2159
+ if (!this.enableSearch)
2160
+ return;
2161
+ this.search$.next(value);
2162
+ }
2163
+ async performSearch(term) {
2164
+ if (!this.enableSearch)
2165
+ return;
2166
+ if (!this.searchFn) {
2167
+ this.filteredOptions = this.options.filter((o) => o.label?.toLowerCase().includes(term.toLowerCase()));
2168
+ this.ref.detectChanges();
2169
+ return;
2170
+ }
2171
+ const result = await this.searchFn(term);
2172
+ this.filteredOptions = result;
2173
+ console.log(this.filteredOptions);
2174
+ Promise.resolve().then(() => this.ref.detectChanges());
2175
+ }
1928
2176
  onSelectionChange(value) {
1929
2177
  this.value = value;
1930
2178
  this.onChange(this.value);
@@ -1936,11 +2184,11 @@ class SelectComponent extends FxComponent {
1936
2184
  return this.value === value;
1937
2185
  }
1938
2186
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: SelectComponent, deps: [{ token: i1$3.NgControl }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
1939
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: SelectComponent, isStandalone: false, selector: "fx-ui-select", inputs: { label: "label", placeholder: "placeholder", options: "options", multiple: "multiple", disabled: "disabled", errorMessages: "errorMessages", required: "required", class: "class" }, usesInheritance: true, ngImport: i0, template: "<div class=\"mb-4 text-left w-full\" [class]=\"class\">\n <label *ngIf=\"label\" class=\"block txt-field-label\">\n {{ label }}\n @if(required) {<span class=\"txt-required\">*</span>}\n </label>\n\n <mat-form-field class=\"fx-select-field w-full shadow-sm\" appearance=\"fill\">\n <mat-select\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n [multiple]=\"multiple\"\n [value]=\"value\"\n (selectionChange)=\"onSelectionChange($event.value)\"\n (blur)=\"onTouched()\"\n >\n <mat-option *ngFor=\"let option of options\" [value]=\"option.value\">\n <span class=\"txt-default\">{{ option.label }}</span>\n </mat-option>\n </mat-select>\n </mat-form-field>\n\n <div *ngIf=\"invalid\" class=\"txt-invalid text-left\">\n {{ getErrorMessage(label) }}\n </div>\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:.5rem;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(--border-interactive))!important;outline:none!important;border-radius:.5rem}::ng-deep .fx-select-field.mat-form-field-invalid .mat-mdc-form-field-flex{border-color:#ef4444!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{color:rgb(var(--text-primary))}::ng-deep .mat-mdc-select-panel{background-color:rgb(var(--bg-primary))!important;border:1px solid rgb(var(--border-default))!important;border-radius:.5rem!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}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i3$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "component", type: i3$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: i3$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }] });
2187
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: SelectComponent, isStandalone: false, selector: "fx-ui-select", inputs: { label: "label", placeholder: "placeholder", options: "options", multiple: "multiple", disabled: "disabled", errorMessages: "errorMessages", required: "required", class: "class", enableSearch: "enableSearch", searchFn: "searchFn" }, usesInheritance: true, ngImport: i0, template: "<div class=\"mb-4 text-left w-full\" [class]=\"class\">\n <label *ngIf=\"label\" class=\"block txt-field-label\">\n {{ label }}\n @if(required) {<span class=\"txt-required\">*</span>}\n </label>\n\n <mat-form-field class=\"fx-select-field w-full shadow-sm\" appearance=\"fill\">\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-border-interactive 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 <div *ngIf=\"invalid\" class=\"txt-invalid text-left\">\n {{ getErrorMessage(label) }}\n </div>\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:.5rem;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(--border-interactive))!important;outline:none!important;border-radius:.5rem}::ng-deep .fx-select-field.mat-form-field-invalid .mat-mdc-form-field-flex{border-color:#ef4444!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{color:rgb(var(--text-primary))}::ng-deep .mat-mdc-select-panel{background-color:rgb(var(--bg-primary))!important;border:1px solid rgb(var(--border-default))!important;border-radius:.5rem!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}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$3.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$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i3$1.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "component", type: i3$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: i3$1.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }] });
1940
2188
  }
1941
2189
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: SelectComponent, decorators: [{
1942
2190
  type: Component,
1943
- args: [{ selector: 'fx-ui-select', standalone: false, template: "<div class=\"mb-4 text-left w-full\" [class]=\"class\">\n <label *ngIf=\"label\" class=\"block txt-field-label\">\n {{ label }}\n @if(required) {<span class=\"txt-required\">*</span>}\n </label>\n\n <mat-form-field class=\"fx-select-field w-full shadow-sm\" appearance=\"fill\">\n <mat-select\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled\"\n [multiple]=\"multiple\"\n [value]=\"value\"\n (selectionChange)=\"onSelectionChange($event.value)\"\n (blur)=\"onTouched()\"\n >\n <mat-option *ngFor=\"let option of options\" [value]=\"option.value\">\n <span class=\"txt-default\">{{ option.label }}</span>\n </mat-option>\n </mat-select>\n </mat-form-field>\n\n <div *ngIf=\"invalid\" class=\"txt-invalid text-left\">\n {{ getErrorMessage(label) }}\n </div>\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:.5rem;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(--border-interactive))!important;outline:none!important;border-radius:.5rem}::ng-deep .fx-select-field.mat-form-field-invalid .mat-mdc-form-field-flex{border-color:#ef4444!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{color:rgb(var(--text-primary))}::ng-deep .mat-mdc-select-panel{background-color:rgb(var(--bg-primary))!important;border:1px solid rgb(var(--border-default))!important;border-radius:.5rem!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}\n"] }]
2191
+ args: [{ selector: 'fx-ui-select', standalone: false, template: "<div class=\"mb-4 text-left w-full\" [class]=\"class\">\n <label *ngIf=\"label\" class=\"block txt-field-label\">\n {{ label }}\n @if(required) {<span class=\"txt-required\">*</span>}\n </label>\n\n <mat-form-field class=\"fx-select-field w-full shadow-sm\" appearance=\"fill\">\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-border-interactive 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 <div *ngIf=\"invalid\" class=\"txt-invalid text-left\">\n {{ getErrorMessage(label) }}\n </div>\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:.5rem;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(--border-interactive))!important;outline:none!important;border-radius:.5rem}::ng-deep .fx-select-field.mat-form-field-invalid .mat-mdc-form-field-flex{border-color:#ef4444!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{color:rgb(var(--text-primary))}::ng-deep .mat-mdc-select-panel{background-color:rgb(var(--bg-primary))!important;border:1px solid rgb(var(--border-default))!important;border-radius:.5rem!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}\n"] }]
1944
2192
  }], ctorParameters: () => [{ type: i1$3.NgControl }, { type: i0.ChangeDetectorRef }], propDecorators: { label: [{
1945
2193
  type: Input
1946
2194
  }], placeholder: [{
@@ -1957,6 +2205,25 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
1957
2205
  type: Input
1958
2206
  }], class: [{
1959
2207
  type: Input
2208
+ }], enableSearch: [{
2209
+ type: Input
2210
+ }], searchFn: [{
2211
+ type: Input
2212
+ }] } });
2213
+
2214
+ class SkeletonTableLoadingComponent {
2215
+ columns = 5;
2216
+ rows = 5;
2217
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: SkeletonTableLoadingComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2218
+ 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: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }] });
2219
+ }
2220
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: SkeletonTableLoadingComponent, decorators: [{
2221
+ type: Component,
2222
+ 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" }]
2223
+ }], propDecorators: { columns: [{
2224
+ type: Input
2225
+ }], rows: [{
2226
+ type: Input
1960
2227
  }] } });
1961
2228
 
1962
2229
  class SliderComponent extends FxComponent {
@@ -2137,11 +2404,11 @@ class SwitchComponent extends FxComponent {
2137
2404
  this.onTouched();
2138
2405
  }
2139
2406
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: SwitchComponent, deps: [{ token: i1$3.NgControl }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
2140
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: SwitchComponent, isStandalone: false, selector: "fx-ui-switch", inputs: { disabled: "disabled" }, outputs: { onSwitch: "onSwitch" }, usesInheritance: true, ngImport: i0, template: "<div\n class=\"relative inline-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: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
2407
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: SwitchComponent, isStandalone: false, selector: "fx-ui-switch", inputs: { disabled: "disabled" }, 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: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] });
2141
2408
  }
2142
2409
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: SwitchComponent, decorators: [{
2143
2410
  type: Component,
2144
- args: [{ selector: 'fx-ui-switch', standalone: false, template: "<div\n class=\"relative inline-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" }]
2411
+ 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" }]
2145
2412
  }], ctorParameters: () => [{ type: i1$3.NgControl }, { type: i0.ChangeDetectorRef }], propDecorators: { disabled: [{
2146
2413
  type: Input
2147
2414
  }], onSwitch: [{
@@ -2313,34 +2580,44 @@ const FX_COMPONENTS = [
2313
2580
  TagComponent,
2314
2581
  ChartComponent,
2315
2582
  SliderComponent,
2316
- SwitchComponent
2583
+ SwitchComponent,
2584
+ RichTextAreaComponent,
2585
+ SkeletonTableLoadingComponent
2317
2586
  ];
2318
2587
 
2319
2588
  class ConfirmationDialogComponent {
2320
2589
  ref;
2590
+ bindings;
2591
+ loading = false;
2321
2592
  title = '';
2322
2593
  message = '';
2323
2594
  cancelLabel = 'Cancel';
2324
2595
  confirmLabel = 'Submit';
2325
2596
  constructor(ref, bindings) {
2326
2597
  this.ref = ref;
2598
+ this.bindings = bindings;
2327
2599
  this.title = _.get(bindings, 'title');
2328
2600
  this.message = _.get(bindings, 'message');
2329
2601
  this.cancelLabel = _.get(bindings, 'cancelLabel');
2330
2602
  this.confirmLabel = _.get(bindings, 'confirmLabel');
2331
2603
  }
2332
- accept() {
2604
+ async accept() {
2605
+ this.loading = true;
2606
+ if (_.get(this.bindings, 'callback')) {
2607
+ await this.bindings.callback();
2608
+ this.loading = false;
2609
+ }
2333
2610
  this.ref.close(true);
2334
2611
  }
2335
2612
  cancel() {
2336
2613
  this.ref.close(false);
2337
2614
  }
2338
2615
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: ConfirmationDialogComponent, deps: [{ token: i1$1.MatDialogRef }, { token: MAT_DIALOG_DATA }], target: i0.ɵɵFactoryTarget.Component });
2339
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.4", type: ConfirmationDialogComponent, isStandalone: false, selector: "ui-confirmation", ngImport: i0, template: "<div animate.enter=\"fade-in-animation\">\n <div class=\"txt-section-header px-2xl py-semi\">{{title}}</div>\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 buttonVariant=\"primary\" class=\"mr-1\" [label]=\"confirmLabel\" (clicked)=\"accept()\"></fx-ui-button>\n </mat-dialog-actions>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1$1.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"] }] });
2616
+ 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 <div class=\"txt-dialog-header\">{{ title }}</div>\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 buttonVariant=\"primary\" class=\"mr-1\" [label]=\"confirmLabel\" (clicked)=\"accept()\" [loading]=\"loading\" class=\"min-w-[100px]\"></fx-ui-button>\n </mat-dialog-actions>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i1$1.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: i1$1.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"] }] });
2340
2617
  }
2341
2618
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: ConfirmationDialogComponent, decorators: [{
2342
2619
  type: Component,
2343
- args: [{ selector: 'ui-confirmation', standalone: false, template: "<div animate.enter=\"fade-in-animation\">\n <div class=\"txt-section-header px-2xl py-semi\">{{title}}</div>\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 buttonVariant=\"primary\" class=\"mr-1\" [label]=\"confirmLabel\" (clicked)=\"accept()\"></fx-ui-button>\n </mat-dialog-actions>\n</div>\n" }]
2620
+ args: [{ selector: 'fx-ui-confirmation-dialog', standalone: false, template: "<div animate.enter=\"fade-in-animation\" class=\"dialog-container\">\n <div class=\"txt-dialog-header\">{{ title }}</div>\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 buttonVariant=\"primary\" class=\"mr-1\" [label]=\"confirmLabel\" (clicked)=\"accept()\" [loading]=\"loading\" class=\"min-w-[100px]\"></fx-ui-button>\n </mat-dialog-actions>\n</div>\n" }]
2344
2621
  }], ctorParameters: () => [{ type: i1$1.MatDialogRef }, { type: undefined, decorators: [{
2345
2622
  type: Inject,
2346
2623
  args: [MAT_DIALOG_DATA]
@@ -2361,20 +2638,21 @@ const MY_FORMATS = {
2361
2638
  };
2362
2639
  class UiModule {
2363
2640
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: UiModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
2364
- 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, ConfirmationDialogComponent], imports: [CommonModule,
2641
+ 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, ConfirmationDialogComponent], imports: [CommonModule,
2365
2642
  FormsModule,
2366
2643
  ReactiveFormsModule,
2367
2644
  OwlDateTimeModule,
2368
2645
  OwlNativeDateTimeModule,
2369
2646
  HasPermissionDirective,
2370
- NgHeroiconsModule, i2$3.NgxEchartsModule, i3$1.MatSelectModule, i23.MatRadioModule, i24.MatButtonModule, i25.MatIconModule, i26.MatPaginatorModule, i27.MatTableModule, i28.MatSnackBarModule, i1$1.MatDialogModule, i30.MatCheckboxModule, i31.MatCardModule, i32.MatDatepickerModule, i33.MatTimepickerModule, i34.MatBadgeModule, i35.MatExpansionModule, i36.MatFormFieldModule], exports: [InputComponent, SelectComponent, RadioButtonComponent, CheckboxComponent, DndUploadComponent, ButtonComponent, RadioButtonToggleComponent, DatetimePicker, LoadingPanel, SearchBarComponent, TabGroupComponent, TabComponent, HeroIconComponent, ToastComponent, ToastContainerComponent, TagComponent, ChartComponent, SliderComponent, SwitchComponent, ConfirmationDialogComponent,
2647
+ TrimOnBlurDirective,
2648
+ NgHeroiconsModule, i2$3.NgxEchartsModule, i3$1.MatSelectModule, i25.MatRadioModule, i26.MatButtonModule, i27.MatIconModule, i28.MatPaginatorModule, i29.MatTableModule, i30.MatSnackBarModule, i1$1.MatDialogModule, i32.MatCheckboxModule, i33.MatCardModule, i34.MatDatepickerModule, i35.MatTimepickerModule, i36.MatBadgeModule, i37.MatExpansionModule, i38.MatFormFieldModule], exports: [InputComponent, SelectComponent, RadioButtonComponent, CheckboxComponent, DndUploadComponent, ButtonComponent, RadioButtonToggleComponent, DatetimePicker, LoadingPanel, SearchBarComponent, TabGroupComponent, TabComponent, HeroIconComponent, ToastComponent, ToastContainerComponent, TagComponent, ChartComponent, SliderComponent, SwitchComponent, RichTextAreaComponent, SkeletonTableLoadingComponent, ConfirmationDialogComponent,
2371
2649
  // Module
2372
2650
  FormsModule,
2373
2651
  ReactiveFormsModule,
2374
2652
  OwlDateTimeModule,
2375
2653
  OwlNativeDateTimeModule,
2376
2654
  HasPermissionDirective,
2377
- NgHeroiconsModule, i3$1.MatSelectModule, i23.MatRadioModule, i24.MatButtonModule, i25.MatIconModule, i26.MatPaginatorModule, i27.MatTableModule, i28.MatSnackBarModule, i1$1.MatDialogModule, i30.MatCheckboxModule, i31.MatCardModule, i32.MatDatepickerModule, i33.MatTimepickerModule, i34.MatBadgeModule, i35.MatExpansionModule, i36.MatFormFieldModule] });
2655
+ NgHeroiconsModule, i3$1.MatSelectModule, i25.MatRadioModule, i26.MatButtonModule, i27.MatIconModule, i28.MatPaginatorModule, i29.MatTableModule, i30.MatSnackBarModule, i1$1.MatDialogModule, i32.MatCheckboxModule, i33.MatCardModule, i34.MatDatepickerModule, i35.MatTimepickerModule, i36.MatBadgeModule, i37.MatExpansionModule, i38.MatFormFieldModule] });
2378
2656
  static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: UiModule, providers: [
2379
2657
  importProvidersFrom(NgHeroiconsModule.forRoot()),
2380
2658
  // { provide: OWL_DATE_TIME_FORMATS, useValue: MY_FORMATS },
@@ -2390,7 +2668,7 @@ class UiModule {
2390
2668
  ReactiveFormsModule,
2391
2669
  OwlDateTimeModule,
2392
2670
  OwlNativeDateTimeModule,
2393
- NgHeroiconsModule, i3$1.MatSelectModule, i23.MatRadioModule, i24.MatButtonModule, i25.MatIconModule, i26.MatPaginatorModule, i27.MatTableModule, i28.MatSnackBarModule, i1$1.MatDialogModule, i30.MatCheckboxModule, i31.MatCardModule, i32.MatDatepickerModule, i33.MatTimepickerModule, i34.MatBadgeModule, i35.MatExpansionModule, i36.MatFormFieldModule] });
2671
+ NgHeroiconsModule, i3$1.MatSelectModule, i25.MatRadioModule, i26.MatButtonModule, i27.MatIconModule, i28.MatPaginatorModule, i29.MatTableModule, i30.MatSnackBarModule, i1$1.MatDialogModule, i32.MatCheckboxModule, i33.MatCardModule, i34.MatDatepickerModule, i35.MatTimepickerModule, i36.MatBadgeModule, i37.MatExpansionModule, i38.MatFormFieldModule] });
2394
2672
  }
2395
2673
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: UiModule, decorators: [{
2396
2674
  type: NgModule,
@@ -2403,6 +2681,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
2403
2681
  OwlDateTimeModule,
2404
2682
  OwlNativeDateTimeModule,
2405
2683
  HasPermissionDirective,
2684
+ TrimOnBlurDirective,
2406
2685
  NgHeroiconsModule,
2407
2686
  NgxEchartsModule.forRoot({ echarts: () => import('echarts') }),
2408
2687
  ...MATERIAL_MODULE,
@@ -2435,5 +2714,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
2435
2714
  * Generated bundle index. Do not edit.
2436
2715
  */
2437
2716
 
2438
- export { AuthInterceptor, AuthStateService, BaseComponent, BaseDialogComponent, BaseResolver, BaseTableComponent, BreadcrumbService, ButtonComponent, ChartComponent, CheckboxComponent, ConfirmationDialogComponent, DatetimePicker, DndUploadComponent, FxLoadingService, FxStorageService, FxToastrService, FxUtils, HasPermissionDirective, HeroIconComponent, HttpLoaderFactory, HttpWrapper, InputComponent, LoadingPanel, MY_FORMATS, PermissionGuard, PermissionService, RadioButtonComponent, RadioButtonToggleComponent, SearchBarComponent, SelectComponent, SliderComponent, SwitchComponent, TabComponent, TabGroupComponent, TagComponent, ToastComponent, ToastContainerComponent, TranslationModule, TranslationService, UiModule };
2717
+ export { AuthInterceptor, AuthStateService, BaseComponent, BaseDialogComponent, BaseResolver, BaseTableComponent, BreadcrumbService, ButtonComponent, ChartComponent, CheckboxComponent, ConfirmationDialogComponent, DatetimePicker, DndUploadComponent, FxLoadingService, FxStorageService, FxToastrService, FxUtils, HasPermissionDirective, HeroIconComponent, HttpLoaderFactory, HttpWrapper, InputComponent, LoadingPanel, MY_FORMATS, PermissionGuard, PermissionService, QuillStyleLoaderService, RadioButtonComponent, RadioButtonToggleComponent, RichTextAreaComponent, SearchBarComponent, SelectComponent, SkeletonTableLoadingComponent, SliderComponent, SwitchComponent, TabComponent, TabGroupComponent, TagComponent, ToastComponent, ToastContainerComponent, TranslationModule, TranslationService, TrimOnBlurDirective, UiModule };
2439
2718
  //# sourceMappingURL=fxlt-common-ui.mjs.map