Skip to content

Commit d8b26dd

Browse files
rorry121luolei
andauthored
feat(module: notification): support top and bottom placement (#7540)
Co-authored-by: luolei <luolei@kuaishou.com>
1 parent a8c3f95 commit d8b26dd

File tree

10 files changed

+120
-19
lines changed

10 files changed

+120
-19
lines changed

components/core/animation/notification.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ export const notificationMotion: AnimationTriggerMetadata = trigger('notificatio
1010
transition('* => enterRight', [style({ opacity: 0, transform: 'translateX(5%)' }), animate('100ms linear')]),
1111
state('enterLeft', style({ opacity: 1, transform: 'translateX(0)' })),
1212
transition('* => enterLeft', [style({ opacity: 0, transform: 'translateX(-5%)' }), animate('100ms linear')]),
13+
state('enterTop', style({ opacity: 1, transform: 'translateY(0)' })),
14+
transition('* => enterTop', [style({ opacity: 0, transform: 'translateY(-5%)' }), animate('100ms linear')]),
15+
state('enterBottom', style({ opacity: 1, transform: 'translateY(0)' })),
16+
transition('* => enterBottom', [style({ opacity: 0, transform: 'translateY(5%)' }), animate('100ms linear')]),
1317
state(
1418
'leave',
1519
style({

components/core/config/config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ export interface ModalConfig {
239239
export interface NotificationConfig extends MessageConfig {
240240
nzTop?: string | number;
241241
nzBottom?: string | number;
242-
nzPlacement?: 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight';
242+
nzPlacement?: 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight' | 'top' | 'bottom';
243243
}
244244

245245
export interface PageHeaderConfig {

components/notification/demo/placement.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ title:
77

88
## zh-CN
99

10-
通知从右上角、右下角、左下角、左上角弹出
10+
通知从右上角、右下角、左下角、左上角、上方、下方弹出
1111

1212
## en-US
1313

14-
A notification box can pop up from `topRight` or `bottomRight` or `bottomLeft` or `topLeft`.
14+
A notification box can pop up from `topRight` or `bottomRight` or `bottomLeft` or `topLeft` or `top` or `bottom`.

components/notification/demo/placement.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,15 @@ import { NzNotificationPlacement, NzNotificationService } from 'ng-zorro-antd/no
55
@Component({
66
selector: 'nz-demo-notification-placement',
77
template: `
8+
<button nz-button (click)="createBasicNotification('top')" nzType="primary">
9+
<i nz-icon nzType="border-top" nzTheme="outline"></i>
10+
top
11+
</button>
12+
<button nz-button (click)="createBasicNotification('bottom')" nzType="primary">
13+
<i nz-icon nzType="border-bottom" nzTheme="outline"></i>
14+
bottom
15+
</button>
16+
<nz-divider></nz-divider>
817
<button nz-button (click)="createBasicNotification('topLeft')" nzType="primary">
918
<i nz-icon nzType="radius-upleft"></i>
1019
topLeft

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ You can use `NzConfigService` to configure this component globally. Please check
6969
| nzAnimate | Whether to turn on animation | `boolean` | `true` |
7070
| nzTop | The top of the notification when it pops up from the top. | `string` | 24px |
7171
| nzBottom | The bottom of the notification when it pops up from the bottom. | `string` | 24px |
72-
| nzPlacement | Popup position, optional `topLeft` `topRight` `bottomLeft` `bottomRight` | `string` | `topRight` |
72+
| nzPlacement | Popup position, optional `topLeft` `topRight` `bottomLeft` `bottomRight` `top` `bottom` | `string` | `topRight` |
7373
| nzDirection | Direction of the text in the notification | `'ltr' \| 'rtl'` | - |
7474

7575
### NzNotificationRef

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ import { NzNotificationModule } from 'ng-zorro-antd/notification';
6969
| nzAnimate | 开关动画效果 | `boolean` | `true` |
7070
| nzTop | 消息从顶部弹出时,距离顶部的位置。 | `string` | 24px |
7171
| nzBottom | 消息从底部弹出时,距离底部的位置。 | `string` | 24px |
72-
| nzPlacement | 弹出位置,可选 `topLeft` `topRight` `bottomLeft` `bottomRight` | `string` | `topRight` |
72+
| nzPlacement | 弹出位置,可选 `topLeft` `topRight` `bottomLeft` `bottomRight` `top` `bottom` | `string` | `topRight` |
7373
| nzDirection | 通知的文字方向 | `'ltr' \| 'rtl'` | - |
7474

7575
### NzNotificationRef

components/notification/notification-container.component.ts

Lines changed: 74 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { NotificationConfig, NzConfigService } from 'ng-zorro-antd/core/config';
1212
import { toCssPixel } from 'ng-zorro-antd/core/util';
1313
import { NzMNContainerComponent } from 'ng-zorro-antd/message';
1414

15-
import { NzNotificationData, NzNotificationDataOptions } from './typings';
15+
import { NzNotificationData, NzNotificationDataOptions, NzNotificationPlacement } from './typings';
1616

1717
const NZ_CONFIG_MODULE_NAME = 'notification';
1818

@@ -43,7 +43,7 @@ const NZ_NOTIFICATION_DEFAULT_CONFIG: Required<NotificationConfig> = {
4343
<nz-notification
4444
*ngFor="let instance of topLeftInstances"
4545
[instance]="instance"
46-
[placement]="config.nzPlacement"
46+
[placement]="'topLeft'"
4747
(destroyed)="remove($event.id, $event.userAction)"
4848
></nz-notification>
4949
</div>
@@ -56,7 +56,7 @@ const NZ_NOTIFICATION_DEFAULT_CONFIG: Required<NotificationConfig> = {
5656
<nz-notification
5757
*ngFor="let instance of topRightInstances"
5858
[instance]="instance"
59-
[placement]="config.nzPlacement"
59+
[placement]="'topRight'"
6060
(destroyed)="remove($event.id, $event.userAction)"
6161
></nz-notification>
6262
</div>
@@ -69,7 +69,7 @@ const NZ_NOTIFICATION_DEFAULT_CONFIG: Required<NotificationConfig> = {
6969
<nz-notification
7070
*ngFor="let instance of bottomLeftInstances"
7171
[instance]="instance"
72-
[placement]="config.nzPlacement"
72+
[placement]="'bottomLeft'"
7373
(destroyed)="remove($event.id, $event.userAction)"
7474
></nz-notification>
7575
</div>
@@ -82,7 +82,35 @@ const NZ_NOTIFICATION_DEFAULT_CONFIG: Required<NotificationConfig> = {
8282
<nz-notification
8383
*ngFor="let instance of bottomRightInstances"
8484
[instance]="instance"
85-
[placement]="config.nzPlacement"
85+
[placement]="'bottomRight'"
86+
(destroyed)="remove($event.id, $event.userAction)"
87+
></nz-notification>
88+
</div>
89+
<div
90+
class="ant-notification ant-notification-top"
91+
[class.ant-notification-rtl]="dir === 'rtl'"
92+
[style.top]="top"
93+
[style.left]="'50%'"
94+
[style.transform]="'translateX(-50%)'"
95+
>
96+
<nz-notification
97+
*ngFor="let instance of topInstances"
98+
[instance]="instance"
99+
[placement]="'top'"
100+
(destroyed)="remove($event.id, $event.userAction)"
101+
></nz-notification>
102+
</div>
103+
<div
104+
class="ant-notification ant-notification-bottom"
105+
[class.ant-notification-rtl]="dir === 'rtl'"
106+
[style.bottom]="bottom"
107+
[style.left]="'50%'"
108+
[style.transform]="'translateX(-50%)'"
109+
>
110+
<nz-notification
111+
*ngFor="let instance of bottomInstances"
112+
[instance]="instance"
113+
[placement]="'bottom'"
86114
(destroyed)="remove($event.id, $event.userAction)"
87115
></nz-notification>
88116
</div>
@@ -98,6 +126,8 @@ export class NzNotificationContainerComponent extends NzMNContainerComponent {
98126
topRightInstances: Array<Required<NzNotificationData>> = [];
99127
bottomLeftInstances: Array<Required<NzNotificationData>> = [];
100128
bottomRightInstances: Array<Required<NzNotificationData>> = [];
129+
topInstances: Array<Required<NzNotificationData>> = [];
130+
bottomInstances: Array<Required<NzNotificationData>> = [];
101131

102132
constructor(cdr: ChangeDetectorRef, nzConfigService: NzConfigService) {
103133
super(cdr, nzConfigService);
@@ -168,10 +198,45 @@ export class NzNotificationContainerComponent extends NzMNContainerComponent {
168198
}
169199

170200
protected override readyInstances(): void {
171-
this.topLeftInstances = this.instances.filter(m => m.options.nzPlacement === 'topLeft');
172-
this.topRightInstances = this.instances.filter(m => m.options.nzPlacement === 'topRight' || !m.options.nzPlacement);
173-
this.bottomLeftInstances = this.instances.filter(m => m.options.nzPlacement === 'bottomLeft');
174-
this.bottomRightInstances = this.instances.filter(m => m.options.nzPlacement === 'bottomRight');
201+
const instancesMap: Record<NzNotificationPlacement, Array<Required<NzNotificationData>>> = {
202+
topLeft: [],
203+
topRight: [],
204+
bottomLeft: [],
205+
bottomRight: [],
206+
top: [],
207+
bottom: []
208+
};
209+
this.instances.forEach(m => {
210+
const placement = m.options.nzPlacement;
211+
switch (placement) {
212+
case 'topLeft':
213+
instancesMap.topLeft.push(m);
214+
break;
215+
case 'topRight':
216+
instancesMap.topRight.push(m);
217+
break;
218+
case 'bottomLeft':
219+
instancesMap.bottomLeft.push(m);
220+
break;
221+
case 'bottomRight':
222+
instancesMap.bottomRight.push(m);
223+
break;
224+
case 'top':
225+
instancesMap.top.push(m);
226+
break;
227+
case 'bottom':
228+
instancesMap.bottom.push(m);
229+
break;
230+
default:
231+
instancesMap.topRight.push(m);
232+
}
233+
});
234+
this.topLeftInstances = instancesMap.topLeft;
235+
this.topRightInstances = instancesMap.topRight;
236+
this.bottomLeftInstances = instancesMap.bottomLeft;
237+
this.bottomRightInstances = instancesMap.bottomRight;
238+
this.topInstances = instancesMap.top;
239+
this.bottomInstances = instancesMap.bottom;
175240

176241
this.cdr.detectChanges();
177242
}

components/notification/notification.component.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,19 @@ export class NzNotificationComponent extends NzMNComponent implements OnDestroy
110110

111111
get state(): string | undefined {
112112
if (this.instance.state === 'enter') {
113-
if (this.placement === 'topLeft' || this.placement === 'bottomLeft') {
114-
return 'enterLeft';
115-
} else {
116-
return 'enterRight';
113+
switch (this.placement) {
114+
case 'topLeft':
115+
case 'bottomLeft':
116+
return 'enterLeft';
117+
case 'topRight':
118+
case 'bottomRight':
119+
return 'enterRight';
120+
case 'top':
121+
return 'enterTop';
122+
case 'bottom':
123+
return 'enterBottom';
124+
default:
125+
return 'enterRight';
117126
}
118127
} else {
119128
return this.instance.state;

components/notification/notification.spec.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,20 @@ describe('NzNotification', () => {
189189
expect(overlayContainerElement.textContent).toContain('EXISTS');
190190
expect(overlayContainerElement.querySelector('.ant-notification-topLeft')).not.toBeNull();
191191
});
192+
it('should show with placement of top', () => {
193+
nzConfigService.set('notification', { nzPlacement: 'top' });
194+
notificationService.create('', '', 'EXISTS');
195+
fixture.detectChanges();
196+
expect(overlayContainerElement.textContent).toContain('EXISTS');
197+
expect(overlayContainerElement.querySelector('.ant-notification-top')).not.toBeNull();
198+
});
199+
it('should show with placement of bottom', () => {
200+
nzConfigService.set('notification', { nzPlacement: 'bottom' });
201+
notificationService.create('', '', 'EXISTS');
202+
fixture.detectChanges();
203+
expect(overlayContainerElement.textContent).toContain('EXISTS');
204+
expect(overlayContainerElement.querySelector('.ant-notification-bottom')).not.toBeNull();
205+
});
192206
// Should support nzData as context.
193207
it('should open a message box with template ref', () => {
194208
notificationService.template(fixture.componentInstance.demoTemplateRef, { nzData: 'data' });

components/notification/typings.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { Subject } from 'rxjs';
88

99
import { NgClassInterface, NgStyleInterface } from 'ng-zorro-antd/core/types';
1010

11-
export type NzNotificationPlacement = 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight';
11+
export type NzNotificationPlacement = 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight' | 'top' | 'bottom';
1212

1313
export interface NzNotificationDataOptions<T = {}> {
1414
nzKey?: string;

0 commit comments

Comments
 (0)