UNPKG

ng-zorro-antd

Version:

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

1 lines 80 kB
{"version":3,"file":"ng-zorro-antd-cascader.mjs","sources":["../../components/cascader/typings.ts","../../components/cascader/utils.ts","../../components/cascader/cascader-li.component.ts","../../components/cascader/cascader.service.ts","../../components/cascader/cascader.component.ts","../../components/cascader/cascader.module.ts","../../components/cascader/public-api.ts","../../components/cascader/ng-zorro-antd-cascader.ts"],"sourcesContent":["/**\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE\n */\n\nimport { NzSafeAny } from 'ng-zorro-antd/core/types';\n\nexport type NzCascaderExpandTrigger = 'click' | 'hover';\nexport type NzCascaderTriggerType = 'click' | 'hover';\nexport type NzCascaderSize = 'small' | 'large' | 'default';\n\nexport type NzCascaderFilter = (searchValue: string, path: NzCascaderOption[]) => boolean;\nexport type NzCascaderSorter = (a: NzCascaderOption[], b: NzCascaderOption[], inputValue: string) => number;\n\nexport interface NzCascaderOption {\n value?: NzSafeAny;\n label?: string;\n title?: string;\n disabled?: boolean;\n loading?: boolean;\n isLeaf?: boolean;\n parent?: NzCascaderOption;\n children?: NzCascaderOption[];\n\n [key: string]: NzSafeAny;\n}\n\nexport interface NzCascaderSearchOption extends NzCascaderOption {\n path: NzCascaderOption[];\n}\n\nexport interface NzShowSearchOptions {\n filter?: NzCascaderFilter;\n sorter?: NzCascaderSorter;\n}\n\nexport function isShowSearchObject(options: NzShowSearchOptions | boolean): options is NzShowSearchOptions {\n return typeof options !== 'boolean';\n}\n\n/**\n * To avoid circular dependency, provide an interface of `NzCascaderComponent`\n * for `NzCascaderService`.\n */\nexport interface NzCascaderComponentAsSource {\n inputValue: string;\n nzShowSearch: NzShowSearchOptions | boolean;\n nzLabelProperty: string;\n nzValueProperty: string;\n nzChangeOnSelect: boolean;\n\n nzChangeOn?(option: NzCascaderOption, level: number): boolean;\n\n nzLoadData?(node: NzCascaderOption, index: number): PromiseLike<NzSafeAny>;\n}\n","/**\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE\n */\n\nimport { NzCascaderOption } from './typings';\n\nexport function isChildOption(o: NzCascaderOption): boolean {\n return o.isLeaf || !o.children || !o.children.length;\n}\n\nexport function isParentOption(o: NzCascaderOption): boolean {\n return !!o.children && !!o.children.length && !o.isLeaf;\n}\n","/**\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE\n */\n\nimport { Direction } from '@angular/cdk/bidi';\nimport {\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n ElementRef,\n Input,\n OnInit,\n Renderer2,\n TemplateRef,\n ViewEncapsulation\n} from '@angular/core';\n\nimport { NzCascaderOption } from './typings';\n\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n selector: '[nz-cascader-option]',\n exportAs: 'nzCascaderOption',\n template: `\n <ng-container *ngIf=\"optionTemplate; else defaultOptionTemplate\">\n <ng-template\n [ngTemplateOutlet]=\"optionTemplate\"\n [ngTemplateOutletContext]=\"{ $implicit: option, index: columnIndex }\"\n ></ng-template>\n </ng-container>\n <ng-template #defaultOptionTemplate>\n <div\n class=\"ant-cascader-menu-item-content\"\n [innerHTML]=\"optionLabel | nzHighlight: highlightText:'g':'ant-cascader-menu-item-keyword'\"\n ></div>\n </ng-template>\n <div *ngIf=\"!option.isLeaf || option.children?.length || option.loading\" class=\"ant-cascader-menu-item-expand-icon\">\n <i *ngIf=\"option.loading; else icon\" nz-icon nzType=\"loading\"></i>\n <ng-template #icon>\n <ng-container *nzStringTemplateOutlet=\"expandIcon\">\n <i nz-icon [nzType]=\"$any(expandIcon)\"></i>\n </ng-container>\n </ng-template>\n </div>\n `,\n host: {\n '[attr.title]': 'option.title || optionLabel',\n '[class.ant-cascader-menu-item-active]': 'activated',\n '[class.ant-cascader-menu-item-expand]': '!option.isLeaf',\n '[class.ant-cascader-menu-item-disabled]': 'option.disabled'\n }\n})\nexport class NzCascaderOptionComponent implements OnInit {\n @Input() optionTemplate: TemplateRef<NzCascaderOption> | null = null;\n @Input() option!: NzCascaderOption;\n @Input() activated = false;\n @Input() highlightText!: string;\n @Input() nzLabelProperty = 'label';\n @Input() columnIndex!: number;\n @Input() expandIcon: string | TemplateRef<void> = '';\n @Input() dir: Direction = 'ltr';\n\n readonly nativeElement: HTMLElement;\n\n constructor(private cdr: ChangeDetectorRef, elementRef: ElementRef, renderer: Renderer2) {\n renderer.addClass(elementRef.nativeElement, 'ant-cascader-menu-item');\n renderer.addClass(elementRef.nativeElement, 'ant-cascader-menu-item-expanded');\n this.nativeElement = elementRef.nativeElement;\n }\n ngOnInit(): void {\n if (this.expandIcon === '' && this.dir === 'rtl') {\n this.expandIcon = 'left';\n } else if (this.expandIcon === '') {\n this.expandIcon = 'right';\n }\n }\n\n get optionLabel(): string {\n return this.option[this.nzLabelProperty];\n }\n\n markForCheck(): void {\n this.cdr.markForCheck();\n }\n}\n","/**\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE\n */\n\nimport { Injectable, OnDestroy } from '@angular/core';\nimport { BehaviorSubject, Subject } from 'rxjs';\n\nimport { NzSafeAny } from 'ng-zorro-antd/core/types';\nimport { arraysEqual, isNotNil } from 'ng-zorro-antd/core/util';\n\nimport {\n isShowSearchObject,\n NzCascaderComponentAsSource,\n NzCascaderFilter,\n NzCascaderOption,\n NzCascaderSearchOption\n} from './typings';\nimport { isChildOption, isParentOption } from './utils';\n\n/**\n * All data is stored and parsed in NzCascaderService.\n */\n@Injectable()\nexport class NzCascaderService implements OnDestroy {\n /** Activated options in each column. */\n activatedOptions: NzCascaderOption[] = [];\n\n /** An array to store cascader items arranged in different layers. */\n columns: NzCascaderOption[][] = [];\n\n /** If user has entered searching mode. */\n inSearchingMode = false;\n\n /** Selected options would be output to user. */\n selectedOptions: NzCascaderOption[] = [];\n\n values: NzSafeAny[] = [];\n\n readonly $loading = new BehaviorSubject<boolean>(false);\n\n /**\n * Emit an event to notify cascader it needs to redraw because activated or\n * selected options are changed.\n */\n readonly $redraw = new Subject<void>();\n\n /**\n * Emit an event when an option gets selected.\n * Emit true if a leaf options is selected.\n */\n readonly $optionSelected = new Subject<{\n option: NzCascaderOption;\n index: number;\n } | null>();\n\n /**\n * Emit an event to notify cascader it needs to quit searching mode.\n * Only emit when user do select a searching option.\n */\n readonly $quitSearching = new Subject<void>();\n\n /** To hold columns before entering searching mode. */\n private columnsSnapshot: NzCascaderOption[][] = [[]];\n\n /** To hold activated options before entering searching mode. */\n private activatedOptionsSnapshot: NzCascaderOption[] = [];\n\n private cascaderComponent!: NzCascaderComponentAsSource;\n\n /** Return cascader options in the first layer. */\n get nzOptions(): NzCascaderOption[] {\n return this.columns[0];\n }\n\n ngOnDestroy(): void {\n this.$redraw.complete();\n this.$quitSearching.complete();\n this.$optionSelected.complete();\n this.$loading.complete();\n }\n\n /**\n * Make sure that value matches what is displayed in the dropdown.\n */\n syncOptions(first: boolean = false): void {\n const values = this.values;\n const hasValue = values && values.length;\n const lastColumnIndex = values.length - 1;\n const initColumnWithIndex = (columnIndex: number): void => {\n const activatedOptionSetter = (): void => {\n const currentValue = values[columnIndex];\n\n if (!isNotNil(currentValue)) {\n this.$redraw.next();\n return;\n }\n\n const option =\n this.findOptionWithValue(columnIndex, values[columnIndex]) ||\n (typeof currentValue === 'object'\n ? currentValue\n : {\n [`${this.cascaderComponent.nzValueProperty}`]: currentValue,\n [`${this.cascaderComponent.nzLabelProperty}`]: currentValue\n });\n\n this.setOptionActivated(option, columnIndex, false, false);\n\n if (columnIndex < lastColumnIndex) {\n initColumnWithIndex(columnIndex + 1);\n } else {\n this.dropBehindColumns(columnIndex);\n this.selectedOptions = [...this.activatedOptions];\n this.$redraw.next();\n }\n };\n\n if (this.isLoaded(columnIndex) || !this.cascaderComponent.nzLoadData) {\n activatedOptionSetter();\n } else {\n const option = this.activatedOptions[columnIndex - 1] || {};\n this.loadChildren(option, columnIndex - 1, activatedOptionSetter);\n }\n };\n\n this.activatedOptions = [];\n this.selectedOptions = [];\n\n if (first && this.cascaderComponent.nzLoadData && !hasValue) {\n // Should also notify the component that value changes. Fix #3480.\n this.$redraw.next();\n return;\n } else {\n initColumnWithIndex(0);\n }\n }\n\n /**\n * Bind cascader component so this service could use inputs.\n */\n withComponent(cascaderComponent: NzCascaderComponentAsSource): void {\n this.cascaderComponent = cascaderComponent;\n }\n\n /**\n * Reset all options. Rebuild searching options if in searching mode.\n */\n withOptions(options: NzCascaderOption[] | null): void {\n this.columnsSnapshot = this.columns = options && options.length ? [options] : [];\n\n if (this.inSearchingMode) {\n this.prepareSearchOptions(this.cascaderComponent.inputValue);\n } else if (this.columns.length) {\n this.syncOptions();\n }\n }\n\n /**\n * Try to set a option as activated.\n *\n * @param option Cascader option\n * @param columnIndex Of which column this option is in\n * @param performSelect Select\n * @param loadingChildren Try to load children asynchronously.\n */\n setOptionActivated(\n option: NzCascaderOption,\n columnIndex: number,\n performSelect: boolean = false,\n loadingChildren: boolean = true\n ): void {\n if (option.disabled) {\n return;\n }\n\n this.activatedOptions[columnIndex] = option;\n this.trackAncestorActivatedOptions(columnIndex);\n this.dropBehindActivatedOptions(columnIndex);\n\n const isParent = isParentOption(option);\n\n if (isParent) {\n // Parent option that has children.\n this.setColumnData(option.children!, columnIndex + 1, option);\n } else if (!option.isLeaf && loadingChildren) {\n // Parent option that should try to load children asynchronously.\n this.loadChildren(option, columnIndex);\n } else if (option.isLeaf) {\n // Leaf option.\n this.dropBehindColumns(columnIndex);\n }\n\n // Actually perform selection to make an options not only activated but also selected.\n if (performSelect) {\n this.setOptionSelected(option, columnIndex);\n }\n\n this.$redraw.next();\n }\n\n setOptionSelected(option: NzCascaderOption, index: number): void {\n const changeOn = this.cascaderComponent.nzChangeOn;\n const shouldPerformSelection = (o: NzCascaderOption, i: number): boolean =>\n typeof changeOn === 'function' ? changeOn(o, i) : false;\n\n if (option.isLeaf || this.cascaderComponent.nzChangeOnSelect || shouldPerformSelection(option, index)) {\n this.selectedOptions = [...this.activatedOptions];\n this.prepareEmitValue();\n this.$redraw.next();\n this.$optionSelected.next({ option, index });\n }\n }\n\n setOptionDeactivatedSinceColumn(column: number): void {\n this.dropBehindActivatedOptions(column - 1);\n this.dropBehindColumns(column);\n this.$redraw.next();\n }\n\n /**\n * Set a searching option as selected, finishing up things.\n *\n * @param option\n */\n setSearchOptionSelected(option: NzCascaderSearchOption): void {\n this.activatedOptions = [option];\n this.selectedOptions = [...option.path];\n this.prepareEmitValue();\n this.$redraw.next();\n this.$optionSelected.next({ option, index: 0 });\n\n setTimeout(() => {\n // Reset data and tell UI only to remove input and reset dropdown width style.\n this.$quitSearching.next();\n this.$redraw.next();\n this.inSearchingMode = false;\n this.columns = [...this.columnsSnapshot];\n this.activatedOptions = [...this.selectedOptions];\n }, 200);\n }\n\n /**\n * Filter cascader options to reset `columns`.\n *\n * @param searchValue The string user wants to search.\n */\n prepareSearchOptions(searchValue: string): void {\n const results: NzCascaderOption[] = []; // Search results only have one layer.\n const path: NzCascaderOption[] = [];\n const defaultFilter: NzCascaderFilter = (i, p) =>\n p.some(o => {\n const label = this.getOptionLabel(o);\n return !!label && label.indexOf(i) !== -1;\n });\n const showSearch = this.cascaderComponent.nzShowSearch;\n const filter = isShowSearchObject(showSearch) && showSearch.filter ? showSearch.filter : defaultFilter;\n const sorter = isShowSearchObject(showSearch) && showSearch.sorter ? showSearch.sorter : null;\n const loopChild = (node: NzCascaderOption, forceDisabled = false): void => {\n path.push(node);\n const cPath = Array.from(path);\n if (filter(searchValue, cPath)) {\n const disabled = forceDisabled || node.disabled;\n const option: NzCascaderSearchOption = {\n disabled,\n isLeaf: true,\n path: cPath,\n [this.cascaderComponent.nzLabelProperty]: cPath.map(p => this.getOptionLabel(p)).join(' / ')\n };\n results.push(option);\n }\n path.pop();\n };\n const loopParent = (node: NzCascaderOption, forceDisabled = false): void => {\n const disabled = forceDisabled || node.disabled;\n path.push(node);\n node.children!.forEach(sNode => {\n if (!sNode.parent) {\n sNode.parent = node;\n }\n if (!sNode.isLeaf) {\n loopParent(sNode, disabled);\n }\n if (sNode.isLeaf || !sNode.children || !sNode.children.length) {\n loopChild(sNode, disabled);\n }\n });\n path.pop();\n };\n\n if (!this.columnsSnapshot.length) {\n this.columns = [[]];\n return;\n }\n\n this.columnsSnapshot[0].forEach(o => (isChildOption(o) ? loopChild(o) : loopParent(o)));\n\n if (sorter) {\n results.sort((a, b) => sorter(a.path, b.path, searchValue));\n }\n\n this.columns = [results];\n\n this.$redraw.next(); // Search results may be empty, so should redraw.\n }\n\n /**\n * Toggle searching mode by UI. It deals with things not directly related to UI.\n *\n * @param toSearching If this cascader is entering searching mode\n */\n toggleSearchingMode(toSearching: boolean): void {\n this.inSearchingMode = toSearching;\n\n if (toSearching) {\n this.activatedOptionsSnapshot = [...this.activatedOptions];\n this.activatedOptions = [];\n this.selectedOptions = [];\n this.$redraw.next();\n } else {\n // User quit searching mode without selecting an option.\n this.activatedOptions = [...this.activatedOptionsSnapshot];\n this.selectedOptions = [...this.activatedOptions];\n this.columns = [...this.columnsSnapshot];\n this.syncOptions();\n this.$redraw.next();\n }\n }\n\n /**\n * Clear selected options.\n */\n clear(): void {\n this.values = [];\n this.selectedOptions = [];\n this.activatedOptions = [];\n this.dropBehindColumns(0);\n this.$redraw.next();\n this.$optionSelected.next(null);\n }\n\n getOptionLabel(o: NzCascaderOption): string {\n return o[this.cascaderComponent.nzLabelProperty || 'label'] as string;\n }\n\n getOptionValue(o: NzCascaderOption): NzSafeAny {\n return o[this.cascaderComponent.nzValueProperty || 'value'];\n }\n\n /**\n * Try to insert options into a column.\n *\n * @param options Options to insert\n * @param columnIndex Position\n */\n private setColumnData(options: NzCascaderOption[], columnIndex: number, parent: NzCascaderOption): void {\n const existingOptions = this.columns[columnIndex];\n if (!arraysEqual(existingOptions, options)) {\n options.forEach(o => (o.parent = parent));\n this.columns[columnIndex] = options;\n this.dropBehindColumns(columnIndex);\n }\n }\n\n /**\n * Set all ancestor options as activated.\n */\n private trackAncestorActivatedOptions(startIndex: number): void {\n for (let i = startIndex - 1; i >= 0; i--) {\n if (!this.activatedOptions[i]) {\n this.activatedOptions[i] = this.activatedOptions[i + 1].parent!;\n }\n }\n }\n\n private dropBehindActivatedOptions(lastReserveIndex: number): void {\n this.activatedOptions = this.activatedOptions.splice(0, lastReserveIndex + 1);\n }\n\n private dropBehindColumns(lastReserveIndex: number): void {\n if (lastReserveIndex < this.columns.length - 1) {\n this.columns = this.columns.slice(0, lastReserveIndex + 1);\n }\n }\n\n /**\n * Load children of an option asynchronously.\n */\n loadChildren(\n option: NzCascaderOption | NzSafeAny,\n columnIndex: number,\n success?: VoidFunction,\n failure?: VoidFunction\n ): void {\n const loadFn = this.cascaderComponent.nzLoadData;\n\n if (loadFn) {\n // If there isn't any option in columns.\n this.$loading.next(columnIndex < 0);\n\n if (typeof option === 'object') {\n option.loading = true;\n }\n\n loadFn(option, columnIndex).then(\n () => {\n option.loading = false;\n if (option.children) {\n this.setColumnData(option.children, columnIndex + 1, option);\n }\n if (success) {\n success();\n }\n this.$loading.next(false);\n this.$redraw.next();\n },\n () => {\n option.loading = false;\n option.isLeaf = true;\n if (failure) {\n failure();\n }\n this.$redraw.next();\n }\n );\n }\n }\n\n private isLoaded(index: number): boolean {\n return this.columns[index] && this.columns[index].length > 0;\n }\n\n /**\n * Find a option that has a given value in a given column.\n */\n private findOptionWithValue(columnIndex: number, value: NzCascaderOption | NzSafeAny): NzCascaderOption | null {\n const targetColumn = this.columns[columnIndex];\n if (targetColumn) {\n const v = typeof value === 'object' ? this.getOptionValue(value) : value;\n return targetColumn.find(o => v === this.getOptionValue(o))!;\n }\n return null;\n }\n\n private prepareEmitValue(): void {\n this.values = this.selectedOptions.map(o => this.getOptionValue(o));\n }\n}\n","/**\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE\n */\n\nimport { Direction, Directionality } from '@angular/cdk/bidi';\nimport { BACKSPACE, DOWN_ARROW, ENTER, ESCAPE, LEFT_ARROW, RIGHT_ARROW, UP_ARROW } from '@angular/cdk/keycodes';\nimport { CdkConnectedOverlay, ConnectionPositionPair } from '@angular/cdk/overlay';\nimport {\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n ElementRef,\n EventEmitter,\n forwardRef,\n Host,\n HostListener,\n Input,\n NgZone,\n OnDestroy,\n OnInit,\n Optional,\n Output,\n QueryList,\n Renderer2,\n TemplateRef,\n ViewChild,\n ViewChildren,\n ViewEncapsulation\n} from '@angular/core';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\nimport { fromEvent, Subject } from 'rxjs';\nimport { startWith, takeUntil } from 'rxjs/operators';\n\nimport { slideMotion } from 'ng-zorro-antd/core/animation';\nimport { NzConfigKey, NzConfigService, WithConfig } from 'ng-zorro-antd/core/config';\nimport { NzNoAnimationDirective } from 'ng-zorro-antd/core/no-animation';\nimport { DEFAULT_CASCADER_POSITIONS } from 'ng-zorro-antd/core/overlay';\nimport { BooleanInput, NgClassType, NgStyleInterface, NzSafeAny } from 'ng-zorro-antd/core/types';\nimport { InputBoolean, toArray } from 'ng-zorro-antd/core/util';\nimport { NzCascaderI18nInterface, NzI18nService } from 'ng-zorro-antd/i18n';\n\nimport { NzCascaderOptionComponent } from './cascader-li.component';\nimport { NzCascaderService } from './cascader.service';\nimport {\n NzCascaderComponentAsSource,\n NzCascaderExpandTrigger,\n NzCascaderOption,\n NzCascaderSearchOption,\n NzCascaderSize,\n NzCascaderTriggerType,\n NzShowSearchOptions\n} from './typings';\n\nconst NZ_CONFIG_MODULE_NAME: NzConfigKey = 'cascader';\nconst defaultDisplayRender = (labels: string[]): string => labels.join(' / ');\n\n@Component({\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n selector: 'nz-cascader, [nz-cascader]',\n exportAs: 'nzCascader',\n preserveWhitespaces: false,\n template: `\n <div cdkOverlayOrigin #origin=\"cdkOverlayOrigin\" #trigger>\n <ng-container *ngIf=\"nzShowInput\">\n <div #selectContainer class=\"ant-select-selector\">\n <span class=\"ant-select-selection-search\">\n <input\n #input\n type=\"search\"\n class=\"ant-select-selection-search-input\"\n [style.opacity]=\"nzShowSearch ? '' : '0'\"\n [attr.autoComplete]=\"'off'\"\n [attr.expanded]=\"menuVisible\"\n [attr.autofocus]=\"nzAutoFocus ? 'autofocus' : null\"\n [readonly]=\"!nzShowSearch\"\n [disabled]=\"nzDisabled\"\n [(ngModel)]=\"inputValue\"\n (blur)=\"handleInputBlur()\"\n (focus)=\"handleInputFocus()\"\n (change)=\"$event.stopPropagation()\"\n />\n </span>\n <span *ngIf=\"showLabelRender\" class=\"ant-select-selection-item\" [title]=\"labelRenderText\">\n <ng-container *ngIf=\"!isLabelRenderTemplate; else labelTemplate\">{{ labelRenderText }}</ng-container>\n <ng-template #labelTemplate>\n <ng-template\n [ngTemplateOutlet]=\"nzLabelRender\"\n [ngTemplateOutletContext]=\"labelRenderContext\"\n ></ng-template>\n </ng-template>\n </span>\n <span\n *ngIf=\"!showLabelRender\"\n class=\"ant-select-selection-placeholder\"\n [style.visibility]=\"!inputValue ? 'visible' : 'hidden'\"\n >{{ showPlaceholder ? nzPlaceHolder || locale?.placeholder : null }}</span\n >\n </div>\n <span class=\"ant-select-arrow\" [class.ant-select-arrow-loading]=\"isLoading\" *ngIf=\"nzShowArrow\">\n <i\n *ngIf=\"!isLoading\"\n nz-icon\n [nzType]=\"$any(nzSuffixIcon)\"\n [class.ant-cascader-picker-arrow-expand]=\"menuVisible\"\n ></i>\n <i *ngIf=\"isLoading\" nz-icon nzType=\"loading\"></i>\n </span>\n <span class=\"ant-select-clear\" *ngIf=\"clearIconVisible\">\n <i nz-icon nzType=\"close-circle\" nzTheme=\"fill\" (click)=\"clearSelection($event)\"></i>\n </span>\n </ng-container>\n <ng-content></ng-content>\n </div>\n <ng-template\n cdkConnectedOverlay\n nzConnectedOverlay\n [cdkConnectedOverlayHasBackdrop]=\"nzBackdrop\"\n [cdkConnectedOverlayOrigin]=\"origin\"\n [cdkConnectedOverlayPositions]=\"positions\"\n [cdkConnectedOverlayTransformOriginOn]=\"'.ant-cascader-dropdown'\"\n [cdkConnectedOverlayOpen]=\"menuVisible\"\n (overlayOutsideClick)=\"onClickOutside($event)\"\n (detach)=\"closeMenu()\"\n >\n <div\n class=\"ant-select-dropdown ant-cascader-dropdown ant-select-dropdown-placement-bottomLeft\"\n [class.ant-cascader-dropdown-rtl]=\"dir === 'rtl'\"\n [@slideMotion]=\"'enter'\"\n [@.disabled]=\"noAnimation?.nzNoAnimation\"\n [nzNoAnimation]=\"noAnimation?.nzNoAnimation\"\n (mouseleave)=\"onTriggerMouseLeave($event)\"\n >\n <div\n #menu\n class=\"ant-cascader-menus\"\n [class.ant-cascader-rtl]=\"dir === 'rtl'\"\n [class.ant-cascader-menus-hidden]=\"!menuVisible\"\n [class.ant-cascader-menu-empty]=\"shouldShowEmpty\"\n [ngClass]=\"menuCls\"\n [ngStyle]=\"nzMenuStyle\"\n >\n <ul\n *ngIf=\"shouldShowEmpty; else hasOptionsTemplate\"\n class=\"ant-cascader-menu\"\n [style.width]=\"dropdownWidthStyle\"\n [style.height]=\"dropdownHeightStyle\"\n >\n <li class=\"ant-cascader-menu-item ant-cascader-menu-item-disabled\">\n <nz-embed-empty\n class=\"ant-cascader-menu-item-content\"\n [nzComponentName]=\"'cascader'\"\n [specificContent]=\"nzNotFoundContent\"\n ></nz-embed-empty>\n </li>\n </ul>\n <ng-template #hasOptionsTemplate>\n <ul\n *ngFor=\"let options of cascaderService.columns; let i = index\"\n class=\"ant-cascader-menu\"\n role=\"menuitemcheckbox\"\n [ngClass]=\"menuColumnCls\"\n [style.height]=\"dropdownHeightStyle\"\n [style.width]=\"dropdownWidthStyle\"\n >\n <li\n nz-cascader-option\n *ngFor=\"let option of options\"\n [expandIcon]=\"nzExpandIcon\"\n [columnIndex]=\"i\"\n [nzLabelProperty]=\"nzLabelProperty\"\n [optionTemplate]=\"nzOptionRender\"\n [activated]=\"isOptionActivated(option, i)\"\n [highlightText]=\"inSearchingMode ? inputValue : ''\"\n [option]=\"option\"\n [dir]=\"dir\"\n (mouseenter)=\"onOptionMouseEnter(option, i, $event)\"\n (mouseleave)=\"onOptionMouseLeave(option, i, $event)\"\n (click)=\"onOptionClick(option, i, $event)\"\n ></li>\n </ul>\n </ng-template>\n </div>\n </div>\n </ng-template>\n `,\n animations: [slideMotion],\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => NzCascaderComponent),\n multi: true\n },\n NzCascaderService\n ],\n host: {\n '[attr.tabIndex]': '\"0\"',\n '[class.ant-select-lg]': 'nzSize === \"large\"',\n '[class.ant-select-sm]': 'nzSize === \"small\"',\n '[class.ant-select-allow-clear]': 'nzAllowClear',\n '[class.ant-select-show-arrow]': 'nzShowArrow',\n '[class.ant-select-show-search]': '!!nzShowSearch',\n '[class.ant-select-disabled]': 'nzDisabled',\n '[class.ant-select-open]': 'menuVisible',\n '[class.ant-select-focused]': 'isFocused',\n '[class.ant-select-single]': 'true',\n '[class.ant-select-rtl]': `dir ==='rtl'`\n }\n})\nexport class NzCascaderComponent implements NzCascaderComponentAsSource, OnInit, OnDestroy, ControlValueAccessor {\n readonly _nzModuleName: NzConfigKey = NZ_CONFIG_MODULE_NAME;\n static ngAcceptInputType_nzShowInput: BooleanInput;\n static ngAcceptInputType_nzShowArrow: BooleanInput;\n static ngAcceptInputType_nzAllowClear: BooleanInput;\n static ngAcceptInputType_nzAutoFocus: BooleanInput;\n static ngAcceptInputType_nzChangeOnSelect: BooleanInput;\n static ngAcceptInputType_nzDisabled: BooleanInput;\n\n @ViewChild('selectContainer', { static: false }) selectContainer!: ElementRef;\n @ViewChild('input', { static: false }) input!: ElementRef;\n @ViewChild('menu', { static: false }) menu!: ElementRef;\n @ViewChild(CdkConnectedOverlay, { static: false }) overlay!: CdkConnectedOverlay;\n @ViewChildren(NzCascaderOptionComponent) cascaderItems!: QueryList<NzCascaderOptionComponent>;\n\n @Input() nzOptionRender: TemplateRef<{ $implicit: NzCascaderOption; index: number }> | null = null;\n @Input() @InputBoolean() nzShowInput = true;\n @Input() @InputBoolean() nzShowArrow = true;\n @Input() @InputBoolean() nzAllowClear = true;\n @Input() @InputBoolean() nzAutoFocus = false;\n @Input() @InputBoolean() nzChangeOnSelect = false;\n @Input() @InputBoolean() nzDisabled = false;\n @Input() nzColumnClassName?: string;\n @Input() nzExpandTrigger: NzCascaderExpandTrigger = 'click';\n @Input() nzValueProperty = 'value';\n @Input() nzLabelRender: TemplateRef<void> | null = null;\n @Input() nzLabelProperty = 'label';\n @Input() nzNotFoundContent?: string | TemplateRef<void>;\n @Input() @WithConfig() nzSize: NzCascaderSize = 'default';\n @Input() @WithConfig() nzBackdrop = false;\n @Input() nzShowSearch: boolean | NzShowSearchOptions = false;\n @Input() nzPlaceHolder: string = '';\n @Input() nzMenuClassName?: string;\n @Input() nzMenuStyle: NgStyleInterface | null = null;\n @Input() nzMouseEnterDelay: number = 150; // ms\n @Input() nzMouseLeaveDelay: number = 150; // ms\n @Input() nzTriggerAction: NzCascaderTriggerType | NzCascaderTriggerType[] = ['click'] as NzCascaderTriggerType[];\n @Input() nzChangeOn?: (option: NzCascaderOption, level: number) => boolean;\n @Input() nzLoadData?: (node: NzCascaderOption, index: number) => PromiseLike<NzSafeAny>;\n // TODO: RTL\n @Input() nzSuffixIcon: string | TemplateRef<void> = 'down';\n @Input() nzExpandIcon: string | TemplateRef<void> = '';\n\n @Input()\n get nzOptions(): NzCascaderOption[] | null {\n return this.cascaderService.nzOptions;\n }\n\n set nzOptions(options: NzCascaderOption[] | null) {\n this.cascaderService.withOptions(options);\n }\n\n @Output() readonly nzVisibleChange = new EventEmitter<boolean>();\n @Output() readonly nzSelectionChange = new EventEmitter<NzCascaderOption[]>();\n @Output() readonly nzSelect = new EventEmitter<{ option: NzCascaderOption; index: number } | null>();\n @Output() readonly nzClear = new EventEmitter<void>();\n\n /**\n * If the dropdown should show the empty content.\n * `true` if there's no options.\n */\n shouldShowEmpty: boolean = false;\n\n el: HTMLElement;\n menuVisible = false;\n isLoading = false;\n labelRenderText?: string;\n labelRenderContext = {};\n onChange = Function.prototype;\n onTouched = Function.prototype;\n positions: ConnectionPositionPair[] = [...DEFAULT_CASCADER_POSITIONS];\n\n /**\n * Dropdown's with in pixel.\n */\n dropdownWidthStyle?: string;\n dropdownHeightStyle: 'auto' | '' = '';\n isFocused = false;\n\n locale!: NzCascaderI18nInterface;\n dir: Direction = 'ltr';\n\n private destroy$ = new Subject<void>();\n private inputString = '';\n private isOpening = false;\n private delayMenuTimer: number | null = null;\n private delaySelectTimer: number | null = null;\n\n get inSearchingMode(): boolean {\n return this.cascaderService.inSearchingMode;\n }\n\n set inputValue(inputValue: string) {\n this.inputString = inputValue;\n this.toggleSearchingMode(!!inputValue);\n }\n\n get inputValue(): string {\n return this.inputString;\n }\n\n get menuCls(): NgClassType {\n return { [`${this.nzMenuClassName}`]: !!this.nzMenuClassName };\n }\n\n get menuColumnCls(): NgClassType {\n return { [`${this.nzColumnClassName}`]: !!this.nzColumnClassName };\n }\n\n private get hasInput(): boolean {\n return !!this.inputValue;\n }\n\n private get hasValue(): boolean {\n return this.cascaderService.values && this.cascaderService.values.length > 0;\n }\n\n get showLabelRender(): boolean {\n return this.hasValue;\n }\n\n get showPlaceholder(): boolean {\n return !(this.hasInput || this.hasValue);\n }\n\n get clearIconVisible(): boolean {\n return this.nzAllowClear && !this.nzDisabled && (this.hasValue || this.hasInput);\n }\n\n get isLabelRenderTemplate(): boolean {\n return !!this.nzLabelRender;\n }\n\n constructor(\n public cascaderService: NzCascaderService,\n public nzConfigService: NzConfigService,\n private ngZone: NgZone,\n private cdr: ChangeDetectorRef,\n private i18nService: NzI18nService,\n elementRef: ElementRef,\n renderer: Renderer2,\n @Optional() private directionality: Directionality,\n @Host() @Optional() public noAnimation?: NzNoAnimationDirective\n ) {\n this.el = elementRef.nativeElement;\n this.cascaderService.withComponent(this);\n renderer.addClass(elementRef.nativeElement, 'ant-select');\n renderer.addClass(elementRef.nativeElement, 'ant-cascader');\n }\n\n ngOnInit(): void {\n const srv = this.cascaderService;\n\n srv.$redraw.pipe(takeUntil(this.destroy$)).subscribe(() => {\n // These operations would not mutate data.\n this.checkChildren();\n this.setDisplayLabel();\n this.reposition();\n this.setDropdownStyles();\n\n this.cdr.markForCheck();\n });\n\n srv.$loading.pipe(takeUntil(this.destroy$)).subscribe(loading => {\n this.isLoading = loading;\n });\n\n srv.$optionSelected.pipe(takeUntil(this.destroy$)).subscribe(data => {\n if (!data) {\n this.onChange([]);\n this.nzSelect.emit(null);\n this.nzSelectionChange.emit([]);\n } else {\n const { option, index } = data;\n const shouldClose = option.isLeaf || (this.nzChangeOnSelect && this.nzExpandTrigger === 'hover');\n if (shouldClose) {\n this.delaySetMenuVisible(false);\n }\n this.onChange(this.cascaderService.values);\n this.nzSelectionChange.emit(this.cascaderService.selectedOptions);\n this.nzSelect.emit({ option, index });\n this.cdr.markForCheck();\n }\n });\n\n srv.$quitSearching.pipe(takeUntil(this.destroy$)).subscribe(() => {\n this.inputString = '';\n this.dropdownWidthStyle = '';\n });\n\n this.i18nService.localeChange.pipe(startWith(), takeUntil(this.destroy$)).subscribe(() => {\n this.setLocale();\n });\n\n this.nzConfigService\n .getConfigChangeEventForComponent(NZ_CONFIG_MODULE_NAME)\n .pipe(takeUntil(this.destroy$))\n .subscribe(() => {\n this.cdr.markForCheck();\n });\n\n this.dir = this.directionality.value;\n this.directionality.change.pipe(takeUntil(this.destroy$)).subscribe(() => {\n this.dir = this.directionality.value;\n srv.$redraw.next();\n });\n\n this.setupKeydownListener();\n }\n\n ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n this.clearDelayMenuTimer();\n this.clearDelaySelectTimer();\n }\n\n registerOnChange(fn: () => {}): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => {}): void {\n this.onTouched = fn;\n }\n\n writeValue(value: NzSafeAny): void {\n this.cascaderService.values = toArray(value);\n this.cascaderService.syncOptions(true);\n }\n\n delaySetMenuVisible(visible: boolean, delay: number = 100, setOpening: boolean = false): void {\n this.clearDelayMenuTimer();\n if (delay) {\n if (visible && setOpening) {\n this.isOpening = true;\n }\n this.delayMenuTimer = setTimeout(() => {\n this.setMenuVisible(visible);\n this.cdr.detectChanges();\n this.clearDelayMenuTimer();\n if (visible) {\n setTimeout(() => {\n this.isOpening = false;\n }, 100);\n }\n }, delay);\n } else {\n this.setMenuVisible(visible);\n }\n }\n\n setMenuVisible(visible: boolean): void {\n if (this.nzDisabled || this.menuVisible === visible) {\n return;\n }\n if (visible) {\n this.cascaderService.syncOptions();\n this.scrollToActivatedOptions();\n }\n\n if (!visible) {\n this.inputValue = '';\n }\n\n this.menuVisible = visible;\n this.nzVisibleChange.emit(visible);\n this.cdr.detectChanges();\n }\n\n private clearDelayMenuTimer(): void {\n if (this.delayMenuTimer) {\n clearTimeout(this.delayMenuTimer);\n this.delayMenuTimer = null;\n }\n }\n\n clearSelection(event?: Event): void {\n if (event) {\n event.preventDefault();\n event.stopPropagation();\n }\n\n this.labelRenderText = '';\n this.labelRenderContext = {};\n this.inputValue = '';\n this.setMenuVisible(false);\n this.cascaderService.clear();\n this.nzClear.emit();\n }\n\n getSubmitValue(): NzSafeAny[] {\n return this.cascaderService.selectedOptions.map(o => this.cascaderService.getOptionValue(o));\n }\n\n focus(): void {\n if (!this.isFocused) {\n (this.input ? this.input.nativeElement : this.el).focus();\n this.isFocused = true;\n }\n }\n\n blur(): void {\n if (this.isFocused) {\n (this.input ? this.input.nativeElement : this.el).blur();\n this.isFocused = false;\n }\n }\n\n handleInputBlur(): void {\n this.menuVisible ? this.focus() : this.blur();\n }\n\n handleInputFocus(): void {\n this.focus();\n }\n\n @HostListener('click')\n onTriggerClick(): void {\n if (this.nzDisabled) {\n return;\n }\n if (this.nzShowSearch) {\n this.focus();\n }\n if (this.isActionTrigger('click')) {\n this.delaySetMenuVisible(!this.menuVisible, 100);\n }\n this.onTouched();\n }\n\n @HostListener('mouseenter')\n onTriggerMouseEnter(): void {\n if (this.nzDisabled || !this.isActionTrigger('hover')) {\n return;\n }\n\n this.delaySetMenuVisible(true, this.nzMouseEnterDelay, true);\n }\n\n @HostListener('mouseleave', ['$event'])\n onTriggerMouseLeave(event: MouseEvent): void {\n if (this.nzDisabled || !this.menuVisible || this.isOpening || !this.isActionTrigger('hover')) {\n event.preventDefault();\n return;\n }\n const mouseTarget = event.relatedTarget as HTMLElement;\n const hostEl = this.el;\n const menuEl = this.menu && (this.menu.nativeElement as HTMLElement);\n if (hostEl.contains(mouseTarget) || (menuEl && menuEl.contains(mouseTarget))) {\n return;\n }\n this.delaySetMenuVisible(false, this.nzMouseLeaveDelay);\n }\n\n onOptionMouseEnter(option: NzCascaderOption, columnIndex: number, event: Event): void {\n event.preventDefault();\n if (this.nzExpandTrigger === 'hover') {\n if (!option.isLeaf) {\n this.delaySetOptionActivated(option, columnIndex, false);\n } else {\n this.cascaderService.setOptionDeactivatedSinceColumn(columnIndex);\n }\n }\n }\n\n onOptionMouseLeave(option: NzCascaderOption, _columnIndex: number, event: Event): void {\n event.preventDefault();\n if (this.nzExpandTrigger === 'hover' && !option.isLeaf) {\n this.clearDelaySelectTimer();\n }\n }\n\n onOptionClick(option: NzCascaderOption, columnIndex: number, event: Event): void {\n if (event) {\n event.preventDefault();\n }\n if (option && option.disabled) {\n return;\n }\n this.el.focus();\n this.inSearchingMode\n ? this.cascaderService.setSearchOptionSelected(option as NzCascaderSearchOption)\n : this.cascaderService.setOptionActivated(option, columnIndex, true);\n }\n\n onClickOutside(event: MouseEvent): void {\n if (!this.el.contains(event.target as Node)) {\n this.closeMenu();\n }\n }\n\n private isActionTrigger(action: 'click' | 'hover'): boolean {\n return typeof this.nzTriggerAction === 'string'\n ? this.nzTriggerAction === action\n : this.nzTriggerAction.indexOf(action) !== -1;\n }\n\n private onEnter(): void {\n const columnIndex = Math.max(this.cascaderService.activatedOptions.length - 1, 0);\n const option = this.cascaderService.activatedOptions[columnIndex];\n if (option && !option.disabled) {\n this.inSearchingMode\n ? this.cascaderService.setSearchOptionSelected(option as NzCascaderSearchOption)\n : this.cascaderService.setOptionActivated(option, columnIndex, true);\n }\n }\n\n private moveUpOrDown(isUp: boolean): void {\n const columnIndex = Math.max(this.cascaderService.activatedOptions.length - 1, 0);\n const activeOption = this.cascaderService.activatedOptions[columnIndex];\n const options = this.cascaderService.columns[columnIndex] || [];\n const length = options.length;\n let nextIndex = -1;\n if (!activeOption) {\n // Not selected options in this column\n nextIndex = isUp ? length : -1;\n } else {\n nextIndex = options.indexOf(activeOption);\n }\n\n while (true) {\n nextIndex = isUp ? nextIndex - 1 : nextIndex + 1;\n if (nextIndex < 0 || nextIndex >= length) {\n break;\n }\n const nextOption = options[nextIndex];\n if (!nextOption || nextOption.disabled) {\n continue;\n }\n this.cascaderService.setOptionActivated(nextOption, columnIndex);\n break;\n }\n }\n\n private moveLeft(): void {\n const options = this.cascaderService.activatedOptions;\n if (options.length) {\n options.pop(); // Remove the last one\n }\n }\n\n private moveRight(): void {\n const length = this.cascaderService.activatedOptions.length;\n const options = this.cascaderService.columns[length];\n if (options && options.length) {\n const nextOpt = options.find(o => !o.disabled);\n if (nextOpt) {\n this.cascaderService.setOptionActivated(nextOpt, length);\n }\n }\n }\n\n private clearDelaySelectTimer(): void {\n if (this.delaySelectTimer) {\n clearTimeout(this.delaySelectTimer);\n this.delaySelectTimer = null;\n }\n }\n\n private delaySetOptionActivated(option: NzCascaderOption, columnIndex: number, performSelect: boolean): void {\n this.clearDelaySelectTimer();\n this.delaySelectTimer = setTimeout(() => {\n this.cascaderService.setOptionActivated(option, columnIndex, performSelect);\n this.delaySelectTimer = null;\n }, 150);\n }\n\n private toggleSearchingMode(toSearching: boolean): void {\n if (this.inSearchingMode !== toSearching) {\n this.cascaderService.toggleSearchingMode(toSearching);\n }\n\n if (this.inSearchingMode) {\n this.cascaderService.prepareSearchOptions(this.inputValue);\n }\n }\n\n isOptionActivated(option: NzCascaderOption, index: number): boolean {\n const activeOpt = this.cascaderService.activatedOptions[index];\n return activeOpt === option;\n }\n\n setDisabledState(isDisabled: boolean): void {\n if (isDisabled) {\n this.closeMenu();\n }\n this.nzDisabled = isDisabled;\n }\n\n closeMenu(): void {\n this.blur();\n this.clearDelayMenuTimer();\n this.setMenuVisible(false);\n }\n\n /**\n * Reposition the cascader panel. When a menu opens, the cascader expands\n * and may exceed the boundary of browser's window.\n */\n private reposition(): void {\n if (this.overlay && this.overlay.overlayRef && this.menuVisible) {\n Promise.resolve().then(() => {\n this.overlay.overlayRef.updatePosition();\n });\n }\n }\n\n /**\n * When a cascader options is changed, a child needs to know that it should re-render.\n */\n private checkChildren(): void {\n if (this.cascaderItems) {\n this.cascaderItems.forEach(item => item.markForCheck());\n }\n }\n\n private setDisplayLabel(): void {\n const selectedOptions = this.cascaderService.selectedOptions;\n const labels: string[] = selectedOptions.map(o => this.cascaderService.getOptionLabel(o));\n\n if (this.isLabelRenderTemplate) {\n this.labelRenderContext = { labels, selectedOptions };\n } else {\n this.labelRenderText = defaultDisplayRender.call(this, labels);\n }\n }\n\n private setDropdownStyles(): void {\n const firstColumn = this.cascaderService.columns[0];\n\n this.shouldShowEmpty =\n (this.inSearchingMode && (!firstColumn || !firstColumn.length)) || // Should show empty when there's no searching result\n (!(this.nzOptions && this.nzOptions.length) && !this.nzLoadData); // Should show when there's no options and developer does not use nzLoadData\n this.dropdownHeightStyle = this.shouldShowEmpty ? 'auto' : '';\n\n if (this.input) {\n this.dropdownWidthStyle =\n this.inSearchingMode || this.shouldShowEmpty ? `${this.selectContainer.nativeElement.offsetWidth}px` : '';\n }\n }\n\n private setLocale(): void {\n this.locale = this.i18nService.getLocaleData('global');\n this.cdr.markForCheck();\n }\n\n private scrollToActivatedOptions(): void {\n // The `scrollIntoView` is a native DOM API, which doesn't require Angular to run\n // a change detection when a promise microtask is resolved.\n this.ngZone.runOutsideAngular(() => {\n Promise.resolve().then(() => {\n // scroll only until option menu view is ready\n this.cascaderItems\n .toArray()\n .filter(e => e.activated)\n .forEach(e => {\n e.nativeElement.scrollIntoView({ block: 'start', inline: 'nearest' });\n });\n });\n });\n }\n\n private setupKeydownListener(): void {\n this.ngZone.runOutsideAngular(() => {\n fromEvent<KeyboardEvent>(this.el, 'keydown')\n .pipe(takeUntil(this.destroy$))\n .subscribe(event => {\n const keyCode = event.keyCode;\n\n if (\n keyCode !== DOWN_ARROW &&\n keyCode !== UP_ARROW &&\n keyCode !== LEFT_ARROW &&\n keyCode !== RIGHT_ARROW &&\n keyCode !== ENTER &&\n keyCode !== BACKSPACE &&\n keyCode !== ESCAPE\n ) {\n return;\n }\n\n // Press any keys above to reopen menu.\n if (!this.menuVisible && keyCode !== BACKSPACE && keyCode !== ESCAPE) {\n // The `setMenuVisible` runs `detectChanges()`, so we don't need to run `markForCheck()` additionally.\n return this.ngZone.run(() => this.setMenuVisible(true));\n }\n\n // Make these keys work as default in searching mode.\n if (this.inSearchingMode && (keyCode === BACKSPACE || keyCode === LEFT_ARROW || keyCode === RIGHT_ARROW)) {\n return;\n }\n\n if (!this.menuVisible) {\n return;\n }\n\n event.preventDefault();\n\n this.ngZone.run(() => {\n // Interact with the component.\n if (keyCode === DOWN_ARROW) {\n this.moveUpOrDown(false);\n } else if (keyCode === UP_ARROW) {\n this.moveUpOrDown(true);\n } else if (keyCode === LEFT_ARROW) {\n this.moveLeft();\n } else if (keyCode === RIGHT_ARROW) {\n this.moveRight();\n } else if (keyCode === ENTER) {\n this.onEnter();\n }\n // `@HostListener`s run `markForCheck()` internally before calling the actual handler so\n // we call `markForCheck()` to be backwards-compatible.\n this.cdr.markForCheck();\n });\n });\n });\n }\n}\n","/**\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE\n */\n\nimport { BidiModule } from '@angular/cdk/bidi';\nimport { OverlayModule } from '@angular/cdk/overlay';\nimport { CommonModule } from '@angular/common';\nimport { NgModule } from '@angular/core';\nimport { FormsModule } from '@angular/forms';\n\nimport { NzHighlightModule } from 'ng-zorro-antd/core/highlight';\nimport { NzNoAnimationModule } from 'ng-zorro-antd/core/no-animation';\nimport { NzOutletModule } from 'ng-zorro-antd/core/outlet';\nimport { NzOverlayModule } from 'ng-zorro-antd/core/overlay';\nimport { NzEmptyModule } from 'ng-zorro-antd/empty';\nimport { NzIconModule } from 'ng-zorro-antd/icon';\nimport { NzInputModule } from 'ng-zorro-antd/input';\n\nimport { NzCascaderOptionComponent } from './cascader-li.component';\nimport { NzCascaderComponent } from './cascader.component';\n\n@NgModule({\n imports: [\n BidiModule,\n CommonModule,\n FormsModule,\n OverlayModule,\n NzOutletModule,\n NzEmptyModule,\n NzHighlightModule,\n NzIconModule,\n NzInputModule,\n NzNoAnimationModule,\n NzOverlayModule\n ],\n declarations: [NzCascaderComponent, NzCascaderOptionComponent],\n exports: [NzCascaderComponent]\n})\nexport class NzCascaderModule {}\n","/**\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE\n */\n\nexport * from './typings';\nexport * from './utils';\nexport * from './cascader.component';\nexport * from './cascader.module';\nexport * from './cascader.service';\nexport * from './cascader-li.component';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;SAoCgB,kBAAkB,CAAC,OAAsC;IACvE,OAAO,OAAO,OAAO,KAAK,SAAS,CAAC;AACtC;;ACtCA;;;;SAOgB,aAAa,CAAC,CAAmB;IAC/C,OAAO,CAAC,CAAC,