@wlcm/angular 17.6.0 → 17.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,9 +6,10 @@ import { Validators, NgControl, ControlContainer, FormControl, NG_VALUE_ACCESSOR
6
6
  import * as i1 from '@angular/common';
7
7
  import { CommonModule } from '@angular/common';
8
8
  import { Subject, Observable, takeUntil, merge, fromEvent, observeOn, asyncScheduler, BehaviorSubject, EMPTY, switchMap, take, tap, concatMap, filter, timer, map, first } from 'rxjs';
9
- import { WlcmAutocompleteOption, DEFAULT_QUERY_PARAMS, WlcmIconName, WlcmIconDirective, WlcmLoaderComponent } from '@wlcm/angular/core';
9
+ import * as i1$3 from '@wlcm/angular/core';
10
+ import { WlcmAutocompleteOption, DEFAULT_QUERY_PARAMS, WlcmIconName, WlcmIconDirective, WlcmLoaderComponent, ScrollDetectionApi } from '@wlcm/angular/core';
10
11
  import { untilDestroyed, UntilDestroy } from '@ngneat/until-destroy';
11
- import * as i3$1 from '@angular/material/select';
12
+ import * as i4$1 from '@angular/material/select';
12
13
  import { MatOption, MAT_SELECT_CONFIG, MatSelect, MatSelectModule } from '@angular/material/select';
13
14
  import * as i1$1 from '@angular/material/autocomplete';
14
15
  import { MatAutocomplete, MatAutocompleteOrigin, MAT_AUTOCOMPLETE_DEFAULT_OPTIONS, MatAutocompleteTrigger, MatAutocompleteModule } from '@angular/material/autocomplete';
@@ -870,22 +871,31 @@ let WlcmSelectComponent = class WlcmSelectComponent {
870
871
  openPanel() {
871
872
  this.matSelect.open();
872
873
  }
873
- constructor(changeDetectorRef, formField, parentFormMember) {
874
+ constructor(zone, changeDetectorRef, scrollDetectionApi, formField, parentFormMember) {
875
+ this.zone = zone;
874
876
  this.changeDetectorRef = changeDetectorRef;
877
+ this.scrollDetectionApi = scrollDetectionApi;
875
878
  this.formField = formField;
876
879
  this.parentFormMember = parentFormMember;
877
880
  this.multiple = false;
878
881
  this.placeholder = 'Not selected';
879
- this.options = input.required();
882
+ this.queryParams = DEFAULT_QUERY_PARAMS;
883
+ this.paginated = input(false);
884
+ this.options = input([]);
885
+ this.paginatedOptions = signal([]);
880
886
  this.selectOptionFormat = input('ValueOnly');
881
887
  this.optionTemplate = input(null);
882
- this.triggerTemplate = input(null);
888
+ this.triggerTemplate = input();
883
889
  this.isOptionDisabled = input(() => false);
884
890
  this.selectionChange = output();
885
891
  this.opened = output();
886
892
  this.closed = output();
887
893
  this.control = new FormControl();
888
894
  this.WlcmIconName = WlcmIconName;
895
+ this._paginatedData = null;
896
+ this.computedOptions = computed(() => {
897
+ return this.paginated() ? this.paginatedOptions() : this.options();
898
+ });
889
899
  this.matOptions = viewChildren(MatOption);
890
900
  this._focusStream$ = new BehaviorSubject(EMPTY);
891
901
  this._blurStream$ = new BehaviorSubject(EMPTY);
@@ -897,7 +907,11 @@ let WlcmSelectComponent = class WlcmSelectComponent {
897
907
  this.handleStateChange();
898
908
  }
899
909
  effect(() => {
900
- if (this.isOptionDisabled() && this.options().length > 0) {
910
+ if (this.paginated())
911
+ this.loadPaginatedOptions();
912
+ }, { allowSignalWrites: true });
913
+ effect(() => {
914
+ if (this.isOptionDisabled() && this.computedOptions().length > 0) {
901
915
  this.updateOptionsStatus();
902
916
  }
903
917
  });
@@ -917,7 +931,11 @@ let WlcmSelectComponent = class WlcmSelectComponent {
917
931
  }
918
932
  panelOpened() {
919
933
  this.opened.emit();
920
- this.handleClickOutside();
934
+ this.handleScrollDown();
935
+ }
936
+ panelClosed() {
937
+ this.closed.emit();
938
+ this._touched?.();
921
939
  }
922
940
  updateOptionsStatus() {
923
941
  this.matOptions().forEach((matOption) => {
@@ -950,27 +968,41 @@ let WlcmSelectComponent = class WlcmSelectComponent {
950
968
  get isOpen() {
951
969
  return this.matSelect?.panelOpen ?? false;
952
970
  }
971
+ loadPaginatedOptions() {
972
+ this.fetchPaginatedOptions({ ...this.queryParams, page: 1 })
973
+ .pipe(untilDestroyed(this), first())
974
+ .subscribe((paginatedData) => {
975
+ this._paginatedData = paginatedData;
976
+ this.paginatedOptions.set(paginatedData.data);
977
+ });
978
+ }
979
+ loadMorePaginatedOptions() {
980
+ if (!this._paginatedData || this._paginatedData.currPage + 1 > this._paginatedData.totalPages)
981
+ return;
982
+ this.queryParams.page++;
983
+ this.fetchPaginatedOptions({ ...this.queryParams })
984
+ .pipe(untilDestroyed(this), first())
985
+ .subscribe((paginatedData) => {
986
+ this._paginatedData = paginatedData;
987
+ this.paginatedOptions.update((options) => [...options, ...paginatedData.data]);
988
+ });
989
+ }
990
+ handleScrollDown() {
991
+ const element = document.querySelector('.mat-mdc-select-panel');
992
+ this.zone.runOutsideAngular(() => {
993
+ this.scrollDetectionApi.onScrolledDown(element).subscribe(() => {
994
+ this.zone.run(() => this.loadMorePaginatedOptions());
995
+ });
996
+ });
997
+ }
953
998
  handleStateChange() {
954
999
  this.parentFormMember.stateChanges$.pipe(untilDestroyed(this)).subscribe(() => {
955
1000
  this._validatorChanged?.();
956
1001
  this.changeDetectorRef.markForCheck();
957
1002
  });
958
1003
  }
959
- handleClickOutside() {
960
- const overlayContainer = document.querySelector(`.cdk-overlay-container:has(.${PANEL_CLASS})`);
961
- const backdrop = overlayContainer?.querySelector(`.cdk-overlay-backdrop`);
962
- if (backdrop instanceof HTMLElement) {
963
- fromEvent(backdrop, 'click')
964
- .pipe(first())
965
- .subscribe(() => {
966
- this._touched?.();
967
- this._validatorChanged?.();
968
- this.changeDetectorRef.markForCheck();
969
- });
970
- }
971
- }
972
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.5", ngImport: i0, type: WlcmSelectComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: WLCM_FORM_FIELD }, { token: WLCM_FORM_CONTROL, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
973
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.5", type: WlcmSelectComponent, isStandalone: true, selector: "wlcm-select", inputs: { multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: false, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: false, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, selectOptionFormat: { classPropertyName: "selectOptionFormat", publicName: "selectOptionFormat", isSignal: true, isRequired: false, transformFunction: null }, optionTemplate: { classPropertyName: "optionTemplate", publicName: "optionTemplate", isSignal: true, isRequired: false, transformFunction: null }, triggerTemplate: { classPropertyName: "triggerTemplate", publicName: "triggerTemplate", isSignal: true, isRequired: false, transformFunction: null }, isOptionDisabled: { classPropertyName: "isOptionDisabled", publicName: "isOptionDisabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectionChange: "selectionChange", opened: "opened", closed: "closed" }, host: { listeners: { "click": "openPanel()" } }, providers: [
1004
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.5", ngImport: i0, type: WlcmSelectComponent, deps: [{ token: i0.NgZone }, { token: i0.ChangeDetectorRef }, { token: i1$3.ScrollDetectionApi }, { token: WLCM_FORM_FIELD }, { token: WLCM_FORM_CONTROL, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
1005
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.5", type: WlcmSelectComponent, isStandalone: true, selector: "wlcm-select", inputs: { multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: false, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: false, isRequired: false, transformFunction: null }, fetchPaginatedOptions: { classPropertyName: "fetchPaginatedOptions", publicName: "fetchPaginatedOptions", isSignal: false, isRequired: false, transformFunction: null }, queryParams: { classPropertyName: "queryParams", publicName: "queryParams", isSignal: false, isRequired: false, transformFunction: null }, paginated: { classPropertyName: "paginated", publicName: "paginated", isSignal: true, isRequired: false, transformFunction: null }, options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, selectOptionFormat: { classPropertyName: "selectOptionFormat", publicName: "selectOptionFormat", isSignal: true, isRequired: false, transformFunction: null }, optionTemplate: { classPropertyName: "optionTemplate", publicName: "optionTemplate", isSignal: true, isRequired: false, transformFunction: null }, triggerTemplate: { classPropertyName: "triggerTemplate", publicName: "triggerTemplate", isSignal: true, isRequired: false, transformFunction: null }, isOptionDisabled: { classPropertyName: "isOptionDisabled", publicName: "isOptionDisabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectionChange: "selectionChange", opened: "opened", closed: "closed" }, host: { listeners: { "click": "openPanel()" } }, providers: [
974
1006
  WLCM_FORM_CONTROL_PROVIDER,
975
1007
  {
976
1008
  provide: MAT_SELECT_CONFIG,
@@ -981,11 +1013,13 @@ let WlcmSelectComponent = class WlcmSelectComponent {
981
1013
  },
982
1014
  { provide: NG_VALIDATORS, useExisting: forwardRef(() => WlcmSelectComponent), multi: true },
983
1015
  { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => WlcmSelectComponent), multi: true },
984
- ], viewQueries: [{ propertyName: "matOptions", predicate: MatOption, descendants: true, isSignal: true }, { propertyName: "matSelect", first: true, predicate: MatSelect, descendants: true }], hostDirectives: [{ directive: WlcmSelectInputBinderDirective }], ngImport: i0, template: "<mat-select\n #selectComponent\n [multiple]=\"multiple\"\n [disableRipple]=\"true\"\n [formControl]=\"control\"\n [placeholder]=\"placeholder\"\n [hideSingleSelectionIndicator]=\"true\"\n [ngClass]=\"{ focused: selectComponent.focused }\"\n (selectionChange)=\"select($event)\"\n (opened)=\"panelOpened()\"\n (closed)=\"closed.emit()\"\n>\n @if (triggerTemplate()) {\n <mat-select-trigger>\n <ng-container\n *ngTemplateOutlet=\"\n triggerTemplate();\n context: $any({ $implicit: selectComponent.selected })\n \"\n ></ng-container>\n </mat-select-trigger>\n }\n\n <mat-option\n *ngFor=\"let option of options()\"\n [value]=\"selectOptionFormat() === 'CompleteOption' ? option : option.value\"\n >\n @if (optionTemplate()) {\n <ng-container\n *ngTemplateOutlet=\"\n optionTemplate();\n context: $any({ $implicit: option })\n \"\n ></ng-container>\n } @else {\n {{ option.viewValue }}\n }\n </mat-option>\n</mat-select>\n\n<div class=\"wlcm-select-arrow\">\n <ng-container\n [wlcmIcon]=\"WlcmIconName.CHEVRON_DOWN\"\n [wlcmIconStopPropagation]=\"false\"\n ></ng-container>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: MatSelectModule }, { 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"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "directive", type: i3$1.MatSelectTrigger, selector: "mat-select-trigger" }, { kind: "component", type: i3.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: WlcmIconDirective, selector: "[wlcmIcon]", inputs: ["wlcmIcon", "wlcmIconStopPropagation"], outputs: ["wlcmIconClicked"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1016
+ ], viewQueries: [{ propertyName: "matOptions", predicate: MatOption, descendants: true, isSignal: true }, { propertyName: "matSelect", first: true, predicate: MatSelect, descendants: true }], hostDirectives: [{ directive: WlcmSelectInputBinderDirective }], ngImport: i0, template: "<mat-select\n #selectComponent\n [multiple]=\"multiple\"\n [disableRipple]=\"true\"\n [formControl]=\"control\"\n [placeholder]=\"placeholder\"\n [hideSingleSelectionIndicator]=\"true\"\n [ngClass]=\"{ focused: selectComponent.focused }\"\n (selectionChange)=\"select($event)\"\n (opened)=\"panelOpened()\"\n (closed)=\"panelClosed()\"\n>\n @if (triggerTemplate()) {\n <mat-select-trigger>\n <ng-container\n *ngTemplateOutlet=\"\n triggerTemplate()!;\n context: $any({ $implicit: selectComponent.selected })\n \"\n ></ng-container>\n </mat-select-trigger>\n }\n\n <mat-option\n *ngFor=\"let option of computedOptions()\"\n [value]=\"selectOptionFormat() === 'CompleteOption' ? option : option.value\"\n >\n @if (optionTemplate()) {\n <ng-container\n *ngTemplateOutlet=\"\n optionTemplate();\n context: $any({ $implicit: option })\n \"\n ></ng-container>\n } @else {\n {{ option.viewValue }}\n }\n </mat-option>\n</mat-select>\n\n<div class=\"wlcm-select-arrow\">\n <ng-container\n [wlcmIcon]=\"WlcmIconName.CHEVRON_DOWN\"\n [wlcmIconStopPropagation]=\"false\"\n ></ng-container>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i4$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"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "directive", type: i4$1.MatSelectTrigger, selector: "mat-select-trigger" }, { kind: "component", type: i3.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: WlcmIconDirective, selector: "[wlcmIcon]", inputs: ["wlcmIcon", "wlcmIconStopPropagation"], outputs: ["wlcmIconClicked"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
985
1017
  };
986
1018
  WlcmSelectComponent = __decorate([
987
1019
  UntilDestroy(),
988
- __metadata("design:paramtypes", [ChangeDetectorRef, Object, Object])
1020
+ __metadata("design:paramtypes", [NgZone,
1021
+ ChangeDetectorRef,
1022
+ ScrollDetectionApi, Object, Object])
989
1023
  ], WlcmSelectComponent);
990
1024
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.5", ngImport: i0, type: WlcmSelectComponent, decorators: [{
991
1025
  type: Component,
@@ -1000,8 +1034,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.5", ngImpor
1000
1034
  },
1001
1035
  { provide: NG_VALIDATORS, useExisting: forwardRef(() => WlcmSelectComponent), multi: true },
1002
1036
  { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => WlcmSelectComponent), multi: true },
1003
- ], template: "<mat-select\n #selectComponent\n [multiple]=\"multiple\"\n [disableRipple]=\"true\"\n [formControl]=\"control\"\n [placeholder]=\"placeholder\"\n [hideSingleSelectionIndicator]=\"true\"\n [ngClass]=\"{ focused: selectComponent.focused }\"\n (selectionChange)=\"select($event)\"\n (opened)=\"panelOpened()\"\n (closed)=\"closed.emit()\"\n>\n @if (triggerTemplate()) {\n <mat-select-trigger>\n <ng-container\n *ngTemplateOutlet=\"\n triggerTemplate();\n context: $any({ $implicit: selectComponent.selected })\n \"\n ></ng-container>\n </mat-select-trigger>\n }\n\n <mat-option\n *ngFor=\"let option of options()\"\n [value]=\"selectOptionFormat() === 'CompleteOption' ? option : option.value\"\n >\n @if (optionTemplate()) {\n <ng-container\n *ngTemplateOutlet=\"\n optionTemplate();\n context: $any({ $implicit: option })\n \"\n ></ng-container>\n } @else {\n {{ option.viewValue }}\n }\n </mat-option>\n</mat-select>\n\n<div class=\"wlcm-select-arrow\">\n <ng-container\n [wlcmIcon]=\"WlcmIconName.CHEVRON_DOWN\"\n [wlcmIconStopPropagation]=\"false\"\n ></ng-container>\n</div>\n" }]
1004
- }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: undefined, decorators: [{
1037
+ ], template: "<mat-select\n #selectComponent\n [multiple]=\"multiple\"\n [disableRipple]=\"true\"\n [formControl]=\"control\"\n [placeholder]=\"placeholder\"\n [hideSingleSelectionIndicator]=\"true\"\n [ngClass]=\"{ focused: selectComponent.focused }\"\n (selectionChange)=\"select($event)\"\n (opened)=\"panelOpened()\"\n (closed)=\"panelClosed()\"\n>\n @if (triggerTemplate()) {\n <mat-select-trigger>\n <ng-container\n *ngTemplateOutlet=\"\n triggerTemplate()!;\n context: $any({ $implicit: selectComponent.selected })\n \"\n ></ng-container>\n </mat-select-trigger>\n }\n\n <mat-option\n *ngFor=\"let option of computedOptions()\"\n [value]=\"selectOptionFormat() === 'CompleteOption' ? option : option.value\"\n >\n @if (optionTemplate()) {\n <ng-container\n *ngTemplateOutlet=\"\n optionTemplate();\n context: $any({ $implicit: option })\n \"\n ></ng-container>\n } @else {\n {{ option.viewValue }}\n }\n </mat-option>\n</mat-select>\n\n<div class=\"wlcm-select-arrow\">\n <ng-container\n [wlcmIcon]=\"WlcmIconName.CHEVRON_DOWN\"\n [wlcmIconStopPropagation]=\"false\"\n ></ng-container>\n</div>\n" }]
1038
+ }], ctorParameters: () => [{ type: i0.NgZone }, { type: i0.ChangeDetectorRef }, { type: i1$3.ScrollDetectionApi }, { type: undefined, decorators: [{
1005
1039
  type: Inject,
1006
1040
  args: [WLCM_FORM_FIELD]
1007
1041
  }] }, { type: undefined, decorators: [{
@@ -1013,6 +1047,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.5", ngImpor
1013
1047
  type: Input
1014
1048
  }], placeholder: [{
1015
1049
  type: Input
1050
+ }], fetchPaginatedOptions: [{
1051
+ type: Input
1052
+ }], queryParams: [{
1053
+ type: Input
1016
1054
  }], matSelect: [{
1017
1055
  type: ViewChild,
1018
1056
  args: [MatSelect]