UNPKG

ng-ytl-zorro-antd

Version:

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

197 lines (172 loc) 6.57 kB
import { animate, state, style, transition, trigger } from '@angular/animations'; import { AfterViewInit, ChangeDetectorRef, Component, ContentChildren, EventEmitter, HostBinding, HostListener, Input, OnDestroy, OnInit, Output } from '@angular/core'; import { Subject } from 'rxjs/Subject'; import { debounceTime } from 'rxjs/operators/debounceTime'; import { toBoolean } from '../util/convert'; import { NzMenuComponent } from './nz-menu.component'; @Component({ selector : '[nz-submenu]', animations: [ trigger('expandAnimation', [ state('fade', style({ opacity: 1 })), transition('expand => void', [ style({ height: '*', overflow: 'hidden' }), animate(150, style({ height: 0 })) ]), transition('void => expand', [ style({ height: 0, overflow: 'hidden' }), animate(150, style({ height: '*' })) ]), transition('fade => void', [ animate(150, style({ opacity: 0 })) ]), transition('void => fade', [ style({ opacity: '0' }), animate(150, style({ opacity: 1 })) ]) ]) ], template : ` <div [class.ant-dropdown-menu-submenu-title]="isInDropDown" [class.ant-menu-submenu-title]="!isInDropDown" (mouseenter)="onMouseEnterEvent($event)" (mouseleave)="onMouseLeaveEvent($event)" (click)="clickSubMenuTitle()" [style.paddingLeft.px]="(nzMenuComponent.nzMode === 'inline')?(level*24):null"> <ng-content select="[title]"></ng-content> </div> <ul [class.ant-dropdown-menu]="isInDropDown" [@expandAnimation]="expandState" [class.ant-menu]="!isInDropDown" [class.ant-dropdown-menu-vertical]="isInDropDown" [class.ant-menu-vertical]="(!isInDropDown)&&(nzMenuComponent.nzMode!=='inline')" [class.ant-menu-inline]="(!isInDropDown)&&(nzMenuComponent.nzMode==='inline')" [class.ant-dropdown-menu-sub]="isInDropDown" [class.ant-menu-sub]="!isInDropDown" *ngIf="nzOpen" (click)="clickSubMenuDropDown()" (mouseleave)="onMouseLeaveEvent($event)" (mouseenter)="onMouseEnterEvent($event)"> <ng-content></ng-content> </ul> `, }) export class NzSubMenuComponent implements OnInit, OnDestroy, AfterViewInit { private _open = false; isInDropDown = false; level = 1; _$mouseSubject = new Subject(); @ContentChildren(NzSubMenuComponent) subMenus; @Output() nzOpenChange: EventEmitter<boolean> = new EventEmitter(); @Input() set nzOpen(value: boolean) { this._open = toBoolean(value); } get nzOpen(): boolean { return this._open; } get subItemSelected(): boolean { return !!this.nzMenuComponent.menuItems.find(e => e.nzSelected && e.nzSubMenuComponent === this); } get submenuSelected(): boolean { return !!this.subMenus._results.find(e => e !== this && e.subItemSelected); } get expandState(): string { if (this.nzOpen && this.nzMenuComponent.nzMode === 'inline') { return 'expand'; } else if (this.nzOpen && this.nzMenuComponent.nzMode !== 'inline') { return 'fade'; } return null; } clickSubMenuTitle(): void { if ((this.nzMenuComponent.nzMode === 'inline') && (!this.isInDropDown)) { this.nzOpen = !this.nzOpen; this.nzOpenChange.emit(this.nzOpen); } } clickSubMenuDropDown(): void { if (this.isInDropDown || (this.nzMenuComponent.nzMode === 'vertical') || (this.nzMenuComponent.nzMode === 'horizontal')) { this._$mouseSubject.next(false); this.nzOpen = false; this.nzOpenChange.emit(this.nzOpen); } } @HostListener('mouseenter', [ '$event' ]) onMouseEnterEvent(e: MouseEvent): void { if ((this.nzMenuComponent.nzMode === 'horizontal') || (this.nzMenuComponent.nzMode === 'vertical') || this.isInDropDown) { this._$mouseSubject.next(true); } } @HostListener('mouseleave', [ '$event' ]) onMouseLeaveEvent(e: MouseEvent): void { if ((this.nzMenuComponent.nzMode === 'horizontal') || (this.nzMenuComponent.nzMode === 'vertical') || this.isInDropDown) { this._$mouseSubject.next(false); } } @HostBinding('class.ant-dropdown-menu-submenu') get setDropDownSubmenuClass(): boolean { return this.isInDropDown; } @HostBinding('class.ant-menu-submenu-open') get setMenuSubmenuOpenClass(): boolean { return (!this.isInDropDown) && (this.nzOpen); } @HostBinding('class.ant-dropdown-menu-submenu-vertical') get setDropDownVerticalClass(): boolean { return this.isInDropDown && (this.nzMenuComponent.nzMode === 'vertical'); } @HostBinding('class.ant-dropdown-menu-submenu-horizontal') get setDropDownHorizontalClass(): boolean { return this.isInDropDown && (this.nzMenuComponent.nzMode === 'horizontal'); } @HostBinding('class.ant-menu-submenu') get setMenuSubmenuClass(): boolean { return !this.isInDropDown; } @HostBinding('class.ant-menu-submenu-selected') get setMenuSubmenuSelectedClass(): boolean { return this.submenuSelected || this.subItemSelected; } @HostBinding('class.ant-menu-submenu-vertical') get setMenuVerticalClass(): boolean { return (!this.isInDropDown) && (this.nzMenuComponent.nzMode === 'vertical'); } @HostBinding('class.ant-menu-submenu-horizontal') get setMenuHorizontalClass(): boolean { return (!this.isInDropDown) && (this.nzMenuComponent.nzMode === 'horizontal'); } @HostBinding('class.ant-menu-submenu-inline') get setMenuInlineClass(): boolean { return (!this.isInDropDown) && (this.nzMenuComponent.nzMode === 'inline'); } constructor(public nzMenuComponent: NzMenuComponent, public cd: ChangeDetectorRef) { this.nzMenuComponent.setHasSubMenu(true); this.nzMenuComponent.subMenus.push(this); } ngAfterViewInit(): void { this.isInDropDown = this.nzMenuComponent.isInDropDown; if (this.subMenus.length && (this.nzMenuComponent.nzMode === 'inline')) { this.subMenus.filter(x => x !== this).forEach(menu => { setTimeout(_ => { menu.level = this.level + 1; }); }); } } ngOnInit(): void { this._$mouseSubject.pipe(debounceTime(300)).subscribe((data: boolean) => { if (this.nzOpen !== data) { this.nzOpen = data; this.nzOpenChange.emit(this.nzOpen); } }); } ngOnDestroy(): void { this._$mouseSubject.unsubscribe(); } }