Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(module: notification): support top and bottom placement #7540

Merged
merged 1 commit into from Jul 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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