ng-zorro-antd
Version:
An enterprise-class UI components based on Ant Design and Angular
1,159 lines • 65.3 kB
JavaScript
import { Directionality } from '@angular/cdk/bidi';
import * as i0 from '@angular/core';
import { Injectable, InjectionToken, inject, DestroyRef, ChangeDetectorRef, booleanAttribute, ContentChildren, Input, ViewEncapsulation, ChangeDetectionStrategy, Component, input, computed, output, EventEmitter, Output, ElementRef, forwardRef, ViewChild, Directive, Renderer2, NgModule } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { Subject, BehaviorSubject, merge, combineLatest } from 'rxjs';
import { RouterLink, Router, NavigationEnd } from '@angular/router';
import { map, mergeMap, filter, auditTime, distinctUntilChanged, startWith, switchMap } from 'rxjs/operators';
import { numberAttributeWithZeroFallback, generateClassName, getClassListFromValue } from 'ng-zorro-antd/core/util';
import * as i1$2 from '@angular/cdk/overlay';
import { OverlayModule, CdkOverlayOrigin } from '@angular/cdk/overlay';
import { Platform } from '@angular/cdk/platform';
import { NgTemplateOutlet } from '@angular/common';
import * as i1 from 'ng-zorro-antd/core/animation';
import { NzAnimationCollapseDirective, SLIDE_UP_ANIMATION_CLASS, withAnimationCheck, NzNoAnimationDirective } from 'ng-zorro-antd/core/animation';
import { POSITION_MAP, getPlacementName } from 'ng-zorro-antd/core/overlay';
import * as i2 from 'ng-zorro-antd/core/outlet';
import { NzOutletModule } from 'ng-zorro-antd/core/outlet';
import * as i1$1 from 'ng-zorro-antd/icon';
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 MenuService {
/** all descendant menu click **/
descendantMenuItemClick$ = new Subject();
/** child menu item click **/
childMenuItemClick$ = new Subject();
theme$ = new BehaviorSubject('light');
mode$ = new BehaviorSubject('vertical');
inlineIndent$ = new BehaviorSubject(24);
isChildSubMenuOpen$ = new BehaviorSubject(false);
onDescendantMenuItemClick(menu) {
this.descendantMenuItemClick$.next(menu);
}
onChildMenuItemClick(menu) {
this.childMenuItemClick$.next(menu);
}
setMode(mode) {
this.mode$.next(mode);
}
setTheme(theme) {
this.theme$.next(theme);
}
setInlineIndent(indent) {
this.inlineIndent$.next(indent);
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: MenuService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: MenuService });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: MenuService, 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
*/
/**
* A flag to mark if the menu is inside a dropdown.
* @note Internally used only, please do not use it.
*/
const NzIsMenuInsideDropdownToken = new InjectionToken(typeof ngDevMode !== 'undefined' && ngDevMode ? 'nz-is-in-dropdown-menu' : '');
/**
* A token to hold the local {@link MenuService} instance. This is used for nested menu.
* @note Internally used only, please do not use it.
*/
const NzMenuServiceLocalToken = new InjectionToken(typeof ngDevMode !== 'undefined' && ngDevMode ? 'nz-menu-service-local' : '');
/**
* 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 NzSubmenuService {
nzMenuService = inject(MenuService);
isMenuInsideDropdown = inject(NzIsMenuInsideDropdownToken);
nzHostSubmenuService = inject(NzSubmenuService, { optional: true, skipSelf: true });
mode$ = this.nzMenuService.mode$.pipe(map(mode => {
if (mode === 'inline') {
return 'inline';
/** if inside another submenu, set the mode to vertical **/
}
else if (mode === 'vertical' || this.nzHostSubmenuService) {
return 'vertical';
}
else {
return 'horizontal';
}
}));
level = 1;
isCurrentSubMenuOpen$ = new BehaviorSubject(false);
isChildSubMenuOpen$ = new BehaviorSubject(false);
/** submenu title & overlay mouse enter status **/
isMouseEnterTitleOrOverlay$ = new Subject();
childMenuItemClick$ = new Subject();
/**
* menu item inside submenu clicked
*/
onChildMenuItemClick(menu) {
this.childMenuItemClick$.next(menu);
}
setOpenStateWithoutDebounce(value) {
this.isCurrentSubMenuOpen$.next(value);
}
setMouseEnterTitleOrOverlayState(value) {
this.isMouseEnterTitleOrOverlay$.next(value);
}
constructor() {
if (this.nzHostSubmenuService) {
this.level = this.nzHostSubmenuService.level + 1;
}
/** close if menu item clicked **/
const isClosedByMenuItemClick = this.childMenuItemClick$.pipe(mergeMap(() => this.mode$), filter(mode => mode !== 'inline' || this.isMenuInsideDropdown), map(() => false));
const isCurrentSubmenuOpen$ = merge(this.isMouseEnterTitleOrOverlay$, isClosedByMenuItemClick);
/** combine the child submenu status with current submenu status to calculate host submenu open **/
const isSubMenuOpenWithDebounce$ = combineLatest([this.isChildSubMenuOpen$, isCurrentSubmenuOpen$]).pipe(map(([isChildSubMenuOpen, isCurrentSubmenuOpen]) => isChildSubMenuOpen || isCurrentSubmenuOpen), auditTime(150));
isSubMenuOpenWithDebounce$.pipe(distinctUntilChanged(), takeUntilDestroyed()).subscribe(data => {
this.setOpenStateWithoutDebounce(data);
if (this.nzHostSubmenuService) {
/** set parent submenu's child submenu open status **/
this.nzHostSubmenuService.isChildSubMenuOpen$.next(data);
}
else {
this.nzMenuService.isChildSubMenuOpen$.next(data);
}
});
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NzSubmenuService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NzSubmenuService });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NzSubmenuService, decorators: [{
type: Injectable
}], ctorParameters: () => [] });
/**
* 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 NzMenuItemComponent {
nzMenuService = inject(MenuService);
destroyRef = inject(DestroyRef);
cdr = inject(ChangeDetectorRef);
nzSubmenuService = inject(NzSubmenuService, { optional: true });
routerLink = inject(RouterLink, { optional: true });
router = inject(Router, { optional: true });
isMenuInsideDropdown = inject(NzIsMenuInsideDropdownToken);
level = this.nzSubmenuService ? this.nzSubmenuService.level + 1 : 1;
selected$ = new Subject();
inlinePaddingLeft = null;
nzPaddingLeft;
nzDisabled = false;
nzSelected = false;
nzDanger = false;
nzMatchRouterExact = false;
nzMatchRouter = false;
listOfRouterLink;
/** clear all item selected status except this */
clickMenuItem(e) {
if (this.nzDisabled) {
e.preventDefault();
e.stopPropagation();
return;
}
this.nzMenuService.onDescendantMenuItemClick(this);
if (this.nzSubmenuService) {
/** menu item inside the submenu **/
this.nzSubmenuService.onChildMenuItemClick(this);
}
else {
/** menu item inside the root menu **/
this.nzMenuService.onChildMenuItemClick(this);
}
}
setSelectedState(value) {
this.nzSelected = value;
this.selected$.next(value);
}
updateRouterActive() {
if (!this.listOfRouterLink || !this.router || !this.router.navigated || !this.nzMatchRouter) {
return;
}
Promise.resolve().then(() => {
const hasActiveLinks = this.hasActiveLinks();
if (this.nzSelected !== hasActiveLinks) {
this.nzSelected = hasActiveLinks;
this.setSelectedState(this.nzSelected);
this.cdr.markForCheck();
}
});
}
hasActiveLinks() {
const isActiveCheckFn = this.isLinkActive(this.router);
return (this.routerLink && isActiveCheckFn(this.routerLink)) || this.listOfRouterLink.some(isActiveCheckFn);
}
isLinkActive(router) {
return (link) => router.isActive(link.urlTree || '', {
paths: this.nzMatchRouterExact ? 'exact' : 'subset',
queryParams: this.nzMatchRouterExact ? 'exact' : 'subset',
fragment: 'ignored',
matrixParams: 'ignored'
});
}
constructor() {
this.router?.events
.pipe(takeUntilDestroyed(), filter(e => e instanceof NavigationEnd))
.subscribe(() => this.updateRouterActive());
}
ngOnInit() {
/** store origin padding in padding */
combineLatest([this.nzMenuService.mode$, this.nzMenuService.inlineIndent$])
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe(([mode, inlineIndent]) => {
this.inlinePaddingLeft = mode === 'inline' ? this.level * inlineIndent : null;
});
}
ngAfterContentInit() {
this.listOfRouterLink.changes.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => this.updateRouterActive());
this.updateRouterActive();
}
ngOnChanges(changes) {
const { nzSelected } = changes;
if (nzSelected) {
this.setSelectedState(this.nzSelected);
}
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NzMenuItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "16.1.0", version: "21.2.14", type: NzMenuItemComponent, isStandalone: true, selector: "[nz-menu-item]", inputs: { nzPaddingLeft: ["nzPaddingLeft", "nzPaddingLeft", numberAttributeWithZeroFallback], nzDisabled: ["nzDisabled", "nzDisabled", booleanAttribute], nzSelected: ["nzSelected", "nzSelected", booleanAttribute], nzDanger: ["nzDanger", "nzDanger", booleanAttribute], nzMatchRouterExact: ["nzMatchRouterExact", "nzMatchRouterExact", booleanAttribute], nzMatchRouter: ["nzMatchRouter", "nzMatchRouter", booleanAttribute] }, host: { listeners: { "click": "clickMenuItem($event)" }, properties: { "class.ant-dropdown-menu-item": "isMenuInsideDropdown", "class.ant-dropdown-menu-item-selected": "isMenuInsideDropdown && nzSelected", "class.ant-dropdown-menu-item-danger": "isMenuInsideDropdown && nzDanger", "class.ant-dropdown-menu-item-disabled": "isMenuInsideDropdown && nzDisabled", "class.ant-menu-item": "!isMenuInsideDropdown", "class.ant-menu-item-selected": "!isMenuInsideDropdown && nzSelected", "class.ant-menu-item-danger": "!isMenuInsideDropdown && nzDanger", "class.ant-menu-item-disabled": "!isMenuInsideDropdown && nzDisabled", "style.padding-inline-start.px": "nzPaddingLeft || inlinePaddingLeft" } }, queries: [{ propertyName: "listOfRouterLink", predicate: RouterLink, descendants: true }], exportAs: ["nzMenuItem"], usesOnChanges: true, ngImport: i0, template: `
<span class="ant-menu-title-content">
<ng-content />
</span>
`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NzMenuItemComponent, decorators: [{
type: Component,
args: [{
selector: '[nz-menu-item]',
exportAs: 'nzMenuItem',
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
template: `
<span class="ant-menu-title-content">
<ng-content />
</span>
`,
host: {
'[class.ant-dropdown-menu-item]': `isMenuInsideDropdown`,
'[class.ant-dropdown-menu-item-selected]': `isMenuInsideDropdown && nzSelected`,
'[class.ant-dropdown-menu-item-danger]': `isMenuInsideDropdown && nzDanger`,
'[class.ant-dropdown-menu-item-disabled]': `isMenuInsideDropdown && nzDisabled`,
'[class.ant-menu-item]': `!isMenuInsideDropdown`,
'[class.ant-menu-item-selected]': `!isMenuInsideDropdown && nzSelected`,
'[class.ant-menu-item-danger]': `!isMenuInsideDropdown && nzDanger`,
'[class.ant-menu-item-disabled]': `!isMenuInsideDropdown && nzDisabled`,
'[style.padding-inline-start.px]': 'nzPaddingLeft || inlinePaddingLeft',
'(click)': 'clickMenuItem($event)'
}
}]
}], ctorParameters: () => [], propDecorators: { nzPaddingLeft: [{
type: Input,
args: [{ transform: numberAttributeWithZeroFallback }]
}], nzDisabled: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], nzSelected: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], nzDanger: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], nzMatchRouterExact: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], nzMatchRouter: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], listOfRouterLink: [{
type: ContentChildren,
args: [RouterLink, { descendants: 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
*/
const MENU_PREFIX$1 = 'ant-menu';
class NzSubmenuInlineChildComponent {
dir = inject(Directionality).valueSignal;
menuClass = input('', ...(ngDevMode ? [{ debugName: "menuClass" }] : /* istanbul ignore next */ []));
open = input(false, ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
leavedClassName = input(generateClassName(MENU_PREFIX$1, 'submenu-hidden'), ...(ngDevMode ? [{ debugName: "leavedClassName" }] : /* istanbul ignore next */ []));
mergedClass = computed(() => {
const customCls = getClassListFromValue(this.menuClass()) || [];
const cls = [
MENU_PREFIX$1,
generateClassName(MENU_PREFIX$1, 'inline'),
generateClassName(MENU_PREFIX$1, 'sub'),
...customCls
];
if (this.dir() === 'rtl') {
cls.push(generateClassName(MENU_PREFIX$1, 'rtl'));
}
return cls;
}, ...(ngDevMode ? [{ debugName: "mergedClass" }] : /* istanbul ignore next */ []));
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NzSubmenuInlineChildComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.14", type: NzSubmenuInlineChildComponent, isStandalone: true, selector: "[nz-submenu-inline-child]", inputs: { menuClass: { classPropertyName: "menuClass", publicName: "menuClass", isSignal: true, isRequired: false, transformFunction: null }, open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, leavedClassName: { classPropertyName: "leavedClassName", publicName: "leavedClassName", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "mergedClass()" } }, exportAs: ["nzSubmenuInlineChild"], hostDirectives: [{ directive: i1.NzAnimationCollapseDirective, inputs: ["open", "open", "leavedClassName", "leavedClassName"] }], ngImport: i0, template: `<ng-content />`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NzSubmenuInlineChildComponent, decorators: [{
type: Component,
args: [{
selector: '[nz-submenu-inline-child]',
exportAs: 'nzSubmenuInlineChild',
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
template: `<ng-content />`,
hostDirectives: [
{
directive: NzAnimationCollapseDirective,
inputs: ['open', 'leavedClassName']
}
],
host: {
'[class]': 'mergedClass()'
}
}]
}], propDecorators: { menuClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "menuClass", required: false }] }], open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }], leavedClassName: [{ type: i0.Input, args: [{ isSignal: true, alias: "leavedClassName", required: false }] }] } });
/**
* 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 ANT_PREFIX = 'ant';
const MENU_PREFIX = `${ANT_PREFIX}-menu`;
const SUBMENU_PREFIX = `${MENU_PREFIX}-submenu`;
const DROPDOWN_PREFIX = `${ANT_PREFIX}-dropdown`;
const ANIMATION_PREFIX = `${ANT_PREFIX}-zoom-big`;
const ANIMATION_CLASS = {
vertical: {
enter: `${ANIMATION_PREFIX}-enter ${ANIMATION_PREFIX}-enter-active`,
leave: `${ANIMATION_PREFIX}-leave ${ANIMATION_PREFIX}-leave-active`
},
horizontal: SLIDE_UP_ANIMATION_CLASS
};
class NzSubmenuNoneInlineChildComponent {
isMenuInsideDropdown = inject(NzIsMenuInsideDropdownToken);
dir = inject(Directionality).valueSignal;
menuClass = input('', ...(ngDevMode ? [{ debugName: "menuClass" }] : /* istanbul ignore next */ []));
theme = input('light', ...(ngDevMode ? [{ debugName: "theme" }] : /* istanbul ignore next */ []));
mode = input('vertical', ...(ngDevMode ? [{ debugName: "mode" }] : /* istanbul ignore next */ []));
position = input('right', ...(ngDevMode ? [{ debugName: "position" }] : /* istanbul ignore next */ []));
open = input(false, ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
nzDisabled = input(false, ...(ngDevMode ? [{ debugName: "nzDisabled" }] : /* istanbul ignore next */ []));
nzTriggerSubMenuAction = input('hover', ...(ngDevMode ? [{ debugName: "nzTriggerSubMenuAction" }] : /* istanbul ignore next */ []));
subMenuMouseState = output();
animationEnter = withAnimationCheck(() => ANIMATION_CLASS[this.mode()].enter);
animationLeave = withAnimationCheck(() => ANIMATION_CLASS[this.mode()].leave);
submenuClass = computed(() => {
const cls = [
SUBMENU_PREFIX,
generateClassName(SUBMENU_PREFIX, 'popup'),
generateClassName(MENU_PREFIX, this.theme() === 'dark' ? 'dark' : 'light')
];
const mode = this.mode();
const position = this.position() === 'left' ? 'left' : 'right';
if (mode === 'horizontal') {
cls.push(generateClassName(SUBMENU_PREFIX, 'placement-bottom'));
}
else if (mode === 'vertical') {
cls.push(generateClassName(SUBMENU_PREFIX, `placement-${position}`));
}
if (this.dir() === 'rtl') {
cls.push(generateClassName(SUBMENU_PREFIX, 'rtl'));
}
return cls;
}, ...(ngDevMode ? [{ debugName: "submenuClass" }] : /* istanbul ignore next */ []));
mergedMenuClass = computed(() => {
const cls = getClassListFromValue(this.menuClass()) || [];
if (this.isMenuInsideDropdown) {
cls.push(generateClassName(DROPDOWN_PREFIX, 'menu'), generateClassName(DROPDOWN_PREFIX, 'menu-sub'), generateClassName(DROPDOWN_PREFIX, 'menu-vertical'));
}
else {
cls.push(MENU_PREFIX, generateClassName(MENU_PREFIX, 'sub'), generateClassName(MENU_PREFIX, 'vertical'));
}
if (this.dir() === 'rtl') {
cls.push(generateClassName(MENU_PREFIX, 'rtl'));
}
return cls;
}, ...(ngDevMode ? [{ debugName: "mergedMenuClass" }] : /* istanbul ignore next */ []));
setMouseState(state) {
if (!this.nzDisabled() && this.nzTriggerSubMenuAction() === 'hover') {
this.subMenuMouseState.emit(state);
}
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NzSubmenuNoneInlineChildComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.14", type: NzSubmenuNoneInlineChildComponent, isStandalone: true, selector: "[nz-submenu-none-inline-child]", inputs: { menuClass: { classPropertyName: "menuClass", publicName: "menuClass", isSignal: true, isRequired: false, transformFunction: null }, theme: { classPropertyName: "theme", publicName: "theme", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, position: { classPropertyName: "position", publicName: "position", isSignal: true, isRequired: false, transformFunction: null }, open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, nzDisabled: { classPropertyName: "nzDisabled", publicName: "nzDisabled", isSignal: true, isRequired: false, transformFunction: null }, nzTriggerSubMenuAction: { classPropertyName: "nzTriggerSubMenuAction", publicName: "nzTriggerSubMenuAction", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { subMenuMouseState: "subMenuMouseState" }, host: { listeners: { "mouseenter": "setMouseState(true)", "mouseleave": "setMouseState(false)" }, properties: { "class": "submenuClass()", "animate.enter": "animationEnter()", "animate.leave": "animationLeave()" } }, exportAs: ["nzSubmenuNoneInlineChild"], ngImport: i0, template: `
<div [class]="mergedMenuClass()">
<ng-content />
</div>
`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NzSubmenuNoneInlineChildComponent, decorators: [{
type: Component,
args: [{
selector: '[nz-submenu-none-inline-child]',
exportAs: 'nzSubmenuNoneInlineChild',
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<div [class]="mergedMenuClass()">
<ng-content />
</div>
`,
host: {
'[class]': 'submenuClass()',
'(mouseenter)': 'setMouseState(true)',
'(mouseleave)': 'setMouseState(false)',
'[animate.enter]': `animationEnter()`,
'[animate.leave]': `animationLeave()`
}
}]
}], propDecorators: { menuClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "menuClass", required: false }] }], theme: [{ type: i0.Input, args: [{ isSignal: true, alias: "theme", required: false }] }], mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }], nzDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "nzDisabled", required: false }] }], nzTriggerSubMenuAction: [{ type: i0.Input, args: [{ isSignal: true, alias: "nzTriggerSubMenuAction", required: false }] }], subMenuMouseState: [{ type: i0.Output, args: ["subMenuMouseState"] }] } });
/**
* 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 NzSubMenuTitleComponent {
isMenuInsideDropdown = inject(NzIsMenuInsideDropdownToken);
dir = inject(Directionality).valueSignal;
nzIcon = null;
nzTitle = null;
nzDisabled = false;
paddingLeft = null;
mode = 'vertical';
nzTriggerSubMenuAction = 'hover';
toggleSubMenu = new EventEmitter();
subMenuMouseState = new EventEmitter();
setMouseState(state) {
if (!this.nzDisabled && this.nzTriggerSubMenuAction === 'hover') {
this.subMenuMouseState.next(state);
}
}
clickTitle() {
if ((this.mode === 'inline' || this.nzTriggerSubMenuAction === 'click') && !this.nzDisabled) {
this.subMenuMouseState.next(true);
this.toggleSubMenu.emit();
}
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NzSubMenuTitleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: NzSubMenuTitleComponent, isStandalone: true, selector: "[nz-submenu-title]", inputs: { nzIcon: "nzIcon", nzTitle: "nzTitle", nzDisabled: "nzDisabled", paddingLeft: "paddingLeft", mode: "mode", nzTriggerSubMenuAction: "nzTriggerSubMenuAction" }, outputs: { toggleSubMenu: "toggleSubMenu", subMenuMouseState: "subMenuMouseState" }, host: { listeners: { "click": "clickTitle()", "mouseenter": "setMouseState(true)", "mouseleave": "setMouseState(false)" }, properties: { "class.ant-dropdown-menu-submenu-title": "isMenuInsideDropdown", "class.ant-menu-submenu-title": "!isMenuInsideDropdown", "style.padding-inline-start.px": "paddingLeft" } }, exportAs: ["nzSubmenuTitle"], ngImport: i0, template: `
@if (nzIcon) {
<nz-icon [nzType]="nzIcon" />
}
<ng-container *nzStringTemplateOutlet="nzTitle">
<span class="ant-menu-title-content">{{ nzTitle }}</span>
</ng-container>
<ng-content />
@if (isMenuInsideDropdown) {
<span class="ant-dropdown-menu-submenu-expand-icon">
<nz-icon [nzType]="dir() === 'rtl' ? 'left' : 'right'" class="ant-dropdown-menu-submenu-arrow-icon" />
</span>
} @else {
<span class="ant-menu-submenu-arrow"></span>
}
`, isInline: true, dependencies: [{ kind: "ngmodule", type: NzIconModule }, { kind: "directive", type: i1$1.NzIconDirective, selector: "nz-icon,[nz-icon]", inputs: ["nzSpin", "nzRotate", "nzType", "nzTheme", "nzTwotoneColor", "nzIconfont"], exportAs: ["nzIcon"] }, { kind: "ngmodule", type: NzOutletModule }, { kind: "directive", type: i2.NzStringTemplateOutletDirective, selector: "[nzStringTemplateOutlet]", inputs: ["nzStringTemplateOutletContext", "nzStringTemplateOutlet"], exportAs: ["nzStringTemplateOutlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NzSubMenuTitleComponent, decorators: [{
type: Component,
args: [{
selector: '[nz-submenu-title]',
exportAs: 'nzSubmenuTitle',
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
@if (nzIcon) {
<nz-icon [nzType]="nzIcon" />
}
<ng-container *nzStringTemplateOutlet="nzTitle">
<span class="ant-menu-title-content">{{ nzTitle }}</span>
</ng-container>
<ng-content />
@if (isMenuInsideDropdown) {
<span class="ant-dropdown-menu-submenu-expand-icon">
<nz-icon [nzType]="dir() === 'rtl' ? 'left' : 'right'" class="ant-dropdown-menu-submenu-arrow-icon" />
</span>
} @else {
<span class="ant-menu-submenu-arrow"></span>
}
`,
host: {
'[class.ant-dropdown-menu-submenu-title]': 'isMenuInsideDropdown',
'[class.ant-menu-submenu-title]': '!isMenuInsideDropdown',
'[style.padding-inline-start.px]': 'paddingLeft',
'(click)': 'clickTitle()',
'(mouseenter)': 'setMouseState(true)',
'(mouseleave)': 'setMouseState(false)'
},
imports: [NzIconModule, NzOutletModule]
}]
}], propDecorators: { nzIcon: [{
type: Input
}], nzTitle: [{
type: Input
}], nzDisabled: [{
type: Input
}], paddingLeft: [{
type: Input
}], mode: [{
type: Input
}], nzTriggerSubMenuAction: [{
type: Input
}], toggleSubMenu: [{
type: Output
}], subMenuMouseState: [{
type: Output
}] } });
/**
* 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 listOfVerticalPositions = [
POSITION_MAP.rightTop,
POSITION_MAP.right,
POSITION_MAP.rightBottom,
POSITION_MAP.leftTop,
POSITION_MAP.left,
POSITION_MAP.leftBottom
];
const listOfHorizontalPositions = [
POSITION_MAP.bottomLeft,
POSITION_MAP.bottomRight,
POSITION_MAP.topRight,
POSITION_MAP.topLeft
];
class NzSubMenuComponent {
nzSubmenuService = inject(NzSubmenuService);
isMenuInsideDropdown = inject(NzIsMenuInsideDropdownToken);
noAnimation = inject(NzNoAnimationDirective, { optional: true, host: true });
dir = inject(Directionality).valueSignal;
destroyRef = inject(DestroyRef);
nzMenuService = inject(MenuService);
cdr = inject(ChangeDetectorRef);
platform = inject(Platform);
nzMenuClassName = '';
nzPaddingLeft = null;
nzTitle = null;
nzIcon = null;
nzTriggerSubMenuAction = 'hover';
nzOpen = false;
nzDisabled = false;
nzPlacement = 'bottomLeft';
nzOpenChange = new EventEmitter();
cdkOverlayOrigin = null;
// fix errors about circular dependency
// Can't construct a query for the property ... since the query selector wasn't defined
listOfNzSubMenuComponent = null;
listOfNzMenuItemDirective = null;
level = this.nzSubmenuService.level;
position = 'right';
triggerWidth = null;
theme = 'light';
mode = 'vertical';
inlinePaddingLeft = null;
overlayPositions = listOfVerticalPositions;
isSelected = false;
isActive = false;
/** set the submenu host open status directly **/
setOpenStateWithoutDebounce(open) {
this.nzSubmenuService.setOpenStateWithoutDebounce(open);
}
toggleSubMenu() {
this.setOpenStateWithoutDebounce(!this.nzOpen);
}
setMouseEnterState(value) {
this.isActive = value;
if (this.mode !== 'inline') {
this.nzSubmenuService.setMouseEnterTitleOrOverlayState(value);
}
}
setTriggerWidth() {
if (this.mode === 'horizontal' &&
this.platform.isBrowser &&
this.cdkOverlayOrigin &&
this.nzPlacement === 'bottomLeft') {
/** TODO: fast dom */
this.triggerWidth = this.cdkOverlayOrigin.nativeElement.getBoundingClientRect().width;
}
}
onPositionChange(position) {
const placement = getPlacementName(position);
if (placement === 'rightTop' || placement === 'rightBottom' || placement === 'right') {
this.position = 'right';
}
else if (placement === 'leftTop' || placement === 'leftBottom' || placement === 'left') {
this.position = 'left';
}
}
ngOnInit() {
/** submenu theme update **/
this.nzMenuService.theme$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(theme => {
this.theme = theme;
this.cdr.markForCheck();
});
/** submenu mode update **/
this.nzSubmenuService.mode$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(mode => {
this.mode = mode;
if (mode === 'horizontal') {
this.overlayPositions = [POSITION_MAP[this.nzPlacement], ...listOfHorizontalPositions];
}
else if (mode === 'vertical') {
this.overlayPositions = listOfVerticalPositions;
}
this.cdr.markForCheck();
});
/** inlineIndent update **/
combineLatest([this.nzSubmenuService.mode$, this.nzMenuService.inlineIndent$])
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe(([mode, inlineIndent]) => {
this.inlinePaddingLeft = mode === 'inline' ? this.level * inlineIndent : null;
this.cdr.markForCheck();
});
/** current submenu open status **/
this.nzSubmenuService.isCurrentSubMenuOpen$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(open => {
this.isActive = open;
if (open !== this.nzOpen) {
this.setTriggerWidth();
this.nzOpen = open;
this.nzOpenChange.emit(this.nzOpen);
this.cdr.markForCheck();
}
});
}
ngAfterContentInit() {
this.setTriggerWidth();
const listOfNzMenuItemDirective = this.listOfNzMenuItemDirective;
const changes = listOfNzMenuItemDirective.changes;
const mergedObservable = merge(changes, ...listOfNzMenuItemDirective.map(menu => menu.selected$));
changes
.pipe(startWith(listOfNzMenuItemDirective), switchMap(() => mergedObservable), startWith(true), map(() => listOfNzMenuItemDirective.some(e => e.nzSelected)), takeUntilDestroyed(this.destroyRef))
.subscribe(selected => {
this.isSelected = selected;
this.cdr.markForCheck();
});
}
ngOnChanges(changes) {
const { nzOpen } = changes;
if (nzOpen) {
this.nzSubmenuService.setOpenStateWithoutDebounce(this.nzOpen);
this.setTriggerWidth();
}
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NzSubMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: NzSubMenuComponent, isStandalone: true, selector: "[nz-submenu]", inputs: { nzMenuClassName: "nzMenuClassName", nzPaddingLeft: "nzPaddingLeft", nzTitle: "nzTitle", nzIcon: "nzIcon", nzTriggerSubMenuAction: "nzTriggerSubMenuAction", nzOpen: ["nzOpen", "nzOpen", booleanAttribute], nzDisabled: ["nzDisabled", "nzDisabled", booleanAttribute], nzPlacement: "nzPlacement" }, outputs: { nzOpenChange: "nzOpenChange" }, host: { properties: { "class.ant-dropdown-menu-submenu": "isMenuInsideDropdown", "class.ant-dropdown-menu-submenu-disabled": "isMenuInsideDropdown && nzDisabled", "class.ant-dropdown-menu-submenu-open": "isMenuInsideDropdown && nzOpen", "class.ant-dropdown-menu-submenu-selected": "isMenuInsideDropdown && isSelected", "class.ant-dropdown-menu-submenu-vertical": "isMenuInsideDropdown && mode === 'vertical'", "class.ant-dropdown-menu-submenu-horizontal": "isMenuInsideDropdown && mode === 'horizontal'", "class.ant-dropdown-menu-submenu-inline": "isMenuInsideDropdown && mode === 'inline'", "class.ant-dropdown-menu-submenu-active": "isMenuInsideDropdown && isActive", "class.ant-menu-submenu": "!isMenuInsideDropdown", "class.ant-menu-submenu-disabled": "!isMenuInsideDropdown && nzDisabled", "class.ant-menu-submenu-open": "!isMenuInsideDropdown && nzOpen", "class.ant-menu-submenu-selected": "!isMenuInsideDropdown && isSelected", "class.ant-menu-submenu-vertical": "!isMenuInsideDropdown && mode === 'vertical'", "class.ant-menu-submenu-horizontal": "!isMenuInsideDropdown && mode === 'horizontal'", "class.ant-menu-submenu-inline": "!isMenuInsideDropdown && mode === 'inline'", "class.ant-menu-submenu-active": "!isMenuInsideDropdown && isActive", "class.ant-menu-submenu-rtl": "dir() === 'rtl'" } }, providers: [NzSubmenuService], queries: [{ propertyName: "listOfNzSubMenuComponent", predicate: i0.forwardRef(() => NzSubMenuComponent), descendants: true }, { propertyName: "listOfNzMenuItemDirective", predicate: NzMenuItemComponent, descendants: true }], viewQueries: [{ propertyName: "cdkOverlayOrigin", first: true, predicate: CdkOverlayOrigin, descendants: true, read: ElementRef, static: true }], exportAs: ["nzSubmenu"], usesOnChanges: true, ngImport: i0, template: `
<div
nz-submenu-title
cdkOverlayOrigin
#origin="cdkOverlayOrigin"
[nzIcon]="nzIcon"
[nzTitle]="nzTitle"
[mode]="mode"
[nzDisabled]="nzDisabled"
[paddingLeft]="nzPaddingLeft || inlinePaddingLeft"
[nzTriggerSubMenuAction]="nzTriggerSubMenuAction"
(subMenuMouseState)="setMouseEnterState($event)"
(toggleSubMenu)="toggleSubMenu()"
>
@if (!nzTitle) {
<ng-content select="[title]" />
}
</div>
@if (mode === 'inline') {
<div
nz-submenu-inline-child
[open]="nzOpen"
[menuClass]="nzMenuClassName"
leavedClassName="ant-menu-submenu-hidden"
>
<ng-template [ngTemplateOutlet]="subMenuTemplate" />
</div>
} @else {
<ng-template
cdkConnectedOverlay
(positionChange)="onPositionChange($event)"
[cdkConnectedOverlayPositions]="overlayPositions"
[cdkConnectedOverlayOrigin]="origin"
[cdkConnectedOverlayWidth]="triggerWidth!"
[cdkConnectedOverlayOpen]="nzOpen"
cdkConnectedOverlayTransformOriginOn=".ant-menu-submenu"
(overlayOutsideClick)="setMouseEnterState(false)"
>
<div
nz-submenu-none-inline-child
[theme]="theme"
[mode]="mode"
[open]="nzOpen"
[position]="position"
[menuClass]="nzMenuClassName"
[nzDisabled]="nzDisabled"
[nzTriggerSubMenuAction]="nzTriggerSubMenuAction"
[nzNoAnimation]="noAnimation?.nzNoAnimation?.()"
(subMenuMouseState)="setMouseEnterState($event)"
>
<ng-template [ngTemplateOutlet]="subMenuTemplate" />
</div>
</ng-template>
}
<ng-template #subMenuTemplate>
<ng-content />
</ng-template>
`, isInline: true, dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: NzSubMenuTitleComponent, selector: "[nz-submenu-title]", inputs: ["nzIcon", "nzTitle", "nzDisabled", "paddingLeft", "mode", "nzTriggerSubMenuAction"], outputs: ["toggleSubMenu", "subMenuMouseState"], exportAs: ["nzSubmenuTitle"] }, { kind: "component", type: NzSubmenuInlineChildComponent, selector: "[nz-submenu-inline-child]", inputs: ["menuClass", "open", "leavedClassName"], exportAs: ["nzSubmenuInlineChild"] }, { kind: "directive", type: NzNoAnimationDirective, selector: "[nzNoAnimation]", inputs: ["nzNoAnimation"], exportAs: ["nzNoAnimation"] }, { kind: "component", type: NzSubmenuNoneInlineChildComponent, selector: "[nz-submenu-none-inline-child]", inputs: ["menuClass", "theme", "mode", "position", "open", "nzDisabled", "nzTriggerSubMenuAction"], outputs: ["subMenuMouseState"], exportAs: ["nzSubmenuNoneInlineChild"] }, { kind: "ngmodule", type: OverlayModule }, { kind: "directive", type: i1$2.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", "cdkConnectedOverlayUsePopover", "cdkConnectedOverlayMatchWidth", "cdkConnectedOverlay"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: i1$2.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NzSubMenuComponent, decorators: [{
type: Component,
args: [{
selector: '[nz-submenu]',
exportAs: 'nzSubmenu',
providers: [NzSubmenuService],
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<div
nz-submenu-title
cdkOverlayOrigin
#origin="cdkOverlayOrigin"
[nzIcon]="nzIcon"
[nzTitle]="nzTitle"
[mode]="mode"
[nzDisabled]="nzDisabled"
[paddingLeft]="nzPaddingLeft || inlinePaddingLeft"
[nzTriggerSubMenuAction]="nzTriggerSubMenuAction"
(subMenuMouseState)="setMouseEnterState($event)"
(toggleSubMenu)="toggleSubMenu()"
>
@if (!nzTitle) {
<ng-content select="[title]" />
}
</div>
@if (mode === 'inline') {
<div
nz-submenu-inline-child
[open]="nzOpen"
[menuClass]="nzMenuClassName"
leavedClassName="ant-menu-submenu-hidden"
>
<ng-template [ngTemplateOutlet]="subMenuTemplate" />
</div>
} @else {
<ng-template
cdkConnectedOverlay
(positionChange)="onPositionChange($event)"
[cdkConnectedOverlayPositions]="overlayPositions"
[cdkConnectedOverlayOrigin]="origin"
[cdkConnectedOverlayWidth]="triggerWidth!"
[cdkConnectedOverlayOpen]="nzOpen"
cdkConnectedOverlayTransformOriginOn=".ant-menu-submenu"
(overlayOutsideClick)="setMouseEnterState(false)"
>
<div
nz-submenu-none-inline-child
[theme]="theme"
[mode]="mode"
[open]="nzOpen"
[position]="position"
[menuClass]="nzMenuClassName"
[nzDisabled]="nzDisabled"
[nzTriggerSubMenuAction]="nzTriggerSubMenuAction"
[nzNoAnimation]="noAnimation?.nzNoAnimation?.()"
(subMenuMouseState)="setMouseEnterState($event)"
>
<ng-template [ngTemplateOutlet]="subMenuTemplate" />
</div>
</ng-template>
}
<ng-template #subMenuTemplate>
<ng-content />
</ng-template>
`,
host: {
'[class.ant-dropdown-menu-submenu]': `isMenuInsideDropdown`,
'[class.ant-dropdown-menu-submenu-disabled]': `isMenuInsideDropdown && nzDisabled`,
'[class.ant-dropdown-menu-submenu-open]': `isMenuInsideDropdown && nzOpen`,
'[class.ant-dropdown-menu-submenu-selected]': `isMenuInsideDropdown && isSelected`,
'[class.ant-dropdown-menu-submenu-vertical]': `isMenuInsideDropdown && mode === 'vertical'`,
'[class.ant-dropdown-menu-submenu-horizontal]': `isMenuInsideDropdown && mode === 'horizontal'`,
'[class.ant-dropdown-menu-submenu-inline]': `isMenuInsideDropdown && mode === 'inline'`,
'[class.ant-dropdown-menu-submenu-active]': `isMenuInsideDropdown && isActive`,
'[class.ant-menu-submenu]': `!isMenuInsideDropdown`,
'[class.ant-menu-submenu-disabled]': `!isMenuInsideDropdown && nzDisabled`,
'[class.ant-menu-submenu-open]': `!isMenuInsideDropdown && nzOpen`,
'[class.ant-menu-submenu-selected]': `!isMenuInsideDropdown && isSelected`,
'[class.ant-menu-submenu-vertical]': `!isMenuInsideDropdown && mode === 'vertical'`,
'[class.ant-menu-submenu-horizontal]': `!isMenuInsideDropdown && mode === 'horizontal'`,
'[class.ant-menu-submenu-inline]': `!isMenuInsideDropdown && mode === 'inline'`,
'[class.ant-menu-submenu-active]': `!isMenuInsideDropdown && isActive`,
'[class.ant-menu-submenu-rtl]': `dir() === 'rtl'`
},
imports: [
NgTemplateOutlet,
NzSubMenuTitleComponent,
NzSubmenuInlineChildComponent,
NzNoAnimationDirective,
NzSubmenuNoneInlineChildComponent,
OverlayModule
]
}]
}], propDecorators: { nzMenuClassName: [{
type: Input
}], nzPaddingLeft: [{
type: Input
}], nzTitle: [{
type: Input
}], nzIcon: [{
type: Input
}], nzTriggerSubMenuAction: [{
type: Input
}], nzOpen: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], nzDisabled: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], nzPlacement: [{
type: Input
}], nzOpenChange: [{
type: Output
}], cdkOverlayOrigin: [{
type: ViewChild,
args: [CdkOverlayOrigin, { static: true, read: ElementRef }]
}], listOfNzSubMenuComponent: [{
type: ContentChildren,
args: [forwardRef(() => NzSubMenuComponent), { descendants: true }]
}], listOfNzMenuItemDirective: [{
type: ContentChildren,
args: [NzMenuItemComponent, { descendants: 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
*/
function MenuServiceFactory() {
const serviceInsideDropdown = inject(MenuService, { skipSelf: true, optional: true });
const serviceOutsideDropdown = inject(NzMenuServiceLocalToken);
return serviceInsideDropdown ?? serviceOutsideDropdown;
}
function MenuDropdownTokenFactory() {
const isMenuInsideDropdownToken = inject(NzIsMenuInsideDropdownToken, { skipSelf: true, optional: true });
return isMenuInsideDropdownToken ?? false;
}
class NzMenuDirective {
nzMenuService = inject(MenuService);
destroyRef = inject(DestroyRef);
cdr = inject(ChangeDetectorRef);
dir = inject(Directionality).valueSignal;
isMenuInsideDropdown = inject(NzIsMenuInsideDropdownToken);
listOfNzMenuItemDirective;
listOfNzSubMenuComponent;
nzInlineIndent = 24;
nzTheme = 'light';
nzMode = 'vertical';
nzInlineCollapsed = false;
nzSelectable = !this.isMenuInsideDropdown;
nzClick = new EventEmitter();
actualMode = 'vertical';
inlineCollapsed$ = new BehaviorSubject(this.nzInlineCollapsed);
mode$ = new BehaviorSubject(this.nzMode);
listOfOpenedNzSubMenuComponent = [];
setInlineCollapsed(inlineCollapsed) {
this.nzInlineCollapsed = inlineCollapsed;
this.inlineCollapsed$.next(inlineCollapsed);
}
updateInlineCollapse() {
if (this.listOfNzMenuItemDirective) {
if (this.nzInlineCollapsed) {
this.listOfOpenedNzSubMenuComponent = this.listOfNzSubMenuComponent.filter(submenu => submenu.nzOpen);
this.listOfNzSubMenuComponent.forEach(submenu => submenu.setOpenStateWithoutDebounce(false));
}
else {
this.listOfOpenedNzSubMenuComponent.forEach(submenu => submenu.setOpenStateWithoutDebounce(true));
this.listOfOpenedNzSubMenuComponent = [];
}
}
}
ngOnInit() {
combineLatest([this.inlineCollapsed$, this.mode$])
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe(([inlineCollapsed, mode]) => {
this.actualMode = inlineCollapsed ? 'vertical' : mode;
this.nzMenuService.setMode(this.actualMode);
this.cdr.markForCheck();
});
this.nzMenuService.descendantMenuItemClick$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(menu => {
this.nzClick.emit(menu);
if (this.nzSelectable && !menu.nzMatchRouter) {
this.listOfNzMenuItemDirective.forEach(item => item.setSelectedState(item === menu));
}
});
}
ngAfterContentInit() {
this.inlineCollapsed$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => {
this.updateInlineCollapse();
this.cdr.markForCheck();
});
}
ngOnChanges(changes) {
const { nzInlineCollapsed, nzInlineIndent, nzTheme, nzMode } = changes;
if (nzInlineCollapsed) {
this.inlineCollapsed$.next(this.nzInlineCollapsed);
}
if (nzInlineIndent) {
this.nzMenuService.setInlineIndent(this.nzInlineIndent);
}
if (nzTheme) {
this.nzMenuService.setTheme(this.nzTheme);
}
if (nzMode) {
this.mode$.next(this.nzMode);
if (!nzMode.isFirstChange() && this.listOfNzSubMenuComponent) {
this.listOfNzSubMenuComponent.forEach(submenu => submenu.setOpenStateWithoutDebounce(false));
}
}
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NzMenuDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "21.2.14", type: NzMenuDirective, isStandalone: true, selector: "[nz-menu]", inputs: { nzInlineIndent: "nzInlineIndent", nzTheme: "nzTheme", nzMode: "nzMode", nzInlineCollapsed: ["nzInlineCollapsed", "nzInlineCollapsed", booleanAttribute], nzSelectable: ["nzSelectable", "nzSelectable", booleanAttribute] }, outputs: { nzClick: "nzClick" }, host: { properties: { "class.ant-dropdown-menu": "isMenuInsideDropdown", "class.ant-dropdown-menu-root": "isMenuInsideDropdown", "class.ant-dropdown-menu-light": "isMenuInsideDropdown && nzTheme === 'light'", "class.ant-dropdown-menu-dark": "isMenuInsideDropdown && nzTheme === 'dark'", "class.ant-dropdown-menu-vertical": "isMenuInsideDropdown && actualMode === 'vertical'", "class.ant-dropdown-menu-horizontal": "isMenuInsideDropdown && actualMode === 'horizontal'", "class.ant-dropdown-menu-inline": "isMenuInsideDropdown && actualMode === 'inline'", "class.ant-dropdown-menu-inline-collapsed": "isMenuInsideDropdown && nzInlineCollapsed", "class.ant-menu": "!isMenuInsideDropdown", "class.ant-menu-root": "!isMenuInsideDropdown", "class.ant-menu-light": "!isMenuInsideDropdown && nzTheme === 'light'", "class.ant-menu-dark": "!isMenuInsideDropdown && nzTheme === 'dark'", "class.ant-menu-vertical": "!isMenuInsideDropdown && actualMode === 'vertical'", "class.ant-menu-horizontal": "!isMenuInsideDropdown && actualMode === 'horizontal'", "class.ant-menu-inline": "!isMenuInsideDropdown && actualMode === 'inline'", "class.ant-menu-inline-collapsed": "!isMenuInsideDropdown && nzInlineCollapsed", "class.ant-menu-rtl": "dir() === 'rtl'" } }, providers: [
{
provide: NzMenuServiceLocalToken,
useClass: MenuService
},
/** use the top level service **/
{
provide: MenuService,
useFactory: MenuServiceFactory
},
/** check if menu inside dropdown-menu component **/
{
provide: NzIsMenuInsideDropdownToken,
useFactory: MenuDropdownTokenFactory
}
], queries: [{ propertyName: "listOfNzMenuItemDirective", predicate: NzMenuItemComponent, descendants: true }, { propertyName: "listOfNzSubMenuComponent", predicate: NzSubMenuComponent, descendants: true }], exportAs: ["nzMenu"], usesOnChanges: true, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NzMenuDirective, decorators: [{
type: Directive,
args: [{
selector: '[nz-menu]',
exportAs: 'nzMenu',
providers: [
{
provide: NzMenuServiceLocalToken,
useClass: MenuService
},
/** use the top level service **/
{
provide: MenuService,
useFactory: MenuServiceFactory
},
/** check if menu inside dropdown-menu component **/
{
provide: NzIsMenuInsideDropdownToken,
useFactory: MenuDropdownTokenFactory
}
],
host: {
'[class.ant-dropdown-menu]': `isMenuInsideDropdown`,
'[class.ant-dropdown-menu-root]': `isMenuInsideDropdown`,
'[class.ant-dropdown-menu-light]': `isMenuInsideDropdown && nzTheme === 'light'`,
'[class.ant-dropdown-menu-dark]': `isMenuInsideDropdown && nzTheme === 'dark'`,
'[class.ant-dropdown-menu-vertical]': `isMenuInsideDropdown && actualMode === 'vertical'`,
'[class.ant-dropdown-menu-horizontal]': `isMenuInsideDropdown && actualMode === 'horizontal'`,
'[class.ant-dropdown-menu-inline]': `isMenuInsideDropdown && actualMode === 'inline'`,
'[class.ant-dropdown-menu-inline-collapsed]': `isMenuInsideDropdown && nzInlineCollapsed`,
'[class.ant-menu]': `!isMenuInsideDropdown`,
'[class.ant-menu-root]': `!isMenuInsideDropdown`,
'[class.ant-menu-light]': `!isMenuInsideDropdown && nzTheme === 'light'`,
'[class.ant-menu-dark]': `!isMenuInsideDropdown && nzTheme === 'dark'`,
'[class.ant-menu-vertical]': `!isMenuInsideDropdown && actualMode === 'vertical'`,
'[class.ant-menu-horizontal]': `!isMenuInsideDropdown && actualMode === 'horizontal'`,
'[class.ant-menu-inline]': `!isMenuInsideDropdown && actualMode === 'inline'`,
'[class.ant-menu-inline-collapsed]': `!isMenuInsideDropdown && nzInlineCollapsed`,
'[class.ant-menu-rtl]': `dir() === 'rtl'`
}
}]
}], propDecorators: { listOfNzMenuItemDirective: [{
type: ContentChildren,
args: [NzMenuItemComponent, { descendants: true }]
}], listOfNzSubMenuComponent: [{
type: ContentChildren,
args: [NzSubMenuComponent, { descendants: true }]
}], nzInlineIndent: [{
type: Input
}], nzTheme: [{
type: Input
}], nzMode: [{
type: Input
}], nzInlineCollapsed: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], nzSelectable: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], nzClick: [{
type: Output
}] } });
/**
* 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 MenuGroupFactory() {
const isMenuInsideDropdownToken = inject(NzIsMenuInsideDropdownToken, { optional: true, skipSelf: true });
return isMenuInsideDropdownToken ?? false;
}
class NzMenuGroupComponent {
renderer = inject(Renderer2);
isMenuInsideDropdown = inject(NzIsMenuInsideDropdownToken);
nzTitle;
titleElement;
ngAfterViewInit() {
const ulElement = this.titleElement.nativeElement.nextElementSibling;
if (ulElement) {
/** add classname to ul **/
const className = this.isMenuInsideDropdown ? 'ant-dropdown-menu-item-group-list' : 'ant-menu-item-group-list';
this.renderer.addClass(ulElement, className);
}
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NzMenuGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.14", type: NzMenuGroupComponent, isStandalone: true, selector: "[nz-menu-group]", inputs: { nzTitle: "nzTitle" }, host: { properties: { "class.ant-menu-item-group": "!isMenuInsideDropdown", "class.ant-dropdown-menu-item-group": "isMenuInsideDropdown" } }, providers: [
/** check if menu inside dropdown-menu component **/
{
provide: NzIsMenuInsideDropdownToken,
useFactory: MenuGroupFactory
}
], viewQueries: [{ propertyName: "titleElement", first: true, predicate: ["titleElement"], descendants: true }], exportAs: ["nzMenuGroup"], ngImport: i0, template: `
<div
[class.ant-menu-item-group-title]="!isMenuInsideDropdown"
[class.ant-dropdown-menu-item-group-title]="isMenuInsideDropdown"
#titleElement
>
<ng-container *nzStringTemplateOutlet="nzTitle">{{ nzTitle }}</ng-container>
@if (!nzTitle) {
<ng-content select="[title]" />
}
</div>
<ng-content />
`, isInline: true, dependencies: [{ kind: "ngmodule", type: NzOutletModule }, { kind: "directive", type: i2.NzStringTemplateOutletDirective, selector: "[nzStringTemplateOutlet]", inputs: ["nzStringTemplateOutletContext", "nzStringTemplateOutlet"], exportAs: ["nzStringTemplateOutlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NzMenuGroupComponent, decorators: [{
type: Component,
args: [{
selector: '[nz-menu-group]',
exportAs: 'nzMenuGroup',
providers: [
/** check if menu inside dropdown-menu component **/
{
provide: NzIsMenuInsideDropdownToken,
useFactory: MenuGroupFactory
}
],
template: `
<div
[class.ant-menu-item-group-title]="!isMenuInsideDropdown"
[class.ant-dropdown-menu-item-group-title]="isMenuInsideDropdown"
#titleElement
>
<ng-container *nzStringTemplateOutlet="nzTitle">{{ nzTitle }}</ng-container>
@if (!nzTitle) {
<ng-content select="[title]" />
}
</div>
<ng-content />
`,
imports: [NzOutletModule],
host: {
'[class.ant-menu-item-group]': '!isMenuInsideDropdown',
'[class.ant-dropdown-menu-item-group]': 'isMenuInsideDropdown'
},
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None
}]
}], propDecorators: { nzTitle: [{
type: Input
}], titleElement: [{
type: ViewChild,
args: ['titleElement']
}] } });
/**
* 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 NzMenuDividerDirective {
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NzMenuDividerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.2.14", type: NzMenuDividerDirective, isStandalone: true, selector: "[nz-menu-divider]", host: { classAttribute: "ant-dropdown-menu-item-divider" }, exportAs: ["nzMenuDivider"], ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NzMenuDividerDirective, decorators: [{
type: Directive,
args: [{
selector: '[nz-menu-divider]',
exportAs: 'nzMenuDivider',
host: {
class: 'ant-dropdown-menu-item-divider'
}
}]
}] });
/**
* 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 NzMenuModule {
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NzMenuModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.14", ngImport: i0, type: NzMenuModule, imports: [NzMenuDirective,
NzMenuItemComponent,
NzSubMenuComponent,
NzMenuDividerDirective,
NzMenuGroupComponent,
NzSubMenuTitleComponent,
NzSubmenuInlineChildComponent,
NzSubmenuNoneInlineChildComponent], exports: [NzMenuDirective, NzMenuItemComponent, NzSubMenuComponent, NzMenuDividerDirective, NzMenuGroupComponent] });
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NzMenuModule, imports: [NzSubMenuComponent,
NzMenuGroupComponent,
NzSubMenuTitleComponent] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: NzMenuModule, decorators: [{
type: NgModule,
args: [{
imports: [
NzMenuDirective,
NzMenuItemComponent,
NzSubMenuComponent,
NzMenuDividerDirective,
NzMenuGroupComponent,
NzSubMenuTitleComponent,
NzSubmenuInlineChildComponent,
NzSubmenuNoneInlineChildComponent
],
exports: [NzMenuDirective, NzMenuItemComponent, NzSubMenuComponent, NzMenuDividerDirective, NzMenuGroupComponent]
}]
}] });
/**
* 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
*/
/**
* 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 { MenuService, NzIsMenuInsideDropdownToken, NzMenuDirective, NzMenuDividerDirective, NzMenuGroupComponent, NzMenuItemComponent, NzMenuModule, NzMenuServiceLocalToken, NzSubMenuComponent, NzSubMenuTitleComponent, NzSubmenuInlineChildComponent, NzSubmenuNoneInlineChildComponent, NzSubmenuService };
//# sourceMappingURL=ng-zorro-antd-menu.mjs.map