Skip to content

Commit

Permalink
feat(module:menu): add support nzPlacement for nz-submenu (#7420)
Browse files Browse the repository at this point in the history
Closes #4743

Co-authored-by: Alexander Kharkovey <alexander.kharkovey@nordigy.ru>
  • Loading branch information
klerick and Alexander Kharkovey committed Sep 26, 2022
1 parent d14f20d commit b1223bd
Show file tree
Hide file tree
Showing 6 changed files with 213 additions and 4 deletions.
4 changes: 4 additions & 0 deletions components/core/overlay/overlay-position.ts
Expand Up @@ -37,6 +37,10 @@ export const POSITION_MAP = {
)
};
export type POSITION_TYPE = keyof typeof POSITION_MAP;
export type POSITION_TYPE_HORIZONTAL = Extract<
POSITION_TYPE,
'bottomLeft' | 'bottomCenter' | 'bottomRight' | 'topLeft' | 'topCenter' | 'topRight'
>;

export const DEFAULT_TOOLTIP_POSITIONS = [POSITION_MAP.top, POSITION_MAP.right, POSITION_MAP.bottom, POSITION_MAP.left];

Expand Down
14 changes: 14 additions & 0 deletions components/menu/demo/horizontal-position.md
@@ -0,0 +1,14 @@
---
order: 1
title:
zh-CN: 弹出位置
en-US: Placement
---

## zh-CN

支持 6 个弹出位置。

## en-US

Support 6 placements.
178 changes: 178 additions & 0 deletions components/menu/demo/horizontal-position.ts
@@ -0,0 +1,178 @@
import { Component } from '@angular/core';

@Component({
selector: 'nz-demo-menu-horizontal-position',
template: `
<ul nz-menu nzMode="horizontal">
<li nz-submenu nzPlacement="bottomLeft" nzTitle="bottomLeft">
<ul>
<li nz-menu-group nzTitle="Item 1">
<ul>
<li nz-menu-item>Option 1</li>
<li nz-menu-item>Option 2</li>
</ul>
</li>
<li nz-menu-group nzTitle="Item 2">
<ul>
<li nz-menu-item>Option 3</li>
<li nz-menu-item>Option 4</li>
<li nz-submenu nzTitle="Sub Menu">
<ul>
<li nz-menu-item nzDisabled>Option 5</li>
<li nz-menu-item>Option 6</li>
</ul>
</li>
<li nz-submenu nzDisabled nzTitle="Disabled Sub Menu">
<ul>
<li nz-menu-item>Option 5</li>
<li nz-menu-item>Option 6</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li nz-submenu nzPlacement="bottomCenter" nzTitle="bottomCenter">
<ul>
<li nz-menu-group nzTitle="Item 1">
<ul>
<li nz-menu-item>Option 1</li>
<li nz-menu-item>Option 2</li>
</ul>
</li>
<li nz-menu-group nzTitle="Item 2">
<ul>
<li nz-menu-item>Option 3</li>
<li nz-menu-item>Option 4</li>
<li nz-submenu nzTitle="Sub Menu">
<ul>
<li nz-menu-item nzDisabled>Option 5</li>
<li nz-menu-item>Option 6</li>
</ul>
</li>
<li nz-submenu nzDisabled nzTitle="Disabled Sub Menu">
<ul>
<li nz-menu-item>Option 5</li>
<li nz-menu-item>Option 6</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li nz-submenu nzPlacement="bottomRight" nzTitle="bottomRight">
<ul>
<li nz-menu-group nzTitle="Item 1">
<ul>
<li nz-menu-item>Option 1</li>
<li nz-menu-item>Option 2</li>
</ul>
</li>
<li nz-menu-group nzTitle="Item 2">
<ul>
<li nz-menu-item>Option 3</li>
<li nz-menu-item>Option 4</li>
<li nz-submenu nzTitle="Sub Menu">
<ul>
<li nz-menu-item nzDisabled>Option 5</li>
<li nz-menu-item>Option 6</li>
</ul>
</li>
<li nz-submenu nzDisabled nzTitle="Disabled Sub Menu">
<ul>
<li nz-menu-item>Option 5</li>
<li nz-menu-item>Option 6</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li nz-submenu nzPlacement="topLeft" nzTitle="topLeft">
<ul>
<li nz-menu-group nzTitle="Item 1">
<ul>
<li nz-menu-item>Option 1</li>
<li nz-menu-item>Option 2</li>
</ul>
</li>
<li nz-menu-group nzTitle="Item 2">
<ul>
<li nz-menu-item>Option 3</li>
<li nz-menu-item>Option 4</li>
<li nz-submenu nzTitle="Sub Menu">
<ul>
<li nz-menu-item nzDisabled>Option 5</li>
<li nz-menu-item>Option 6</li>
</ul>
</li>
<li nz-submenu nzDisabled nzTitle="Disabled Sub Menu">
<ul>
<li nz-menu-item>Option 5</li>
<li nz-menu-item>Option 6</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li nz-submenu nzPlacement="topCenter" nzTitle="topCenter">
<ul>
<li nz-menu-group nzTitle="Item 1">
<ul>
<li nz-menu-item>Option 1</li>
<li nz-menu-item>Option 2</li>
</ul>
</li>
<li nz-menu-group nzTitle="Item 2">
<ul>
<li nz-menu-item>Option 3</li>
<li nz-menu-item>Option 4</li>
<li nz-submenu nzTitle="Sub Menu">
<ul>
<li nz-menu-item nzDisabled>Option 5</li>
<li nz-menu-item>Option 6</li>
</ul>
</li>
<li nz-submenu nzDisabled nzTitle="Disabled Sub Menu">
<ul>
<li nz-menu-item>Option 5</li>
<li nz-menu-item>Option 6</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li nz-submenu nzPlacement="topRight" nzTitle="topRight">
<ul>
<li nz-menu-group nzTitle="Item 1">
<ul>
<li nz-menu-item>Option 1</li>
<li nz-menu-item>Option 2</li>
</ul>
</li>
<li nz-menu-group nzTitle="Item 2">
<ul>
<li nz-menu-item>Option 3</li>
<li nz-menu-item>Option 4</li>
<li nz-submenu nzTitle="Sub Menu">
<ul>
<li nz-menu-item nzDisabled>Option 5</li>
<li nz-menu-item>Option 6</li>
</ul>
</li>
<li nz-submenu nzDisabled nzTitle="Disabled Sub Menu">
<ul>
<li nz-menu-item>Option 5</li>
<li nz-menu-item>Option 6</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
`
})
export class NzDemoMenuHorizontalPositionComponent {}
1 change: 1 addition & 0 deletions components/menu/doc/index.en-US.md
Expand Up @@ -70,6 +70,7 @@ You can set the title of `[nz-submenu]` in the following ways.

