UNPKG

ng-zorro-antd

Version:

An enterprise-class UI components based on Ant Design and Angular

1,030 lines (1,028 loc) 123 kB
import { __decorate } from "tslib"; import { BACKSPACE, DOWN_ARROW, ENTER, ESCAPE, LEFT_ARROW, RIGHT_ARROW, UP_ARROW } from '@angular/cdk/keycodes'; import { CdkConnectedOverlay, OverlayModule } from '@angular/cdk/overlay'; import { _getEventTarget } from '@angular/cdk/platform'; import { NgClass, NgStyle, NgTemplateOutlet } from '@angular/common'; import { ChangeDetectionStrategy, Component, EventEmitter, HostListener, Input, Output, ViewChild, ViewChildren, ViewEncapsulation, booleanAttribute, forwardRef, inject, numberAttribute } from '@angular/core'; import { FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms'; import { BehaviorSubject, EMPTY, Observable, fromEvent, of as observableOf } from 'rxjs'; import { distinctUntilChanged, map, startWith, switchMap, takeUntil, withLatestFrom } from 'rxjs/operators'; import { slideMotion } from 'ng-zorro-antd/core/animation'; import { WithConfig } from 'ng-zorro-antd/core/config'; import { NzFormNoStatusService, NzFormPatchModule, NzFormStatusService } from 'ng-zorro-antd/core/form'; import { NzNoAnimationDirective } from 'ng-zorro-antd/core/no-animation'; import { DEFAULT_CASCADER_POSITIONS, NzOverlayModule } from 'ng-zorro-antd/core/overlay'; import { NzDestroyService } from 'ng-zorro-antd/core/services'; import { getStatusClassNames, toArray } from 'ng-zorro-antd/core/util'; import { NzEmptyModule } from 'ng-zorro-antd/empty'; import { NzIconModule } from 'ng-zorro-antd/icon'; import { NzCascaderOptionComponent } from './cascader-li.component'; import { NzCascaderService } from './cascader.service'; import * as i0 from "@angular/core"; import * as i1 from "./cascader.service"; import * as i2 from "ng-zorro-antd/core/config"; import * as i3 from "ng-zorro-antd/i18n"; import * as i4 from "ng-zorro-antd/core/services"; import * as i5 from "@angular/cdk/bidi"; import * as i6 from "@angular/cdk/overlay"; import * as i7 from "@angular/forms"; import * as i8 from "ng-zorro-antd/icon"; import * as i9 from "ng-zorro-antd/core/form"; import * as i10 from "ng-zorro-antd/core/overlay"; import * as i11 from "ng-zorro-antd/empty"; const NZ_CONFIG_MODULE_NAME = 'cascader'; const defaultDisplayRender = (labels) => labels.join(' / '); export class NzCascaderComponent { set input(input) { this.input$.next(input); } get input() { return this.input$.getValue(); } get nzOptions() { return this.cascaderService.nzOptions; } set nzOptions(options) { this.cascaderService.withOptions(options); } get inSearchingMode() { return this.cascaderService.inSearchingMode; } set inputValue(inputValue) { this.inputString = inputValue; this.toggleSearchingMode(!!inputValue); } get inputValue() { return this.inputString; } get menuCls() { return { [`${this.nzMenuClassName}`]: !!this.nzMenuClassName }; } get menuColumnCls() { return { [`${this.nzColumnClassName}`]: !!this.nzColumnClassName }; } get hasInput() { return !!this.inputValue; } get hasValue() { return this.cascaderService.values && this.cascaderService.values.length > 0; } get showLabelRender() { return this.hasValue; } get showPlaceholder() { return !(this.hasInput || this.hasValue); } get clearIconVisible() { return this.nzAllowClear && !this.nzDisabled && (this.hasValue || this.hasInput); } get isLabelRenderTemplate() { return !!this.nzLabelRender; } constructor(cascaderService, nzConfigService, ngZone, cdr, i18nService, destroy$, elementRef, renderer, directionality) { this.cascaderService = cascaderService; this.nzConfigService = nzConfigService; this.ngZone = ngZone; this.cdr = cdr; this.i18nService = i18nService; this.destroy$ = destroy$; this.elementRef = elementRef; this.renderer = renderer; this.directionality = directionality; this._nzModuleName = NZ_CONFIG_MODULE_NAME; /** Used to store the native `<input type="search" />` element since it might be set asynchronously. */ this.input$ = new BehaviorSubject(undefined); this.nzOptionRender = null; this.nzShowInput = true; this.nzShowArrow = true; this.nzAllowClear = true; this.nzAutoFocus = false; this.nzChangeOnSelect = false; this.nzDisabled = false; this.nzExpandTrigger = 'click'; this.nzValueProperty = 'value'; this.nzLabelRender = null; this.nzLabelProperty = 'label'; this.nzSize = 'default'; this.nzBackdrop = false; this.nzShowSearch = false; this.nzPlaceHolder = ''; this.nzMenuStyle = null; this.nzMouseEnterDelay = 150; // ms this.nzMouseLeaveDelay = 150; // ms this.nzStatus = ''; this.nzTriggerAction = ['click']; // TODO: RTL this.nzSuffixIcon = 'down'; this.nzExpandIcon = ''; this.nzVisibleChange = new EventEmitter(); this.nzSelectionChange = new EventEmitter(); this.nzSelect = new EventEmitter(); this.nzClear = new EventEmitter(); this.prefixCls = 'ant-select'; this.statusCls = {}; this.status = ''; this.hasFeedback = false; /** * If the dropdown should show the empty content. * `true` if there's no options. */ this.shouldShowEmpty = false; this.menuVisible = false; this.isLoading = false; this.labelRenderContext = {}; this.onChange = Function.prototype; this.onTouched = Function.prototype; this.positions = [...DEFAULT_CASCADER_POSITIONS]; this.dropdownHeightStyle = ''; this.isFocused = false; this.dir = 'ltr'; this.isComposing = false; this.inputString = ''; this.isOpening = false; this.isNzDisableFirstChange = true; this.noAnimation = inject(NzNoAnimationDirective, { host: true, optional: true }); this.nzFormStatusService = inject(NzFormStatusService, { optional: true }); this.nzFormNoStatusService = inject(NzFormNoStatusService, { optional: true }); this.el = elementRef.nativeElement; this.cascaderService.withComponent(this); this.renderer.addClass(this.elementRef.nativeElement, 'ant-select'); this.renderer.addClass(this.elementRef.nativeElement, 'ant-cascader'); } ngOnInit() { this.nzFormStatusService?.formStatusChanges .pipe(distinctUntilChanged((pre, cur) => { return pre.status === cur.status && pre.hasFeedback === cur.hasFeedback; }), withLatestFrom(this.nzFormNoStatusService ? this.nzFormNoStatusService.noFormStatus : observableOf(false)), map(([{ status, hasFeedback }, noStatus]) => ({ status: noStatus ? '' : status, hasFeedback })), takeUntil(this.destroy$)) .subscribe(({ status, hasFeedback }) => { this.setStatusStyles(status, hasFeedback); }); const srv = this.cascaderService; srv.$redraw.pipe(takeUntil(this.destroy$)).subscribe(() => { // These operations would not mutate data. this.checkChildren(); this.setDisplayLabel(); this.cdr.detectChanges(); this.reposition(); this.setDropdownStyles(); }); srv.$loading.pipe(takeUntil(this.destroy$)).subscribe(loading => { this.isLoading = loading; }); srv.$optionSelected.pipe(takeUntil(this.destroy$)).subscribe(data => { if (!data) { this.onChange([]); this.nzSelect.emit(null); this.nzSelectionChange.emit([]); } else { const { option, index } = data; const shouldClose = option.isLeaf || (this.nzChangeOnSelect && this.nzExpandTrigger === 'hover'); if (shouldClose) { this.delaySetMenuVisible(false); } this.onChange(this.cascaderService.values); this.nzSelectionChange.emit(this.cascaderService.selectedOptions); this.nzSelect.emit({ option, index }); this.cdr.markForCheck(); } }); srv.$quitSearching.pipe(takeUntil(this.destroy$)).subscribe(() => { this.inputString = ''; this.dropdownWidthStyle = ''; }); this.i18nService.localeChange.pipe(startWith(), takeUntil(this.destroy$)).subscribe(() => { this.setLocale(); }); this.nzConfigService .getConfigChangeEventForComponent(NZ_CONFIG_MODULE_NAME) .pipe(takeUntil(this.destroy$)) .subscribe(() => { this.cdr.markForCheck(); }); this.dir = this.directionality.value; this.directionality.change.pipe(takeUntil(this.destroy$)).subscribe(() => { this.dir = this.directionality.value; srv.$redraw.next(); }); this.setupChangeListener(); this.setupKeydownListener(); } ngOnChanges(changes) { const { nzStatus } = changes; if (nzStatus) { this.setStatusStyles(this.nzStatus, this.hasFeedback); } } ngOnDestroy() { this.clearDelayMenuTimer(); this.clearDelaySelectTimer(); } registerOnChange(fn) { this.onChange = fn; } registerOnTouched(fn) { this.onTouched = fn; } writeValue(value) { this.cascaderService.values = toArray(value); this.cascaderService.syncOptions(true); } delaySetMenuVisible(visible, delay = 100, setOpening = false) { this.clearDelayMenuTimer(); if (delay) { if (visible && setOpening) { this.isOpening = true; } this.delayMenuTimer = setTimeout(() => { this.setMenuVisible(visible); this.cdr.detectChanges(); this.clearDelayMenuTimer(); if (visible) { setTimeout(() => { this.isOpening = false; }, 100); } }, delay); } else { this.setMenuVisible(visible); } } setMenuVisible(visible) { if (this.nzDisabled || this.menuVisible === visible) { return; } if (visible) { this.cascaderService.syncOptions(); this.scrollToActivatedOptions(); } if (!visible) { this.inputValue = ''; } this.menuVisible = visible; this.nzVisibleChange.emit(visible); this.cdr.detectChanges(); } clearDelayMenuTimer() { if (this.delayMenuTimer) { clearTimeout(this.delayMenuTimer); this.delayMenuTimer = undefined; } } clearSelection(event) { if (event) { event.preventDefault(); event.stopPropagation(); } this.labelRenderText = ''; this.labelRenderContext = {}; this.inputValue = ''; this.setMenuVisible(false); this.cascaderService.clear(); this.nzClear.emit(); } getSubmitValue() { return this.cascaderService.selectedOptions.map(o => this.cascaderService.getOptionValue(o)); } focus() { if (!this.isFocused) { (this.input?.nativeElement || this.el).focus(); this.isFocused = true; } } blur() { if (this.isFocused) { (this.input?.nativeElement || this.el).blur(); this.isFocused = false; } } handleInputBlur() { this.menuVisible ? this.focus() : this.blur(); } handleInputFocus() { this.focus(); } handleInputCompositionstart() { this.isComposing = true; } handleInputCompositionend() { this.isComposing = false; } onTriggerClick() { if (this.nzDisabled) { return; } if (this.nzShowSearch) { this.focus(); } if (this.isActionTrigger('click')) { this.delaySetMenuVisible(!this.menuVisible, 100); } this.onTouched(); } onTriggerMouseEnter() { if (this.nzDisabled || !this.isActionTrigger('hover')) { return; } this.delaySetMenuVisible(true, this.nzMouseEnterDelay, true); } onTriggerMouseLeave(event) { if (this.nzDisabled || !this.menuVisible || this.isOpening || !this.isActionTrigger('hover')) { event.preventDefault(); return; } const mouseTarget = event.relatedTarget; const hostEl = this.el; const menuEl = this.menu && this.menu.nativeElement; if (hostEl.contains(mouseTarget) || (menuEl && menuEl.contains(mouseTarget))) { return; } this.delaySetMenuVisible(false, this.nzMouseLeaveDelay); } onOptionMouseEnter(option, columnIndex, event) { event.preventDefault(); if (this.nzExpandTrigger === 'hover') { if (!option.isLeaf) { this.delaySetOptionActivated(option, columnIndex, false); } else { this.cascaderService.setOptionDeactivatedSinceColumn(columnIndex); } } } onOptionMouseLeave(option, _columnIndex, event) { event.preventDefault(); if (this.nzExpandTrigger === 'hover' && !option.isLeaf) { this.clearDelaySelectTimer(); } } onOptionClick(option, columnIndex, event) { if (event) { event.preventDefault(); } if (option && option.disabled) { return; } this.el.focus(); this.inSearchingMode ? this.cascaderService.setSearchOptionSelected(option) : this.cascaderService.setOptionActivated(option, columnIndex, true); } onClickOutside(event) { const target = _getEventTarget(event); if (!this.el.contains(target)) { this.closeMenu(); } } isActionTrigger(action) { return typeof this.nzTriggerAction === 'string' ? this.nzTriggerAction === action : this.nzTriggerAction.indexOf(action) !== -1; } onEnter() { const columnIndex = Math.max(this.cascaderService.activatedOptions.length - 1, 0); const option = this.cascaderService.activatedOptions[columnIndex]; if (option && !option.disabled) { this.inSearchingMode ? this.cascaderService.setSearchOptionSelected(option) : this.cascaderService.setOptionActivated(option, columnIndex, true); } } moveUpOrDown(isUp) { const columnIndex = Math.max(this.cascaderService.activatedOptions.length - 1, 0); const activeOption = this.cascaderService.activatedOptions[columnIndex]; const options = this.cascaderService.columns[columnIndex] || []; const length = options.length; let nextIndex = -1; if (!activeOption) { // Not selected options in this column nextIndex = isUp ? length : -1; } else { nextIndex = options.indexOf(activeOption); } while (true) { nextIndex = isUp ? nextIndex - 1 : nextIndex + 1; if (nextIndex < 0 || nextIndex >= length) { break; } const nextOption = options[nextIndex]; if (!nextOption || nextOption.disabled) { continue; } this.cascaderService.setOptionActivated(nextOption, columnIndex); break; } } moveLeft() { const options = this.cascaderService.activatedOptions; if (options.length) { options.pop(); // Remove the last one } } moveRight() { const length = this.cascaderService.activatedOptions.length; const options = this.cascaderService.columns[length]; if (options && options.length) { const nextOpt = options.find(o => !o.disabled); if (nextOpt) { this.cascaderService.setOptionActivated(nextOpt, length); } } } clearDelaySelectTimer() { if (this.delaySelectTimer) { clearTimeout(this.delaySelectTimer); this.delaySelectTimer = undefined; } } delaySetOptionActivated(option, columnIndex, performSelect) { this.clearDelaySelectTimer(); this.delaySelectTimer = setTimeout(() => { this.cascaderService.setOptionActivated(option, columnIndex, performSelect); this.delaySelectTimer = undefined; }, 150); } toggleSearchingMode(toSearching) { if (this.inSearchingMode !== toSearching) { this.cascaderService.toggleSearchingMode(toSearching); } if (this.inSearchingMode) { this.cascaderService.prepareSearchOptions(this.inputValue); } } isOptionActivated(option, index) { const activeOpt = this.cascaderService.activatedOptions[index]; return activeOpt === option; } setDisabledState(isDisabled) { this.nzDisabled = (this.isNzDisableFirstChange && this.nzDisabled) || isDisabled; this.isNzDisableFirstChange = false; if (this.nzDisabled) { this.closeMenu(); } } closeMenu() { this.blur(); this.clearDelayMenuTimer(); this.setMenuVisible(false); } /** * Reposition the cascader panel. When a menu opens, the cascader expands * and may exceed the boundary of browser's window. */ reposition() { if (this.overlay && this.overlay.overlayRef && this.menuVisible) { Promise.resolve().then(() => { this.overlay.overlayRef.updatePosition(); this.cdr.markForCheck(); }); } } /** * When a cascader options is changed, a child needs to know that it should re-render. */ checkChildren() { if (this.cascaderItems) { this.cascaderItems.forEach(item => item.markForCheck()); } } setDisplayLabel() { const selectedOptions = this.cascaderService.selectedOptions; const labels = selectedOptions.map(o => this.cascaderService.getOptionLabel(o)); if (this.isLabelRenderTemplate) { this.labelRenderContext = { labels, selectedOptions }; } this.labelRenderText = defaultDisplayRender.call(this, labels); } setDropdownStyles() { const firstColumn = this.cascaderService.columns[0]; this.shouldShowEmpty = (this.inSearchingMode && (!firstColumn || !firstColumn.length)) || // Should show empty when there's no searching result (!(this.nzOptions && this.nzOptions.length) && !this.nzLoadData); // Should show when there's no options and developer does not use nzLoadData this.dropdownHeightStyle = this.shouldShowEmpty ? 'auto' : ''; if (this.input) { this.dropdownWidthStyle = this.inSearchingMode || this.shouldShowEmpty ? `${this.selectContainer.nativeElement.offsetWidth}px` : ''; } } setStatusStyles(status, hasFeedback) { // set inner status this.status = status; this.hasFeedback = hasFeedback; this.cdr.markForCheck(); // render status if nzStatus is set this.statusCls = getStatusClassNames(this.prefixCls, status, hasFeedback); Object.keys(this.statusCls).forEach(status => { if (this.statusCls[status]) { this.renderer.addClass(this.elementRef.nativeElement, status); } else { this.renderer.removeClass(this.elementRef.nativeElement, status); } }); } setLocale() { this.locale = this.i18nService.getLocaleData('global'); this.cdr.markForCheck(); } scrollToActivatedOptions() { // The `scrollIntoView` is a native DOM API, which doesn't require Angular to run // a change detection when a promise microtask is resolved. this.ngZone.runOutsideAngular(() => { Promise.resolve().then(() => { // scroll only until option menu view is ready this.cascaderItems .toArray() .filter(e => e.activated) .forEach(e => { e.nativeElement.scrollIntoView({ block: 'start', inline: 'nearest' }); }); }); }); } setupChangeListener() { this.input$ .pipe(switchMap(input => input ? new Observable(subscriber => this.ngZone.runOutsideAngular(() => fromEvent(input.nativeElement, 'change').subscribe(subscriber))) : EMPTY), takeUntil(this.destroy$)) .subscribe(event => event.stopPropagation()); } setupKeydownListener() { this.ngZone.runOutsideAngular(() => { fromEvent(this.el, 'keydown') .pipe(takeUntil(this.destroy$)) .subscribe(event => { const keyCode = event.keyCode; if (keyCode !== DOWN_ARROW && keyCode !== UP_ARROW && keyCode !== LEFT_ARROW && keyCode !== RIGHT_ARROW && keyCode !== ENTER && keyCode !== BACKSPACE && keyCode !== ESCAPE) { return; } // Press any keys above to reopen menu. if (!this.menuVisible && keyCode !== BACKSPACE && keyCode !== ESCAPE) { // The `setMenuVisible` runs `detectChanges()`, so we don't need to run `markForCheck()` additionally. return this.ngZone.run(() => this.setMenuVisible(true)); } // Make these keys work as default in searching mode. if (this.inSearchingMode && (keyCode === BACKSPACE || keyCode === LEFT_ARROW || keyCode === RIGHT_ARROW)) { return; } if (!this.menuVisible) { return; } event.preventDefault(); this.ngZone.run(() => { // Interact with the component. if (keyCode === DOWN_ARROW) { this.moveUpOrDown(false); } else if (keyCode === UP_ARROW) { this.moveUpOrDown(true); } else if (keyCode === LEFT_ARROW) { this.moveLeft(); } else if (keyCode === RIGHT_ARROW) { this.moveRight(); } else if (keyCode === ENTER) { this.onEnter(); } // `@HostListener`s run `markForCheck()` internally before calling the actual handler so // we call `markForCheck()` to be backwards-compatible. this.cdr.markForCheck(); }); }); }); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.2", ngImport: i0, type: NzCascaderComponent, deps: [{ token: i1.NzCascaderService }, { token: i2.NzConfigService }, { token: i0.NgZone }, { token: i0.ChangeDetectorRef }, { token: i3.NzI18nService }, { token: i4.NzDestroyService }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i5.Directionality }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.1.2", type: NzCascaderComponent, isStandalone: true, selector: "nz-cascader, [nz-cascader]", inputs: { nzOptionRender: "nzOptionRender", nzShowInput: ["nzShowInput", "nzShowInput", booleanAttribute], nzShowArrow: ["nzShowArrow", "nzShowArrow", booleanAttribute], nzAllowClear: ["nzAllowClear", "nzAllowClear", booleanAttribute], nzAutoFocus: ["nzAutoFocus", "nzAutoFocus", booleanAttribute], nzChangeOnSelect: ["nzChangeOnSelect", "nzChangeOnSelect", booleanAttribute], nzDisabled: ["nzDisabled", "nzDisabled", booleanAttribute], nzColumnClassName: "nzColumnClassName", nzExpandTrigger: "nzExpandTrigger", nzValueProperty: "nzValueProperty", nzLabelRender: "nzLabelRender", nzLabelProperty: "nzLabelProperty", nzNotFoundContent: "nzNotFoundContent", nzSize: "nzSize", nzBackdrop: "nzBackdrop", nzShowSearch: "nzShowSearch", nzPlaceHolder: "nzPlaceHolder", nzMenuClassName: "nzMenuClassName", nzMenuStyle: "nzMenuStyle", nzMouseEnterDelay: ["nzMouseEnterDelay", "nzMouseEnterDelay", numberAttribute], nzMouseLeaveDelay: ["nzMouseLeaveDelay", "nzMouseLeaveDelay", numberAttribute], nzStatus: "nzStatus", nzTriggerAction: "nzTriggerAction", nzChangeOn: "nzChangeOn", nzLoadData: "nzLoadData", nzSuffixIcon: "nzSuffixIcon", nzExpandIcon: "nzExpandIcon", nzOptions: "nzOptions" }, outputs: { nzVisibleChange: "nzVisibleChange", nzSelectionChange: "nzSelectionChange", nzSelect: "nzSelect", nzClear: "nzClear" }, host: { listeners: { "click": "onTriggerClick()", "mouseenter": "onTriggerMouseEnter()", "mouseleave": "onTriggerMouseLeave($event)" }, properties: { "attr.tabIndex": "\"0\"", "class.ant-select-in-form-item": "!!nzFormStatusService", "class.ant-select-lg": "nzSize === \"large\"", "class.ant-select-sm": "nzSize === \"small\"", "class.ant-select-allow-clear": "nzAllowClear", "class.ant-select-show-arrow": "nzShowArrow", "class.ant-select-show-search": "!!nzShowSearch", "class.ant-select-disabled": "nzDisabled", "class.ant-select-open": "menuVisible", "class.ant-select-focused": "isFocused", "class.ant-select-single": "true", "class.ant-select-rtl": "dir === 'rtl'" } }, providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => NzCascaderComponent), multi: true }, NzCascaderService, NzDestroyService ], viewQueries: [{ propertyName: "selectContainer", first: true, predicate: ["selectContainer"], descendants: true }, { propertyName: "input", first: true, predicate: ["input"], descendants: true }, { propertyName: "menu", first: true, predicate: ["menu"], descendants: true }, { propertyName: "overlay", first: true, predicate: CdkConnectedOverlay, descendants: true }, { propertyName: "cascaderItems", predicate: NzCascaderOptionComponent, descendants: true }], exportAs: ["nzCascader"], usesOnChanges: true, ngImport: i0, template: ` <div cdkOverlayOrigin #origin="cdkOverlayOrigin" #trigger> @if (nzShowInput) { <div #selectContainer class="ant-select-selector"> <span class="ant-select-selection-search"> <input #input type="search" class="ant-select-selection-search-input" [style.opacity]="nzShowSearch ? '' : '0'" [attr.autoComplete]="'off'" [attr.expanded]="menuVisible" [attr.autofocus]="nzAutoFocus ? 'autofocus' : null" [readonly]="!nzShowSearch" [disabled]="nzDisabled" [(ngModel)]="inputValue" (blur)="handleInputBlur()" (focus)="handleInputFocus()" (compositionstart)="handleInputCompositionstart()" (compositionend)="handleInputCompositionend()" /> </span> @if (showLabelRender) { <span class="ant-select-selection-item" [title]="labelRenderText"> @if (!isLabelRenderTemplate) { <ng-container>{{ labelRenderText }}</ng-container> } @else { <ng-template [ngTemplateOutlet]="nzLabelRender" [ngTemplateOutletContext]="labelRenderContext" ></ng-template> } </span> } @else { <span class="ant-select-selection-placeholder" [style.visibility]="isComposing || inputValue ? 'hidden' : 'visible'" >{{ showPlaceholder ? nzPlaceHolder || locale?.placeholder : null }}</span > } </div> @if (nzShowArrow) { <span class="ant-select-arrow" [class.ant-select-arrow-loading]="isLoading"> @if (!isLoading) { <span nz-icon [nzType]="$any(nzSuffixIcon)" [class.ant-cascader-picker-arrow-expand]="menuVisible"></span> } @else { <span nz-icon nzType="loading"></span> } @if (hasFeedback && !!status) { <nz-form-item-feedback-icon [status]="status" /> } </span> } @if (clearIconVisible) { <span class="ant-select-clear"> <span nz-icon nzType="close-circle" nzTheme="fill" (click)="clearSelection($event)"></span> </span> } } <ng-content></ng-content> </div> <ng-template cdkConnectedOverlay nzConnectedOverlay [cdkConnectedOverlayHasBackdrop]="nzBackdrop" [cdkConnectedOverlayOrigin]="origin" [cdkConnectedOverlayPositions]="positions" [cdkConnectedOverlayTransformOriginOn]="'.ant-cascader-dropdown'" [cdkConnectedOverlayOpen]="menuVisible" (overlayOutsideClick)="onClickOutside($event)" (detach)="closeMenu()" > <div class="ant-select-dropdown ant-cascader-dropdown ant-select-dropdown-placement-bottomLeft" [class.ant-cascader-dropdown-rtl]="dir === 'rtl'" [@slideMotion]="'enter'" [@.disabled]="!!noAnimation?.nzNoAnimation" [nzNoAnimation]="noAnimation?.nzNoAnimation" (mouseenter)="onTriggerMouseEnter()" (mouseleave)="onTriggerMouseLeave($event)" > <div #menu class="ant-cascader-menus" [class.ant-cascader-rtl]="dir === 'rtl'" [class.ant-cascader-menus-hidden]="!menuVisible" [class.ant-cascader-menu-empty]="shouldShowEmpty" [ngClass]="menuCls" [ngStyle]="nzMenuStyle" > @if (shouldShowEmpty) { <ul class="ant-cascader-menu" [style.width]="dropdownWidthStyle" [style.height]="dropdownHeightStyle"> <li class="ant-cascader-menu-item ant-cascader-menu-item-disabled"> <nz-embed-empty class="ant-cascader-menu-item-content" [nzComponentName]="'cascader'" [specificContent]="nzNotFoundContent" /> </li> </ul> } @else { @for (options of cascaderService.columns; track options; let i = $index) { <ul class="ant-cascader-menu" role="menuitemcheckbox" [ngClass]="menuColumnCls" [style.height]="dropdownHeightStyle" [style.width]="dropdownWidthStyle" > @for (option of options; track option.value) { <li nz-cascader-option [expandIcon]="nzExpandIcon" [columnIndex]="i" [nzLabelProperty]="nzLabelProperty" [optionTemplate]="nzOptionRender" [activated]="isOptionActivated(option, i)" [highlightText]="inSearchingMode ? inputValue : ''" [option]="option" [dir]="dir" (mouseenter)="onOptionMouseEnter(option, i, $event)" (mouseleave)="onOptionMouseLeave(option, i, $event)" (click)="onOptionClick(option, i, $event)" ></li> } </ul> } } </div> </div> </ng-template> `, isInline: true, dependencies: [{ kind: "ngmodule", type: OverlayModule }, { kind: "directive", type: i6.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: i6.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "directive", type: i5.Dir, selector: "[dir]", inputs: ["dir"], outputs: ["dirChange"], exportAs: ["dir"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i7.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: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i7.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: NzIconModule }, { kind: "directive", type: i8.NzIconDirective, selector: "[nz-icon]", inputs: ["nzSpin", "nzRotate", "nzType", "nzTheme", "nzTwotoneColor", "nzIconfont"], exportAs: ["nzIcon"] }, { kind: "ngmodule", type: NzFormPatchModule }, { kind: "component", type: i9.NzFormItemFeedbackIconComponent, selector: "nz-form-item-feedback-icon", inputs: ["status"], exportAs: ["nzFormFeedbackIcon"] }, { kind: "ngmodule", type: NzOverlayModule }, { kind: "directive", type: i10.NzConnectedOverlayDirective, selector: "[cdkConnectedOverlay][nzConnectedOverlay]", inputs: ["nzArrowPointAtCenter"], exportAs: ["nzConnectedOverlay"] }, { kind: "directive", type: NzNoAnimationDirective, selector: "[nzNoAnimation]", inputs: ["nzNoAnimation"], exportAs: ["nzNoAnimation"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: NzEmptyModule }, { kind: "component", type: i11.NzEmbedEmptyComponent, selector: "nz-embed-empty", inputs: ["nzComponentName", "specificContent"], exportAs: ["nzEmbedEmpty"] }, { kind: "component", type: NzCascaderOptionComponent, selector: "[nz-cascader-option]", inputs: ["optionTemplate", "option", "activated", "highlightText", "nzLabelProperty", "columnIndex", "expandIcon", "dir"], exportAs: ["nzCascaderOption"] }], animations: [slideMotion], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); } } __decorate([ WithConfig() ], NzCascaderComponent.prototype, "nzSize", void 0); __decorate([ WithConfig() ], NzCascaderComponent.prototype, "nzBackdrop", void 0); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.2", ngImport: i0, type: NzCascaderComponent, decorators: [{ type: Component, args: [{ changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, selector: 'nz-cascader, [nz-cascader]', exportAs: 'nzCascader', preserveWhitespaces: false, template: ` <div cdkOverlayOrigin #origin="cdkOverlayOrigin" #trigger> @if (nzShowInput) { <div #selectContainer class="ant-select-selector"> <span class="ant-select-selection-search"> <input #input type="search" class="ant-select-selection-search-input" [style.opacity]="nzShowSearch ? '' : '0'" [attr.autoComplete]="'off'" [attr.expanded]="menuVisible" [attr.autofocus]="nzAutoFocus ? 'autofocus' : null" [readonly]="!nzShowSearch" [disabled]="nzDisabled" [(ngModel)]="inputValue" (blur)="handleInputBlur()" (focus)="handleInputFocus()" (compositionstart)="handleInputCompositionstart()" (compositionend)="handleInputCompositionend()" /> </span> @if (showLabelRender) { <span class="ant-select-selection-item" [title]="labelRenderText"> @if (!isLabelRenderTemplate) { <ng-container>{{ labelRenderText }}</ng-container> } @else { <ng-template [ngTemplateOutlet]="nzLabelRender" [ngTemplateOutletContext]="labelRenderContext" ></ng-template> } </span> } @else { <span class="ant-select-selection-placeholder" [style.visibility]="isComposing || inputValue ? 'hidden' : 'visible'" >{{ showPlaceholder ? nzPlaceHolder || locale?.placeholder : null }}</span > } </div> @if (nzShowArrow) { <span class="ant-select-arrow" [class.ant-select-arrow-loading]="isLoading"> @if (!isLoading) { <span nz-icon [nzType]="$any(nzSuffixIcon)" [class.ant-cascader-picker-arrow-expand]="menuVisible"></span> } @else { <span nz-icon nzType="loading"></span> } @if (hasFeedback && !!status) { <nz-form-item-feedback-icon [status]="status" /> } </span> } @if (clearIconVisible) { <span class="ant-select-clear"> <span nz-icon nzType="close-circle" nzTheme="fill" (click)="clearSelection($event)"></span> </span> } } <ng-content></ng-content> </div> <ng-template cdkConnectedOverlay nzConnectedOverlay [cdkConnectedOverlayHasBackdrop]="nzBackdrop" [cdkConnectedOverlayOrigin]="origin" [cdkConnectedOverlayPositions]="positions" [cdkConnectedOverlayTransformOriginOn]="'.ant-cascader-dropdown'" [cdkConnectedOverlayOpen]="menuVisible" (overlayOutsideClick)="onClickOutside($event)" (detach)="closeMenu()" > <div class="ant-select-dropdown ant-cascader-dropdown ant-select-dropdown-placement-bottomLeft" [class.ant-cascader-dropdown-rtl]="dir === 'rtl'" [@slideMotion]="'enter'" [@.disabled]="!!noAnimation?.nzNoAnimation" [nzNoAnimation]="noAnimation?.nzNoAnimation" (mouseenter)="onTriggerMouseEnter()" (mouseleave)="onTriggerMouseLeave($event)" > <div #menu class="ant-cascader-menus" [class.ant-cascader-rtl]="dir === 'rtl'" [class.ant-cascader-menus-hidden]="!menuVisible" [class.ant-cascader-menu-empty]="shouldShowEmpty" [ngClass]="menuCls" [ngStyle]="nzMenuStyle" > @if (shouldShowEmpty) { <ul class="ant-cascader-menu" [style.width]="dropdownWidthStyle" [style.height]="dropdownHeightStyle"> <li class="ant-cascader-menu-item ant-cascader-menu-item-disabled"> <nz-embed-empty class="ant-cascader-menu-item-content" [nzComponentName]="'cascader'" [specificContent]="nzNotFoundContent" /> </li> </ul> } @else { @for (options of cascaderService.columns; track options; let i = $index) { <ul class="ant-cascader-menu" role="menuitemcheckbox" [ngClass]="menuColumnCls" [style.height]="dropdownHeightStyle" [style.width]="dropdownWidthStyle" > @for (option of options; track option.value) { <li nz-cascader-option [expandIcon]="nzExpandIcon" [columnIndex]="i" [nzLabelProperty]="nzLabelProperty" [optionTemplate]="nzOptionRender" [activated]="isOptionActivated(option, i)" [highlightText]="inSearchingMode ? inputValue : ''" [option]="option" [dir]="dir" (mouseenter)="onOptionMouseEnter(option, i, $event)" (mouseleave)="onOptionMouseLeave(option, i, $event)" (click)="onOptionClick(option, i, $event)" ></li> } </ul> } } </div> </div> </ng-template> `, animations: [slideMotion], providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => NzCascaderComponent), multi: true }, NzCascaderService, NzDestroyService ], host: { '[attr.tabIndex]': '"0"', '[class.ant-select-in-form-item]': '!!nzFormStatusService', '[class.ant-select-lg]': 'nzSize === "large"', '[class.ant-select-sm]': 'nzSize === "small"', '[class.ant-select-allow-clear]': 'nzAllowClear', '[class.ant-select-show-arrow]': 'nzShowArrow', '[class.ant-select-show-search]': '!!nzShowSearch', '[class.ant-select-disabled]': 'nzDisabled', '[class.ant-select-open]': 'menuVisible', '[class.ant-select-focused]': 'isFocused', '[class.ant-select-single]': 'true', '[class.ant-select-rtl]': `dir === 'rtl'` }, imports: [ OverlayModule, FormsModule, NgTemplateOutlet, NzIconModule, NzFormPatchModule, NzOverlayModule, NzNoAnimationDirective, NgClass, NgStyle, NzEmptyModule, NzCascaderOptionComponent ], standalone: true }] }], ctorParameters: () => [{ type: i1.NzCascaderService }, { type: i2.NzConfigService }, { type: i0.NgZone }, { type: i0.ChangeDetectorRef }, { type: i3.NzI18nService }, { type: i4.NzDestroyService }, { type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i5.Directionality }], propDecorators: { selectContainer: [{ type: ViewChild, args: ['selectContainer', { static: false }] }], input: [{ type: ViewChild, args: ['input', { static: false }] }], menu: [{ type: ViewChild, args: ['menu', { static: false }] }], overlay: [{ type: ViewChild, args: [CdkConnectedOverlay, { static: false }] }], cascaderItems: [{ type: ViewChildren, args: [NzCascaderOptionComponent] }], nzOptionRender: [{ type: Input }], nzShowInput: [{ type: Input, args: [{ transform: booleanAttribute }] }], nzShowArrow: [{ type: Input, args: [{ transform: booleanAttribute }] }], nzAllowClear: [{ type: Input, args: [{ transform: booleanAttribute }] }], nzAutoFocus: [{ type: Input, args: [{ transform: booleanAttribute }] }], nzChangeOnSelect: [{ type: Input, args: [{ transform: booleanAttribute }] }], nzDisabled: [{ type: Input, args: [{ transform: booleanAttribute }] }], nzColumnClassName: [{ type: Input }], nzExpandTrigger: [{ type: Input }], nzValueProperty: [{ type: Input }], nzLabelRender: [{ type: Input }], nzLabelProperty: [{ type: Input }], nzNotFoundContent: [{ type: Input }], nzSize: [{ type: Input }], nzBackdrop: [{ type: Input }], nzShowSearch: [{ type: Input }], nzPlaceHolder: [{ type: Input }], nzMenuClassName: [{ type: Input }], nzMenuStyle: [{ type: Input }], nzMouseEnterDelay: [{ type: Input, args: [{ transform: numberAttribute }] }], nzMouseLeaveDelay: [{ type: Input, args: [{ transform: numberAttribute }] }], nzStatus: [{ type: Input }], nzTriggerAction: [{ type: Input }], nzChangeOn: [{ type: Input }], nzLoadData: [{ type: Input }], nzSuffixIcon: [{ type: Input }], nzExpandIcon: [{ type: Input }], nzOptions: [{ type: Input }], nzVisibleChange: [{ type: Output }], nzSelectionChange: [{ type: Output }], nzSelect: [{ type: Output }], nzClear: [{ type: Output }], onTriggerClick: [{ type: HostListener, args: ['click'] }], onTriggerMouseEnter: [{ type: HostListener, args: ['mouseenter'] }], onTriggerMouseLeave: [{ type: HostListener, args: ['mouseleave', ['$event']] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FzY2FkZXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vY29tcG9uZW50cy9jYXNjYWRlci9jYXNjYWRlci5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQU1BLE9BQU8sRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLFdBQVcsRUFBRSxRQUFRLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNoSCxPQUFPLEVBQUUsbUJBQW1CLEVBQTBCLGFBQWEsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ2xHLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUN4RCxPQUFPLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3JFLE9BQU8sRUFDTCx1QkFBdUIsRUFFdkIsU0FBUyxFQUVULFlBQVksRUFDWixZQUFZLEVBQ1osS0FBSyxFQUtMLE1BQU0sRUFLTixTQUFTLEVBQ1QsWUFBWSxFQUNaLGlCQUFpQixFQUNqQixnQkFBZ0IsRUFDaEIsVUFBVSxFQUNWLE1BQU0sRUFDTixlQUFlLEVBQ2hCLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBd0IsV0FBVyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDdEYsT0FBTyxFQUFFLGVBQWUsRUFBRSxLQUFLLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxFQUFFLElBQUksWUFBWSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ3pGLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxHQUFHLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsY0FBYyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFNUcsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQzNELE9BQU8sRUFBZ0MsVUFBVSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDckYsT0FBTyxFQUFFLHFCQUFxQixFQUFFLGlCQUFpQixFQUFFLG1CQUFtQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDeEcsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDekUsT0FBTyxFQUFFLDBCQUEwQixFQUFFLGVBQWUsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ3pGLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBUy9ELE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxPQUFPLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN2RSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFFcEQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBRWxELE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3BFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLG9CQUFvQixDQUFDOzs7Ozs7Ozs7Ozs7O0FBV3ZELE1BQU0scUJBQXFCLEdBQWdCLFVBQVUsQ0FBQztBQUN0RCxNQUFNLG9CQUFvQixHQUFHLENBQUMsTUFBZ0IsRUFBVSxFQUFFLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztBQW9MOUUsTUFBTSxPQUFPLG1CQUFtQjtJQU85QixJQUNJLEtBQUssQ0FBQyxLQUErQztRQUN2RCxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUMxQixDQUFDO0lBQ0QsSUFBSSxLQUFLO1FBQ1AsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUFDO0lBQ2hDLENBQUM7SUFzQ0QsSUFDSSxTQUFTO1FBQ1gsT0FBTyxJQUFJLENBQUMsZUFBZSxDQUFDLFNBQVMsQ0FBQztJQUN4QyxDQUFDO0lBRUQsSUFBSSxTQUFTLENBQUMsT0FBa0M7UUFDOUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDNUMsQ0FBQztJQTZDRCxJQUFJLGVBQWU7UUFDakIsT0FBTyxJQUFJLENBQUMsZUFBZSxDQUFDLGVBQWUsQ0FBQztJQUM5QyxDQUFDO0lBRUQsSUFBSSxVQUFVLENBQUMsVUFBa0I7U