UNPKG

ng-zorro-antd

Version:

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

475 lines (464 loc) 20.1 kB
import { __decorate, __metadata } from 'tslib'; import { ESCAPE, hasModifierKey } from '@angular/cdk/keycodes'; import { Overlay, OverlayModule, ConnectionPositionPair } from '@angular/cdk/overlay'; import { Platform, PlatformModule } from '@angular/cdk/platform'; import { TemplatePortal } from '@angular/cdk/portal'; import { EventEmitter, Directive, ElementRef, Renderer2, ViewContainerRef, Input, Output, NgModule, Host, Optional, Component, ViewEncapsulation, ChangeDetectionStrategy, ChangeDetectorRef, ViewChild, TemplateRef, ɵɵdefineInjectable, ɵɵinject, Injectable } from '@angular/core'; import { warnDeprecation } from 'ng-zorro-antd/core/logger'; import { POSITION_MAP, NzOverlayModule } from 'ng-zorro-antd/core/overlay'; import { InputBoolean } from 'ng-zorro-antd/core/util'; import { Subject, BehaviorSubject, merge, fromEvent, EMPTY, combineLatest, Subscription } from 'rxjs'; import { mapTo, map, switchMap, filter, auditTime, distinctUntilChanged, takeUntil, take } from 'rxjs/operators'; import { Directionality, BidiModule } from '@angular/cdk/bidi'; import { CommonModule } from '@angular/common'; import { FormsModule } from '@angular/forms'; import { NzButtonGroupComponent, NzButtonModule } from 'ng-zorro-antd/button'; import { NzNoAnimationDirective, NzNoAnimationModule } from 'ng-zorro-antd/core/no-animation'; import { NzOutletModule } from 'ng-zorro-antd/core/outlet'; import { NzIconModule } from 'ng-zorro-antd/icon'; import { MenuService, NzIsMenuInsideDropDownToken, NzMenuModule } from 'ng-zorro-antd/menu'; import { slideMotion } from 'ng-zorro-antd/core/animation'; /** * 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 */ const listOfPositions = [POSITION_MAP.bottomLeft, POSITION_MAP.bottomRight, POSITION_MAP.topRight, POSITION_MAP.topLeft]; class NzDropDownDirective { constructor(elementRef, overlay, renderer, viewContainerRef, platform) { this.elementRef = elementRef; this.overlay = overlay; this.renderer = renderer; this.viewContainerRef = viewContainerRef; this.platform = platform; this.overlayRef = null; this.destroy$ = new Subject(); this.positionStrategy = this.overlay .position() .flexibleConnectedTo(this.elementRef.nativeElement) .withLockedPosition() .withTransformOriginOn('.ant-dropdown'); this.inputVisible$ = new BehaviorSubject(false); this.nzTrigger$ = new BehaviorSubject('hover'); this.overlayClose$ = new Subject(); this.nzDropdownMenu = null; this.nzTrigger = 'hover'; this.nzMatchWidthElement = null; /** * @deprecated Not supported, use `nzHasBackDrop` instead. * @breaking-change 12.0.0 */ this.nzBackdrop = false; this.nzHasBackdrop = false; this.nzClickHide = true; this.nzDisabled = false; this.nzVisible = false; this.nzOverlayClassName = ''; this.nzOverlayStyle = {}; this.nzPlacement = 'bottomLeft'; this.nzVisibleChange = new EventEmitter(); // TODO: move to host after View Engine deprecation this.elementRef.nativeElement.classList.add('ant-dropdown-trigger'); } setDropdownMenuValue(key, value) { if (this.nzDropdownMenu) { this.nzDropdownMenu.setValue(key, value); } } ngOnInit() { } ngAfterViewInit() { if (this.nzDropdownMenu) { const nativeElement = this.elementRef.nativeElement; /** host mouse state **/ const hostMouseState$ = merge(fromEvent(nativeElement, 'mouseenter').pipe(mapTo(true)), fromEvent(nativeElement, 'mouseleave').pipe(mapTo(false))); /** menu mouse state **/ const menuMouseState$ = this.nzDropdownMenu.mouseState$; /** merged mouse state **/ const mergedMouseState$ = merge(menuMouseState$, hostMouseState$); /** host click state **/ const hostClickState$ = fromEvent(nativeElement, 'click').pipe(map(() => !this.nzVisible)); /** visible state switch by nzTrigger **/ const visibleStateByTrigger$ = this.nzTrigger$.pipe(switchMap(trigger => { if (trigger === 'hover') { return mergedMouseState$; } else if (trigger === 'click') { return hostClickState$; } else { return EMPTY; } })); const descendantMenuItemClick$ = this.nzDropdownMenu.descendantMenuItemClick$.pipe(filter(() => this.nzClickHide), mapTo(false)); const domTriggerVisible$ = merge(visibleStateByTrigger$, descendantMenuItemClick$, this.overlayClose$).pipe(filter(() => !this.nzDisabled)); const visible$ = merge(this.inputVisible$, domTriggerVisible$); combineLatest([visible$, this.nzDropdownMenu.isChildSubMenuOpen$]) .pipe(map(([visible, sub]) => visible || sub), auditTime(150), distinctUntilChanged(), filter(() => this.platform.isBrowser), takeUntil(this.destroy$)) .subscribe((visible) => { const element = this.nzMatchWidthElement ? this.nzMatchWidthElement.nativeElement : nativeElement; const triggerWidth = element.getBoundingClientRect().width; if (this.nzVisible !== visible) { this.nzVisibleChange.emit(visible); } this.nzVisible = visible; if (visible) { /** set up overlayRef **/ if (!this.overlayRef) { /** new overlay **/ this.overlayRef = this.overlay.create({ positionStrategy: this.positionStrategy, minWidth: triggerWidth, disposeOnNavigation: true, hasBackdrop: (this.nzHasBackdrop || this.nzBackdrop) && this.nzTrigger === 'click', scrollStrategy: this.overlay.scrollStrategies.reposition() }); merge(this.overlayRef.backdropClick(), this.overlayRef.detachments(), this.overlayRef.outsidePointerEvents().pipe(filter((e) => !this.elementRef.nativeElement.contains(e.target))), this.overlayRef.keydownEvents().pipe(filter(e => e.keyCode === ESCAPE && !hasModifierKey(e)))) .pipe(mapTo(false), takeUntil(this.destroy$)) .subscribe(this.overlayClose$); } else { /** update overlay config **/ const overlayConfig = this.overlayRef.getConfig(); overlayConfig.minWidth = triggerWidth; } /** open dropdown with animation **/ this.positionStrategy.withPositions([POSITION_MAP[this.nzPlacement], ...listOfPositions]); /** reset portal if needed **/ if (!this.portal || this.portal.templateRef !== this.nzDropdownMenu.templateRef) { this.portal = new TemplatePortal(this.nzDropdownMenu.templateRef, this.viewContainerRef); } this.overlayRef.attach(this.portal); } else { /** detach overlayRef if needed **/ if (this.overlayRef) { this.overlayRef.detach(); } } }); } } ngOnDestroy() { this.destroy$.next(); this.destroy$.complete(); if (this.overlayRef) { this.overlayRef.dispose(); this.overlayRef = null; } } ngOnChanges(changes) { const { nzVisible, nzDisabled, nzOverlayClassName, nzOverlayStyle, nzTrigger, nzBackdrop } = changes; if (nzTrigger) { this.nzTrigger$.next(this.nzTrigger); } if (nzVisible) { this.inputVisible$.next(this.nzVisible); } if (nzDisabled) { const nativeElement = this.elementRef.nativeElement; if (this.nzDisabled) { this.renderer.setAttribute(nativeElement, 'disabled', ''); this.inputVisible$.next(false); } else { this.renderer.removeAttribute(nativeElement, 'disabled'); } } if (nzOverlayClassName) { this.setDropdownMenuValue('nzOverlayClassName', this.nzOverlayClassName); } if (nzOverlayStyle) { this.setDropdownMenuValue('nzOverlayStyle', this.nzOverlayStyle); } if (nzBackdrop) { warnDeprecation('`nzBackdrop` in dropdown component will be removed in 12.0.0, please use `nzHasBackdrop` instead.'); } } } NzDropDownDirective.decorators = [ { type: Directive, args: [{ selector: '[nz-dropdown]', exportAs: 'nzDropdown' },] } ]; NzDropDownDirective.ctorParameters = () => [ { type: ElementRef }, { type: Overlay }, { type: Renderer2 }, { type: ViewContainerRef }, { type: Platform } ]; NzDropDownDirective.propDecorators = { nzDropdownMenu: [{ type: Input }], nzTrigger: [{ type: Input }], nzMatchWidthElement: [{ type: Input }], nzBackdrop: [{ type: Input }], nzHasBackdrop: [{ type: Input }], nzClickHide: [{ type: Input }], nzDisabled: [{ type: Input }], nzVisible: [{ type: Input }], nzOverlayClassName: [{ type: Input }], nzOverlayStyle: [{ type: Input }], nzPlacement: [{ type: Input }], nzVisibleChange: [{ type: Output }] }; __decorate([ InputBoolean(), __metadata("design:type", Object) ], NzDropDownDirective.prototype, "nzBackdrop", void 0); __decorate([ InputBoolean(), __metadata("design:type", Object) ], NzDropDownDirective.prototype, "nzHasBackdrop", void 0); __decorate([ InputBoolean(), __metadata("design:type", Object) ], NzDropDownDirective.prototype, "nzClickHide", void 0); __decorate([ InputBoolean(), __metadata("design:type", Object) ], NzDropDownDirective.prototype, "nzDisabled", void 0); __decorate([ InputBoolean(), __metadata("design:type", Object) ], NzDropDownDirective.prototype, "nzVisible", 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 NzContextMenuServiceModule { } NzContextMenuServiceModule.decorators = [ { type: NgModule } ]; /** * 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 NzDropDownADirective { constructor(elementRef) { this.elementRef = elementRef; // TODO: move to host after View Engine deprecation this.elementRef.nativeElement.classList.add('ant-dropdown-link'); } } NzDropDownADirective.decorators = [ { type: Directive, args: [{ selector: 'a[nz-dropdown]' },] } ]; NzDropDownADirective.ctorParameters = () => [ { type: ElementRef } ]; /** * 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 NzDropdownButtonDirective { constructor(renderer, nzButtonGroupComponent, elementRef) { this.renderer = renderer; this.nzButtonGroupComponent = nzButtonGroupComponent; this.elementRef = elementRef; } ngAfterViewInit() { const parentElement = this.renderer.parentNode(this.elementRef.nativeElement); if (this.nzButtonGroupComponent && parentElement) { this.renderer.addClass(parentElement, 'ant-dropdown-button'); } } } NzDropdownButtonDirective.decorators = [ { type: Directive, args: [{ selector: '[nz-button][nz-dropdown]' },] } ]; NzDropdownButtonDirective.ctorParameters = () => [ { type: Renderer2 }, { type: NzButtonGroupComponent, decorators: [{ type: Host }, { type: Optional }] }, { type: ElementRef } ]; /** * 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 NzDropdownMenuComponent { constructor(cdr, elementRef, renderer, viewContainerRef, nzMenuService, directionality, noAnimation) { this.cdr = cdr; this.elementRef = elementRef; this.renderer = renderer; this.viewContainerRef = viewContainerRef; this.nzMenuService = nzMenuService; this.directionality = directionality; this.noAnimation = noAnimation; this.mouseState$ = new BehaviorSubject(false); this.isChildSubMenuOpen$ = this.nzMenuService.isChildSubMenuOpen$; this.descendantMenuItemClick$ = this.nzMenuService.descendantMenuItemClick$; this.nzOverlayClassName = ''; this.nzOverlayStyle = {}; this.dir = 'ltr'; this.destroy$ = new Subject(); } setMouseState(visible) { this.mouseState$.next(visible); } setValue(key, value) { this[key] = value; this.cdr.markForCheck(); } ngOnInit() { var _a; (_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; } ngAfterContentInit() { this.renderer.removeChild(this.renderer.parentNode(this.elementRef.nativeElement), this.elementRef.nativeElement); } ngOnDestroy() { this.destroy$.next(); this.destroy$.complete(); } } NzDropdownMenuComponent.decorators = [ { type: Component, args: [{ selector: `nz-dropdown-menu`, exportAs: `nzDropdownMenu`, animations: [slideMotion], providers: [ MenuService, /** menu is inside dropdown-menu component **/ { provide: NzIsMenuInsideDropDownToken, useValue: true } ], template: ` <ng-template> <div class="ant-dropdown" [class.ant-dropdown-rtl]="dir === 'rtl'" [ngClass]="nzOverlayClassName" [ngStyle]="nzOverlayStyle" [@slideMotion]="'enter'" [@.disabled]="noAnimation?.nzNoAnimation" [nzNoAnimation]="noAnimation?.nzNoAnimation" (mouseenter)="setMouseState(true)" (mouseleave)="setMouseState(false)" > <ng-content></ng-content> </div> </ng-template> `, preserveWhitespaces: false, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush },] } ]; NzDropdownMenuComponent.ctorParameters = () => [ { type: ChangeDetectorRef }, { type: ElementRef }, { type: Renderer2 }, { type: ViewContainerRef }, { type: MenuService }, { type: Directionality, decorators: [{ type: Optional }] }, { type: NzNoAnimationDirective, decorators: [{ type: Host }, { type: Optional }] } ]; NzDropdownMenuComponent.propDecorators = { templateRef: [{ type: ViewChild, args: [TemplateRef, { static: true },] }] }; /** * 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 NzDropDownModule { } NzDropDownModule.decorators = [ { type: NgModule, args: [{ imports: [ BidiModule, CommonModule, OverlayModule, FormsModule, NzButtonModule, NzMenuModule, NzIconModule, NzNoAnimationModule, PlatformModule, NzOverlayModule, NzContextMenuServiceModule, NzOutletModule ], entryComponents: [NzDropdownMenuComponent], declarations: [NzDropDownDirective, NzDropDownADirective, NzDropdownMenuComponent, NzDropdownButtonDirective], exports: [NzMenuModule, NzDropDownDirective, NzDropDownADirective, NzDropdownMenuComponent, NzDropdownButtonDirective] },] } ]; /** * 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 */ const listOfPositions$1 = [ new ConnectionPositionPair({ originX: 'start', originY: 'top' }, { overlayX: 'start', overlayY: 'top' }), new ConnectionPositionPair({ originX: 'start', originY: 'top' }, { overlayX: 'start', overlayY: 'bottom' }), new ConnectionPositionPair({ originX: 'start', originY: 'top' }, { overlayX: 'end', overlayY: 'bottom' }), new ConnectionPositionPair({ originX: 'start', originY: 'top' }, { overlayX: 'end', overlayY: 'top' }) ]; class NzContextMenuService { constructor(overlay) { this.overlay = overlay; this.overlayRef = null; this.closeSubscription = Subscription.EMPTY; } create($event, nzDropdownMenuComponent) { this.close(true); const { x, y } = $event; if ($event instanceof MouseEvent) { $event.preventDefault(); } const positionStrategy = this.overlay .position() .flexibleConnectedTo({ x, y }) .withPositions(listOfPositions$1) .withTransformOriginOn('.ant-dropdown'); this.overlayRef = this.overlay.create({ positionStrategy, disposeOnNavigation: true, scrollStrategy: this.overlay.scrollStrategies.close() }); this.closeSubscription = merge(nzDropdownMenuComponent.descendantMenuItemClick$, fromEvent(document, 'click').pipe(filter(event => !!this.overlayRef && !this.overlayRef.overlayElement.contains(event.target)), /** handle firefox contextmenu event **/ filter(event => event.button !== 2), take(1))).subscribe(() => { this.close(); }); this.overlayRef.attach(new TemplatePortal(nzDropdownMenuComponent.templateRef, nzDropdownMenuComponent.viewContainerRef)); } close(clear = false) { if (this.overlayRef) { this.overlayRef.detach(); if (clear) { this.overlayRef.dispose(); } this.overlayRef = null; this.closeSubscription.unsubscribe(); } } } NzContextMenuService.ɵprov = ɵɵdefineInjectable({ factory: function NzContextMenuService_Factory() { return new NzContextMenuService(ɵɵinject(Overlay)); }, token: NzContextMenuService, providedIn: NzContextMenuServiceModule }); NzContextMenuService.decorators = [ { type: Injectable, args: [{ providedIn: NzContextMenuServiceModule },] } ]; NzContextMenuService.ctorParameters = () => [ { type: Overlay } ]; /** * 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 { NzContextMenuService, NzContextMenuServiceModule, NzDropDownADirective, NzDropDownDirective, NzDropDownModule, NzDropdownButtonDirective, NzDropdownMenuComponent }; //# sourceMappingURL=ng-zorro-antd-dropdown.js.map