| Param | Description | Type | Default value |
| ----- | ----------- | ---- | ------------- |
| `[nzPlacement]` | placement of pop menu | `'bottomLeft' \| 'bottomCenter' \| 'bottomRight' \| 'topLeft' \| 'topCenter' \| 'topRight'` | `'bottomLeft'` |
| `[nzOpen]` | whether sub menu is open or not, double binding | `boolean` | `false` |
| `[nzDisabled]` | whether sub menu is disabled or not | `boolean` | `false` |
| `[nzTitle]` | set submenu title | `string \| TemplateRef<void>` | - |
Expand Down
1 change: 1 addition & 0 deletions components/menu/doc/index.zh-CN.md
Expand Up @@ -71,6 +71,7 @@ import { NzMenuModule } from 'ng-zorro-antd/menu';

| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| `[nzPlacement]` | 菜单弹出位置 | `'bottomLeft' \| 'bottomCenter' \| 'bottomRight' \| 'topLeft' \| 'topCenter' \| 'topRight'` | `'bottomLeft'` |
| `[nzOpen]` | 是否展开,可双向绑定 | `boolean` | `false` |
| `[nzDisabled]` | 是否禁用 | `boolean` | `false` |
| `[nzTitle]` | 标题内容 | `string \| TemplateRef<void>` | - |
Expand Down
19 changes: 15 additions & 4 deletions components/menu/submenu.component.ts
Expand Up @@ -32,7 +32,7 @@ import { combineLatest, merge, Subject } from 'rxjs';
import { map, startWith, switchMap, takeUntil } from 'rxjs/operators';

import { NzNoAnimationDirective } from 'ng-zorro-antd/core/no-animation';
import { getPlacementName, POSITION_MAP } from 'ng-zorro-antd/core/overlay';
import { getPlacementName, POSITION_MAP, POSITION_TYPE_HORIZONTAL } from 'ng-zorro-antd/core/overlay';
import { BooleanInput } from 'ng-zorro-antd/core/types';
import { InputBoolean } from 'ng-zorro-antd/core/util';

Expand All @@ -50,7 +50,12 @@ const listOfVerticalPositions = [
POSITION_MAP.left,
POSITION_MAP.leftBottom
];
const listOfHorizontalPositions = [POSITION_MAP.bottomLeft];
const listOfHorizontalPositions = [
POSITION_MAP.bottomLeft,
POSITION_MAP.bottomRight,
POSITION_MAP.topRight,
POSITION_MAP.topLeft
];

@Component({
selector: '[nz-submenu]',
Expand Down Expand Up @@ -146,6 +151,7 @@ export class NzSubMenuComponent implements OnInit, OnDestroy, AfterContentInit,
@Input() nzIcon: string | null = null;
@Input() @InputBoolean() nzOpen = false;
@Input() @InputBoolean() nzDisabled = false;
@Input() nzPlacement: POSITION_TYPE_HORIZONTAL = 'bottomLeft';
@Output() readonly nzOpenChange: EventEmitter<boolean> = new EventEmitter();
@ViewChild(CdkOverlayOrigin, { static: true, read: ElementRef }) cdkOverlayOrigin: ElementRef | null = null;
@ContentChildren(NzSubMenuComponent, { descendants: true })
Expand Down Expand Up @@ -181,7 +187,12 @@ export class NzSubMenuComponent implements OnInit, OnDestroy, AfterContentInit,
}

setTriggerWidth(): void {
if (this.mode === 'horizontal' && this.platform.isBrowser && this.cdkOverlayOrigin) {
if (
this.mode === 'horizontal' &&
this.platform.isBrowser &&
this.cdkOverlayOrigin &&
this.nzPlacement === 'bottomLeft'
) {
/** TODO: fast dom **/
this.triggerWidth = this.cdkOverlayOrigin!.nativeElement.getBoundingClientRect().width;
}
Expand Down Expand Up @@ -216,7 +227,7 @@ export class NzSubMenuComponent implements OnInit, OnDestroy, AfterContentInit,
this.nzSubmenuService.mode$.pipe(takeUntil(this.destroy$)).subscribe(mode => {
this.mode = mode;
if (mode === 'horizontal') {
this.overlayPositions = listOfHorizontalPositions;
this.overlayPositions = [POSITION_MAP[this.nzPlacement], ...listOfHorizontalPositions];
} else if (mode === 'vertical') {
this.overlayPositions = listOfVerticalPositions;
}
Expand Down

0 comments on commit b1223bd

Please sign in to comment.