Skip to content

Commit b1223bd

Browse files
klerickAlexander Kharkovey
andauthored
feat(module:menu): add support nzPlacement for nz-submenu (#7420)
Closes #4743 Co-authored-by: Alexander Kharkovey <alexander.kharkovey@nordigy.ru>
1 parent d14f20d commit b1223bd

6 files changed

Lines changed: 213 additions & 4 deletions

File tree

components/core/overlay/overlay-position.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ export const POSITION_MAP = {
3737
)
3838
};
3939
export type POSITION_TYPE = keyof typeof POSITION_MAP;
40+
export type POSITION_TYPE_HORIZONTAL = Extract<
41+
POSITION_TYPE,
42+
'bottomLeft' | 'bottomCenter' | 'bottomRight' | 'topLeft' | 'topCenter' | 'topRight'
43+
>;
4044

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
order: 1
3+
title:
4+
zh-CN: 弹出位置
5+
en-US: Placement
6+
---
7+
8+
## zh-CN
9+
10+
支持 6 个弹出位置。
11+
12+
## en-US
13+
14+
Support 6 placements.
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
import { Component } from '@angular/core';
2+
3+
@Component({
4+
selector: 'nz-demo-menu-horizontal-position',
5+
template: `
6+
<ul nz-menu nzMode="horizontal">
7+
<li nz-submenu nzPlacement="bottomLeft" nzTitle="bottomLeft">
8+
<ul>
9+
<li nz-menu-group nzTitle="Item 1">
10+
<ul>
11+
<li nz-menu-item>Option 1</li>
12+
<li nz-menu-item>Option 2</li>
13+
</ul>
14+
</li>
15+
<li nz-menu-group nzTitle="Item 2">
16+
<ul>
17+
<li nz-menu-item>Option 3</li>
18+
<li nz-menu-item>Option 4</li>
19+
<li nz-submenu nzTitle="Sub Menu">
20+
<ul>
21+
<li nz-menu-item nzDisabled>Option 5</li>
22+
<li nz-menu-item>Option 6</li>
23+
</ul>
24+
</li>
25+
<li nz-submenu nzDisabled nzTitle="Disabled Sub Menu">
26+
<ul>
27+
<li nz-menu-item>Option 5</li>
28+
<li nz-menu-item>Option 6</li>
29+
</ul>
30+
</li>
31+
</ul>
32+
</li>
33+
</ul>
34+
</li>
35+
<li nz-submenu nzPlacement="bottomCenter" nzTitle="bottomCenter">
36+
<ul>
37+
<li nz-menu-group nzTitle="Item 1">
38+
<ul>
39+
<li nz-menu-item>Option 1</li>
40+
<li nz-menu-item>Option 2</li>
41+
</ul>
42+
</li>
43+
<li nz-menu-group nzTitle="Item 2">
44+
<ul>
45+
<li nz-menu-item>Option 3</li>
46+
<li nz-menu-item>Option 4</li>
47+
<li nz-submenu nzTitle="Sub Menu">
48+
<ul>
49+
<li nz-menu-item nzDisabled>Option 5</li>
50+
<li nz-menu-item>Option 6</li>
51+
</ul>
52+
</li>
53+
<li nz-submenu nzDisabled nzTitle="Disabled Sub Menu">
54+
<ul>
55+
<li nz-menu-item>Option 5</li>
56+
<li nz-menu-item>Option 6</li>
57+
</ul>
58+
</li>
59+
</ul>
60+
</li>
61+
</ul>
62+
</li>
63+
<li nz-submenu nzPlacement="bottomRight" nzTitle="bottomRight">
64+
<ul>
65+
<li nz-menu-group nzTitle="Item 1">
66+
<ul>
67+
<li nz-menu-item>Option 1</li>
68+
<li nz-menu-item>Option 2</li>
69+
</ul>
70+
</li>
71+
<li nz-menu-group nzTitle="Item 2">
72+
<ul>
73+
<li nz-menu-item>Option 3</li>
74+
<li nz-menu-item>Option 4</li>
75+
<li nz-submenu nzTitle="Sub Menu">
76+
<ul>
77+
<li nz-menu-item nzDisabled>Option 5</li>
78+
<li nz-menu-item>Option 6</li>
79+
</ul>
80+
</li>
81+
<li nz-submenu nzDisabled nzTitle="Disabled Sub Menu">
82+
<ul>
83+
<li nz-menu-item>Option 5</li>
84+
<li nz-menu-item>Option 6</li>
85+
</ul>
86+
</li>
87+
</ul>
88+
</li>
89+
</ul>
90+
</li>
91+
<li nz-submenu nzPlacement="topLeft" nzTitle="topLeft">
92+
<ul>
93+
<li nz-menu-group nzTitle="Item 1">
94+
<ul>
95+
<li nz-menu-item>Option 1</li>
96+
<li nz-menu-item>Option 2</li>
97+
</ul>
98+
</li>
99+
<li nz-menu-group nzTitle="Item 2">
100+
<ul>
101+
<li nz-menu-item>Option 3</li>
102+
<li nz-menu-item>Option 4</li>
103+
<li nz-submenu nzTitle="Sub Menu">
104+
<ul>
105+
<li nz-menu-item nzDisabled>Option 5</li>
106+
<li nz-menu-item>Option 6</li>
107+
</ul>
108+
</li>
109+
<li nz-submenu nzDisabled nzTitle="Disabled Sub Menu">
110+
<ul>
111+
<li nz-menu-item>Option 5</li>
112+
<li nz-menu-item>Option 6</li>
113+
</ul>
114+
</li>
115+
</ul>
116+
</li>
117+
</ul>
118+
</li>
119+
<li nz-submenu nzPlacement="topCenter" nzTitle="topCenter">
120+
<ul>
121+
<li nz-menu-group nzTitle="Item 1">
122+
<ul>
123+
<li nz-menu-item>Option 1</li>
124+
<li nz-menu-item>Option 2</li>
125+
</ul>
126+
</li>
127+
<li nz-menu-group nzTitle="Item 2">
128+
<ul>
129+
<li nz-menu-item>Option 3</li>
130+
<li nz-menu-item>Option 4</li>
131+
<li nz-submenu nzTitle="Sub Menu">
132+
<ul>
133+
<li nz-menu-item nzDisabled>Option 5</li>
134+
<li nz-menu-item>Option 6</li>
135+
</ul>
136+
</li>
137+
<li nz-submenu nzDisabled nzTitle="Disabled Sub Menu">
138+
<ul>
139+
<li nz-menu-item>Option 5</li>
140+
<li nz-menu-item>Option 6</li>
141+
</ul>
142+
</li>
143+
</ul>
144+
</li>
145+
</ul>
146+
</li>
147+
<li nz-submenu nzPlacement="topRight" nzTitle="topRight">
148+
<ul>
149+
<li nz-menu-group nzTitle="Item 1">
150+
<ul>
151+
<li nz-menu-item>Option 1</li>
152+
<li nz-menu-item>Option 2</li>
153+
</ul>
154+
</li>
155+
<li nz-menu-group nzTitle="Item 2">
156+
<ul>
157+
<li nz-menu-item>Option 3</li>
158+
<li nz-menu-item>Option 4</li>
159+
<li nz-submenu nzTitle="Sub Menu">
160+
<ul>
161+
<li nz-menu-item nzDisabled>Option 5</li>
162+
<li nz-menu-item>Option 6</li>
163+
</ul>
164+
</li>
165+
<li nz-submenu nzDisabled nzTitle="Disabled Sub Menu">
166+
<ul>
167+
<li nz-menu-item>Option 5</li>
168+
<li nz-menu-item>Option 6</li>
169+
</ul>
170+
</li>
171+
</ul>
172+
</li>
173+
</ul>
174+
</li>
175+
</ul>
176+
`
177+
})
178+
export class NzDemoMenuHorizontalPositionComponent {}

