Skip to content

Commit

Permalink
feat(module:modal): draggable (#8419)
Browse files Browse the repository at this point in the history
  • Loading branch information
ParsaArvanehPA authored Mar 11, 2024
1 parent ec7ec35 commit ce33294
Show file tree
Hide file tree
Showing 9 changed files with 116 additions and 15 deletions.
14 changes: 14 additions & 0 deletions components/modal/demo/draggable.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
order: 11
title:
zh-CN: 基本
en-US: Draggable
---

## zh-CN

可拖动模态。

## en-US

Draggable modal.
43 changes: 43 additions & 0 deletions components/modal/demo/draggable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { Component } from '@angular/core';

@Component({
selector: 'nz-demo-modal-draggable',
template: `
<button nz-button nzType="default" (click)="showModal()">
<span>Open Draggable Modal</span>
</button>
<nz-modal
nzDraggable
nzCentered
[(nzVisible)]="isVisible"
nzTitle="Draggable Modal"
(nzOnCancel)="handleCancel()"
(nzOnOk)="handleOk()"
>
<ng-container *nzModalContent>
<p>Just don't learn physics at school and your life will be full of magic and miracles.</p>
<p>Day before yesterday I saw a rabbit, and yesterday a deer, and today, you.</p>
</ng-container>
</nz-modal>
`
})
export class NzDemoModalDraggableComponent {
isVisible = false;

constructor() {}

showModal(): void {
this.isVisible = true;
}

handleOk(): void {
console.log('Button ok clicked!');
this.isVisible = false;
}

handleCancel(): void {
console.log('Button cancel clicked!');
this.isVisible = false;
}
}
22 changes: 10 additions & 12 deletions components/modal/doc/index.en-US.md

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion components/modal/doc/index.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import { NzModalModule } from 'ng-zorro-antd/modal';
| nzCancelLoading | 取消按钮 loading | `boolean` | `false` |
| nzOkDisabled | 是否禁用确定按钮 | `boolean` | `false` |
| nzCancelDisabled | 是否禁用取消按钮 | `boolean` | `false` |
| nzDraggable | 模态框是否可拖动 | `boolean` | `false` |
| nzFooter | 底部内容。<i>1. 仅在普通模式下有效。<br>2. 可通过传入 ModalButtonOptions 来最大程度自定义按钮(详见案例或下方说明)。<br>3. 当不需要底部时,可以设为 null</i> | string<br>TemplateRef<br>ModalButtonOptions | 默认的确定取消按钮 |
| nzKeyboard | 是否支持键盘 esc 关闭 | `boolean` | `true` |
| nzMask | 是否展示遮罩 | `boolean` | `true` ||
Expand Down Expand Up @@ -119,7 +120,7 @@ constructor(modal: NzModalService) {
| close(result: any) | 关闭(隐藏)对话框。<i>注:当用于以服务方式创建的对话框,此方法将直接 销毁 对话框(同 destroy 方法)</i> |
| destroy(result: any) | 销毁对话框。<i>注:仅用于服务方式创建的对话框(非服务方式创建的对话框,此方法只会隐藏对话框)</i> |
| getContentComponent() | 获取对话框内容中`nzContent`的 Component 实例 instance。<i>注:当对话框还未初始化完毕(`ngOnInit`未执行)时,此函数将返回`undefined`</i> |
| getContentComponentRef() | 获取对话框内容中`nzContent`的 Component 引用 ComponentRef。<i>注:当对话框还未初始化完毕(`ngOnInit`未执行)时,此函数将返回`null`</i> |
| getContentComponentRef() | 获取对话框内容中`nzContent`的 Component 引用 ComponentRef。<i>注:当对话框还未初始化完毕(`ngOnInit`未执行)时,此函数将返回`null`</i> |
| triggerOk() | 手动触发 nzOnOk |
| triggerCancel() | 手动触发 nzOnCancel |
| updateConfig(config: ModalOptions): void | 更新配置 |
Expand Down
10 changes: 8 additions & 2 deletions components/modal/modal-container.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*/

import { FocusTrapFactory } from '@angular/cdk/a11y';
import { CdkDrag, CdkDragHandle } from '@angular/cdk/drag-drop';
import { OverlayRef } from '@angular/cdk/overlay';
import { CdkPortalOutlet, PortalModule } from '@angular/cdk/portal';
import { DOCUMENT, NgClass, NgStyle } from '@angular/common';
Expand Down Expand Up @@ -38,6 +39,9 @@ import { ModalOptions } from './modal-types';
template: `
<div
#modalElement
cdkDrag
cdkDragBoundary=".cdk-overlay-container"
[cdkDragDisabled]="!config.nzDraggable"
role="document"
class="ant-modal"
[ngClass]="config.nzClassName!"
Expand All @@ -49,7 +53,7 @@ import { ModalOptions } from './modal-types';
<button nz-modal-close (click)="onCloseClick()"></button>
}
@if (config.nzTitle) {
<div nz-modal-title></div>
<div nz-modal-title cdkDragHandle [style.cursor]="config.nzDraggable ? 'move' : 'auto'"></div>
}
<div class="ant-modal-body" [ngStyle]="config.nzBodyStyle!">
Expand Down Expand Up @@ -92,7 +96,9 @@ import { ModalOptions } from './modal-types';
NzModalTitleComponent,
PortalModule,
NzModalFooterComponent,
NzPipesModule
NzPipesModule,
CdkDrag,
CdkDragHandle
],
standalone: true
})
Expand Down
1 change: 1 addition & 0 deletions components/modal/modal-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export class ModalOptions<T = NzSafeAny, D = NzSafeAny, R = NzSafeAny> {
nzOkDisabled?: boolean = false;
nzCancelDisabled?: boolean = false;
nzCancelLoading?: boolean = false;
nzDraggable?: boolean = false;
nzNoAnimation?: boolean = false;
nzAutofocus?: 'ok' | 'cancel' | 'auto' | null = 'auto';
nzMask?: boolean;
Expand Down
2 changes: 2 additions & 0 deletions components/modal/modal.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export class NzModalComponent<T extends ModalOptions = NzSafeAny, R = NzSafeAny>
static ngAcceptInputType_nzNoAnimation: BooleanInput;
static ngAcceptInputType_nzOkDanger: BooleanInput;
static ngAcceptInputType_nzCentered: BooleanInput;
static ngAcceptInputType_nzDraggable: BooleanInput;

@Input() @InputBoolean() nzMask?: boolean;
@Input() @InputBoolean() nzMaskClosable?: boolean;
Expand All @@ -70,6 +71,7 @@ export class NzModalComponent<T extends ModalOptions = NzSafeAny, R = NzSafeAny>
@Input() @InputBoolean() nzKeyboard: boolean = true;
@Input() @InputBoolean() nzNoAnimation = false;
@Input() @InputBoolean() nzCentered = false;
@Input() @InputBoolean() nzDraggable = false;
@Input() nzContent?: string | TemplateRef<{}> | Type<T>;
@Input() nzFooter?: string | TemplateRef<{}> | Array<ModalButtonOptions<T>> | null;
@Input() nzZIndex: number = 1000;
Expand Down
34 changes: 34 additions & 0 deletions components/modal/modal.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1328,6 +1328,7 @@ describe('NzModal', () => {
fixture.detectChanges();
expect((overlayContainerElement.querySelector('.ant-modal') as HTMLDivElement).style.width).toBe('416px');
expect(modalRef.getConfig().nzMaskClosable).toBe(false);
expect(modalRef.getConfig().nzDraggable).toBe(false);
expect(modalRef.getConfig().nzCentered).toBe(false);
expect(overlayContainerElement.querySelectorAll('nz-modal-confirm-container').length).toBe(1);
expect(overlayContainerElement.querySelector('.ant-modal-confirm-title')!.textContent).toBe('Test Title');
Expand Down Expand Up @@ -1680,6 +1681,37 @@ describe('NzModal', () => {

expect(overlayContainerElement.querySelector('nz-modal-container')).toBeNull();
}));

it('should be draggable when nzDraggable is set to true', fakeAsync(() => {
componentInstance.isVisible = true;
componentInstance.isDraggable = true;
componentFixture.detectChanges();
flush();
expect(overlayContainerElement.querySelector('.cdk-drag')).not.toBeNull();

componentInstance.isDraggable = false;
componentFixture.detectChanges();
flush();

expect(overlayContainerElement.querySelector('.cdk-drag-disabled')).not.toBeNull();

componentFixture.destroy();
}));

it('should have "move" cursor on the top of modal when modal is draggable', fakeAsync(() => {
componentInstance.isVisible = true;
componentInstance.isDraggable = true;
componentFixture.detectChanges();
flush();
const modalHeader = overlayContainerElement.querySelector('.ant-modal-header');
expect(getComputedStyle(modalHeader!).cursor).toEqual('move');

componentInstance.isVisible = true;
componentInstance.isDraggable = false;
componentFixture.detectChanges();
flush();
expect(getComputedStyle(modalHeader!).cursor).toEqual('auto');
}));
});
});

Expand Down Expand Up @@ -1764,6 +1796,7 @@ class TestWithModalContentComponent {
<nz-modal
[(nzVisible)]="isVisible"
[nzContent]="content"
[nzDraggable]="isDraggable"
nzTitle="Test Title"
(nzOnCancel)="handleCancel()"
(nzOnOk)="handleOk()"
Expand All @@ -1775,6 +1808,7 @@ class TestWithModalContentComponent {
})
class TestModalComponent {
isVisible = false;
isDraggable = false;
cancelSpy = jasmine.createSpy('cancel spy');
okSpy = jasmine.createSpy('ok spy');
@ViewChild(NzModalComponent) nzModalComponent!: NzModalComponent;
Expand Down
2 changes: 2 additions & 0 deletions components/modal/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export function getConfigFromComponent<T extends ModalOptions>(component: T): Mo
nzCancelLoading,
nzKeyboard,
nzNoAnimation,
nzDraggable,
nzContent,
nzFooter,
nzZIndex,
Expand Down Expand Up @@ -61,6 +62,7 @@ export function getConfigFromComponent<T extends ModalOptions>(component: T): Mo
nzCentered,
nzMask,
nzMaskClosable,
nzDraggable,
nzClosable,
nzOkLoading,
nzOkDisabled,
Expand Down

0 comments on commit ce33294

Please sign in to comment.