Skip to content

Commit

Permalink
feat(module: notification): support top and bottom placement (#7540)
Browse files Browse the repository at this point in the history
Co-authored-by: luolei <luolei@kuaishou.com>
  • Loading branch information
rorry121 and luolei committed Jul 11, 2022
1 parent a8c3f95 commit d8b26dd
Show file tree
Hide file tree
Showing 10 changed files with 120 additions and 19 deletions.
4 changes: 4 additions & 0 deletions components/core/animation/notification.ts
Expand Up @@ -10,6 +10,10 @@ export const notificationMotion: AnimationTriggerMetadata = trigger('notificatio
transition('* => enterRight', [style({ opacity: 0, transform: 'translateX(5%)' }), animate('100ms linear')]),
state('enterLeft', style({ opacity: 1, transform: 'translateX(0)' })),
transition('* => enterLeft', [style({ opacity: 0, transform: 'translateX(-5%)' }), animate('100ms linear')]),
state('enterTop', style({ opacity: 1, transform: 'translateY(0)' })),
transition('* => enterTop', [style({ opacity: 0, transform: 'translateY(-5%)' }), animate('100ms linear')]),
state('enterBottom', style({ opacity: 1, transform: 'translateY(0)' })),
transition('* => enterBottom', [style({ opacity: 0, transform: 'translateY(5%)' }), animate('100ms linear')]),
state(
'leave',
style({
Expand Down
2 changes: 1 addition & 1 deletion components/core/config/config.ts
Expand Up @@ -239,7 +239,7 @@ export interface ModalConfig {
export interface NotificationConfig extends MessageConfig {
nzTop?: string | number;
nzBottom?: string | number;
nzPlacement?: 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight';
nzPlacement?: 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight' | 'top' | 'bottom';
}

export interface PageHeaderConfig {
Expand Down
4 changes: 2 additions & 2 deletions components/notification/demo/placement.md
Expand Up @@ -7,8 +7,8 @@ title:

## zh-CN

通知从右上角、右下角、左下角、左上角弹出
通知从右上角、右下角、左下角、左上角、上方、下方弹出

## en-US

A notification box can pop up from `topRight` or `bottomRight` or `bottomLeft` or `topLeft`.
A notification box can pop up from `topRight` or `bottomRight` or `bottomLeft` or `topLeft` or `top` or `bottom`.
9 changes: 9 additions & 0 deletions components/notification/demo/placement.ts
Expand Up @@ -5,6 +5,15 @@ import { NzNotificationPlacement, NzNotificationService } from 'ng-zorro-antd/no
@Component({
selector: 'nz-demo-notification-placement',
template: `
<button nz-button (click)="createBasicNotification('top')" nzType="primary">
<i nz-icon nzType="border-top" nzTheme="outline"></i>
top
</button>
<button nz-button (click)="createBasicNotification('bottom')" nzType="primary">
<i nz-icon nzType="border-bottom" nzTheme="outline"></i>
bottom
</button>
<nz-divider></nz-divider>
<button nz-button (click)="createBasicNotification('topLeft')" nzType="primary">
<i nz-icon nzType="radius-upleft"></i>
topLeft
Expand Down
2 changes: 1 addition & 1 deletion components/notification/doc/index.en-US.md
Expand Up @@ -69,7 +69,7 @@ You can use `NzConfigService` to configure this component globally. Please check
| nzAnimate | Whether to turn on animation | `boolean` | `true` |
| nzTop | The top of the notification when it pops up from the top. | `string` | 24px |
| nzBottom | The bottom of the notification when it pops up from the bottom. | `string` | 24px |
| nzPlacement | Popup position, optional `topLeft` `topRight` `bottomLeft` `bottomRight` | `string` | `topRight` |
| nzPlacement | Popup position, optional `topLeft` `topRight` `bottomLeft` `bottomRight` `top` `bottom` | `string` | `topRight` |
| nzDirection | Direction of the text in the notification | `'ltr' \| 'rtl'` | - |

### NzNotificationRef
Expand Down
2 changes: 1 addition & 1 deletion components/notification/doc/index.zh-CN.md
Expand Up @@ -69,7 +69,7 @@ import { NzNotificationModule } from 'ng-zorro-antd/notification';
| nzAnimate | 开关动画效果 | `boolean` | `true` |
| nzTop | 消息从顶部弹出时,距离顶部的位置。 | `string` | 24px |
| nzBottom | 消息从底部弹出时,距离底部的位置。 | `string` | 24px |
| nzPlacement | 弹出位置,可选 `topLeft` `topRight` `bottomLeft` `bottomRight` | `string` | `topRight` |
| nzPlacement | 弹出位置,可选 `topLeft` `topRight` `bottomLeft` `bottomRight` `top` `bottom` | `string` | `topRight` |
| nzDirection | 通知的文字方向 | `'ltr' \| 'rtl'` | - |

### NzNotificationRef
Expand Down
83 changes: 74 additions & 9 deletions components/notification/notification-container.component.ts
Expand Up @@ -12,7 +12,7 @@ import { NotificationConfig, NzConfigService } from 'ng-zorro-antd/core/config';
import { toCssPixel } from 'ng-zorro-antd/core/util';
import { NzMNContainerComponent } from 'ng-zorro-antd/message';

import { NzNotificationData, NzNotificationDataOptions } from './typings';
import { NzNotificationData, NzNotificationDataOptions, NzNotificationPlacement } from './typings';

const NZ_CONFIG_MODULE_NAME = 'notification';

Expand Down Expand Up @@ -43,7 +43,7 @@ const NZ_NOTIFICATION_DEFAULT_CONFIG: Required<NotificationConfig> = {
<nz-notification
*ngFor="let instance of topLeftInstances"
[instance]="instance"
[placement]="config.nzPlacement"
[placement]="'topLeft'"
(destroyed)="remove($event.id, $event.userAction)"
></nz-notification>
</div>
Expand All @@ -56,7 +56,7 @@ const NZ_NOTIFICATION_DEFAULT_CONFIG: Required<NotificationConfig> = {
<nz-notification
*ngFor="let instance of topRightInstances"
[instance]="instance"
[placement]="config.nzPlacement"
[placement]="'topRight'"
(destroyed)="remove($event.id, $event.userAction)"
></nz-notification>
</div>
Expand All @@ -69,7 +69,7 @@ const NZ_NOTIFICATION_DEFAULT_CONFIG: Required<NotificationConfig> = {
<nz-notification
*ngFor="let instance of bottomLeftInstances"
[instance]="instance"
[placement]="config.nzPlacement"
[placement]="'bottomLeft'"
(destroyed)="remove($event.id, $event.userAction)"
></nz-notification>
</div>
Expand All @@ -82,7 +82,35 @@ const NZ_NOTIFICATION_DEFAULT_CONFIG: Required<NotificationConfig> = {
<nz-notification
*ngFor="let instance of bottomRightInstances"
[instance]="instance"
[placement]="config.nzPlacement"
[placement]="'bottomRight'"
(destroyed)="remove($event.id, $event.userAction)"
></nz-notification>
</div>
<div
class="ant-notification ant-notification-top"
[class.ant-notification-rtl]="dir === 'rtl'"
[style.top]="top"
[style.left]="'50%'"
[style.transform]="'translateX(-50%)'"
>
<nz-notification
*ngFor="let instance of topInstances"
[instance]="instance"
[placement]="'top'"
(destroyed)="remove($event.id, $event.userAction)"
></nz-notification>
</div>
<div
class="ant-notification ant-notification-bottom"
[class.ant-notification-rtl]="dir === 'rtl'"
[style.bottom]="bottom"
[style.left]="'50%'"
[style.transform]="'translateX(-50%)'"
>
<nz-notification
*ngFor="let instance of bottomInstances"
[instance]="instance"
[placement]="'bottom'"
(destroyed)="remove($event.id, $event.userAction)"
></nz-notification>
</div>
Expand All @@ -98,6 +126,8 @@ export class NzNotificationContainerComponent extends NzMNContainerComponent {
topRightInstances: Array<Required<NzNotificationData>> = [];
bottomLeftInstances: Array<Required<NzNotificationData>> = [];
bottomRightInstances: Array<Required<NzNotificationData>> = [];
topInstances: Array<Required<NzNotificationData>> = [];
bottomInstances: Array<Required<NzNotificationData>> = [];

constructor(cdr: ChangeDetectorRef, nzConfigService: NzConfigService) {
super(cdr, nzConfigService);
Expand Down Expand Up @@ -168,10 +198,45 @@ export class NzNotificationContainerComponent extends NzMNContainerComponent {
}

protected override readyInstances(): void {
this.topLeftInstances = this.instances.filter(m => m.options.nzPlacement === 'topLeft');
this.topRightInstances = this.instances.filter(m => m.options.nzPlacement === 'topRight' || !m.options.nzPlacement);
this.bottomLeftInstances = this.instances.filter(m => m.options.nzPlacement === 'bottomLeft');
this.bottomRightInstances = this.instances.filter(m => m.options.nzPlacement === 'bottomRight');
const instancesMap: Record<NzNotificationPlacement, Array<Required<NzNotificationData>>> = {
topLeft: [],
topRight: [],
bottomLeft: [],
bottomRight: [],
top: [],
bottom: []
};
this.instances.forEach(m => {
const placement = m.options.nzPlacement;
switch (placement) {
case 'topLeft':
instancesMap.topLeft.push(m);
break;
case 'topRight':
instancesMap.topRight.push(m);
break;
case 'bottomLeft':
instancesMap.bottomLeft.push(m);
break;
case 'bottomRight':
instancesMap.bottomRight.push(m);
break;
case 'top':
instancesMap.top.push(m);
break;
case 'bottom':
instancesMap.bottom.push(m);
break;
default:
instancesMap.topRight.push(m);
}
});
this.topLeftInstances = instancesMap.topLeft;
this.topRightInstances = instancesMap.topRight;
this.bottomLeftInstances = instancesMap.bottomLeft;
this.bottomRightInstances = instancesMap.bottomRight;
this.topInstances = instancesMap.top;
this.bottomInstances = instancesMap.bottom;

this.cdr.detectChanges();
}
Expand Down
17 changes: 13 additions & 4 deletions components/notification/notification.component.ts
Expand Up @@ -110,10 +110,19 @@ export class NzNotificationComponent extends NzMNComponent implements OnDestroy

get state(): string | undefined {
if (this.instance.state === 'enter') {
if (this.placement === 'topLeft' || this.placement === 'bottomLeft') {
return 'enterLeft';
} else {
return 'enterRight';
switch (this.placement) {
case 'topLeft':
case 'bottomLeft':
return 'enterLeft';
case 'topRight':
case 'bottomRight':
return 'enterRight';
case 'top':
return 'enterTop';
case 'bottom':
return 'enterBottom';
default:
return 'enterRight';
}
} else {
return this.instance.state;
Expand Down
14 changes: 14 additions & 0 deletions components/notification/notification.spec.ts
Expand Up @@ -189,6 +189,20 @@ describe('NzNotification', () => {
expect(overlayContainerElement.textContent).toContain('EXISTS');
expect(overlayContainerElement.querySelector('.ant-notification-topLeft')).not.toBeNull();
});
it('should show with placement of top', () => {
nzConfigService.set('notification', { nzPlacement: 'top' });
notificationService.create('', '', 'EXISTS');
fixture.detectChanges();
expect(overlayContainerElement.textContent).toContain('EXISTS');
expect(overlayContainerElement.querySelector('.ant-notification-top')).not.toBeNull();
});
it('should show with placement of bottom', () => {
nzConfigService.set('notification', { nzPlacement: 'bottom' });
notificationService.create('', '', 'EXISTS');
fixture.detectChanges();
expect(overlayContainerElement.textContent).toContain('EXISTS');
expect(overlayContainerElement.querySelector('.ant-notification-bottom')).not.toBeNull();
});
// Should support nzData as context.
it('should open a message box with template ref', () => {
notificationService.template(fixture.componentInstance.demoTemplateRef, { nzData: 'data' });
Expand Down
2 changes: 1 addition & 1 deletion components/notification/typings.ts
Expand Up @@ -8,7 +8,7 @@ import { Subject } from 'rxjs';

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

export type NzNotificationPlacement = 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight';
export type NzNotificationPlacement = 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight' | 'top' | 'bottom';

export interface NzNotificationDataOptions<T = {}> {
nzKey?: string;
Expand Down

0 comments on commit d8b26dd

Please sign in to comment.