nexheal-lib 0.0.51 → 0.0.53
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 +69 -31
- package/fesm2022/nexheal-lib.mjs.map +1 -1
- package/index.d.ts +10 -2
- package/package.json +1 -1
package/fesm2022/nexheal-lib.mjs
CHANGED
|
@@ -2802,7 +2802,15 @@ class PaginatedAutocompleteControl {
|
|
|
2802
2802
|
_displayedOptions = [];
|
|
2803
2803
|
set options(value) {
|
|
2804
2804
|
const incoming = value || [];
|
|
2805
|
-
if (this.
|
|
2805
|
+
if (this.paginationType === 'arrow') {
|
|
2806
|
+
// Arrow mode: discrete pages — each load REPLACES the view and is cached
|
|
2807
|
+
this._displayedOptions = [...incoming];
|
|
2808
|
+
this.pageCache.set(this._pendingPage, [...incoming]);
|
|
2809
|
+
this.currentPage = this._pendingPage;
|
|
2810
|
+
this.highlightedIndex = incoming.length > 0 ? 0 : null;
|
|
2811
|
+
this.resetListScroll();
|
|
2812
|
+
}
|
|
2813
|
+
else if (this._pendingPage <= 1) {
|
|
2806
2814
|
this._displayedOptions = [...incoming];
|
|
2807
2815
|
}
|
|
2808
2816
|
else {
|
|
@@ -2812,22 +2820,13 @@ class PaginatedAutocompleteControl {
|
|
|
2812
2820
|
...this._displayedOptions,
|
|
2813
2821
|
...incoming.filter((o) => !existingIds.has(o.id)),
|
|
2814
2822
|
];
|
|
2815
|
-
// Keyboard-triggered page load: move the highlight into the new items
|
|
2816
|
-
if (this.pendingHighlightIndex !== null) {
|
|
2817
|
-
const idx = Math.min(this.pendingHighlightIndex, this._displayedOptions.length - 1);
|
|
2818
|
-
this.pendingHighlightIndex = null;
|
|
2819
|
-
if (idx >= 0) {
|
|
2820
|
-
this.highlightedIndex = idx;
|
|
2821
|
-
setTimeout(() => this.scrollHighlightedItemIntoView(), 0);
|
|
2822
|
-
}
|
|
2823
|
-
}
|
|
2824
2823
|
}
|
|
2825
2824
|
this.isPageLoading = false;
|
|
2826
2825
|
this.loadErrorMessage = null;
|
|
2827
2826
|
this.failedPage = null;
|
|
2828
2827
|
this.processValueBuffer();
|
|
2829
2828
|
if (this.isDropdownOpen) {
|
|
2830
|
-
if (this._pendingPage <= 1) {
|
|
2829
|
+
if (this._pendingPage <= 1 && this.paginationType !== 'arrow') {
|
|
2831
2830
|
this.highlightedIndex = this._displayedOptions.length > 0 ? 0 : null;
|
|
2832
2831
|
}
|
|
2833
2832
|
setTimeout(() => {
|
|
@@ -2863,8 +2862,8 @@ class PaginatedAutocompleteControl {
|
|
|
2863
2862
|
preventClearOnBlur = false;
|
|
2864
2863
|
searchInput$ = new Subject();
|
|
2865
2864
|
cancelPendingSearch = false;
|
|
2866
|
-
/**
|
|
2867
|
-
|
|
2865
|
+
/** Arrow mode: cache of visited pages for the current search */
|
|
2866
|
+
pageCache = new Map();
|
|
2868
2867
|
onChange = () => { };
|
|
2869
2868
|
onTouched = () => { };
|
|
2870
2869
|
inputElement;
|
|
@@ -2881,6 +2880,17 @@ class PaginatedAutocompleteControl {
|
|
|
2881
2880
|
get hasMore() {
|
|
2882
2881
|
return this._displayedOptions.length < this.totalCount;
|
|
2883
2882
|
}
|
|
2883
|
+
get totalPages() {
|
|
2884
|
+
return this.pageSize > 0
|
|
2885
|
+
? Math.max(1, Math.ceil(this.totalCount / this.pageSize))
|
|
2886
|
+
: 1;
|
|
2887
|
+
}
|
|
2888
|
+
get pageRangeStart() {
|
|
2889
|
+
return this.totalCount === 0 ? 0 : (this.currentPage - 1) * this.pageSize + 1;
|
|
2890
|
+
}
|
|
2891
|
+
get pageRangeEnd() {
|
|
2892
|
+
return Math.min((this.currentPage - 1) * this.pageSize + this._displayedOptions.length, this.totalCount);
|
|
2893
|
+
}
|
|
2884
2894
|
constructor() { }
|
|
2885
2895
|
ngOnInit() {
|
|
2886
2896
|
this.inputControl.markAsPristine();
|
|
@@ -2952,6 +2962,10 @@ class PaginatedAutocompleteControl {
|
|
|
2952
2962
|
loadPage(page, search) {
|
|
2953
2963
|
this.currentPage = page;
|
|
2954
2964
|
this._pendingPage = page;
|
|
2965
|
+
if (page === 1) {
|
|
2966
|
+
// Fresh page-1 load = new search context; visited pages are stale
|
|
2967
|
+
this.pageCache.clear();
|
|
2968
|
+
}
|
|
2955
2969
|
this.lastLoadedSearch = search;
|
|
2956
2970
|
this.loadErrorMessage = null;
|
|
2957
2971
|
this.failedPage = null;
|
|
@@ -2972,6 +2986,41 @@ class PaginatedAutocompleteControl {
|
|
|
2972
2986
|
// which after a selection holds the display name, not the search term.
|
|
2973
2987
|
this.loadPage(this.currentPage + 1, this.lastLoadedSearch ?? (this.inputControl.value || ""));
|
|
2974
2988
|
}
|
|
2989
|
+
/** Arrow mode: show an already-visited page instantly, no API call */
|
|
2990
|
+
showCachedPage(page) {
|
|
2991
|
+
const cached = this.pageCache.get(page);
|
|
2992
|
+
if (!cached)
|
|
2993
|
+
return false;
|
|
2994
|
+
this.currentPage = page;
|
|
2995
|
+
this._pendingPage = page;
|
|
2996
|
+
this._displayedOptions = [...cached];
|
|
2997
|
+
this.highlightedIndex = cached.length > 0 ? 0 : null;
|
|
2998
|
+
this.resetListScroll();
|
|
2999
|
+
return true;
|
|
3000
|
+
}
|
|
3001
|
+
nextArrowPage() {
|
|
3002
|
+
if (this.isPageLoading || this.currentPage >= this.totalPages)
|
|
3003
|
+
return;
|
|
3004
|
+
const next = this.currentPage + 1;
|
|
3005
|
+
if (!this.showCachedPage(next)) {
|
|
3006
|
+
this.loadPage(next, this.lastLoadedSearch || "");
|
|
3007
|
+
}
|
|
3008
|
+
}
|
|
3009
|
+
prevArrowPage() {
|
|
3010
|
+
if (this.isPageLoading || this.currentPage <= 1)
|
|
3011
|
+
return;
|
|
3012
|
+
const prev = this.currentPage - 1;
|
|
3013
|
+
if (!this.showCachedPage(prev)) {
|
|
3014
|
+
this.loadPage(prev, this.lastLoadedSearch || "");
|
|
3015
|
+
}
|
|
3016
|
+
}
|
|
3017
|
+
resetListScroll() {
|
|
3018
|
+
setTimeout(() => {
|
|
3019
|
+
if (this.dropdownElement) {
|
|
3020
|
+
this.dropdownElement.nativeElement.scrollTop = 0;
|
|
3021
|
+
}
|
|
3022
|
+
}, 0);
|
|
3023
|
+
}
|
|
2975
3024
|
onListScroll(event) {
|
|
2976
3025
|
if (this.paginationType !== 'scroll')
|
|
2977
3026
|
return;
|
|
@@ -3062,6 +3111,9 @@ class PaginatedAutocompleteControl {
|
|
|
3062
3111
|
this.lastLoadedSearch === term &&
|
|
3063
3112
|
this._displayedOptions.length > 0) {
|
|
3064
3113
|
this.openDropdown();
|
|
3114
|
+
if (this.paginationType === 'arrow') {
|
|
3115
|
+
this.showCachedPage(1);
|
|
3116
|
+
}
|
|
3065
3117
|
const idx = this.selectedItems
|
|
3066
3118
|
? this._displayedOptions.findIndex((o) => o.id === this.selectedItems.id)
|
|
3067
3119
|
: -1;
|
|
@@ -3140,28 +3192,14 @@ class PaginatedAutocompleteControl {
|
|
|
3140
3192
|
case "ArrowRight": {
|
|
3141
3193
|
if (this.paginationType !== 'arrow')
|
|
3142
3194
|
break; // caret moves normally
|
|
3143
|
-
|
|
3144
|
-
const target = (this.highlightedIndex ?? -1) + this.pageSize;
|
|
3145
|
-
if (target > this._displayedOptions.length - 1 && this.hasMore) {
|
|
3146
|
-
if (!this.isPageLoading) {
|
|
3147
|
-
this.pendingHighlightIndex = this._displayedOptions.length;
|
|
3148
|
-
this.loadNextPage();
|
|
3149
|
-
}
|
|
3150
|
-
}
|
|
3151
|
-
else {
|
|
3152
|
-
this.highlightedIndex = Math.min(target, this._displayedOptions.length - 1);
|
|
3153
|
-
this.scrollHighlightedItemIntoView();
|
|
3154
|
-
}
|
|
3195
|
+
this.nextArrowPage();
|
|
3155
3196
|
event.preventDefault();
|
|
3156
3197
|
break;
|
|
3157
3198
|
}
|
|
3158
3199
|
case "ArrowLeft": {
|
|
3159
3200
|
if (this.paginationType !== 'arrow')
|
|
3160
3201
|
break; // caret moves normally
|
|
3161
|
-
|
|
3162
|
-
const target = (this.highlightedIndex ?? 0) - this.pageSize;
|
|
3163
|
-
this.highlightedIndex = Math.max(target, 0);
|
|
3164
|
-
this.scrollHighlightedItemIntoView();
|
|
3202
|
+
this.prevArrowPage();
|
|
3165
3203
|
event.preventDefault();
|
|
3166
3204
|
break;
|
|
3167
3205
|
}
|
|
@@ -3253,7 +3291,7 @@ class PaginatedAutocompleteControl {
|
|
|
3253
3291
|
useExisting: PaginatedAutocompleteControl,
|
|
3254
3292
|
multi: true,
|
|
3255
3293
|
},
|
|
3256
|
-
], 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 (input)=\"onUserType($event)\" (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 {{
|
|
3294
|
+
], 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 (input)=\"onUserType($event)\" (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\" [class.pager-footer]=\"paginationType === 'arrow'\">\n @if (paginationType === 'arrow') {\n <span class=\"range\">{{ pageRangeStart }} - {{ pageRangeEnd }} of {{ totalCount }}</span>\n <span class=\"pager-nav\">\n <span class=\"pager-btn\" [class.disabled]=\"currentPage <= 1\" (click)=\"prevArrowPage()\">\u2039</span>\n <span class=\"pager-btn\" [class.disabled]=\"currentPage >= totalPages\" (click)=\"nextArrowPage()\">\u203A</span>\n </span>\n } @else {\n {{ options.length }} of {{ totalCount }}\n @if (hasMore && paginationType === 'scroll') {\n <span> \u00B7 scroll for more</span>\n }\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}.form-group.paginated-autocomplete .option-list .list-footer .pager-nav{display:inline-flex;align-items:center;gap:6px}.form-group.paginated-autocomplete .option-list .list-footer .range{color:#5f6368;font-size:12px}.form-group.paginated-autocomplete .option-list .list-footer .pager-btn{width:24px;height:24px;border-radius:50%;border:1px solid #dadce0;display:inline-flex;align-items:center;justify-content:center;font-size:15px;line-height:1;color:#5f6368;cursor:pointer;background-color:#fff}.form-group.paginated-autocomplete .option-list .list-footer .pager-btn:hover{background-color:#f5f5f5}.form-group.paginated-autocomplete .option-list .list-footer .pager-btn.disabled{border-color:transparent;color:#ccc;cursor:default;pointer-events:none}.form-group.paginated-autocomplete .option-list .list-footer.pager-footer{display:flex;justify-content:space-between;align-items:center;padding:4px 8px}\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"] }] });
|
|
3257
3295
|
}
|
|
3258
3296
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: PaginatedAutocompleteControl, decorators: [{
|
|
3259
3297
|
type: Component,
|
|
@@ -3263,7 +3301,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
|
|
|
3263
3301
|
useExisting: PaginatedAutocompleteControl,
|
|
3264
3302
|
multi: true,
|
|
3265
3303
|
},
|
|
3266
|
-
], 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 (input)=\"onUserType($event)\" (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 {{
|
|
3304
|
+
], 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 (input)=\"onUserType($event)\" (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\" [class.pager-footer]=\"paginationType === 'arrow'\">\n @if (paginationType === 'arrow') {\n <span class=\"range\">{{ pageRangeStart }} - {{ pageRangeEnd }} of {{ totalCount }}</span>\n <span class=\"pager-nav\">\n <span class=\"pager-btn\" [class.disabled]=\"currentPage <= 1\" (click)=\"prevArrowPage()\">\u2039</span>\n <span class=\"pager-btn\" [class.disabled]=\"currentPage >= totalPages\" (click)=\"nextArrowPage()\">\u203A</span>\n </span>\n } @else {\n {{ options.length }} of {{ totalCount }}\n @if (hasMore && paginationType === 'scroll') {\n <span> \u00B7 scroll for more</span>\n }\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}.form-group.paginated-autocomplete .option-list .list-footer .pager-nav{display:inline-flex;align-items:center;gap:6px}.form-group.paginated-autocomplete .option-list .list-footer .range{color:#5f6368;font-size:12px}.form-group.paginated-autocomplete .option-list .list-footer .pager-btn{width:24px;height:24px;border-radius:50%;border:1px solid #dadce0;display:inline-flex;align-items:center;justify-content:center;font-size:15px;line-height:1;color:#5f6368;cursor:pointer;background-color:#fff}.form-group.paginated-autocomplete .option-list .list-footer .pager-btn:hover{background-color:#f5f5f5}.form-group.paginated-autocomplete .option-list .list-footer .pager-btn.disabled{border-color:transparent;color:#ccc;cursor:default;pointer-events:none}.form-group.paginated-autocomplete .option-list .list-footer.pager-footer{display:flex;justify-content:space-between;align-items:center;padding:4px 8px}\n"] }]
|
|
3267
3305
|
}], ctorParameters: () => [], propDecorators: { title: [{
|
|
3268
3306
|
type: Input
|
|
3269
3307
|
}], required: [{
|