nexheal-lib 0.0.45 → 0.0.48
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/nexheal-lib.mjs +89 -16
- package/fesm2022/nexheal-lib.mjs.map +1 -1
- package/index.d.ts +14 -2
- package/package.json +1 -1
package/fesm2022/nexheal-lib.mjs
CHANGED
|
@@ -2791,10 +2791,13 @@ class PaginatedAutocompleteControl {
|
|
|
2791
2791
|
paginationType = 'scroll';
|
|
2792
2792
|
pageSize = 10;
|
|
2793
2793
|
searchDebounce = 300;
|
|
2794
|
+
/** Re-fetch page 1 every time the dropdown opens, instead of reusing cached results */
|
|
2795
|
+
refreshOnOpen = false;
|
|
2794
2796
|
/** Total record count for the current search, from the API response */
|
|
2795
2797
|
totalCount = 0;
|
|
2796
2798
|
_disabled = false;
|
|
2797
2799
|
_pendingPage = 1;
|
|
2800
|
+
lastLoadedSearch = null;
|
|
2798
2801
|
/** Items of the page just loaded. Page 1 replaces the list, later pages append. */
|
|
2799
2802
|
_displayedOptions = [];
|
|
2800
2803
|
set options(value) {
|
|
@@ -2811,6 +2814,8 @@ class PaginatedAutocompleteControl {
|
|
|
2811
2814
|
];
|
|
2812
2815
|
}
|
|
2813
2816
|
this.isPageLoading = false;
|
|
2817
|
+
this.loadErrorMessage = null;
|
|
2818
|
+
this.failedPage = null;
|
|
2814
2819
|
this.processValueBuffer();
|
|
2815
2820
|
if (this.isDropdownOpen) {
|
|
2816
2821
|
if (this._pendingPage <= 1) {
|
|
@@ -2846,7 +2851,6 @@ class PaginatedAutocompleteControl {
|
|
|
2846
2851
|
optionPatched = new EventEmitter();
|
|
2847
2852
|
valueBuffer = null;
|
|
2848
2853
|
popperInstance;
|
|
2849
|
-
preventDropdownReopen = false;
|
|
2850
2854
|
preventClearOnBlur = false;
|
|
2851
2855
|
onChange = () => { };
|
|
2852
2856
|
onTouched = () => { };
|
|
@@ -2856,6 +2860,8 @@ class PaginatedAutocompleteControl {
|
|
|
2856
2860
|
isDropdownOpen = false;
|
|
2857
2861
|
hasFocus = false;
|
|
2858
2862
|
isPageLoading = false;
|
|
2863
|
+
loadErrorMessage = null;
|
|
2864
|
+
failedPage = null;
|
|
2859
2865
|
selectedItems;
|
|
2860
2866
|
highlightedIndex = null;
|
|
2861
2867
|
currentPage = 1;
|
|
@@ -2868,12 +2874,12 @@ class PaginatedAutocompleteControl {
|
|
|
2868
2874
|
this.subscription.add(this.inputControl.valueChanges
|
|
2869
2875
|
.pipe(debounceTime(this.searchDebounce), distinctUntilChanged())
|
|
2870
2876
|
.subscribe((value) => {
|
|
2871
|
-
if (this.preventDropdownReopen) {
|
|
2872
|
-
this.preventDropdownReopen = false;
|
|
2873
|
-
return;
|
|
2874
|
-
}
|
|
2875
2877
|
if (this.readonly || !this.hasFocus)
|
|
2876
2878
|
return;
|
|
2879
|
+
// Discard stale debounced emissions — e.g. an Enter-selection replaced
|
|
2880
|
+
// the text while this search was still waiting out the debounce.
|
|
2881
|
+
if ((value || "") !== (this.inputControl.value || ""))
|
|
2882
|
+
return;
|
|
2877
2883
|
this.loadPage(1, value || "");
|
|
2878
2884
|
}));
|
|
2879
2885
|
}
|
|
@@ -2888,7 +2894,6 @@ class PaginatedAutocompleteControl {
|
|
|
2888
2894
|
}
|
|
2889
2895
|
// CVA
|
|
2890
2896
|
writeValue(value) {
|
|
2891
|
-
this.preventDropdownReopen = true;
|
|
2892
2897
|
if (value == null) {
|
|
2893
2898
|
this.valueBuffer = null;
|
|
2894
2899
|
this.selectedItems = null;
|
|
@@ -2906,7 +2911,6 @@ class PaginatedAutocompleteControl {
|
|
|
2906
2911
|
if (this._displayedOptions.length > 0) {
|
|
2907
2912
|
const matchedSuggestion = this._displayedOptions.find((s) => s.id === this.valueBuffer);
|
|
2908
2913
|
if (matchedSuggestion) {
|
|
2909
|
-
this.preventDropdownReopen = true;
|
|
2910
2914
|
this.inputControl.setValue(matchedSuggestion[this.optionDisplayProperty], { emitEvent: false });
|
|
2911
2915
|
this.selectedItems = matchedSuggestion;
|
|
2912
2916
|
this.onChange(matchedSuggestion.id);
|
|
@@ -2933,6 +2937,9 @@ class PaginatedAutocompleteControl {
|
|
|
2933
2937
|
loadPage(page, search) {
|
|
2934
2938
|
this.currentPage = page;
|
|
2935
2939
|
this._pendingPage = page;
|
|
2940
|
+
this.lastLoadedSearch = search;
|
|
2941
|
+
this.loadErrorMessage = null;
|
|
2942
|
+
this.failedPage = null;
|
|
2936
2943
|
this.isPageLoading = true;
|
|
2937
2944
|
if (page === 1) {
|
|
2938
2945
|
this.openDropdown();
|
|
@@ -2960,6 +2967,22 @@ class PaginatedAutocompleteControl {
|
|
|
2960
2967
|
event.stopPropagation();
|
|
2961
2968
|
this.loadNextPage();
|
|
2962
2969
|
}
|
|
2970
|
+
/** Call from the parent's API error handler to unblock paging and show a
|
|
2971
|
+
* Retry row in the dropdown. e.g. error: () => ctrl.pageLoadFailed() */
|
|
2972
|
+
pageLoadFailed(message = "Couldn't load results") {
|
|
2973
|
+
this.isPageLoading = false;
|
|
2974
|
+
this.loadErrorMessage = message;
|
|
2975
|
+
this.failedPage = this._pendingPage;
|
|
2976
|
+
if (this._pendingPage > 1) {
|
|
2977
|
+
// Roll back so a retry re-requests the failed page, not the one after it
|
|
2978
|
+
this.currentPage = this._pendingPage - 1;
|
|
2979
|
+
}
|
|
2980
|
+
}
|
|
2981
|
+
retryLoad(event) {
|
|
2982
|
+
event.stopPropagation();
|
|
2983
|
+
const page = this.failedPage ?? 1;
|
|
2984
|
+
this.loadPage(page, this.lastLoadedSearch || "");
|
|
2985
|
+
}
|
|
2963
2986
|
openDropdown() {
|
|
2964
2987
|
if (this.isDropdownOpen)
|
|
2965
2988
|
return;
|
|
@@ -2971,7 +2994,6 @@ class PaginatedAutocompleteControl {
|
|
|
2971
2994
|
}
|
|
2972
2995
|
// selection
|
|
2973
2996
|
selectSuggestion(suggestion) {
|
|
2974
|
-
this.preventDropdownReopen = true;
|
|
2975
2997
|
this.inputControl.setValue(suggestion[this.optionDisplayProperty], {
|
|
2976
2998
|
emitEvent: false,
|
|
2977
2999
|
});
|
|
@@ -2987,28 +3009,64 @@ class PaginatedAutocompleteControl {
|
|
|
2987
3009
|
// events
|
|
2988
3010
|
onFocus() {
|
|
2989
3011
|
this.hasFocus = true;
|
|
2990
|
-
if (this.readonly)
|
|
3012
|
+
if (this.readonly || this.isDropdownOpen)
|
|
2991
3013
|
return;
|
|
2992
|
-
this.
|
|
3014
|
+
this.openWithSearch();
|
|
2993
3015
|
}
|
|
2994
3016
|
onInputClick() {
|
|
2995
3017
|
if (this.readonly || this.isDropdownOpen)
|
|
2996
3018
|
return;
|
|
2997
3019
|
if (this.hasFocus) {
|
|
2998
|
-
this.
|
|
3020
|
+
this.openWithSearch();
|
|
2999
3021
|
}
|
|
3000
3022
|
}
|
|
3023
|
+
/** Text to search with when the dropdown opens: if the input just holds the
|
|
3024
|
+
* selected item's display text, open with the full list instead. */
|
|
3025
|
+
openSearchTerm() {
|
|
3026
|
+
const value = this.inputControl.value || "";
|
|
3027
|
+
if (this.selectedItems &&
|
|
3028
|
+
value === this.selectedItems[this.optionDisplayProperty]) {
|
|
3029
|
+
return "";
|
|
3030
|
+
}
|
|
3031
|
+
return value;
|
|
3032
|
+
}
|
|
3033
|
+
openWithSearch() {
|
|
3034
|
+
const term = this.openSearchTerm();
|
|
3035
|
+
// Reuse cached results when reopening with the same search term
|
|
3036
|
+
if (!this.refreshOnOpen &&
|
|
3037
|
+
this.lastLoadedSearch === term &&
|
|
3038
|
+
this._displayedOptions.length > 0) {
|
|
3039
|
+
this.openDropdown();
|
|
3040
|
+
const idx = this.selectedItems
|
|
3041
|
+
? this._displayedOptions.findIndex((o) => o.id === this.selectedItems.id)
|
|
3042
|
+
: -1;
|
|
3043
|
+
this.highlightedIndex =
|
|
3044
|
+
idx >= 0 ? idx : this._displayedOptions.length > 0 ? 0 : null;
|
|
3045
|
+
return;
|
|
3046
|
+
}
|
|
3047
|
+
this.loadPage(1, term);
|
|
3048
|
+
}
|
|
3001
3049
|
onBlur() {
|
|
3002
3050
|
this.blurEvent.emit();
|
|
3003
3051
|
this.onTouched();
|
|
3052
|
+
// mousedown fires before blur — if no dropdown interaction flagged itself,
|
|
3053
|
+
// the user clicked outside: close immediately instead of waiting 300ms.
|
|
3054
|
+
if (!this.preventClearOnBlur) {
|
|
3055
|
+
this.isDropdownOpen = false;
|
|
3056
|
+
this.isPageLoading = false;
|
|
3057
|
+
}
|
|
3004
3058
|
// Delay so option / load-more mousedown and click can occur first.
|
|
3005
3059
|
setTimeout(() => {
|
|
3006
3060
|
if (this.preventClearOnBlur) {
|
|
3007
3061
|
this.preventClearOnBlur = false;
|
|
3008
|
-
//
|
|
3009
|
-
|
|
3062
|
+
// Refocus only while the dropdown is still open (load more / clear).
|
|
3063
|
+
// After selecting an option the dropdown is closed — don't reopen it.
|
|
3064
|
+
if (this.isDropdownOpen && this.inputElement) {
|
|
3010
3065
|
this.inputElement.nativeElement.focus();
|
|
3011
3066
|
}
|
|
3067
|
+
else {
|
|
3068
|
+
this.hasFocus = false;
|
|
3069
|
+
}
|
|
3012
3070
|
return;
|
|
3013
3071
|
}
|
|
3014
3072
|
this.hasFocus = false;
|
|
@@ -3090,6 +3148,19 @@ class PaginatedAutocompleteControl {
|
|
|
3090
3148
|
fallbackPlacements: ["top-start", "bottom-start"],
|
|
3091
3149
|
},
|
|
3092
3150
|
},
|
|
3151
|
+
// Make the dropdown exactly as wide as the input
|
|
3152
|
+
{
|
|
3153
|
+
name: "sameWidth",
|
|
3154
|
+
enabled: true,
|
|
3155
|
+
phase: "beforeWrite",
|
|
3156
|
+
requires: ["computeStyles"],
|
|
3157
|
+
fn: ({ state }) => {
|
|
3158
|
+
state.styles["popper"].width = `${state.rects.reference.width}px`;
|
|
3159
|
+
},
|
|
3160
|
+
effect: ({ state }) => {
|
|
3161
|
+
state.elements.popper.style.width = `${state.elements.reference.offsetWidth}px`;
|
|
3162
|
+
},
|
|
3163
|
+
},
|
|
3093
3164
|
],
|
|
3094
3165
|
});
|
|
3095
3166
|
}
|
|
@@ -3114,13 +3185,13 @@ class PaginatedAutocompleteControl {
|
|
|
3114
3185
|
}
|
|
3115
3186
|
}
|
|
3116
3187
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: PaginatedAutocompleteControl, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3117
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: PaginatedAutocompleteControl, isStandalone: true, selector: "paginated-autocomplete-control", inputs: { title: "title", required: "required", placeholder: "placeholder", customClass: "customClass", clearVal: "clearVal", error: "error", errorMessage: "errorMessage", autocomplete: "autocomplete", inputLoader: "inputLoader", readonly: "readonly", optionDisplayProperty: "optionDisplayProperty", paginationType: "paginationType", pageSize: "pageSize", searchDebounce: "searchDebounce", totalCount: "totalCount", options: "options", disabled: "disabled" }, outputs: { pageChange: "pageChange", optionSelected: "optionSelected", selectionCleared: "selectionCleared", blurEvent: "blurEvent", optionPatched: "optionPatched" }, providers: [
|
|
3188
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: PaginatedAutocompleteControl, isStandalone: true, selector: "paginated-autocomplete-control", inputs: { title: "title", required: "required", placeholder: "placeholder", customClass: "customClass", clearVal: "clearVal", error: "error", errorMessage: "errorMessage", autocomplete: "autocomplete", inputLoader: "inputLoader", readonly: "readonly", optionDisplayProperty: "optionDisplayProperty", paginationType: "paginationType", pageSize: "pageSize", searchDebounce: "searchDebounce", refreshOnOpen: "refreshOnOpen", totalCount: "totalCount", options: "options", disabled: "disabled" }, outputs: { pageChange: "pageChange", optionSelected: "optionSelected", selectionCleared: "selectionCleared", blurEvent: "blurEvent", optionPatched: "optionPatched" }, providers: [
|
|
3118
3189
|
{
|
|
3119
3190
|
provide: NG_VALUE_ACCESSOR,
|
|
3120
3191
|
useExisting: PaginatedAutocompleteControl,
|
|
3121
3192
|
multi: true,
|
|
3122
3193
|
},
|
|
3123
|
-
], viewQueries: [{ propertyName: "inputElement", first: true, predicate: ["inputElement"], descendants: true }, { propertyName: "dropdownElement", first: true, predicate: ["dropdownElement"], descendants: true }], ngImport: i0, template: "<div class=\"form-group auto-complete paginated-autocomplete\" [ngClass]=\"customClass\" [class.readonly]=\"readonly\">\n @if (title) {\n <label class=\"inp-label\" [ngClass]=\"{ 'required': required }\">{{ title }}</label>\n }\n\n <input #inputElement type=\"text\" class=\"form-control\" [placeholder]=\"placeholder\" [formControl]=\"inputControl\"\n (blur)=\"onBlur()\" (keydown)=\"onKeyDown($event)\" (focus)=\"onFocus()\" (click)=\"onInputClick()\"\n [ngClass]=\"{'is-invalid': error}\" [attr.autocomplete]=\"autocomplete || null\" [readonly]=\"readonly\" />\n\n <span class=\"focus-border\"></span>\n\n @if (!inputLoader && inputControl.value && clearVal && hasFocus) {\n <label class=\"clear\" (mousedown)=\"onOptionMouseDown()\" (click)=\"resetInput()\">\n <i class=\"he he-close\"></i>\n </label>\n }\n\n @if (isDropdownOpen) {\n <div #dropdownElement class=\"option-list\" (scroll)=\"onListScroll($event)\">\n @if (options.length === 0 && !isPageLoading) {\n <div class=\"no-results\">\n <div>No results found</div>\n </div>\n } @else {\n @for (suggestion of options; track suggestion.id; let i = $index) {\n <div class=\"list-item\" [ngClass]=\"{\n 'active': suggestion === selectedItems,\n 'highlighted': highlightedIndex === i\n }\" (
|
|
3194
|
+
], viewQueries: [{ propertyName: "inputElement", first: true, predicate: ["inputElement"], descendants: true }, { propertyName: "dropdownElement", first: true, predicate: ["dropdownElement"], descendants: true }], ngImport: i0, template: "<div class=\"form-group auto-complete paginated-autocomplete\" [ngClass]=\"customClass\" [class.readonly]=\"readonly\">\n @if (title) {\n <label class=\"inp-label\" [ngClass]=\"{ 'required': required }\">{{ title }}</label>\n }\n\n <input #inputElement type=\"text\" class=\"form-control\" [placeholder]=\"placeholder\" [formControl]=\"inputControl\"\n (blur)=\"onBlur()\" (keydown)=\"onKeyDown($event)\" (focus)=\"onFocus()\" (click)=\"onInputClick()\"\n [ngClass]=\"{'is-invalid': error}\" [attr.autocomplete]=\"autocomplete || null\" [readonly]=\"readonly\" />\n\n <span class=\"focus-border\"></span>\n\n @if (!inputLoader && inputControl.value && clearVal && hasFocus) {\n <label class=\"clear\" (mousedown)=\"onOptionMouseDown()\" (click)=\"resetInput()\">\n <i class=\"he he-close\"></i>\n </label>\n }\n\n @if (isDropdownOpen) {\n <div #dropdownElement class=\"option-list\" (mousedown)=\"onOptionMouseDown()\" (scroll)=\"onListScroll($event)\">\n @if (options.length === 0 && !isPageLoading && !loadErrorMessage) {\n <div class=\"no-results\">\n <div>No results found</div>\n </div>\n } @else {\n @for (suggestion of options; track suggestion.id; let i = $index) {\n <div class=\"list-item\" [ngClass]=\"{\n 'active': suggestion === selectedItems,\n 'highlighted': highlightedIndex === i\n }\" (click)=\"selectSuggestion(suggestion)\" (mouseover)=\"onMouseOver(i)\">\n {{ suggestion[optionDisplayProperty] }}\n </div>\n }\n\n @if (isPageLoading) {\n <div class=\"list-loading\">Loading...</div>\n }\n\n @if (loadErrorMessage) {\n <div class=\"load-error\" (click)=\"retryLoad($event)\">\n {{ loadErrorMessage }} \u00B7 <span class=\"retry\">Retry</span>\n </div>\n }\n\n @if (paginationType === 'click' && hasMore && !isPageLoading && !loadErrorMessage) {\n <div class=\"load-more\" (click)=\"onLoadMoreClick($event)\">\n Load more ({{ options.length }} of {{ totalCount }})\n </div>\n }\n\n @if (totalCount > 0 && options.length > 0 && !loadErrorMessage && !(paginationType === 'click' && hasMore)) {\n <div class=\"list-footer\">\n {{ options.length }} of {{ totalCount }}\n @if (hasMore && paginationType === 'scroll') {\n <span> \u00B7 scroll for more</span>\n }\n </div>\n }\n }\n </div>\n }\n\n @if (inputLoader) {\n <label class=\"loader input-loader\"></label>\n }\n\n @if (error) {\n <div class=\"val-msg\">{{ errorMessage }}</div>\n }\n</div>\n", styles: [".form-group.paginated-autocomplete .form-control{padding-right:unset}.form-group.paginated-autocomplete .clear{right:7px}.form-group.paginated-autocomplete .option-list{max-height:220px;overflow-y:auto}.form-group.paginated-autocomplete .option-list .no-results{padding:10px;color:#9b9b9b;text-align:center}.form-group.paginated-autocomplete .option-list .list-loading{padding:8px 10px;color:#9b9b9b;text-align:center;font-size:12px}.form-group.paginated-autocomplete .option-list .load-more{padding:8px 10px;text-align:center;cursor:pointer;color:#0d6efd;font-size:13px;border-top:1px solid #eee;-webkit-user-select:none;user-select:none}.form-group.paginated-autocomplete .option-list .load-more:hover{background-color:#f5f5f5}.form-group.paginated-autocomplete .option-list .load-error{padding:8px 10px;text-align:center;font-size:12px;color:#dc3545;cursor:pointer;border-top:1px solid #eee;-webkit-user-select:none;user-select:none}.form-group.paginated-autocomplete .option-list .load-error .retry{color:#0d6efd;text-decoration:underline}.form-group.paginated-autocomplete .option-list .load-error:hover{background-color:#f5f5f5}.form-group.paginated-autocomplete .option-list .list-footer{position:sticky;bottom:0;padding:4px 10px;text-align:center;font-size:11px;color:#9b9b9b;background-color:#fff;border-top:1px solid #eee;-webkit-user-select:none;user-select:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }] });
|
|
3124
3195
|
}
|
|
3125
3196
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: PaginatedAutocompleteControl, decorators: [{
|
|
3126
3197
|
type: Component,
|
|
@@ -3130,7 +3201,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
|
|
|
3130
3201
|
useExisting: PaginatedAutocompleteControl,
|
|
3131
3202
|
multi: true,
|
|
3132
3203
|
},
|
|
3133
|
-
], template: "<div class=\"form-group auto-complete paginated-autocomplete\" [ngClass]=\"customClass\" [class.readonly]=\"readonly\">\n @if (title) {\n <label class=\"inp-label\" [ngClass]=\"{ 'required': required }\">{{ title }}</label>\n }\n\n <input #inputElement type=\"text\" class=\"form-control\" [placeholder]=\"placeholder\" [formControl]=\"inputControl\"\n (blur)=\"onBlur()\" (keydown)=\"onKeyDown($event)\" (focus)=\"onFocus()\" (click)=\"onInputClick()\"\n [ngClass]=\"{'is-invalid': error}\" [attr.autocomplete]=\"autocomplete || null\" [readonly]=\"readonly\" />\n\n <span class=\"focus-border\"></span>\n\n @if (!inputLoader && inputControl.value && clearVal && hasFocus) {\n <label class=\"clear\" (mousedown)=\"onOptionMouseDown()\" (click)=\"resetInput()\">\n <i class=\"he he-close\"></i>\n </label>\n }\n\n @if (isDropdownOpen) {\n <div #dropdownElement class=\"option-list\" (scroll)=\"onListScroll($event)\">\n @if (options.length === 0 && !isPageLoading) {\n <div class=\"no-results\">\n <div>No results found</div>\n </div>\n } @else {\n @for (suggestion of options; track suggestion.id; let i = $index) {\n <div class=\"list-item\" [ngClass]=\"{\n 'active': suggestion === selectedItems,\n 'highlighted': highlightedIndex === i\n }\" (
|
|
3204
|
+
], template: "<div class=\"form-group auto-complete paginated-autocomplete\" [ngClass]=\"customClass\" [class.readonly]=\"readonly\">\n @if (title) {\n <label class=\"inp-label\" [ngClass]=\"{ 'required': required }\">{{ title }}</label>\n }\n\n <input #inputElement type=\"text\" class=\"form-control\" [placeholder]=\"placeholder\" [formControl]=\"inputControl\"\n (blur)=\"onBlur()\" (keydown)=\"onKeyDown($event)\" (focus)=\"onFocus()\" (click)=\"onInputClick()\"\n [ngClass]=\"{'is-invalid': error}\" [attr.autocomplete]=\"autocomplete || null\" [readonly]=\"readonly\" />\n\n <span class=\"focus-border\"></span>\n\n @if (!inputLoader && inputControl.value && clearVal && hasFocus) {\n <label class=\"clear\" (mousedown)=\"onOptionMouseDown()\" (click)=\"resetInput()\">\n <i class=\"he he-close\"></i>\n </label>\n }\n\n @if (isDropdownOpen) {\n <div #dropdownElement class=\"option-list\" (mousedown)=\"onOptionMouseDown()\" (scroll)=\"onListScroll($event)\">\n @if (options.length === 0 && !isPageLoading && !loadErrorMessage) {\n <div class=\"no-results\">\n <div>No results found</div>\n </div>\n } @else {\n @for (suggestion of options; track suggestion.id; let i = $index) {\n <div class=\"list-item\" [ngClass]=\"{\n 'active': suggestion === selectedItems,\n 'highlighted': highlightedIndex === i\n }\" (click)=\"selectSuggestion(suggestion)\" (mouseover)=\"onMouseOver(i)\">\n {{ suggestion[optionDisplayProperty] }}\n </div>\n }\n\n @if (isPageLoading) {\n <div class=\"list-loading\">Loading...</div>\n }\n\n @if (loadErrorMessage) {\n <div class=\"load-error\" (click)=\"retryLoad($event)\">\n {{ loadErrorMessage }} \u00B7 <span class=\"retry\">Retry</span>\n </div>\n }\n\n @if (paginationType === 'click' && hasMore && !isPageLoading && !loadErrorMessage) {\n <div class=\"load-more\" (click)=\"onLoadMoreClick($event)\">\n Load more ({{ options.length }} of {{ totalCount }})\n </div>\n }\n\n @if (totalCount > 0 && options.length > 0 && !loadErrorMessage && !(paginationType === 'click' && hasMore)) {\n <div class=\"list-footer\">\n {{ options.length }} of {{ totalCount }}\n @if (hasMore && paginationType === 'scroll') {\n <span> \u00B7 scroll for more</span>\n }\n </div>\n }\n }\n </div>\n }\n\n @if (inputLoader) {\n <label class=\"loader input-loader\"></label>\n }\n\n @if (error) {\n <div class=\"val-msg\">{{ errorMessage }}</div>\n }\n</div>\n", styles: [".form-group.paginated-autocomplete .form-control{padding-right:unset}.form-group.paginated-autocomplete .clear{right:7px}.form-group.paginated-autocomplete .option-list{max-height:220px;overflow-y:auto}.form-group.paginated-autocomplete .option-list .no-results{padding:10px;color:#9b9b9b;text-align:center}.form-group.paginated-autocomplete .option-list .list-loading{padding:8px 10px;color:#9b9b9b;text-align:center;font-size:12px}.form-group.paginated-autocomplete .option-list .load-more{padding:8px 10px;text-align:center;cursor:pointer;color:#0d6efd;font-size:13px;border-top:1px solid #eee;-webkit-user-select:none;user-select:none}.form-group.paginated-autocomplete .option-list .load-more:hover{background-color:#f5f5f5}.form-group.paginated-autocomplete .option-list .load-error{padding:8px 10px;text-align:center;font-size:12px;color:#dc3545;cursor:pointer;border-top:1px solid #eee;-webkit-user-select:none;user-select:none}.form-group.paginated-autocomplete .option-list .load-error .retry{color:#0d6efd;text-decoration:underline}.form-group.paginated-autocomplete .option-list .load-error:hover{background-color:#f5f5f5}.form-group.paginated-autocomplete .option-list .list-footer{position:sticky;bottom:0;padding:4px 10px;text-align:center;font-size:11px;color:#9b9b9b;background-color:#fff;border-top:1px solid #eee;-webkit-user-select:none;user-select:none}\n"] }]
|
|
3134
3205
|
}], ctorParameters: () => [], propDecorators: { title: [{
|
|
3135
3206
|
type: Input
|
|
3136
3207
|
}], required: [{
|
|
@@ -3159,6 +3230,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
|
|
|
3159
3230
|
type: Input
|
|
3160
3231
|
}], searchDebounce: [{
|
|
3161
3232
|
type: Input
|
|
3233
|
+
}], refreshOnOpen: [{
|
|
3234
|
+
type: Input
|
|
3162
3235
|
}], totalCount: [{
|
|
3163
3236
|
type: Input
|
|
3164
3237
|
}], options: [{
|