UNPKG

ng-zorro-antd

Version:

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

1,166 lines 64.8 kB
import { Directionality } from '@angular/cdk/bidi';
import * as i0 from '@angular/core';
import { Injectable, InjectionToken, inject, DestroyRef, ChangeDetectorRef, booleanAttribute, ContentChildren, Input, ViewEncapsulation, 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: "22.0.6", ngImport: i0, type: MenuService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
    static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: MenuService });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", 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: "22.0.6", ngImport: i0, type: NzSubmenuService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
    static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NzSubmenuService });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", 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: "22.0.6", ngImport: i0, type: NzMenuItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "16.1.0", version: "22.0.6", 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, encapsulation: i0.ViewEncapsulation.None });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NzMenuItemComponent, decorators: [{
            type: Component,
            args: [{
                    selector: '[nz-menu-item]',
                    exportAs: 'nzMenuItem',
                    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('', /* @ts-ignore */
    ...(ngDevMode ? [{ debugName: "menuClass" }] : /* istanbul ignore next */ []));
    open = input(false, /* @ts-ignore */
    ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
    leavedClassName = input(generateClassName(MENU_PREFIX$1, 'submenu-hidden'), /* @ts-ignore */
    ...(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;
    }, /* @ts-ignore */
    ...(ngDevMode ? [{ debugName: "mergedClass" }] : /* istanbul ignore next */ []));
    static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NzSubmenuInlineChildComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.6", 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, encapsulation: i0.ViewEncapsulation.None });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NzSubmenuInlineChildComponent, decorators: [{
            type: Component,
            args: [{
                    selector: '[nz-submenu-inline-child]',
                    exportAs: 'nzSubmenuInlineChild',
                    encapsulation: ViewEncapsulation.None,
                    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('', /* @ts-ignore */
    ...(ngDevMode ? [{ debugName: "menuClass" }] : /* istanbul ignore next */ []));
    theme = input('light', /* @ts-ignore */
    ...(ngDevMode ? [{ debugName: "theme" }] : /* istanbul ignore next */ []));
    mode = input('vertical', /* @ts-ignore */
    ...(ngDevMode ? [{ debugName: "mode" }] : /* istanbul ignore next */ []));
    position = input('right', /* @ts-ignore */
    ...(ngDevMode ? [{ debugName: "position" }] : /* istanbul ignore next */ []));
    open = input(false, /* @ts-ignore */
    ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
    nzDisabled = input(false, /* @ts-ignore */
    ...(ngDevMode ? [{ debugName: "nzDisabled" }] : /* istanbul ignore next */ []));
    nzTriggerSubMenuAction = input('hover', /* @ts-ignore */
    ...(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;
    }, /* @ts-ignore */
    ...(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;
    }, /* @ts-ignore */
    ...(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: "22.0.6", ngImport: i0, type: NzSubmenuNoneInlineChildComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.6", 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, encapsulation: i0.ViewEncapsulation.None });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NzSubmenuNoneInlineChildComponent, decorators: [{
            type: Component,
            args: [{
                    selector: '[nz-submenu-none-inline-child]',
                    exportAs: 'nzSubmenuNoneInlineChild',
                    encapsulation: ViewEncapsulation.None,
                    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: "22.0.6", ngImport: i0, type: NzSubMenuTitleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", 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: ["nzType", "nzTheme", "nzTwotoneColor", "nzSpin", "nzRotate", "nzIconfont"], exportAs: ["nzIcon"] }, { kind: "ngmodule", type: NzOutletModule }, { kind: "directive", type: i2.NzStringTemplateOutletDirective, selector: "[nzStringTemplateOutlet]", inputs: ["nzStringTemplateOutletContext", "nzStringTemplateOutlet"], exportAs: ["nzStringTemplateOutlet"] }], encapsulation: i0.ViewEncapsulation.None });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NzSubMenuTitleComponent, decorators: [{
            type: Component,
            args: [{
                    selector: '[nz-submenu-title]',
                    exportAs: 'nzSubmenuTitle',
                    encapsulation: ViewEncapsulation.None,
                    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: "22.0.6", ngImport: i0, type: NzSubMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", 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"] }], encapsulation: i0.ViewEncapsulation.None });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NzSubMenuComponent, decorators: [{
            type: Component,
            args: [{
                    selector: '[nz-submenu]',
                    exportAs: 'nzSubmenu',
                    providers: [NzSubmenuService],
                    encapsulation: ViewEncapsulation.None,
                    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: "22.0.6", ngImport: i0, type: NzMenuDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
    static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "22.0.6", 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: "22.0.6", 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: "22.0.6", ngImport: i0, type: NzMenuGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
    static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", 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"] }], encapsulation: i0.ViewEncapsulation.None });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", 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'
                    },
                    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: "22.0.6", ngImport: i0, type: NzMenuDividerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
    static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.6", 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: "22.0.6", 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: "22.0.6", ngImport: i0, type: NzMenuModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
    static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.0.6", 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: "22.0.6", ngImport: i0, type: NzMenuModule, imports: [NzSubMenuComponent,
            NzMenuGroupComponent,
            NzSubMenuTitleComponent] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", 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