components/menu/doc/index.en-US.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ You can set the title of `[nz-submenu]` in the following ways.
7070

7171
| Param | Description | Type | Default value |
7272
| ----- | ----------- | ---- | ------------- |
73+
| `[nzPlacement]` | placement of pop menu | `'bottomLeft' \| 'bottomCenter' \| 'bottomRight' \| 'topLeft' \| 'topCenter' \| 'topRight'` | `'bottomLeft'` |
7374
| `[nzOpen]` | whether sub menu is open or not, double binding | `boolean` | `false` |
7475
| `[nzDisabled]` | whether sub menu is disabled or not | `boolean` | `false` |
7576
| `[nzTitle]` | set submenu title | `string \| TemplateRef<void>` | - |

components/menu/doc/index.zh-CN.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ import { NzMenuModule } from 'ng-zorro-antd/menu';
7171

7272
| 参数 | 说明 | 类型 | 默认值 |
7373
| --- | --- | --- | --- |
74+
| `[nzPlacement]` | 菜单弹出位置 | `'bottomLeft' \| 'bottomCenter' \| 'bottomRight' \| 'topLeft' \| 'topCenter' \| 'topRight'` | `'bottomLeft'` |
7475
| `[nzOpen]` | 是否展开,可双向绑定 | `boolean` | `false` |
7576
| `[nzDisabled]` | 是否禁用 | `boolean` | `false` |
7677
| `[nzTitle]` | 标题内容 | `string \| TemplateRef<void>` | - |

components/menu/submenu.component.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import { combineLatest, merge, Subject } from 'rxjs';
3232
import { map, startWith, switchMap, takeUntil } from 'rxjs/operators';
3333

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

@@ -50,7 +50,12 @@ const listOfVerticalPositions = [
5050
POSITION_MAP.left,
5151
POSITION_MAP.leftBottom
5252
];
53-
const listOfHorizontalPositions = [POSITION_MAP.bottomLeft];
53+
const listOfHorizontalPositions = [
54+
POSITION_MAP.bottomLeft,
55+
POSITION_MAP.bottomRight,
56+
POSITION_MAP.topRight,
57+
POSITION_MAP.topLeft
58+
];
5459

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

183189
setTriggerWidth(): void {
184-
if (this.mode === 'horizontal' && this.platform.isBrowser && this.cdkOverlayOrigin) {
190+
if (
191+
this.mode === 'horizontal' &&
192+
this.platform.isBrowser &&
193+
this.cdkOverlayOrigin &&
194+
this.nzPlacement === 'bottomLeft'
195+
) {
185196
/** TODO: fast dom **/
186197
this.triggerWidth = this.cdkOverlayOrigin!.nativeElement.getBoundingClientRect().width;
187198
}
@@ -216,7 +227,7 @@ export class NzSubMenuComponent implements OnInit, OnDestroy, AfterContentInit,
216227
this.nzSubmenuService.mode$.pipe(takeUntil(this.destroy$)).subscribe(mode => {
217228
this.mode = mode;
218229
if (mode === 'horizontal') {
219-
this.overlayPositions = listOfHorizontalPositions;
230+
this.overlayPositions = [POSITION_MAP[this.nzPlacement], ...listOfHorizontalPositions];
220231
} else if (mode === 'vertical') {
221232
this.overlayPositions = listOfVerticalPositions;
222233
}

0 commit comments

Comments
 (0)