ng-zenduit 2.3.11 → 2.3.15
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/ng-zenduit.mjs +115 -13
- package/fesm2022/ng-zenduit.mjs.map +1 -1
- package/package.json +1 -1
- package/types/ng-zenduit.d.ts +49 -3
package/fesm2022/ng-zenduit.mjs
CHANGED
|
@@ -221,8 +221,18 @@ class ZenduOverlayService {
|
|
|
221
221
|
if (config.minWidth != null) {
|
|
222
222
|
overlayConfig.minWidth = config.minWidth;
|
|
223
223
|
}
|
|
224
|
+
if (config.minHeight != null) {
|
|
225
|
+
overlayConfig.minHeight = config.minHeight;
|
|
226
|
+
}
|
|
224
227
|
const overlayRef = this._overlay.create(overlayConfig);
|
|
225
228
|
overlayRef.attach(new TemplatePortal(config.content, config.viewContainerRef));
|
|
229
|
+
// scrollBehavior: 'block' — freeze the trigger's scroll container while
|
|
230
|
+
// the panel is open (mat-select-style). CDK's BlockScrollStrategy only
|
|
231
|
+
// locks <html>, which is useless in an app-shell that scrolls inside a
|
|
232
|
+
// nested overflow:auto pane, so we lock that pane directly instead.
|
|
233
|
+
const unlockScroll = config.scrollBehavior === 'block'
|
|
234
|
+
? this._lockScrollContainer(originEl)
|
|
235
|
+
: null;
|
|
226
236
|
const closed = new Subject();
|
|
227
237
|
const destroyed = new Subject();
|
|
228
238
|
// Ignore the pointer interaction that OPENED the panel. open() is
|
|
@@ -305,6 +315,7 @@ class ZenduOverlayService {
|
|
|
305
315
|
closed: closed.asObservable(),
|
|
306
316
|
updatePosition: () => overlayRef.updatePosition(),
|
|
307
317
|
close: () => {
|
|
318
|
+
unlockScroll?.();
|
|
308
319
|
removeViewportListeners();
|
|
309
320
|
destroyed.next();
|
|
310
321
|
destroyed.complete();
|
|
@@ -329,6 +340,47 @@ class ZenduOverlayService {
|
|
|
329
340
|
{ originX: 'end', originY: 'top', overlayX: 'end', overlayY: 'bottom', offsetY: -offsetY }
|
|
330
341
|
];
|
|
331
342
|
}
|
|
343
|
+
/**
|
|
344
|
+
* Lock the trigger's nearest scrollable ancestor (or the document) with
|
|
345
|
+
* `overflow: hidden` so the page can't scroll while the panel is open, and
|
|
346
|
+
* pad for the now-missing scrollbar so content doesn't jump. Returns an
|
|
347
|
+
* idempotent restore fn that puts the inline styles back.
|
|
348
|
+
*/
|
|
349
|
+
_lockScrollContainer(originEl) {
|
|
350
|
+
const el = this._findScrollContainer(originEl);
|
|
351
|
+
if (!el) {
|
|
352
|
+
return () => { };
|
|
353
|
+
}
|
|
354
|
+
const prevOverflow = el.style.overflow;
|
|
355
|
+
const prevPaddingRight = el.style.paddingRight;
|
|
356
|
+
const scrollbarWidth = el.offsetWidth - el.clientWidth;
|
|
357
|
+
el.style.overflow = 'hidden';
|
|
358
|
+
if (scrollbarWidth > 0) {
|
|
359
|
+
const computed = getComputedStyle(el).paddingRight;
|
|
360
|
+
el.style.paddingRight = `calc(${computed} + ${scrollbarWidth}px)`;
|
|
361
|
+
}
|
|
362
|
+
return () => {
|
|
363
|
+
el.style.overflow = prevOverflow;
|
|
364
|
+
el.style.paddingRight = prevPaddingRight;
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Walk up from the trigger to the first ancestor that actually scrolls
|
|
369
|
+
* (overflow-y auto/scroll AND content taller than the box). Falls back to
|
|
370
|
+
* the document scrolling element so block always has something to lock.
|
|
371
|
+
*/
|
|
372
|
+
_findScrollContainer(originEl) {
|
|
373
|
+
let node = originEl.parentElement;
|
|
374
|
+
while (node && node !== document.body && node !== document.documentElement) {
|
|
375
|
+
const overflowY = getComputedStyle(node).overflowY;
|
|
376
|
+
const scrolls = overflowY === 'auto' || overflowY === 'scroll';
|
|
377
|
+
if (scrolls && node.scrollHeight > node.clientHeight) {
|
|
378
|
+
return node;
|
|
379
|
+
}
|
|
380
|
+
node = node.parentElement;
|
|
381
|
+
}
|
|
382
|
+
return document.scrollingElement ?? document.documentElement;
|
|
383
|
+
}
|
|
332
384
|
_panelClasses(extra) {
|
|
333
385
|
const classes = ['zen-overlay-panel'];
|
|
334
386
|
if (Array.isArray(extra)) {
|
|
@@ -2862,8 +2914,11 @@ class ZenduDatePickerDropdownComponent {
|
|
|
2862
2914
|
return formatted;
|
|
2863
2915
|
}
|
|
2864
2916
|
formatTime(date) {
|
|
2865
|
-
|
|
2866
|
-
|
|
2917
|
+
// Normalize through moment so a string/moment input (the declared type is
|
|
2918
|
+
// Date, but consumers often bind ISO strings) doesn't break native getters.
|
|
2919
|
+
const mDate = moment(date);
|
|
2920
|
+
let h = mDate.hours();
|
|
2921
|
+
const m = mDate.minutes();
|
|
2867
2922
|
const period = h >= 12 ? 'PM' : 'AM';
|
|
2868
2923
|
if (h === 0)
|
|
2869
2924
|
h = 12;
|
|
@@ -2926,17 +2981,18 @@ class ZenduDatePickerDropdownComponent {
|
|
|
2926
2981
|
// dual calendars have laid out.
|
|
2927
2982
|
const rect = anchorEl.getBoundingClientRect();
|
|
2928
2983
|
const viewportHeight = window.innerHeight;
|
|
2984
|
+
const cb = this.containingBlockRect();
|
|
2929
2985
|
const spaceBelow = viewportHeight - rect.bottom - PANEL_GAP - VIEWPORT_MARGIN;
|
|
2930
2986
|
const spaceAbove = rect.top - PANEL_GAP - VIEWPORT_MARGIN;
|
|
2931
2987
|
this.dropdownStyle = spaceBelow >= spaceAbove
|
|
2932
2988
|
? {
|
|
2933
|
-
left: `${rect.left}px`,
|
|
2934
|
-
top: `${rect.bottom + PANEL_GAP}px`,
|
|
2989
|
+
left: `${rect.left - cb.left}px`,
|
|
2990
|
+
top: `${rect.bottom + PANEL_GAP - cb.top}px`,
|
|
2935
2991
|
'max-height': `${Math.max(MIN_PANEL_HEIGHT, spaceBelow)}px`
|
|
2936
2992
|
}
|
|
2937
2993
|
: {
|
|
2938
|
-
left: `${rect.left}px`,
|
|
2939
|
-
bottom: `${
|
|
2994
|
+
left: `${rect.left - cb.left}px`,
|
|
2995
|
+
bottom: `${cb.bottom - rect.top + PANEL_GAP}px`,
|
|
2940
2996
|
'max-height': `${Math.max(MIN_PANEL_HEIGHT, spaceAbove)}px`
|
|
2941
2997
|
};
|
|
2942
2998
|
// Measure AFTER the calendars render. The dual-calendar range layout is
|
|
@@ -2964,22 +3020,54 @@ class ZenduDatePickerDropdownComponent {
|
|
|
2964
3020
|
const panelHeight = panelEl.scrollHeight;
|
|
2965
3021
|
const spaceBelow = viewportHeight - rect.bottom - PANEL_GAP - VIEWPORT_MARGIN;
|
|
2966
3022
|
const spaceAbove = rect.top - PANEL_GAP - VIEWPORT_MARGIN;
|
|
3023
|
+
const cb = this.containingBlockRect();
|
|
2967
3024
|
const style = {};
|
|
2968
|
-
// Horizontal: keep the panel fully on-screen
|
|
2969
|
-
|
|
3025
|
+
// Horizontal: keep the panel fully on-screen (computed in viewport
|
|
3026
|
+
// space), then offset into the panel's containing block.
|
|
3027
|
+
const desiredLeft = Math.max(VIEWPORT_MARGIN, Math.min(rect.left, viewportWidth - panelWidth - VIEWPORT_MARGIN));
|
|
3028
|
+
style['left'] = `${desiredLeft - cb.left}px`;
|
|
2970
3029
|
// Vertical: open below when it fits or there is more room below,
|
|
2971
3030
|
// otherwise above. Always cap max-height to the available space so the
|
|
2972
3031
|
// footer stays reachable via the panel's internal scroll.
|
|
2973
3032
|
if (panelHeight <= spaceBelow || spaceBelow >= spaceAbove) {
|
|
2974
|
-
style['top'] = `${rect.bottom + PANEL_GAP}px`;
|
|
3033
|
+
style['top'] = `${rect.bottom + PANEL_GAP - cb.top}px`;
|
|
2975
3034
|
style['max-height'] = `${Math.max(MIN_PANEL_HEIGHT, spaceBelow)}px`;
|
|
2976
3035
|
}
|
|
2977
3036
|
else {
|
|
2978
|
-
style['bottom'] = `${
|
|
3037
|
+
style['bottom'] = `${cb.bottom - rect.top + PANEL_GAP}px`;
|
|
2979
3038
|
style['max-height'] = `${Math.max(MIN_PANEL_HEIGHT, spaceAbove)}px`;
|
|
2980
3039
|
}
|
|
2981
3040
|
this.dropdownStyle = style;
|
|
2982
3041
|
}
|
|
3042
|
+
/**
|
|
3043
|
+
* The panel is `position: fixed`, so its coordinates are viewport-relative
|
|
3044
|
+
* ONLY when no ancestor establishes a containing block. Inside a CDK
|
|
3045
|
+
* overlay pane (e.g. when this picker sits in a `zen-filter`), the pane is
|
|
3046
|
+
* `transform`ed and becomes the containing block, so `fixed` is measured
|
|
3047
|
+
* from the pane, not the viewport — which detaches the panel from its
|
|
3048
|
+
* trigger. Return that containing block's viewport rect so the
|
|
3049
|
+
* viewport-space coordinates above can be offset into the panel's actual
|
|
3050
|
+
* coordinate space; falls back to the viewport when nothing transforms.
|
|
3051
|
+
*/
|
|
3052
|
+
containingBlockRect() {
|
|
3053
|
+
let node = this._element.nativeElement.parentElement;
|
|
3054
|
+
while (node) {
|
|
3055
|
+
const s = getComputedStyle(node);
|
|
3056
|
+
const establishesContainingBlock = (s.transform && s.transform !== 'none') ||
|
|
3057
|
+
(s.perspective && s.perspective !== 'none') ||
|
|
3058
|
+
(s.filter && s.filter !== 'none') ||
|
|
3059
|
+
s.willChange === 'transform' ||
|
|
3060
|
+
(s.contain
|
|
3061
|
+
? /\b(paint|layout|strict|content)\b/.test(s.contain)
|
|
3062
|
+
: false);
|
|
3063
|
+
if (establishesContainingBlock) {
|
|
3064
|
+
const r = node.getBoundingClientRect();
|
|
3065
|
+
return { left: r.left, top: r.top, bottom: r.bottom };
|
|
3066
|
+
}
|
|
3067
|
+
node = node.parentElement;
|
|
3068
|
+
}
|
|
3069
|
+
return { left: 0, top: 0, bottom: window.innerHeight };
|
|
3070
|
+
}
|
|
2983
3071
|
/**
|
|
2984
3072
|
* Anchor to the trigger button, or to the host element when the trigger is
|
|
2985
3073
|
* hidden (an external control drives the popup).
|
|
@@ -3604,6 +3692,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImpor
|
|
|
3604
3692
|
type: Input
|
|
3605
3693
|
}] } });
|
|
3606
3694
|
|
|
3695
|
+
// Lets a tall filter panel clamp to the viewport and scroll instead of being
|
|
3696
|
+
// pushed off-screen. Gates CDK's flexible path; not the panel's actual height.
|
|
3697
|
+
const FILTER_PANEL_MIN_HEIGHT = 120;
|
|
3607
3698
|
class ZenduFilterComponent {
|
|
3608
3699
|
set isVisible(open) {
|
|
3609
3700
|
open = !!open;
|
|
@@ -3708,6 +3799,7 @@ class ZenduFilterComponent {
|
|
|
3708
3799
|
// The panel has its own fixed width (.filter-menu); let it size to content
|
|
3709
3800
|
// and the overlay's flexible dimensions clamp it on small viewports.
|
|
3710
3801
|
width: 'auto',
|
|
3802
|
+
minHeight: FILTER_PANEL_MIN_HEIGHT,
|
|
3711
3803
|
scrollBehavior: 'reposition',
|
|
3712
3804
|
positions: this._buildConnectedPositions(),
|
|
3713
3805
|
});
|
|
@@ -4792,7 +4884,13 @@ class ZenduSelectComponent {
|
|
|
4792
4884
|
content: this.dropdownPanel,
|
|
4793
4885
|
viewContainerRef: this.viewContainerRef,
|
|
4794
4886
|
width: 'origin',
|
|
4795
|
-
|
|
4887
|
+
minWidth: this.panelMinWidth,
|
|
4888
|
+
panelClass: this.panelClass,
|
|
4889
|
+
// Freeze the page while the dropdown is open (mat-select-style) instead
|
|
4890
|
+
// of chasing the trigger on scroll. The overlay service locks the
|
|
4891
|
+
// trigger's nearest scroll container, which works in app shells that
|
|
4892
|
+
// scroll inner panes rather than the document root.
|
|
4893
|
+
scrollBehavior: 'block'
|
|
4796
4894
|
});
|
|
4797
4895
|
// Outside click / Escape / detach → close (and emit, as a user action).
|
|
4798
4896
|
this._panelRef.closed.subscribe(() => this.hideDropDown(true));
|
|
@@ -5464,7 +5562,7 @@ class ZenduSelectComponent {
|
|
|
5464
5562
|
this.isSelectedAll = this.options.every(opt => opt.checked);
|
|
5465
5563
|
}
|
|
5466
5564
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: ZenduSelectComponent, deps: [{ token: i0.ElementRef }, { token: ZenduOverlayService }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
5467
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.0", type: ZenduSelectComponent, isStandalone: false, selector: "zen-select", inputs: { selectModel: "selectModel", options: "options", label: "label", helpIcon: "helpIcon", helpTooltip: "helpTooltip", supportingText: "supportingText", hintText: "hintText", placeholder: "placeholder", leadingType: "leadingType", leadingIcon: "leadingIcon", leadingAvatar: "leadingAvatar", leadingDotColor: "leadingDotColor", displayProp: "displayProp", idProp: "idProp", hasSearch: "hasSearch", isMultiselect: "isMultiselect", multiselect: "multiselect", hideSelectAll: "hideSelectAll", hideTreeSearch: "hideTreeSearch", required: "required", disabled: "disabled", error: "error", errorMessage: "errorMessage", destructive: "destructive", size: "size", returnOption: "returnOption", isTruncate: "isTruncate", enableAddNewOption: "enableAddNewOption", showDefaultAddOption: "showDefaultAddOption", newOptionText: "newOptionText", enableRemoveOption: "enableRemoveOption", removeOptionText: "removeOptionText", isLazyLoading: "isLazyLoading", lazyLoader: "lazyLoader", preferredOpenDirection: "preferredOpenDirection" }, outputs: { selectModelChange: "selectModelChange", addNewOption: "addNewOption", removeOption: "removeOption", closed: "closed" }, queries: [{ propertyName: "optionTemplate", first: true, predicate: ZenduSelectOptionDirective, descendants: true }, { propertyName: "valueTemplate", first: true, predicate: ZenduSelectValueDirective, descendants: true }, { propertyName: "buttonTemplate", first: true, predicate: ZenduSelectButtonDirective, descendants: true }], viewQueries: [{ propertyName: "selectWrapper", first: true, predicate: ["selectWrapper"], descendants: true }, { propertyName: "dropdownPanel", first: true, predicate: ["dropdownPanel"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div [class]=\"getStateClasses()\">\n <!-- Label -->\n @if (label) {\n <label class=\"app-select-label text text-sm text-weight-medium\"\n [ngClass]=\"{'required': required, 'disabled': disabled, 'destructive': destructive}\">\n {{ label | translate }}\n @if (required) {\n <span class=\"required-indicator\">*</span>\n }\n @if (helpIcon) {\n <span\n class=\"zen-help-icon\"\n role=\"img\"\n [class.disabled]=\"disabled\"\n [attr.tabindex]=\"disabled ? -1 : 0\"\n [attr.aria-label]=\"helpTooltip | translate\"\n (mouseenter)=\"updateHelpTooltipPlacement($event)\"\n (focus)=\"updateHelpTooltipPlacement($event)\">\n <i class=\"material-icons-outlined\">help_outline</i>\n <!-- Shown on hover/focus via CSS \u2014 no click state. -->\n <div\n class=\"zen-help-tooltip\"\n [class.align-start]=\"helpTooltipAlign === 'start'\"\n [class.align-end]=\"helpTooltipAlign === 'end'\"\n [class.place-below]=\"helpTooltipPlacement === 'below'\">\n <div class=\"tooltip-content\">{{ helpTooltip | translate }}</div>\n <div class=\"tooltip-arrow\"></div>\n </div>\n </span>\n }\n </label>\n }\n\n <!-- Select Input -->\n <div class=\"app-select-wrapper\" #selectWrapper>\n <!-- Custom Trigger Template (overrides built-in trigger) -->\n @if (buttonTemplate) {\n <div\n class=\"app-select-custom-trigger\"\n (click)=\"toggleDropdown()\">\n <ng-template [ngTemplateOutlet]=\"buttonTemplate.template\"\n [ngTemplateOutletContext]=\"{ isOpen: isOpen, selected: getSelectedOption(), display: selectedDisplay, disabled: disabled }\">\n </ng-template>\n </div>\n }\n\n <!-- Built-in Trigger (when no custom button template provided) -->\n @if (!buttonTemplate) {\n @switch (leadingType) {\n <!-- Default Select (no leading element) -->\n @case ('default') {\n <ng-container *ngTemplateOutlet=\"defaultSelectTemplate\"></ng-container>\n }\n <!-- Icon Leading Select -->\n @case ('icon') {\n <ng-container *ngTemplateOutlet=\"iconSelectTemplate\"></ng-container>\n }\n <!-- Avatar Leading Select -->\n @case ('avatar') {\n <ng-container *ngTemplateOutlet=\"avatarSelectTemplate\"></ng-container>\n }\n <!-- Dot Leading Select -->\n @case ('dot') {\n <ng-container *ngTemplateOutlet=\"dotSelectTemplate\"></ng-container>\n }\n <!-- Search Input Select -->\n @case ('search') {\n <ng-container *ngTemplateOutlet=\"searchInputTemplate\"></ng-container>\n }\n }\n }\n\n <!-- Dropdown Menu (rendered into a CDK overlay via ZenduOverlayService;\n positioning/flip/clamping is handled there, not with absolute CSS) -->\n <ng-template #dropdownPanel>\n <div class=\"app-select-dropdown\">\n <!-- Tree Mode: embed zen-groups inline -->\n @if (isTreeMode && isMultiselect) {\n <zen-groups [inline]=\"true\"\n [dataSource]=\"$any(options)\"\n [filteredDataSource]=\"treeFilteredDataSource\"\n [hideSelectAll]=\"hideSelectAll\"\n [hideSearch]=\"hideTreeSearch\"\n [idProp]=\"idProp\"\n [displayProp]=\"displayProp\"\n [(isSelectedAll)]=\"isSelectedAll\"\n (isSelectedAllChange)=\"onTreeSelectAllChange($event)\"\n (checkedChange)=\"onTreeCheckedChange($event)\">\n </zen-groups>\n } @else {\n <!-- Search Box for hasSearch (not for search type as it has inline search) -->\n @if (leadingType !== 'search' && hasSearch && !disabled) {\n <div class=\"app-select-search\">\n <zen-icon [name]=\"'search'\"\n [customColor]=\"'#667085'\">\n </zen-icon>\n <input type=\"text\"\n [(ngModel)]=\"searchText\"\n (ngModelChange)=\"onSearchChange()\"\n (keydown.enter)=\"onSearchEnter($event)\"\n placeholder=\"Search\"\n class=\"app-select-search-input\">\n @if (searchText) {\n <zen-icon\n class=\"app-select-search-clear\"\n [name]=\"'x'\"\n [customColor]=\"'#667085'\"\n (click)=\"clearSearch(); $event.stopPropagation()\">\n </zen-icon>\n }\n </div>\n }\n <!-- Options List -->\n <div class=\"app-select-options\" (scroll)=\"onOptionsScroll($event)\">\n <!-- Select All Option for Multiselect -->\n @if (isMultiselect && !hideSelectAll && !isLazyLoading && filteredOptions.length > 0) {\n <button\n class=\"app-select-option select-all\"\n (click)=\"toggleSelectAll()\">\n <zen-checkbox class=\"app-select-checkbox\"\n [checked]=\"isAllSelected()\"\n [disableValueChange]=\"true\"\n [label]=\"''\"\n size=\"sm\">\n </zen-checkbox>\n <span class=\"app-select-option-text\">\n Select All\n </span>\n </button>\n }\n <!-- Add New Option -->\n @if (enableAddNewOption && (showDefaultAddOption || searchText)) {\n <button\n class=\"app-select-option add-new-option\"\n (click)=\"handleAddNewOption(); $event.stopPropagation()\">\n <zen-icon [name]=\"'plus'\" [customColor]=\"'#136AB6'\"></zen-icon>\n <span class=\"app-select-option-text\">\n {{ (newOptionText || 'Add New Option') + (searchText ? ': \"' + searchText + '\"' : '') }}\n </span>\n </button>\n }\n <!-- Remove Option -->\n @if (enableRemoveOption) {\n <button\n class=\"app-select-option remove-option\"\n (click)=\"handleRemoveOption(); $event.stopPropagation()\">\n <zen-icon [name]=\"'user-x'\" [customColor]=\"'#344054'\"></zen-icon>\n <span class=\"app-select-option-text\">\n {{ removeOptionText || 'Remove' }}\n </span>\n </button>\n }\n @if (filteredOptions.length === 0 && !enableAddNewOption && !isLoadingNow) {\n <div class=\"app-select-no-options\">\n No matching options found\n </div>\n }\n @for (option of filteredOptions; track option) {\n <button\n class=\"app-select-option\"\n [class.selected]=\"isSelected(option)\"\n (click)=\"selectOption(option)\">\n <!-- Checkbox for Multiselect -->\n @if (isMultiselect) {\n <zen-checkbox class=\"app-select-checkbox\"\n [checked]=\"isSelected(option)\"\n [disableValueChange]=\"true\"\n [label]=\"''\"\n size=\"sm\">\n </zen-checkbox>\n }\n <!-- Option Leading Element -->\n @if (leadingType !== 'default') {\n <div class=\"app-select-option-leading\">\n @switch (leadingType) {\n @case ('icon') {\n <ng-container *ngTemplateOutlet=\"iconLeadingElement; context: { option: option }\"></ng-container>\n }\n @case ('avatar') {\n <ng-container *ngTemplateOutlet=\"avatarLeadingElement; context: { option: option }\"></ng-container>\n }\n @case ('dot') {\n <ng-container *ngTemplateOutlet=\"dotLeadingElement; context: { option: option }\"></ng-container>\n }\n }\n </div>\n }\n <!-- Option Text -->\n <div class=\"app-select-option-text-wrapper\">\n <!-- Use custom template if provided -->\n @if (!isMultiselect && optionTemplate) {\n <ng-template [ngTemplateOutlet]=\"optionTemplate.template\"\n [ngTemplateOutletContext]=\"{ option: option }\">\n </ng-template>\n } @else {\n <span class=\"app-select-option-text\" [class.app-select-option-truncate]=\"isTruncate\">\n {{ getName(option) | translate }}\n </span>\n @if (option.secondaryText) {\n <span class=\"app-select-option-secondary\">\n {{ option.secondaryText }}\n </span>\n }\n }\n </div>\n <!-- Check Icon for Single Select -->\n @if (!isMultiselect && isSelected(option)) {\n <zen-icon\n class=\"app-select-option-check\"\n [name]=\"'check'\"\n [customColor]=\"'#136AB6'\">\n </zen-icon>\n }\n </button>\n }\n <!-- Lazy loading spinner -->\n @if (isLazyLoading && isLoadingNow) {\n <div class=\"app-select-loading\">\n <zen-spinner size=\"small\"></zen-spinner>\n </div>\n }\n </div>\n }\n <!-- Flat List Mode (default) -->\n </div>\n </ng-template>\n </div>\n\n <!-- Hint text / Error message -->\n @if ((destructive && errorMessage) || hintText) {\n <div\n class=\"app-select-hint text text-sm text-weight-regular\"\n [ngClass]=\"{'destructive': destructive}\">\n @if (destructive) {\n <i class=\"material-icons-outlined hint-icon\">error_outline</i>\n }\n <span>{{ ((destructive && errorMessage) ? errorMessage : hintText) | translate }}</span>\n </div>\n }\n</div>\n\n<!-- ============================================= -->\n<!-- MAIN SELECT INPUT TEMPLATES -->\n<!-- ============================================= -->\n\n<!-- Default Select Template (No Leading Element) -->\n<ng-template #defaultSelectTemplate>\n <button class=\"app-select-input\"\n [disabled]=\"disabled\"\n (click)=\"toggleDropdown()\"\n [class.focused]=\"isOpen\"\n [class.has-value]=\"!isModelEmpty()\">\n\n <ng-container *ngTemplateOutlet=\"selectValueDisplay\"></ng-container>\n <ng-container *ngTemplateOutlet=\"dropdownArrow\"></ng-container>\n </button>\n</ng-template>\n\n<!-- Icon Select Template -->\n<ng-template #iconSelectTemplate>\n <button class=\"app-select-input\"\n [disabled]=\"disabled\"\n (click)=\"toggleDropdown()\"\n [class.focused]=\"isOpen\"\n [class.has-value]=\"!isModelEmpty()\">\n\n <div class=\"app-select-leading\">\n <ng-container *ngTemplateOutlet=\"iconLeadingElement; context: { option: getSelectedOption(), icon: leadingIcon }\"></ng-container>\n </div>\n\n <ng-container *ngTemplateOutlet=\"selectValueDisplay\"></ng-container>\n <ng-container *ngTemplateOutlet=\"dropdownArrow\"></ng-container>\n </button>\n</ng-template>\n\n<!-- Avatar Select Template -->\n<ng-template #avatarSelectTemplate>\n <button class=\"app-select-input\"\n [disabled]=\"disabled\"\n (click)=\"toggleDropdown()\"\n [class.focused]=\"isOpen\"\n [class.has-value]=\"!isModelEmpty()\">\n\n <div class=\"app-select-leading\">\n <ng-container *ngTemplateOutlet=\"avatarLeadingElement; context: { option: getSelectedOption(), avatar: leadingAvatar }\"></ng-container>\n </div>\n\n <ng-container *ngTemplateOutlet=\"selectValueDisplay\"></ng-container>\n <ng-container *ngTemplateOutlet=\"dropdownArrow\"></ng-container>\n </button>\n</ng-template>\n\n<!-- Dot Select Template -->\n<ng-template #dotSelectTemplate>\n <button class=\"app-select-input\"\n [disabled]=\"disabled\"\n (click)=\"toggleDropdown()\"\n [class.focused]=\"isOpen\"\n [class.has-value]=\"!isModelEmpty()\">\n\n <div class=\"app-select-leading\">\n <ng-container *ngTemplateOutlet=\"dotLeadingElement; context: { option: getSelectedOption(), color: leadingDotColor }\"></ng-container>\n </div>\n\n <ng-container *ngTemplateOutlet=\"selectValueDisplay\"></ng-container>\n <ng-container *ngTemplateOutlet=\"dropdownArrow\"></ng-container>\n </button>\n</ng-template>\n\n<!-- Search Input Template -->\n<ng-template #searchInputTemplate>\n <div class=\"app-select-input app-select-search-input\"\n [class.focused]=\"isOpen || searchFocused\"\n [class.has-value]=\"!isModelEmpty()\">\n\n <!-- Search Icon -->\n <zen-icon [name]=\"'search'\"\n [customColor]=\"disabled ? '#9CA3AF' : '#667085'\">\n </zen-icon>\n\n <!-- Search Input Field -->\n <input type=\"text\"\n class=\"app-select-search-field\"\n [(ngModel)]=\"searchInputValue\"\n (ngModelChange)=\"onSearchInputChange()\"\n (keydown.enter)=\"onSearchEnter($event)\"\n (focus)=\"onSearchFocus()\"\n (blur)=\"onSearchBlur($event)\"\n [placeholder]=\"selectedDisplay || placeholder\"\n [disabled]=\"disabled\">\n </div>\n</ng-template>\n\n<!-- ============================================= -->\n<!-- SHARED COMPONENT TEMPLATES -->\n<!-- ============================================= -->\n\n<!-- Select Value Display -->\n<ng-template #selectValueDisplay>\n <div class=\"app-select-value-wrapper\">\n @if (valueTemplate && !isModelEmpty()) {\n <ng-template [ngTemplateOutlet]=\"valueTemplate.template\"\n [ngTemplateOutletContext]=\"{ option: getSelectedOption(), display: selectedDisplay }\">\n </ng-template>\n } @else {\n <span class=\"app-select-value\" [class.placeholder]=\"isModelEmpty()\">\n {{ selectedDisplay || placeholder | translate }}\n </span>\n @if (getSelectedSecondaryText() && !isModelEmpty()) {\n <span class=\"app-select-secondary\">\n {{ getSelectedSecondaryText() }}\n </span>\n }\n }\n </div>\n</ng-template>\n\n<!-- Dropdown Arrow -->\n<ng-template #dropdownArrow>\n <zen-icon class=\"app-select-arrow\"\n [class.rotated]=\"isOpen\"\n [name]=\"'chevron-down'\"\n [customColor]=\"'#667085'\">\n </zen-icon>\n</ng-template>\n\n<!-- ============================================= -->\n<!-- LEADING ELEMENT TEMPLATES -->\n<!-- ============================================= -->\n\n<!-- Icon Leading Element (with smart resolution) -->\n<ng-template #iconLeadingElement let-option=\"option\" let-icon=\"icon\">\n @if (icon || option?.icon || option?.iconName) {\n @if (getIconPath(option, icon); as iconPath) {\n <!-- If icon contains / or . treat as SVG path -->\n @if ((icon && (icon.includes('/') || icon.includes('.'))) ||\n (option?.icon && (option.icon.includes('/') || option.icon.includes('.'))) ||\n (option?.iconName && (option.iconName.includes('/') || option.iconName.includes('.')))) {\n <!-- Use img tag for Excel to preserve colors -->\n @if (iconPath.includes('excel')) {\n <img\n [src]=\"iconPath\"\n alt=\"\"\n style=\"width: 20px; height: 20px;\">\n }\n <!-- Use zen-icon with src for other SVG files -->\n @if (!iconPath.includes('excel')) {\n <zen-icon\n [src]=\"iconPath\"\n [customColor]=\"'#667085'\">\n </zen-icon>\n }\n }\n <!-- Otherwise treat as Material icon name or special cases -->\n @if (!((icon && (icon.includes('/') || icon.includes('.'))) ||\n (option?.icon && (option.icon.includes('/') || option.icon.includes('.'))) ||\n (option?.iconName && (option.iconName.includes('/') || option.iconName.includes('.'))))) {\n <!-- Special case for Excel icon - use img to preserve colors -->\n @if ((icon === 'excel') || (option?.icon === 'excel') || (option?.iconName === 'excel')) {\n <img\n src=\"assets/ng-zenduit/icons/excel.svg\"\n alt=\"Excel\"\n style=\"width: 20px; height: 20px;\">\n }\n <!-- Material icon names -->\n @if ((icon !== 'excel') && (option?.icon !== 'excel') && (option?.iconName !== 'excel')) {\n <zen-icon\n [name]=\"icon || option?.icon || option?.iconName\"\n [customColor]=\"'#667085'\">\n </zen-icon>\n }\n }\n }\n }\n</ng-template>\n\n<!-- Avatar Leading Element -->\n<ng-template #avatarLeadingElement let-option=\"option\" let-avatar=\"avatar\">\n @if (avatar || option?.avatar) {\n <div class=\"app-select-avatar\" >\n <img [src]=\"avatar || option?.avatar\" alt=\"\">\n </div>\n }\n</ng-template>\n\n<!-- Dot Leading Element -->\n<ng-template #dotLeadingElement let-option=\"option\" let-color=\"color\">\n <div class=\"app-select-dot\"\n [style.background-color]=\"color || option?.dotColor || '#10B981'\">\n </div>\n</ng-template>", styles: [".text{margin:0;padding:0;color:#101828}.text-display-2xl{font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:72px;line-height:90px;letter-spacing:-.02em}.text-display-xl{font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:60px;line-height:72px;letter-spacing:-.02em}.text-display-lg{font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:48px;line-height:60px;letter-spacing:-.02em}.text-display-md{font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:36px;line-height:44px;letter-spacing:-.02em}.text-display-sm{font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:30px;line-height:38px;letter-spacing:0}.text-display-xs{font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:24px;line-height:32px;letter-spacing:0}.text-xl{font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:20px;line-height:30px;letter-spacing:0}.text-lg{font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:18px;line-height:28px;letter-spacing:0}.text-md{font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:16px;line-height:24px;letter-spacing:0}.text-sm{font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:14px;line-height:20px;letter-spacing:0}.text-xs{font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:12px;line-height:18px;letter-spacing:0}.text-weight-regular{font-weight:400;font-style:normal}.text-weight-medium{font-weight:500;font-style:normal}.text-weight-semibold{font-weight:600;font-style:normal}.text-weight-bold{font-weight:700;font-style:normal}@media(max-width:768px){.text-display-2xl{font-size:48px;line-height:56px}.text-display-xl{font-size:40px;line-height:48px}.text-display-lg{font-size:32px;line-height:40px}}.app-select-container{width:100%;position:relative}.app-select-label{display:flex;align-items:center;gap:8px;margin-bottom:6px;color:#344054}.app-select-label .required-indicator{color:#f04438}.app-select-label.disabled{color:#d0d5dd}.app-select-label .zen-help-icon{position:relative;display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;cursor:help;outline:none}.app-select-label .zen-help-icon i{font-size:20px;color:#98a2b3}.app-select-label .zen-help-icon:not(.disabled):hover i,.app-select-label .zen-help-icon:not(.disabled):focus-visible i{color:#475467}.app-select-label .zen-help-icon.disabled{cursor:not-allowed}.app-select-label .zen-help-icon.disabled i{color:#d0d5dd}.app-select-label .zen-help-icon:not(.disabled):hover .zen-help-tooltip,.app-select-label .zen-help-icon:not(.disabled):focus-visible .zen-help-tooltip{display:block}.app-select-label .zen-help-icon .zen-help-tooltip{display:none;position:absolute;bottom:calc(100% + 8px);right:50%;transform:translate(50%);z-index:1000;white-space:nowrap}.app-select-label .zen-help-icon .zen-help-tooltip.align-start{left:-6px;right:auto;transform:none}.app-select-label .zen-help-icon .zen-help-tooltip.align-start .tooltip-arrow{left:8px;right:auto;transform:none}.app-select-label .zen-help-icon .zen-help-tooltip.align-end{left:auto;right:-6px;transform:none}.app-select-label .zen-help-icon .zen-help-tooltip.align-end .tooltip-arrow{left:auto;right:8px;transform:none}.app-select-label .zen-help-icon .zen-help-tooltip.place-below{top:calc(100% + 8px);bottom:auto}.app-select-label .zen-help-icon .zen-help-tooltip.place-below .tooltip-arrow{top:-6px;bottom:auto;border-top:none;border-bottom:6px solid #101828}.app-select-label .zen-help-icon .zen-help-tooltip .tooltip-content{background:#101828;color:#fff;padding:6px 10px;border-radius:6px;font-family:Inter,sans-serif;font-size:12px;line-height:16px;box-shadow:0 12px 16px #10182814,0 4px 6px #10182808;width:max-content;max-width:260px;white-space:normal;text-align:left}.app-select-label .zen-help-icon .zen-help-tooltip .tooltip-arrow{position:absolute;bottom:-6px;left:50%;transform:translate(-50%);width:0;height:0;border-left:6px solid transparent;border-right:6px solid transparent;border-top:6px solid #101828}.app-select-wrapper{position:relative;width:100%}.app-select-custom-trigger{display:inline-flex;cursor:pointer;-webkit-user-select:none;user-select:none}.app-select-input{width:100%;min-height:44px;padding:10px 14px;box-sizing:border-box;display:flex;align-items:center;gap:8px;background:#fff;border:1px solid #D0D5DD;border-radius:8px;box-shadow:0 1px 2px #1018280d;color:#101828;text-align:left;cursor:pointer;transition:all .2s ease}.app-select-input.app-select-search-input{cursor:text}.app-select-input.app-select-search-input .app-select-search-field{font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:16px;line-height:24px;letter-spacing:0;font-weight:400;font-style:normal;flex:1;border:none;outline:none;background:transparent;color:#101828;min-width:0}.app-select-input.app-select-search-input .app-select-search-field::placeholder{color:#667085}.app-select-input.app-select-search-input .app-select-search-field:disabled{cursor:not-allowed;color:#667085}.app-select-input:hover:not(:disabled){border-color:#98a2b3}.app-select-input.focused,.app-select-input:focus{outline:none;border-color:#88c1f1;box-shadow:0 1px 2px #1018280d,0 0 0 4px #e3eefb}.app-select-input:disabled{background:#f9fafb;border-color:#d0d5dd;cursor:not-allowed}.app-select-container.error .app-select-input:hover:not(:disabled){border-color:#f97066}.app-select-container.error .app-select-input:focus{box-shadow:0 1px 2px #1018280d,0 0 0 4px #fee4e2}.app-select-leading,.app-select-option-leading{display:flex;align-items:center;flex-shrink:0}.app-select-avatar,.app-select-option-avatar{width:24px;height:24px;border-radius:50%;overflow:hidden;flex-shrink:0}.app-select-avatar img,.app-select-option-avatar img{width:100%;height:100%;object-fit:cover}.app-select-avatar .avatar-placeholder,.app-select-option-avatar .avatar-placeholder{width:100%;height:100%;background:#f2f4f7;color:#667085;display:flex;align-items:center;justify-content:center;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:12px;line-height:18px;letter-spacing:0;font-weight:600;font-style:normal}.app-select-dot,.app-select-option-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0}.app-select-value-wrapper{flex:1;display:flex;align-items:center;gap:8px;overflow:hidden}.app-select-value-wrapper .app-select-secondary{font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:16px;line-height:24px;letter-spacing:0;font-weight:400;font-style:normal;color:#667085}.app-select-value{font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:16px;line-height:24px;letter-spacing:0;font-weight:400;font-style:normal;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.app-select-value.placeholder{color:#667085}.app-select-secondary,.app-select-option-secondary{font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:16px;line-height:24px;letter-spacing:0;font-weight:400;font-style:normal;color:#667085;white-space:nowrap;flex-shrink:0}.app-select-arrow{margin-left:auto;flex-shrink:0;transition:transform .2s ease}.app-select-arrow.rotated{transform:rotate(180deg)}.app-select-dropdown{width:100%;background:#fff;border:1px solid #EAECF0;border-radius:8px;box-shadow:0 4px 6px -2px #10182808,0 12px 16px -4px #10182814;overflow:hidden;max-height:320px;display:flex;flex-direction:column}.app-select-search{padding:12px;border-bottom:1px solid #EAECF0;display:flex;align-items:center;gap:8px}.app-select-search zen-icon{flex-shrink:0;width:20px;height:20px}.app-select-search .app-select-search-input{font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:16px;line-height:24px;letter-spacing:0;font-weight:400;font-style:normal;flex:1;border:none;outline:none;color:#101828}.app-select-search .app-select-search-input::placeholder{color:#667085}.app-select-search .app-select-search-clear{cursor:pointer}.app-select-loading{display:flex;justify-content:center;align-items:center;padding:8px 0}.app-select-options{flex:1;min-height:0;overflow-y:auto;padding:4px 0}.app-select-options::-webkit-scrollbar{width:6px}.app-select-options::-webkit-scrollbar-track{background:transparent}.app-select-options::-webkit-scrollbar-thumb{background:#d0d5dd;border-radius:3px}.app-select-no-options{padding:32px 24px;text-align:center;color:#667085;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:14px;line-height:20px;letter-spacing:0}.app-select-option{width:100%;padding:10px 14px;display:flex;align-items:center;gap:8px;background:transparent;border:none;text-align:left;cursor:pointer;transition:background .15s ease}.app-select-option:hover,.app-select-option.selected{background:#f9fafb}.app-select-option-text-wrapper{flex:1;display:flex;align-items:center;gap:8px;overflow:hidden}.app-select-option-text{font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:16px;line-height:24px;letter-spacing:0;font-weight:400;font-style:normal;color:#344054;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.app-select-option-text.app-select-option-truncate{max-width:200px}.app-select-option-check{margin-left:auto;flex-shrink:0}.app-select-checkbox{display:flex;align-items:center;flex-shrink:0;margin-right:8px}.app-select-checkbox .checkbox-wrapper{margin-bottom:0}.app-select-checkbox .checkbox-content{display:none}.app-select-checkbox .checkbox-input{margin-right:0}.app-select-supporting{margin-top:6px;color:#667085}.app-select-supporting .error-text{color:#f04438}.app-select-container.size-sm .app-select-input{min-height:36px;padding:8px 12px}.app-select-container.size-sm .app-select-option{padding:8px 12px}.app-select-container.error .app-select-input{border-color:#fda29b}.app-select-container.error .app-select-supporting{color:#f04438}.app-select-container.destructive .app-select-input{border-color:#fda29b}.app-select-container.destructive .app-select-input:focus,.app-select-container.destructive .app-select-input.focused{box-shadow:0 1px 2px #1018280d,0 0 0 4px #fee4e2}.app-select-container.disabled .app-select-label,.app-select-container.disabled .app-select-value,.app-select-container.disabled .app-select-secondary,.app-select-container.disabled .app-select-search-field{color:#667085}.app-select-container.disabled .app-select-arrow,.app-select-container.disabled .app-select-leading zen-icon,.app-select-container.disabled .app-select-search-input zen-icon,.app-select-container.disabled .app-select-dot{opacity:.6}.app-select-container.disabled .app-select-input,.app-select-container.disabled .app-select-search-input{background:#f9fafb;cursor:not-allowed}.app-select-hint{display:flex;align-items:center;gap:4px;margin-top:6px;color:#667085}.app-select-hint .hint-icon{font-size:16px;color:#f04438}.app-select-hint.destructive{color:#f04438}.app-select-option.select-all{border-bottom:1px solid #F2F4F7;margin-bottom:4px;padding-bottom:14px}.app-select-option.add-new-option{color:#136ab6;font-weight:500}.app-select-option.add-new-option:hover{background:#eff8ff}.app-select-option.remove-option{background:#f9fafb;color:#344054}.app-select-option.remove-option .app-select-option-text{color:#344054}.app-select-spinner{display:flex;justify-content:center;padding:16px}.app-select-spinner .spinner-small{width:20px;height:20px;border:2px solid #F2F4F7;border-top-color:#136ab6;border-radius:50%;animation:spin .6s linear infinite}.app-select-load-more{padding:8px 14px}.app-select-load-more .app-select-load-more-btn{width:100%;padding:8px 16px;background:#fff;border:1px solid #D0D5DD;border-radius:6px;color:#344054;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:14px;line-height:20px;letter-spacing:0;font-weight:500;font-style:normal;cursor:pointer;transition:all .15s ease}.app-select-load-more .app-select-load-more-btn:hover{background:#f9fafb;border-color:#667085}@keyframes spin{to{transform:rotate(360deg)}}.app-select-dropdown ::ng-deep zen-groups .zen-groups-inline{display:flex;flex-direction:column;max-height:310px}.app-select-dropdown ::ng-deep zen-groups .zen-groups-tree{flex:1;overflow-y:auto;padding:4px 14px}.app-select-dropdown ::ng-deep zen-groups .zen-groups-tree::-webkit-scrollbar{width:6px}.app-select-dropdown ::ng-deep zen-groups .zen-groups-tree::-webkit-scrollbar-track{background:transparent}.app-select-dropdown ::ng-deep zen-groups .zen-groups-tree::-webkit-scrollbar-thumb{background:#d0d5dd;border-radius:3px}.app-select-dropdown ::ng-deep zen-groups .action-item-checkbox{padding:10px 0;font-weight:400;font-size:14px;line-height:20px;color:#344054}.app-select-dropdown ::ng-deep zen-groups .action-item-checkbox:hover{background:#f9fafb}.app-select-dropdown ::ng-deep zen-groups .select-all{border-bottom:none;margin-bottom:0;font-weight:500}.app-select-dropdown ::ng-deep zen-groups .tree-item-badge{background:#f1f7fe;color:#105494}.app-select-dropdown ::ng-deep zen-groups .checkbox-component .app-checkbox-label{font-weight:400;color:#344054}.app-select-dropdown ::ng-deep zen-groups .zen-groups-no-results{padding:32px 0;text-align:center;color:#667085}@media(max-width:640px){.app-select-dropdown{position:fixed;inset:auto 0 0;max-height:70vh;border-radius:16px 16px 0 0}}\n"], dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: ZenduCheckboxComponent, selector: "zen-checkbox", inputs: ["checked", "label", "labelColor", "disabled", "disableValueChange", "indeterminate", "imageUrl", "size", "supportingText"], outputs: ["checkedChange"] }, { kind: "component", type: ZenduGroupsComponent, selector: "zen-groups", inputs: ["dataSource", "filteredDataSource", "hideSelectAll", "isSelectedAll", "inline", "width", "placeholder", "hideSearch", "idProp", "displayProp"], outputs: ["isSelectedAllChange", "checkedChange"] }, { kind: "component", type: ZenduIconComponent, selector: "zen-icon", inputs: ["src", "name", "size", "color", "theme", "customColor"] }, { kind: "component", type: ZenduSpinner, selector: "zen-spinner", inputs: ["size"] }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
|
|
5565
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.0", type: ZenduSelectComponent, isStandalone: false, selector: "zen-select", inputs: { selectModel: "selectModel", options: "options", label: "label", helpIcon: "helpIcon", helpTooltip: "helpTooltip", supportingText: "supportingText", hintText: "hintText", placeholder: "placeholder", leadingType: "leadingType", leadingIcon: "leadingIcon", leadingAvatar: "leadingAvatar", leadingDotColor: "leadingDotColor", displayProp: "displayProp", idProp: "idProp", hasSearch: "hasSearch", isMultiselect: "isMultiselect", multiselect: "multiselect", hideSelectAll: "hideSelectAll", hideTreeSearch: "hideTreeSearch", required: "required", disabled: "disabled", error: "error", errorMessage: "errorMessage", destructive: "destructive", size: "size", returnOption: "returnOption", isTruncate: "isTruncate", enableAddNewOption: "enableAddNewOption", showDefaultAddOption: "showDefaultAddOption", newOptionText: "newOptionText", enableRemoveOption: "enableRemoveOption", removeOptionText: "removeOptionText", isLazyLoading: "isLazyLoading", lazyLoader: "lazyLoader", preferredOpenDirection: "preferredOpenDirection", panelClass: "panelClass", panelMinWidth: "panelMinWidth" }, outputs: { selectModelChange: "selectModelChange", addNewOption: "addNewOption", removeOption: "removeOption", closed: "closed" }, queries: [{ propertyName: "optionTemplate", first: true, predicate: ZenduSelectOptionDirective, descendants: true }, { propertyName: "valueTemplate", first: true, predicate: ZenduSelectValueDirective, descendants: true }, { propertyName: "buttonTemplate", first: true, predicate: ZenduSelectButtonDirective, descendants: true }], viewQueries: [{ propertyName: "selectWrapper", first: true, predicate: ["selectWrapper"], descendants: true }, { propertyName: "dropdownPanel", first: true, predicate: ["dropdownPanel"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div [class]=\"getStateClasses()\">\n <!-- Label -->\n @if (label) {\n <label class=\"app-select-label text text-sm text-weight-medium\"\n [ngClass]=\"{'required': required, 'disabled': disabled, 'destructive': destructive}\">\n {{ label | translate }}\n @if (required) {\n <span class=\"required-indicator\">*</span>\n }\n @if (helpIcon) {\n <span\n class=\"zen-help-icon\"\n role=\"img\"\n [class.disabled]=\"disabled\"\n [attr.tabindex]=\"disabled ? -1 : 0\"\n [attr.aria-label]=\"helpTooltip | translate\"\n (mouseenter)=\"updateHelpTooltipPlacement($event)\"\n (focus)=\"updateHelpTooltipPlacement($event)\">\n <i class=\"material-icons-outlined\">help_outline</i>\n <!-- Shown on hover/focus via CSS \u2014 no click state. -->\n <div\n class=\"zen-help-tooltip\"\n [class.align-start]=\"helpTooltipAlign === 'start'\"\n [class.align-end]=\"helpTooltipAlign === 'end'\"\n [class.place-below]=\"helpTooltipPlacement === 'below'\">\n <div class=\"tooltip-content\">{{ helpTooltip | translate }}</div>\n <div class=\"tooltip-arrow\"></div>\n </div>\n </span>\n }\n </label>\n }\n\n <!-- Select Input -->\n <div class=\"app-select-wrapper\" #selectWrapper>\n <!-- Custom Trigger Template (overrides built-in trigger) -->\n @if (buttonTemplate) {\n <div\n class=\"app-select-custom-trigger\"\n (click)=\"toggleDropdown()\">\n <ng-template [ngTemplateOutlet]=\"buttonTemplate.template\"\n [ngTemplateOutletContext]=\"{ isOpen: isOpen, selected: getSelectedOption(), display: selectedDisplay, disabled: disabled }\">\n </ng-template>\n </div>\n }\n\n <!-- Built-in Trigger (when no custom button template provided) -->\n @if (!buttonTemplate) {\n @switch (leadingType) {\n <!-- Default Select (no leading element) -->\n @case ('default') {\n <ng-container *ngTemplateOutlet=\"defaultSelectTemplate\"></ng-container>\n }\n <!-- Icon Leading Select -->\n @case ('icon') {\n <ng-container *ngTemplateOutlet=\"iconSelectTemplate\"></ng-container>\n }\n <!-- Avatar Leading Select -->\n @case ('avatar') {\n <ng-container *ngTemplateOutlet=\"avatarSelectTemplate\"></ng-container>\n }\n <!-- Dot Leading Select -->\n @case ('dot') {\n <ng-container *ngTemplateOutlet=\"dotSelectTemplate\"></ng-container>\n }\n <!-- Search Input Select -->\n @case ('search') {\n <ng-container *ngTemplateOutlet=\"searchInputTemplate\"></ng-container>\n }\n }\n }\n\n <!-- Dropdown Menu (rendered into a CDK overlay via ZenduOverlayService;\n positioning/flip/clamping is handled there, not with absolute CSS) -->\n <ng-template #dropdownPanel>\n <div class=\"app-select-dropdown\">\n <!-- Tree Mode: embed zen-groups inline -->\n @if (isTreeMode && isMultiselect) {\n <zen-groups [inline]=\"true\"\n [dataSource]=\"$any(options)\"\n [filteredDataSource]=\"treeFilteredDataSource\"\n [hideSelectAll]=\"hideSelectAll\"\n [hideSearch]=\"hideTreeSearch\"\n [idProp]=\"idProp\"\n [displayProp]=\"displayProp\"\n [(isSelectedAll)]=\"isSelectedAll\"\n (isSelectedAllChange)=\"onTreeSelectAllChange($event)\"\n (checkedChange)=\"onTreeCheckedChange($event)\">\n </zen-groups>\n } @else {\n <!-- Search Box for hasSearch (not for search type as it has inline search) -->\n @if (leadingType !== 'search' && hasSearch && !disabled) {\n <div class=\"app-select-search\">\n <zen-icon [name]=\"'search'\"\n [customColor]=\"'#667085'\">\n </zen-icon>\n <input type=\"text\"\n [(ngModel)]=\"searchText\"\n (ngModelChange)=\"onSearchChange()\"\n (keydown.enter)=\"onSearchEnter($event)\"\n placeholder=\"Search\"\n class=\"app-select-search-input\">\n @if (searchText) {\n <zen-icon\n class=\"app-select-search-clear\"\n [name]=\"'x'\"\n [customColor]=\"'#667085'\"\n (click)=\"clearSearch(); $event.stopPropagation()\">\n </zen-icon>\n }\n </div>\n }\n <!-- Options List -->\n <div class=\"app-select-options\" (scroll)=\"onOptionsScroll($event)\">\n <!-- Select All Option for Multiselect -->\n @if (isMultiselect && !hideSelectAll && !isLazyLoading && filteredOptions.length > 0) {\n <button\n class=\"app-select-option select-all\"\n (click)=\"toggleSelectAll()\">\n <zen-checkbox class=\"app-select-checkbox\"\n [checked]=\"isAllSelected()\"\n [disableValueChange]=\"true\"\n [label]=\"''\"\n size=\"sm\">\n </zen-checkbox>\n <span class=\"app-select-option-text\">\n Select All\n </span>\n </button>\n }\n <!-- Add New Option -->\n @if (enableAddNewOption && (showDefaultAddOption || searchText)) {\n <button\n class=\"app-select-option add-new-option\"\n (click)=\"handleAddNewOption(); $event.stopPropagation()\">\n <zen-icon [name]=\"'plus'\" [customColor]=\"'#136AB6'\"></zen-icon>\n <span class=\"app-select-option-text\">\n {{ (newOptionText || 'Add New Option') + (searchText ? ': \"' + searchText + '\"' : '') }}\n </span>\n </button>\n }\n <!-- Remove Option -->\n @if (enableRemoveOption) {\n <button\n class=\"app-select-option remove-option\"\n (click)=\"handleRemoveOption(); $event.stopPropagation()\">\n <zen-icon [name]=\"'user-x'\" [customColor]=\"'#344054'\"></zen-icon>\n <span class=\"app-select-option-text\">\n {{ removeOptionText || 'Remove' }}\n </span>\n </button>\n }\n @if (filteredOptions.length === 0 && !enableAddNewOption && !isLoadingNow) {\n <div class=\"app-select-no-options\">\n No matching options found\n </div>\n }\n @for (option of filteredOptions; track option) {\n <button\n class=\"app-select-option\"\n [class.selected]=\"isSelected(option)\"\n (click)=\"selectOption(option)\">\n <!-- Checkbox for Multiselect -->\n @if (isMultiselect) {\n <zen-checkbox class=\"app-select-checkbox\"\n [checked]=\"isSelected(option)\"\n [disableValueChange]=\"true\"\n [label]=\"''\"\n size=\"sm\">\n </zen-checkbox>\n }\n <!-- Option Leading Element -->\n @if (leadingType !== 'default') {\n <div class=\"app-select-option-leading\">\n @switch (leadingType) {\n @case ('icon') {\n <ng-container *ngTemplateOutlet=\"iconLeadingElement; context: { option: option }\"></ng-container>\n }\n @case ('avatar') {\n <ng-container *ngTemplateOutlet=\"avatarLeadingElement; context: { option: option }\"></ng-container>\n }\n @case ('dot') {\n <ng-container *ngTemplateOutlet=\"dotLeadingElement; context: { option: option }\"></ng-container>\n }\n }\n </div>\n }\n <!-- Option Text -->\n <div class=\"app-select-option-text-wrapper\">\n <!-- Use custom template if provided -->\n @if (!isMultiselect && optionTemplate) {\n <ng-template [ngTemplateOutlet]=\"optionTemplate.template\"\n [ngTemplateOutletContext]=\"{ option: option }\">\n </ng-template>\n } @else {\n <span class=\"app-select-option-text\" [class.app-select-option-truncate]=\"isTruncate\">\n {{ getName(option) | translate }}\n </span>\n @if (option.secondaryText) {\n <span class=\"app-select-option-secondary\">\n {{ option.secondaryText }}\n </span>\n }\n }\n </div>\n <!-- Check Icon for Single Select -->\n @if (!isMultiselect && isSelected(option)) {\n <zen-icon\n class=\"app-select-option-check\"\n [name]=\"'check'\"\n [customColor]=\"'#136AB6'\">\n </zen-icon>\n }\n </button>\n }\n <!-- Lazy loading spinner -->\n @if (isLazyLoading && isLoadingNow) {\n <div class=\"app-select-loading\">\n <zen-spinner size=\"small\"></zen-spinner>\n </div>\n }\n </div>\n }\n <!-- Flat List Mode (default) -->\n </div>\n </ng-template>\n </div>\n\n <!-- Hint text / Error message -->\n @if ((destructive && errorMessage) || hintText) {\n <div\n class=\"app-select-hint text text-sm text-weight-regular\"\n [ngClass]=\"{'destructive': destructive}\">\n @if (destructive) {\n <i class=\"material-icons-outlined hint-icon\">error_outline</i>\n }\n <span>{{ ((destructive && errorMessage) ? errorMessage : hintText) | translate }}</span>\n </div>\n }\n</div>\n\n<!-- ============================================= -->\n<!-- MAIN SELECT INPUT TEMPLATES -->\n<!-- ============================================= -->\n\n<!-- Default Select Template (No Leading Element) -->\n<ng-template #defaultSelectTemplate>\n <button class=\"app-select-input\"\n [disabled]=\"disabled\"\n (click)=\"toggleDropdown()\"\n [class.focused]=\"isOpen\"\n [class.has-value]=\"!isModelEmpty()\">\n\n <ng-container *ngTemplateOutlet=\"selectValueDisplay\"></ng-container>\n <ng-container *ngTemplateOutlet=\"dropdownArrow\"></ng-container>\n </button>\n</ng-template>\n\n<!-- Icon Select Template -->\n<ng-template #iconSelectTemplate>\n <button class=\"app-select-input\"\n [disabled]=\"disabled\"\n (click)=\"toggleDropdown()\"\n [class.focused]=\"isOpen\"\n [class.has-value]=\"!isModelEmpty()\">\n\n <div class=\"app-select-leading\">\n <ng-container *ngTemplateOutlet=\"iconLeadingElement; context: { option: getSelectedOption(), icon: leadingIcon }\"></ng-container>\n </div>\n\n <ng-container *ngTemplateOutlet=\"selectValueDisplay\"></ng-container>\n <ng-container *ngTemplateOutlet=\"dropdownArrow\"></ng-container>\n </button>\n</ng-template>\n\n<!-- Avatar Select Template -->\n<ng-template #avatarSelectTemplate>\n <button class=\"app-select-input\"\n [disabled]=\"disabled\"\n (click)=\"toggleDropdown()\"\n [class.focused]=\"isOpen\"\n [class.has-value]=\"!isModelEmpty()\">\n\n <div class=\"app-select-leading\">\n <ng-container *ngTemplateOutlet=\"avatarLeadingElement; context: { option: getSelectedOption(), avatar: leadingAvatar }\"></ng-container>\n </div>\n\n <ng-container *ngTemplateOutlet=\"selectValueDisplay\"></ng-container>\n <ng-container *ngTemplateOutlet=\"dropdownArrow\"></ng-container>\n </button>\n</ng-template>\n\n<!-- Dot Select Template -->\n<ng-template #dotSelectTemplate>\n <button class=\"app-select-input\"\n [disabled]=\"disabled\"\n (click)=\"toggleDropdown()\"\n [class.focused]=\"isOpen\"\n [class.has-value]=\"!isModelEmpty()\">\n\n <div class=\"app-select-leading\">\n <ng-container *ngTemplateOutlet=\"dotLeadingElement; context: { option: getSelectedOption(), color: leadingDotColor }\"></ng-container>\n </div>\n\n <ng-container *ngTemplateOutlet=\"selectValueDisplay\"></ng-container>\n <ng-container *ngTemplateOutlet=\"dropdownArrow\"></ng-container>\n </button>\n</ng-template>\n\n<!-- Search Input Template -->\n<ng-template #searchInputTemplate>\n <div class=\"app-select-input app-select-search-input\"\n [class.focused]=\"isOpen || searchFocused\"\n [class.has-value]=\"!isModelEmpty()\">\n\n <!-- Search Icon -->\n <zen-icon [name]=\"'search'\"\n [customColor]=\"disabled ? '#9CA3AF' : '#667085'\">\n </zen-icon>\n\n <!-- Search Input Field -->\n <input type=\"text\"\n class=\"app-select-search-field\"\n [(ngModel)]=\"searchInputValue\"\n (ngModelChange)=\"onSearchInputChange()\"\n (keydown.enter)=\"onSearchEnter($event)\"\n (focus)=\"onSearchFocus()\"\n (blur)=\"onSearchBlur($event)\"\n [placeholder]=\"selectedDisplay || placeholder\"\n [disabled]=\"disabled\">\n </div>\n</ng-template>\n\n<!-- ============================================= -->\n<!-- SHARED COMPONENT TEMPLATES -->\n<!-- ============================================= -->\n\n<!-- Select Value Display -->\n<ng-template #selectValueDisplay>\n <div class=\"app-select-value-wrapper\">\n @if (valueTemplate && !isModelEmpty()) {\n <ng-template [ngTemplateOutlet]=\"valueTemplate.template\"\n [ngTemplateOutletContext]=\"{ option: getSelectedOption(), display: selectedDisplay }\">\n </ng-template>\n } @else {\n <span class=\"app-select-value\" [class.placeholder]=\"isModelEmpty()\">\n {{ selectedDisplay || placeholder | translate }}\n </span>\n @if (getSelectedSecondaryText() && !isModelEmpty()) {\n <span class=\"app-select-secondary\">\n {{ getSelectedSecondaryText() }}\n </span>\n }\n }\n </div>\n</ng-template>\n\n<!-- Dropdown Arrow -->\n<ng-template #dropdownArrow>\n <zen-icon class=\"app-select-arrow\"\n [class.rotated]=\"isOpen\"\n [name]=\"'chevron-down'\"\n [customColor]=\"'#667085'\">\n </zen-icon>\n</ng-template>\n\n<!-- ============================================= -->\n<!-- LEADING ELEMENT TEMPLATES -->\n<!-- ============================================= -->\n\n<!-- Icon Leading Element (with smart resolution) -->\n<ng-template #iconLeadingElement let-option=\"option\" let-icon=\"icon\">\n @if (icon || option?.icon || option?.iconName) {\n @if (getIconPath(option, icon); as iconPath) {\n <!-- If icon contains / or . treat as SVG path -->\n @if ((icon && (icon.includes('/') || icon.includes('.'))) ||\n (option?.icon && (option.icon.includes('/') || option.icon.includes('.'))) ||\n (option?.iconName && (option.iconName.includes('/') || option.iconName.includes('.')))) {\n <!-- Use img tag for Excel to preserve colors -->\n @if (iconPath.includes('excel')) {\n <img\n [src]=\"iconPath\"\n alt=\"\"\n style=\"width: 20px; height: 20px;\">\n }\n <!-- Use zen-icon with src for other SVG files -->\n @if (!iconPath.includes('excel')) {\n <zen-icon\n [src]=\"iconPath\"\n [customColor]=\"'#667085'\">\n </zen-icon>\n }\n }\n <!-- Otherwise treat as Material icon name or special cases -->\n @if (!((icon && (icon.includes('/') || icon.includes('.'))) ||\n (option?.icon && (option.icon.includes('/') || option.icon.includes('.'))) ||\n (option?.iconName && (option.iconName.includes('/') || option.iconName.includes('.'))))) {\n <!-- Special case for Excel icon - use img to preserve colors -->\n @if ((icon === 'excel') || (option?.icon === 'excel') || (option?.iconName === 'excel')) {\n <img\n src=\"assets/ng-zenduit/icons/excel.svg\"\n alt=\"Excel\"\n style=\"width: 20px; height: 20px;\">\n }\n <!-- Material icon names -->\n @if ((icon !== 'excel') && (option?.icon !== 'excel') && (option?.iconName !== 'excel')) {\n <zen-icon\n [name]=\"icon || option?.icon || option?.iconName\"\n [customColor]=\"'#667085'\">\n </zen-icon>\n }\n }\n }\n }\n</ng-template>\n\n<!-- Avatar Leading Element -->\n<ng-template #avatarLeadingElement let-option=\"option\" let-avatar=\"avatar\">\n @if (avatar || option?.avatar) {\n <div class=\"app-select-avatar\" >\n <img [src]=\"avatar || option?.avatar\" alt=\"\">\n </div>\n }\n</ng-template>\n\n<!-- Dot Leading Element -->\n<ng-template #dotLeadingElement let-option=\"option\" let-color=\"color\">\n <div class=\"app-select-dot\"\n [style.background-color]=\"color || option?.dotColor || '#10B981'\">\n </div>\n</ng-template>", styles: [".text{margin:0;padding:0;color:#101828}.text-display-2xl{font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:72px;line-height:90px;letter-spacing:-.02em}.text-display-xl{font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:60px;line-height:72px;letter-spacing:-.02em}.text-display-lg{font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:48px;line-height:60px;letter-spacing:-.02em}.text-display-md{font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:36px;line-height:44px;letter-spacing:-.02em}.text-display-sm{font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:30px;line-height:38px;letter-spacing:0}.text-display-xs{font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:24px;line-height:32px;letter-spacing:0}.text-xl{font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:20px;line-height:30px;letter-spacing:0}.text-lg{font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:18px;line-height:28px;letter-spacing:0}.text-md{font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:16px;line-height:24px;letter-spacing:0}.text-sm{font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:14px;line-height:20px;letter-spacing:0}.text-xs{font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:12px;line-height:18px;letter-spacing:0}.text-weight-regular{font-weight:400;font-style:normal}.text-weight-medium{font-weight:500;font-style:normal}.text-weight-semibold{font-weight:600;font-style:normal}.text-weight-bold{font-weight:700;font-style:normal}@media(max-width:768px){.text-display-2xl{font-size:48px;line-height:56px}.text-display-xl{font-size:40px;line-height:48px}.text-display-lg{font-size:32px;line-height:40px}}.app-select-container{width:100%;position:relative}.app-select-label{display:flex;align-items:center;gap:8px;margin-bottom:6px;color:#344054}.app-select-label .required-indicator{color:#f04438}.app-select-label.disabled{color:#d0d5dd}.app-select-label .zen-help-icon{position:relative;display:inline-flex;align-items:center;justify-content:center;width:20px;height:20px;cursor:help;outline:none}.app-select-label .zen-help-icon i{font-size:20px;color:#98a2b3}.app-select-label .zen-help-icon:not(.disabled):hover i,.app-select-label .zen-help-icon:not(.disabled):focus-visible i{color:#475467}.app-select-label .zen-help-icon.disabled{cursor:not-allowed}.app-select-label .zen-help-icon.disabled i{color:#d0d5dd}.app-select-label .zen-help-icon:not(.disabled):hover .zen-help-tooltip,.app-select-label .zen-help-icon:not(.disabled):focus-visible .zen-help-tooltip{display:block}.app-select-label .zen-help-icon .zen-help-tooltip{display:none;position:absolute;bottom:calc(100% + 8px);right:50%;transform:translate(50%);z-index:1000;white-space:nowrap}.app-select-label .zen-help-icon .zen-help-tooltip.align-start{left:-6px;right:auto;transform:none}.app-select-label .zen-help-icon .zen-help-tooltip.align-start .tooltip-arrow{left:8px;right:auto;transform:none}.app-select-label .zen-help-icon .zen-help-tooltip.align-end{left:auto;right:-6px;transform:none}.app-select-label .zen-help-icon .zen-help-tooltip.align-end .tooltip-arrow{left:auto;right:8px;transform:none}.app-select-label .zen-help-icon .zen-help-tooltip.place-below{top:calc(100% + 8px);bottom:auto}.app-select-label .zen-help-icon .zen-help-tooltip.place-below .tooltip-arrow{top:-6px;bottom:auto;border-top:none;border-bottom:6px solid #101828}.app-select-label .zen-help-icon .zen-help-tooltip .tooltip-content{background:#101828;color:#fff;padding:6px 10px;border-radius:6px;font-family:Inter,sans-serif;font-size:12px;line-height:16px;box-shadow:0 12px 16px #10182814,0 4px 6px #10182808;width:max-content;max-width:260px;white-space:normal;text-align:left}.app-select-label .zen-help-icon .zen-help-tooltip .tooltip-arrow{position:absolute;bottom:-6px;left:50%;transform:translate(-50%);width:0;height:0;border-left:6px solid transparent;border-right:6px solid transparent;border-top:6px solid #101828}.app-select-wrapper{position:relative;width:100%}.app-select-custom-trigger{display:inline-flex;cursor:pointer;-webkit-user-select:none;user-select:none}.app-select-input{width:100%;min-height:44px;padding:10px 14px;box-sizing:border-box;display:flex;align-items:center;gap:8px;background:#fff;border:1px solid #D0D5DD;border-radius:8px;box-shadow:0 1px 2px #1018280d;color:#101828;text-align:left;cursor:pointer;transition:all .2s ease}.app-select-input.app-select-search-input{cursor:text}.app-select-input.app-select-search-input .app-select-search-field{font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:16px;line-height:24px;letter-spacing:0;font-weight:400;font-style:normal;flex:1;border:none;outline:none;background:transparent;color:#101828;min-width:0}.app-select-input.app-select-search-input .app-select-search-field::placeholder{color:#667085}.app-select-input.app-select-search-input .app-select-search-field:disabled{cursor:not-allowed;color:#667085}.app-select-input:hover:not(:disabled){border-color:#98a2b3}.app-select-input.focused,.app-select-input:focus{outline:none;border-color:#88c1f1;box-shadow:0 1px 2px #1018280d,0 0 0 4px #e3eefb}.app-select-input:disabled{background:#f9fafb;border-color:#d0d5dd;cursor:not-allowed}.app-select-container.error .app-select-input:hover:not(:disabled){border-color:#f97066}.app-select-container.error .app-select-input:focus{box-shadow:0 1px 2px #1018280d,0 0 0 4px #fee4e2}.app-select-leading,.app-select-option-leading{display:flex;align-items:center;flex-shrink:0}.app-select-avatar,.app-select-option-avatar{width:24px;height:24px;border-radius:50%;overflow:hidden;flex-shrink:0}.app-select-avatar img,.app-select-option-avatar img{width:100%;height:100%;object-fit:cover}.app-select-avatar .avatar-placeholder,.app-select-option-avatar .avatar-placeholder{width:100%;height:100%;background:#f2f4f7;color:#667085;display:flex;align-items:center;justify-content:center;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:12px;line-height:18px;letter-spacing:0;font-weight:600;font-style:normal}.app-select-dot,.app-select-option-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0}.app-select-value-wrapper{flex:1;display:flex;align-items:center;gap:8px;overflow:hidden}.app-select-value-wrapper .app-select-secondary{font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:16px;line-height:24px;letter-spacing:0;font-weight:400;font-style:normal;color:#667085}.app-select-value{font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:16px;line-height:24px;letter-spacing:0;font-weight:400;font-style:normal;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.app-select-value.placeholder{color:#667085}.app-select-secondary,.app-select-option-secondary{font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:16px;line-height:24px;letter-spacing:0;font-weight:400;font-style:normal;color:#667085;white-space:nowrap;flex-shrink:0}.app-select-arrow{margin-left:auto;flex-shrink:0;transition:transform .2s ease}.app-select-arrow.rotated{transform:rotate(180deg)}.app-select-dropdown{width:100%;background:#fff;border:1px solid #EAECF0;border-radius:8px;box-shadow:0 4px 6px -2px #10182808,0 12px 16px -4px #10182814;overflow:hidden;max-height:320px;display:flex;flex-direction:column}.app-select-search{padding:12px;border-bottom:1px solid #EAECF0;display:flex;align-items:center;gap:8px}.app-select-search zen-icon{flex-shrink:0;width:20px;height:20px}.app-select-search .app-select-search-input{font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:16px;line-height:24px;letter-spacing:0;font-weight:400;font-style:normal;flex:1;border:none;outline:none;color:#101828}.app-select-search .app-select-search-input::placeholder{color:#667085}.app-select-search .app-select-search-clear{cursor:pointer}.app-select-loading{display:flex;justify-content:center;align-items:center;padding:8px 0}.app-select-options{flex:1;min-height:0;overflow-y:auto;padding:4px 0}.app-select-options::-webkit-scrollbar{width:6px}.app-select-options::-webkit-scrollbar-track{background:transparent}.app-select-options::-webkit-scrollbar-thumb{background:#d0d5dd;border-radius:3px}.app-select-no-options{padding:32px 24px;text-align:center;color:#667085;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:14px;line-height:20px;letter-spacing:0}.app-select-option{width:100%;padding:10px 14px;display:flex;align-items:center;gap:8px;background:transparent;border:none;text-align:left;cursor:pointer;transition:background .15s ease}.app-select-option:hover,.app-select-option.selected{background:#f9fafb}.app-select-option-text-wrapper{flex:1;display:flex;align-items:center;gap:8px;overflow:hidden}.app-select-option-text{font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:16px;line-height:24px;letter-spacing:0;font-weight:400;font-style:normal;color:#344054;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.app-select-option-text.app-select-option-truncate{max-width:200px}.app-select-option-check{margin-left:auto;flex-shrink:0}.app-select-checkbox{display:flex;align-items:center;flex-shrink:0;margin-right:8px}.app-select-checkbox .checkbox-wrapper{margin-bottom:0}.app-select-checkbox .checkbox-content{display:none}.app-select-checkbox .checkbox-input{margin-right:0}.app-select-supporting{margin-top:6px;color:#667085}.app-select-supporting .error-text{color:#f04438}.app-select-container.size-sm .app-select-input{min-height:36px;padding:8px 12px}.app-select-container.size-sm .app-select-option{padding:8px 12px}.app-select-container.error .app-select-input{border-color:#fda29b}.app-select-container.error .app-select-supporting{color:#f04438}.app-select-container.destructive .app-select-input{border-color:#fda29b}.app-select-container.destructive .app-select-input:focus,.app-select-container.destructive .app-select-input.focused{box-shadow:0 1px 2px #1018280d,0 0 0 4px #fee4e2}.app-select-container.disabled .app-select-label,.app-select-container.disabled .app-select-value,.app-select-container.disabled .app-select-secondary,.app-select-container.disabled .app-select-search-field{color:#667085}.app-select-container.disabled .app-select-arrow,.app-select-container.disabled .app-select-leading zen-icon,.app-select-container.disabled .app-select-search-input zen-icon,.app-select-container.disabled .app-select-dot{opacity:.6}.app-select-container.disabled .app-select-input,.app-select-container.disabled .app-select-search-input{background:#f9fafb;cursor:not-allowed}.app-select-hint{display:flex;align-items:center;gap:4px;margin-top:6px;color:#667085}.app-select-hint .hint-icon{font-size:16px;color:#f04438}.app-select-hint.destructive{color:#f04438}.app-select-option.select-all{border-bottom:1px solid #F2F4F7;margin-bottom:4px;padding-bottom:14px}.app-select-option.add-new-option{color:#136ab6;font-weight:500}.app-select-option.add-new-option:hover{background:#eff8ff}.app-select-option.remove-option{background:#f9fafb;color:#344054}.app-select-option.remove-option .app-select-option-text{color:#344054}.app-select-spinner{display:flex;justify-content:center;padding:16px}.app-select-spinner .spinner-small{width:20px;height:20px;border:2px solid #F2F4F7;border-top-color:#136ab6;border-radius:50%;animation:spin .6s linear infinite}.app-select-load-more{padding:8px 14px}.app-select-load-more .app-select-load-more-btn{width:100%;padding:8px 16px;background:#fff;border:1px solid #D0D5DD;border-radius:6px;color:#344054;font-family:Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:14px;line-height:20px;letter-spacing:0;font-weight:500;font-style:normal;cursor:pointer;transition:all .15s ease}.app-select-load-more .app-select-load-more-btn:hover{background:#f9fafb;border-color:#667085}@keyframes spin{to{transform:rotate(360deg)}}.app-select-dropdown ::ng-deep zen-groups .zen-groups-inline{display:flex;flex-direction:column;max-height:310px}.app-select-dropdown ::ng-deep zen-groups .zen-groups-tree{flex:1;overflow-y:auto;padding:4px 14px}.app-select-dropdown ::ng-deep zen-groups .zen-groups-tree::-webkit-scrollbar{width:6px}.app-select-dropdown ::ng-deep zen-groups .zen-groups-tree::-webkit-scrollbar-track{background:transparent}.app-select-dropdown ::ng-deep zen-groups .zen-groups-tree::-webkit-scrollbar-thumb{background:#d0d5dd;border-radius:3px}.app-select-dropdown ::ng-deep zen-groups .action-item-checkbox{padding:10px 0;font-weight:400;font-size:14px;line-height:20px;color:#344054}.app-select-dropdown ::ng-deep zen-groups .action-item-checkbox:hover{background:#f9fafb}.app-select-dropdown ::ng-deep zen-groups .select-all{border-bottom:none;margin-bottom:0;font-weight:500}.app-select-dropdown ::ng-deep zen-groups .tree-item-badge{background:#f1f7fe;color:#105494}.app-select-dropdown ::ng-deep zen-groups .checkbox-component .app-checkbox-label{font-weight:400;color:#344054}.app-select-dropdown ::ng-deep zen-groups .zen-groups-no-results{padding:32px 0;text-align:center;color:#667085}@media(max-width:640px){.app-select-dropdown{position:fixed;inset:auto 0 0;max-height:70vh;border-radius:16px 16px 0 0}}\n"], dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: ZenduCheckboxComponent, selector: "zen-checkbox", inputs: ["checked", "label", "labelColor", "disabled", "disableValueChange", "indeterminate", "imageUrl", "size", "supportingText"], outputs: ["checkedChange"] }, { kind: "component", type: ZenduGroupsComponent, selector: "zen-groups", inputs: ["dataSource", "filteredDataSource", "hideSelectAll", "isSelectedAll", "inline", "width", "placeholder", "hideSearch", "idProp", "displayProp"], outputs: ["isSelectedAllChange", "checkedChange"] }, { kind: "component", type: ZenduIconComponent, selector: "zen-icon", inputs: ["src", "name", "size", "color", "theme", "customColor"] }, { kind: "component", type: ZenduSpinner, selector: "zen-spinner", inputs: ["size"] }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
|
|
5468
5566
|
}
|
|
5469
5567
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: ZenduSelectComponent, decorators: [{
|
|
5470
5568
|
type: Component,
|
|
@@ -5543,6 +5641,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImpor
|
|
|
5543
5641
|
type: Input
|
|
5544
5642
|
}], preferredOpenDirection: [{
|
|
5545
5643
|
type: Input
|
|
5644
|
+
}], panelClass: [{
|
|
5645
|
+
type: Input
|
|
5646
|
+
}], panelMinWidth: [{
|
|
5647
|
+
type: Input
|
|
5546
5648
|
}], removeOption: [{
|
|
5547
5649
|
type: Output
|
|
5548
5650
|
}], closed: [{
|
|
@@ -5634,7 +5736,7 @@ class ZenduPaginationBarComponent {
|
|
|
5634
5736
|
return result;
|
|
5635
5737
|
}
|
|
5636
5738
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: ZenduPaginationBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
5637
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.0", type: ZenduPaginationBarComponent, isStandalone: false, selector: "zen-pagination-bar", inputs: { page: "page", perPage: "perPage", count: "count", perPageOptions: "perPageOptions" }, outputs: { pageChange: "pageChange", perPageChange: "perPageChange" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"pagination-component\">\n <p class=\"results-text\">\n {{ \"Showing\" | translate }} {{ rangeStart }} - {{ rangeEnd }}\n {{ \"of\" | translate }} {{ count }} {{ \"results\" | translate }}\n </p>\n\n <div class=\"page-navigation\">\n <zen-button\n buttonType=\"button-icon-only\"\n variant=\"tertiary-gray\"\n size=\"md\"\n icon=\"chevron-left\"\n [disabled]=\"page <= 1\"\n (click)=\"goToPage(page - 1)\">\n </zen-button>\n\n <div class=\"pages\">\n @for (item of pages; track item; let i = $index) {\n @if (item.kind === 'page') {\n <button\n type=\"button\"\n class=\"page-btn\"\n [class.is-active]=\"item.active\"\n (click)=\"goToPage(item.page)\">\n {{ item.page }}\n </button>\n }\n @if (item.kind === 'ellipsis') {\n <span class=\"page-ellipsis\">\u2026</span>\n }\n }\n </div>\n\n <zen-button\n buttonType=\"button-icon-only\"\n variant=\"tertiary-gray\"\n size=\"md\"\n icon=\"chevron-right\"\n [disabled]=\"page >= totalPages\"\n (click)=\"goToPage(page + 1)\">\n </zen-button>\n </div>\n\n <div class=\"rows-per-page\">\n <span class=\"rows-label\">{{ \"Rows per page\" | translate }}</span>\n <zen-select\n size=\"sm\"\n [options]=\"perPageOptions\"\n [(selectModel)]=\"perPage\"\n (selectModelChange)=\"onPerPageChange($event)\"\n preferredOpenDirection=\"up\">\n </zen-select>\n </div>\n</div>\n", styles: [".pagination-component{display:grid;grid-template-columns:1fr auto 1fr;align-items:center;border-top:1px solid #EAECF0;padding:11px 24px 16px;font-family:Inter,sans-serif}.pagination-component .results-text{justify-self:start;margin:0;font-size:14px;line-height:20px;color:#667085;white-space:nowrap}.pagination-component .page-navigation{justify-self:center;display:flex;flex-direction:row;align-items:center;gap:8px}.pagination-component .rows-per-page{justify-self:end;display:flex;flex-direction:row;align-items:center;gap:8px}.pagination-component .rows-per-page .rows-label{font-size:14px;font-weight:500;line-height:20px;color:#344054;white-space:nowrap}.pagination-component .rows-per-page zen-select{min-width:80px}.pagination-component .pages{display:flex;flex-direction:row;align-items:center;gap:2px}.pagination-component .page-btn,.pagination-component .page-ellipsis{display:inline-flex;align-items:center;justify-content:center;width:40px;height:40px;border-radius:8px;font-weight:500;font-size:14px;line-height:20px;color:#667085;background:transparent;border:0;padding:0;box-sizing:border-box}.pagination-component .page-btn{cursor:pointer;transition:background-color .1s,color .1s}.pagination-component .page-btn:hover:not(.is-active){background:#f9fafb}.pagination-component .page-btn.is-active{background:#f1f7fe;color:#136ab6;cursor:default}.pagination-component .page-ellipsis{cursor:default}\n"], dependencies: [{ kind: "component", type: ZenduSelectComponent, selector: "zen-select", inputs: ["selectModel", "options", "label", "helpIcon", "helpTooltip", "supportingText", "hintText", "placeholder", "leadingType", "leadingIcon", "leadingAvatar", "leadingDotColor", "displayProp", "idProp", "hasSearch", "isMultiselect", "multiselect", "hideSelectAll", "hideTreeSearch", "required", "disabled", "error", "errorMessage", "destructive", "size", "returnOption", "isTruncate", "enableAddNewOption", "showDefaultAddOption", "newOptionText", "enableRemoveOption", "removeOptionText", "isLazyLoading", "lazyLoader", "preferredOpenDirection"], outputs: ["selectModelChange", "addNewOption", "removeOption", "closed"] }, { kind: "component", type: ZenButtonComponent, selector: "zen-button", inputs: ["variant", "buttonType", "icon", "iconRotated", "size", "destructive", "disabled", "fullWidth", "type"] }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
|
|
5739
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.0", type: ZenduPaginationBarComponent, isStandalone: false, selector: "zen-pagination-bar", inputs: { page: "page", perPage: "perPage", count: "count", perPageOptions: "perPageOptions" }, outputs: { pageChange: "pageChange", perPageChange: "perPageChange" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"pagination-component\">\n <p class=\"results-text\">\n {{ \"Showing\" | translate }} {{ rangeStart }} - {{ rangeEnd }}\n {{ \"of\" | translate }} {{ count }} {{ \"results\" | translate }}\n </p>\n\n <div class=\"page-navigation\">\n <zen-button\n buttonType=\"button-icon-only\"\n variant=\"tertiary-gray\"\n size=\"md\"\n icon=\"chevron-left\"\n [disabled]=\"page <= 1\"\n (click)=\"goToPage(page - 1)\">\n </zen-button>\n\n <div class=\"pages\">\n @for (item of pages; track item; let i = $index) {\n @if (item.kind === 'page') {\n <button\n type=\"button\"\n class=\"page-btn\"\n [class.is-active]=\"item.active\"\n (click)=\"goToPage(item.page)\">\n {{ item.page }}\n </button>\n }\n @if (item.kind === 'ellipsis') {\n <span class=\"page-ellipsis\">\u2026</span>\n }\n }\n </div>\n\n <zen-button\n buttonType=\"button-icon-only\"\n variant=\"tertiary-gray\"\n size=\"md\"\n icon=\"chevron-right\"\n [disabled]=\"page >= totalPages\"\n (click)=\"goToPage(page + 1)\">\n </zen-button>\n </div>\n\n <div class=\"rows-per-page\">\n <span class=\"rows-label\">{{ \"Rows per page\" | translate }}</span>\n <zen-select\n size=\"sm\"\n [options]=\"perPageOptions\"\n [(selectModel)]=\"perPage\"\n (selectModelChange)=\"onPerPageChange($event)\"\n preferredOpenDirection=\"up\">\n </zen-select>\n </div>\n</div>\n", styles: [".pagination-component{display:grid;grid-template-columns:1fr auto 1fr;align-items:center;border-top:1px solid #EAECF0;padding:11px 24px 16px;font-family:Inter,sans-serif}.pagination-component .results-text{justify-self:start;margin:0;font-size:14px;line-height:20px;color:#667085;white-space:nowrap}.pagination-component .page-navigation{justify-self:center;display:flex;flex-direction:row;align-items:center;gap:8px}.pagination-component .rows-per-page{justify-self:end;display:flex;flex-direction:row;align-items:center;gap:8px}.pagination-component .rows-per-page .rows-label{font-size:14px;font-weight:500;line-height:20px;color:#344054;white-space:nowrap}.pagination-component .rows-per-page zen-select{min-width:80px}.pagination-component .pages{display:flex;flex-direction:row;align-items:center;gap:2px}.pagination-component .page-btn,.pagination-component .page-ellipsis{display:inline-flex;align-items:center;justify-content:center;width:40px;height:40px;border-radius:8px;font-weight:500;font-size:14px;line-height:20px;color:#667085;background:transparent;border:0;padding:0;box-sizing:border-box}.pagination-component .page-btn{cursor:pointer;transition:background-color .1s,color .1s}.pagination-component .page-btn:hover:not(.is-active){background:#f9fafb}.pagination-component .page-btn.is-active{background:#f1f7fe;color:#136ab6;cursor:default}.pagination-component .page-ellipsis{cursor:default}\n"], dependencies: [{ kind: "component", type: ZenduSelectComponent, selector: "zen-select", inputs: ["selectModel", "options", "label", "helpIcon", "helpTooltip", "supportingText", "hintText", "placeholder", "leadingType", "leadingIcon", "leadingAvatar", "leadingDotColor", "displayProp", "idProp", "hasSearch", "isMultiselect", "multiselect", "hideSelectAll", "hideTreeSearch", "required", "disabled", "error", "errorMessage", "destructive", "size", "returnOption", "isTruncate", "enableAddNewOption", "showDefaultAddOption", "newOptionText", "enableRemoveOption", "removeOptionText", "isLazyLoading", "lazyLoader", "preferredOpenDirection", "panelClass", "panelMinWidth"], outputs: ["selectModelChange", "addNewOption", "removeOption", "closed"] }, { kind: "component", type: ZenButtonComponent, selector: "zen-button", inputs: ["variant", "buttonType", "icon", "iconRotated", "size", "destructive", "disabled", "fullWidth", "type"] }, { kind: "pipe", type: i2.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
|
|
5638
5740
|
}
|
|
5639
5741
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: ZenduPaginationBarComponent, decorators: [{
|
|
5640
5742
|
type: Component,
|