ng-zorro-antd
Version:
An enterprise-class UI components based on Ant Design and Angular
653 lines (639 loc) • 24.7 kB
JavaScript
import { __decorate, __metadata } from 'tslib';
import { FocusMonitor } from '@angular/cdk/a11y';
import { Directionality, BidiModule } from '@angular/cdk/bidi';
import { TAB, ESCAPE, BACKSPACE } from '@angular/cdk/keycodes';
import { CdkOverlayOrigin, CdkConnectedOverlay, OverlayModule } from '@angular/cdk/overlay';
import { Injectable, EventEmitter, Component, Self, Injector, forwardRef, Renderer2, ChangeDetectorRef, ElementRef, Optional, Host, Input, Output, ViewChild, ContentChild, NgModule } from '@angular/core';
import { NG_VALUE_ACCESSOR, FormsModule } from '@angular/forms';
import { slideMotion } from 'ng-zorro-antd/core/animation';
import { NzConfigService, WithConfig } from 'ng-zorro-antd/core/config';
import { NzNoAnimationDirective, NzNoAnimationModule } from 'ng-zorro-antd/core/no-animation';
import { reqAnimFrame } from 'ng-zorro-antd/core/polyfill';
import { NzTreeBaseService, NzTreeBase, NzTreeHigherOrderServiceToken } from 'ng-zorro-antd/core/tree';
import { isNotNil, InputBoolean } from 'ng-zorro-antd/core/util';
import { NzSelectSearchComponent, NzSelectModule } from 'ng-zorro-antd/select';
import { NzTreeModule } from 'ng-zorro-antd/tree';
import { Subject, merge, of } from 'rxjs';
import { takeUntil, tap, filter } from 'rxjs/operators';
import { CommonModule } from '@angular/common';
import { NzOverlayModule } from 'ng-zorro-antd/core/overlay';
import { NzEmptyModule } from 'ng-zorro-antd/empty';
import { NzIconModule } from 'ng-zorro-antd/icon';
/**
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
*/
class NzTreeSelectService extends NzTreeBaseService {
}
NzTreeSelectService.decorators = [
{ type: Injectable }
];
/**
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
*/
function higherOrderServiceFactory(injector) {
return injector.get(NzTreeSelectService);
}
const NZ_CONFIG_MODULE_NAME = 'treeSelect';
const TREE_SELECT_DEFAULT_CLASS = 'ant-select-dropdown ant-select-tree-dropdown';
class NzTreeSelectComponent extends NzTreeBase {
constructor(nzTreeService, nzConfigService, renderer, cdr, elementRef, directionality, focusMonitor, noAnimation) {
super(nzTreeService);
this.nzConfigService = nzConfigService;
this.renderer = renderer;
this.cdr = cdr;
this.elementRef = elementRef;
this.directionality = directionality;
this.focusMonitor = focusMonitor;
this.noAnimation = noAnimation;
this._nzModuleName = NZ_CONFIG_MODULE_NAME;
this.nzId = null;
this.nzAllowClear = true;
this.nzShowExpand = true;
this.nzShowLine = false;
this.nzDropdownMatchSelectWidth = true;
this.nzCheckable = false;
this.nzHideUnMatched = false;
this.nzShowIcon = false;
this.nzShowSearch = false;
this.nzDisabled = false;
this.nzAsyncData = false;
this.nzMultiple = false;
this.nzDefaultExpandAll = false;
this.nzCheckStrictly = false;
this.nzVirtualItemSize = 28;
this.nzVirtualMaxBufferPx = 500;
this.nzVirtualMinBufferPx = 28;
this.nzVirtualHeight = null;
this.nzNodes = [];
this.nzOpen = false;
this.nzSize = 'default';
this.nzPlaceHolder = '';
this.nzDropdownStyle = null;
this.nzDisplayWith = (node) => node.title;
this.nzMaxTagPlaceholder = null;
this.nzOpenChange = new EventEmitter();
this.nzCleared = new EventEmitter();
this.nzRemoved = new EventEmitter();
this.nzExpandChange = new EventEmitter();
this.nzTreeClick = new EventEmitter();
this.nzTreeCheckBoxChange = new EventEmitter();
this.dropdownClassName = TREE_SELECT_DEFAULT_CLASS;
this.isComposing = false;
this.isDestroy = true;
this.isNotFound = false;
this.focused = false;
this.inputValue = '';
this.dropDownPosition = 'bottom';
this.selectedNodes = [];
this.expandedKeys = [];
this.value = [];
this.dir = 'ltr';
this.destroy$ = new Subject();
this.onChange = _value => { };
this.onTouched = () => { };
// TODO: move to host after View Engine deprecation
this.elementRef.nativeElement.classList.add('ant-select');
this.renderer.addClass(this.elementRef.nativeElement, 'ant-select');
this.renderer.addClass(this.elementRef.nativeElement, 'ant-tree-select');
}
set nzExpandedKeys(value) {
this.expandedKeys = value;
}
get nzExpandedKeys() {
return this.expandedKeys;
}
get treeTemplate() {
return this.nzTreeTemplate || this.nzTreeTemplateChild;
}
get placeHolderDisplay() {
return this.inputValue || this.isComposing || this.selectedNodes.length ? 'none' : 'block';
}
get isMultiple() {
return this.nzMultiple || this.nzCheckable;
}
ngOnInit() {
var _a;
this.isDestroy = false;
this.selectionChangeSubscription = this.subscribeSelectionChange();
(_a = this.directionality.change) === null || _a === void 0 ? void 0 : _a.pipe(takeUntil(this.destroy$)).subscribe((direction) => {
this.dir = direction;
this.cdr.detectChanges();
});
this.dir = this.directionality.value;
this.focusChangeSubscription = this.focusMonitor.monitor(this.elementRef, true).subscribe(focusOrigin => {
if (!focusOrigin) {
this.focused = false;
this.cdr.markForCheck();
Promise.resolve().then(() => {
this.onTouched();
});
}
else {
this.focused = true;
this.cdr.markForCheck();
}
});
}
ngOnDestroy() {
this.isDestroy = true;
this.closeDropDown();
this.selectionChangeSubscription.unsubscribe();
this.destroy$.next();
this.destroy$.complete();
this.focusChangeSubscription.unsubscribe();
}
isComposingChange(isComposing) {
this.isComposing = isComposing;
}
setDisabledState(isDisabled) {
this.nzDisabled = isDisabled;
this.closeDropDown();
}
ngOnChanges(changes) {
const { nzNodes, nzDropdownClassName } = changes;
if (nzNodes) {
this.updateSelectedNodes(true);
}
if (nzDropdownClassName) {
const className = this.nzDropdownClassName && this.nzDropdownClassName.trim();
this.dropdownClassName = className ? `${TREE_SELECT_DEFAULT_CLASS} ${className}` : TREE_SELECT_DEFAULT_CLASS;
}
}
writeValue(value) {
if (isNotNil(value)) {
if (this.isMultiple && Array.isArray(value)) {
this.value = value;
}
else {
this.value = [value];
}
this.updateSelectedNodes(true);
}
else {
this.value = [];
this.selectedNodes.forEach(node => {
this.removeSelected(node, false);
});
this.selectedNodes = [];
}
this.cdr.markForCheck();
}
registerOnChange(fn) {
this.onChange = fn;
}
registerOnTouched(fn) {
this.onTouched = fn;
}
onKeydown(event) {
if (this.nzDisabled) {
return;
}
switch (event.keyCode) {
case ESCAPE:
/**
* Skip the ESCAPE processing, it will be handled in {@link onOverlayKeyDown}.
*/
break;
case TAB:
this.closeDropDown();
break;
default:
if (!this.nzOpen) {
this.openDropdown();
}
}
}
trigger() {
if (this.nzDisabled || (!this.nzDisabled && this.nzOpen)) {
this.closeDropDown();
}
else {
this.openDropdown();
}
}
openDropdown() {
if (!this.nzDisabled) {
this.nzOpen = true;
this.nzOpenChange.emit(this.nzOpen);
this.updateCdkConnectedOverlayStatus();
if (this.nzShowSearch || this.isMultiple) {
this.focusOnInput();
}
}
}
closeDropDown() {
this.onTouched();
this.nzOpen = false;
this.inputValue = '';
this.isNotFound = false;
this.nzOpenChange.emit(this.nzOpen);
this.cdr.markForCheck();
}
onKeyDownInput(e) {
const keyCode = e.keyCode;
const eventTarget = e.target;
if (this.isMultiple && !eventTarget.value && keyCode === BACKSPACE) {
e.preventDefault();
if (this.selectedNodes.length) {
const removeNode = this.selectedNodes[this.selectedNodes.length - 1];
this.removeSelected(removeNode);
}
}
}
onExpandedKeysChange(value) {
this.nzExpandChange.emit(value);
this.expandedKeys = [...value.keys];
}
setInputValue(value) {
this.inputValue = value;
this.updatePosition();
}
removeSelected(node, emit = true) {
node.isSelected = false;
node.isChecked = false;
if (this.nzCheckable) {
this.nzTreeService.conduct(node, this.nzCheckStrictly);
}
else {
this.nzTreeService.setSelectedNodeList(node, this.nzMultiple);
}
if (emit) {
this.nzRemoved.emit(node);
}
}
focusOnInput() {
if (this.nzSelectSearchComponent) {
this.nzSelectSearchComponent.focus();
}
}
subscribeSelectionChange() {
return merge(this.nzTreeClick.pipe(tap((event) => {
const node = event.node;
if (this.nzCheckable && !node.isDisabled && !node.isDisableCheckbox) {
node.isChecked = !node.isChecked;
node.isHalfChecked = false;
if (!this.nzCheckStrictly) {
this.nzTreeService.conduct(node);
}
}
if (this.nzCheckable) {
node.isSelected = false;
}
}), filter((event) => {
const node = event.node;
return this.nzCheckable ? !node.isDisabled && !node.isDisableCheckbox : !node.isDisabled && node.isSelectable;
})), this.nzCheckable ? this.nzTreeCheckBoxChange : of(), this.nzCleared, this.nzRemoved).subscribe(() => {
this.updateSelectedNodes();
const value = this.selectedNodes.map(node => node.key);
this.value = [...value];
if (this.nzShowSearch || this.isMultiple) {
this.inputValue = '';
this.isNotFound = false;
}
if (this.isMultiple) {
this.onChange(value);
this.focusOnInput();
this.updatePosition();
}
else {
this.closeDropDown();
this.onChange(value.length ? value[0] : null);
}
});
}
updateSelectedNodes(init = false) {
if (init) {
const nodes = this.coerceTreeNodes(this.nzNodes);
this.nzTreeService.isMultiple = this.isMultiple;
this.nzTreeService.isCheckStrictly = this.nzCheckStrictly;
this.nzTreeService.initTree(nodes);
if (this.nzCheckable) {
this.nzTreeService.conductCheck(this.value, this.nzCheckStrictly);
}
else {
this.nzTreeService.conductSelectedKeys(this.value, this.isMultiple);
}
}
this.selectedNodes = [...(this.nzCheckable ? this.getCheckedNodeList() : this.getSelectedNodeList())];
}
updatePosition() {
reqAnimFrame(() => {
var _a, _b;
(_b = (_a = this.cdkConnectedOverlay) === null || _a === void 0 ? void 0 : _a.overlayRef) === null || _b === void 0 ? void 0 : _b.updatePosition();
});
}
onPositionChange(position) {
this.dropDownPosition = position.connectionPair.originY;
}
onClearSelection() {
this.selectedNodes.forEach(node => {
this.removeSelected(node, false);
});
this.nzCleared.emit();
}
onClickOutside(event) {
if (!this.elementRef.nativeElement.contains(event.target)) {
this.closeDropDown();
}
}
setSearchValues($event) {
Promise.resolve().then(() => {
this.isNotFound = (this.nzShowSearch || this.isMultiple) && !!this.inputValue && $event.matchedKeys.length === 0;
});
}
updateCdkConnectedOverlayStatus() {
this.triggerWidth = this.cdkOverlayOrigin.elementRef.nativeElement.getBoundingClientRect().width;
}
trackValue(_index, option) {
return option.key;
}
}
NzTreeSelectComponent.decorators = [
{ type: Component, args: [{
selector: 'nz-tree-select',
exportAs: 'nzTreeSelect',
animations: [slideMotion],
template: `
<ng-template
cdkConnectedOverlay
nzConnectedOverlay
[cdkConnectedOverlayOrigin]="cdkOverlayOrigin"
[cdkConnectedOverlayOpen]="nzOpen"
[cdkConnectedOverlayTransformOriginOn]="'.ant-select-tree-dropdown'"
[cdkConnectedOverlayMinWidth]="$any(nzDropdownMatchSelectWidth ? null : triggerWidth)"
[cdkConnectedOverlayWidth]="$any(nzDropdownMatchSelectWidth ? triggerWidth : null)"
(overlayOutsideClick)="onClickOutside($event)"
(detach)="closeDropDown()"
(positionChange)="onPositionChange($event)"
>
<div
[ ]="'enter'"
[ngClass]="dropdownClassName"
[@.disabled]="noAnimation?.nzNoAnimation"
[nzNoAnimation]="noAnimation?.nzNoAnimation"
[class.ant-select-dropdown-placement-bottomLeft]="dropDownPosition === 'bottom'"
[class.ant-select-dropdown-placement-topLeft]="dropDownPosition === 'top'"
[class.ant-tree-select-dropdown-rtl]="dir === 'rtl'"
[dir]="dir"
[ngStyle]="nzDropdownStyle"
>
<nz-tree
#treeRef
[hidden]="isNotFound"
nzNoAnimation
nzSelectMode
nzBlockNode
[nzData]="nzNodes"
[nzMultiple]="nzMultiple"
[nzSearchValue]="inputValue"
[nzHideUnMatched]="nzHideUnMatched"
[nzShowIcon]="nzShowIcon"
[nzCheckable]="nzCheckable"
[nzAsyncData]="nzAsyncData"
[nzShowExpand]="nzShowExpand"
[nzShowLine]="nzShowLine"
[nzExpandedIcon]="nzExpandedIcon"
[nzExpandAll]="nzDefaultExpandAll"
[nzExpandedKeys]="expandedKeys"
[nzCheckedKeys]="nzCheckable ? value : []"
[nzSelectedKeys]="!nzCheckable ? value : []"
[nzTreeTemplate]="treeTemplate"
[nzCheckStrictly]="nzCheckStrictly"
[nzVirtualItemSize]="nzVirtualItemSize"
[nzVirtualMaxBufferPx]="nzVirtualMaxBufferPx"
[nzVirtualMinBufferPx]="nzVirtualMinBufferPx"
[nzVirtualHeight]="nzVirtualHeight"
(nzExpandChange)="onExpandedKeysChange($event)"
(nzClick)="nzTreeClick.emit($event)"
(nzCheckedKeysChange)="updateSelectedNodes()"
(nzSelectedKeysChange)="updateSelectedNodes()"
(nzCheckBoxChange)="nzTreeCheckBoxChange.emit($event)"
(nzSearchValueChange)="setSearchValues($event)"
></nz-tree>
<span *ngIf="nzNodes.length === 0 || isNotFound" class="ant-select-not-found">
<nz-embed-empty [nzComponentName]="'tree-select'" [specificContent]="nzNotFoundContent"></nz-embed-empty>
</span>
</div>
</ng-template>
<div cdkOverlayOrigin class="ant-select-selector">
<ng-container *ngIf="isMultiple">
<nz-select-item
*ngFor="let node of selectedNodes | slice: 0:nzMaxTagCount; trackBy: trackValue"
[deletable]="true"
[disabled]="node.isDisabled || nzDisabled"
[label]="nzDisplayWith(node)"
(delete)="removeSelected(node, true)"
></nz-select-item>
<nz-select-item
*ngIf="selectedNodes.length > nzMaxTagCount"
[contentTemplateOutlet]="nzMaxTagPlaceholder"
[contentTemplateOutletContext]="selectedNodes | slice: nzMaxTagCount"
[deletable]="false"
[disabled]="false"
[label]="'+ ' + (selectedNodes.length - nzMaxTagCount) + ' ...'"
></nz-select-item>
</ng-container>
<nz-select-search
[nzId]="nzId"
[showInput]="nzShowSearch"
(keydown)="onKeyDownInput($event)"
(isComposingChange)="isComposing = $event"
(valueChange)="setInputValue($event)"
[value]="inputValue"
[mirrorSync]="isMultiple"
[disabled]="nzDisabled"
[focusTrigger]="nzOpen"
></nz-select-search>
<nz-select-placeholder
*ngIf="nzPlaceHolder && selectedNodes.length === 0"
[placeholder]="nzPlaceHolder"
[style.display]="placeHolderDisplay"
></nz-select-placeholder>
<nz-select-item
*ngIf="!isMultiple && selectedNodes.length === 1 && !isComposing && inputValue === ''"
[deletable]="false"
[disabled]="false"
[label]="nzDisplayWith(selectedNodes[0])"
></nz-select-item>
<nz-select-arrow *ngIf="!isMultiple"></nz-select-arrow>
<nz-select-clear *ngIf="nzAllowClear && !nzDisabled && selectedNodes.length" (clear)="onClearSelection()"></nz-select-clear>
</div>
`,
providers: [
NzTreeSelectService,
{
provide: NzTreeHigherOrderServiceToken,
useFactory: higherOrderServiceFactory,
deps: [[new Self(), Injector]]
},
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => NzTreeSelectComponent),
multi: true
}
],
host: {
'[class.ant-select-lg]': 'nzSize==="large"',
'[class.ant-select-rtl]': 'dir==="rtl"',
'[class.ant-select-sm]': 'nzSize==="small"',
'[class.ant-select-disabled]': 'nzDisabled',
'[class.ant-select-single]': '!isMultiple',
'[class.ant-select-show-arrow]': '!isMultiple',
'[class.ant-select-show-search]': '!isMultiple',
'[class.ant-select-multiple]': 'isMultiple',
'[class.ant-select-allow-clear]': 'nzAllowClear',
'[class.ant-select-open]': 'nzOpen',
'[class.ant-select-focused]': 'nzOpen || focused',
'(click)': 'trigger()',
'(keydown)': 'onKeydown($event)'
}
},] }
];
NzTreeSelectComponent.ctorParameters = () => [
{ type: NzTreeSelectService },
{ type: NzConfigService },
{ type: Renderer2 },
{ type: ChangeDetectorRef },
{ type: ElementRef },
{ type: Directionality, decorators: [{ type: Optional }] },
{ type: FocusMonitor },
{ type: NzNoAnimationDirective, decorators: [{ type: Host }, { type: Optional }] }
];
NzTreeSelectComponent.propDecorators = {
nzId: [{ type: Input }],
nzAllowClear: [{ type: Input }],
nzShowExpand: [{ type: Input }],
nzShowLine: [{ type: Input }],
nzDropdownMatchSelectWidth: [{ type: Input }],
nzCheckable: [{ type: Input }],
nzHideUnMatched: [{ type: Input }],
nzShowIcon: [{ type: Input }],
nzShowSearch: [{ type: Input }],
nzDisabled: [{ type: Input }],
nzAsyncData: [{ type: Input }],
nzMultiple: [{ type: Input }],
nzDefaultExpandAll: [{ type: Input }],
nzCheckStrictly: [{ type: Input }],
nzVirtualItemSize: [{ type: Input }],
nzVirtualMaxBufferPx: [{ type: Input }],
nzVirtualMinBufferPx: [{ type: Input }],
nzVirtualHeight: [{ type: Input }],
nzExpandedIcon: [{ type: Input }],
nzNotFoundContent: [{ type: Input }],
nzNodes: [{ type: Input }],
nzOpen: [{ type: Input }],
nzSize: [{ type: Input }],
nzPlaceHolder: [{ type: Input }],
nzDropdownStyle: [{ type: Input }],
nzDropdownClassName: [{ type: Input }],
nzExpandedKeys: [{ type: Input }],
nzDisplayWith: [{ type: Input }],
nzMaxTagCount: [{ type: Input }],
nzMaxTagPlaceholder: [{ type: Input }],
nzOpenChange: [{ type: Output }],
nzCleared: [{ type: Output }],
nzRemoved: [{ type: Output }],
nzExpandChange: [{ type: Output }],
nzTreeClick: [{ type: Output }],
nzTreeCheckBoxChange: [{ type: Output }],
nzSelectSearchComponent: [{ type: ViewChild, args: [NzSelectSearchComponent, { static: false },] }],
treeRef: [{ type: ViewChild, args: ['treeRef', { static: false },] }],
cdkOverlayOrigin: [{ type: ViewChild, args: [CdkOverlayOrigin, { static: true },] }],
cdkConnectedOverlay: [{ type: ViewChild, args: [CdkConnectedOverlay, { static: false },] }],
nzTreeTemplate: [{ type: Input }],
nzTreeTemplateChild: [{ type: ContentChild, args: ['nzTreeTemplate', { static: true },] }]
};
__decorate([
InputBoolean(),
__metadata("design:type", Boolean)
], NzTreeSelectComponent.prototype, "nzAllowClear", void 0);
__decorate([
InputBoolean(),
__metadata("design:type", Boolean)
], NzTreeSelectComponent.prototype, "nzShowExpand", void 0);
__decorate([
InputBoolean(),
__metadata("design:type", Boolean)
], NzTreeSelectComponent.prototype, "nzShowLine", void 0);
__decorate([
InputBoolean(),
WithConfig(),
__metadata("design:type", Boolean)
], NzTreeSelectComponent.prototype, "nzDropdownMatchSelectWidth", void 0);
__decorate([
InputBoolean(),
__metadata("design:type", Boolean)
], NzTreeSelectComponent.prototype, "nzCheckable", void 0);
__decorate([
InputBoolean(),
WithConfig(),
__metadata("design:type", Boolean)
], NzTreeSelectComponent.prototype, "nzHideUnMatched", void 0);
__decorate([
InputBoolean(),
WithConfig(),
__metadata("design:type", Boolean)
], NzTreeSelectComponent.prototype, "nzShowIcon", void 0);
__decorate([
InputBoolean(),
__metadata("design:type", Boolean)
], NzTreeSelectComponent.prototype, "nzShowSearch", void 0);
__decorate([
InputBoolean(),
__metadata("design:type", Object)
], NzTreeSelectComponent.prototype, "nzDisabled", void 0);
__decorate([
InputBoolean(),
__metadata("design:type", Object)
], NzTreeSelectComponent.prototype, "nzAsyncData", void 0);
__decorate([
InputBoolean(),
__metadata("design:type", Object)
], NzTreeSelectComponent.prototype, "nzMultiple", void 0);
__decorate([
InputBoolean(),
__metadata("design:type", Object)
], NzTreeSelectComponent.prototype, "nzDefaultExpandAll", void 0);
__decorate([
InputBoolean(),
__metadata("design:type", Object)
], NzTreeSelectComponent.prototype, "nzCheckStrictly", void 0);
__decorate([
WithConfig(),
__metadata("design:type", String)
], NzTreeSelectComponent.prototype, "nzSize", void 0);
/**
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
*/
class NzTreeSelectModule {
}
NzTreeSelectModule.decorators = [
{ type: NgModule, args: [{
imports: [
BidiModule,
CommonModule,
OverlayModule,
FormsModule,
NzSelectModule,
NzTreeModule,
NzIconModule,
NzEmptyModule,
NzOverlayModule,
NzNoAnimationModule
],
declarations: [NzTreeSelectComponent],
exports: [NzTreeSelectComponent]
},] }
];
/**
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
*/
/**
* Generated bundle index. Do not edit.
*/
export { NzTreeSelectComponent, NzTreeSelectModule, NzTreeSelectService, higherOrderServiceFactory };
//# sourceMappingURL=ng-zorro-antd-tree-select.js.map