Skip to content

Commit

Permalink
feat(theme:modal): support drag (#1607)
Browse files Browse the repository at this point in the history
  • Loading branch information
cipchk authored Jul 15, 2023
1 parent 701c506 commit 3cd73f7
Show file tree
Hide file tree
Showing 7 changed files with 127 additions and 8 deletions.
37 changes: 37 additions & 0 deletions packages/theme/src/services/modal/demo/drag.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
title:
zh-CN: 拖动
en-US: Drag
order: 1
---

## zh-CN

支持拖动对话框。

## en-US

Support for dragging dialogs.

```ts
import { Component } from '@angular/core';
import { ModalHelper } from '@delon/theme';
import { DemoModalComponent } from '@shared';
import { NzMessageService } from 'ng-zorro-antd/message';

@Component({
selector: 'app-demo',
template: `
<button nz-button (click)="open()">Open</button>
`,
})
export class DemoComponent {
constructor(private modalHelper: ModalHelper, private msg: NzMessageService) {}

open(): void {
this.modalHelper.create(DemoModalComponent, { record: { a: 1, b: '2', c: new Date() } }, { drag: true }).subscribe(res => {
this.msg.info(res);
});
}
}
```
1 change: 1 addition & 0 deletions packages/theme/src/services/modal/index.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,5 @@ Your body content
| `size` | Specify modal size | `sm,md,lg,xl,number` | `lg` |
| `exact` | Exact match return value, default is `true`, If the return value is not null (`null` or `undefined`) is considered successful, otherwise it is considered error. | `boolean` | `true` |
| `includeTabs` | Whether to wrap the tab page | `boolean` | `false` |
| `drag` | Drag | `boolean, ModalHelperDragOptions` | - |
| `modalOptions` | nz-modal raw parameters [ModalOptions](https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/components/modal/modal-types.ts) | `ModalOptions` | - |
1 change: 1 addition & 0 deletions packages/theme/src/services/modal/index.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,5 @@ Your body content
| `size` | 指定对话框大小 | `sm,md,lg,xl,number` | `lg` |
| `exact` | 是否精准(默认:`true`),若返回值非空值(`null``undefined`)视为成功,否则视为错误 | `boolean` | `true` |
| `includeTabs` | 是否包裹标签页 | `boolean` | `false` |
| `drag` | 支持拖动 | `boolean, ModalHelperDragOptions` | - |
| `modalOptions` | 对话框 [ModalOptions](https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/components/modal/modal-types.ts) 参数 | `ModalOptions` | - |
63 changes: 57 additions & 6 deletions packages/theme/src/services/modal/modal.helper.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { Injectable, TemplateRef, Type } from '@angular/core';
import { Observable, Observer } from 'rxjs';
import { DragDrop, DragRef } from '@angular/cdk/drag-drop';
import { DOCUMENT } from '@angular/common';
import { Inject, Injectable, TemplateRef, Type } from '@angular/core';
import { Observable, Observer, filter, take } from 'rxjs';

import { deepMerge } from '@delon/util/other';
import type { NzSafeAny } from 'ng-zorro-antd/core/types';
Expand All @@ -14,14 +16,45 @@ export interface ModalHelperOptions {
exact?: boolean;
/** 是否包裹标签页,修复模态包含标签间距问题 */
includeTabs?: boolean;
/**
* 是否支持拖动,默认是通过标题来触发
*/
drag?: ModalHelperDragOptions | boolean;
}

export interface ModalHelperDragOptions {
/**
* 指定拖地区域的类名,若指定为 `null` 时表示整个对话框,默认:`.modal-header, .ant-modal-title`
*/
handleCls?: string | null;
}

/**
* 对话框辅助类
*/
@Injectable({ providedIn: 'root' })
export class ModalHelper {
constructor(private srv: NzModalService) {}
private document: Document;
private dragClsPrefix = 'MODAL-DRAG';

constructor(private srv: NzModalService, private drag: DragDrop, @Inject(DOCUMENT) doc: NzSafeAny) {
this.document = doc;
}

private createDragRef(options: ModalHelperDragOptions, wrapCls: string): DragRef {
const wrapEl = this.document.querySelector(wrapCls) as HTMLDivElement;
const modalEl = wrapEl.firstChild as HTMLDivElement;
const handelEl = options.handleCls ? wrapEl.querySelector<HTMLDivElement>(options.handleCls) : null;
if (handelEl) {
handelEl.classList.add(`${this.dragClsPrefix}-HANDLE`);
}

return this.drag
.createDrag(handelEl ?? modalEl)
.withHandles([handelEl ?? modalEl])
.withBoundaryElement(wrapEl)
.withRootElement(modalEl);
}

/**
* 构建一个对话框
Expand Down Expand Up @@ -53,7 +86,7 @@ export class ModalHelper {
options
);
return new Observable((observer: Observer<NzSafeAny>) => {
const { size, includeTabs, modalOptions } = options as ModalHelperOptions;
const { size, includeTabs, modalOptions, drag } = options as ModalHelperOptions;
let cls = '';
let width = '';
if (size) {
Expand All @@ -70,6 +103,16 @@ export class ModalHelper {
cls += ` ${modalOptions.nzWrapClassName}`;
delete modalOptions.nzWrapClassName;
}
let dragOptions: ModalHelperDragOptions | null;
let dragWrapCls = `${this.dragClsPrefix}-${+new Date()}`;
let dragRef: DragRef | null;
if (drag != null && drag !== false) {
dragOptions = {
handleCls: `.modal-header, .ant-modal-title`,
...(typeof drag === 'object' ? drag : {})
};
cls += ` ${this.dragClsPrefix} ${dragWrapCls}`;
}
const defaultOptions: ModalOptions = {
nzWrapClassName: cls,
nzContent: comp,
Expand All @@ -78,7 +121,15 @@ export class ModalHelper {
nzComponentParams: params
};
const subject = this.srv.create({ ...defaultOptions, ...modalOptions });
const afterClose$ = subject.afterClose.subscribe((res: NzSafeAny) => {
subject.afterOpen
.pipe(
take(1),
filter(() => dragOptions != null)
)
.subscribe(() => {
dragRef = this.createDragRef(dragOptions!!, `.${dragWrapCls}`);
});
subject.afterClose.pipe(take(1)).subscribe((res: NzSafeAny) => {
if (options!.exact === true) {
if (res != null) {
observer.next(res);
Expand All @@ -87,7 +138,7 @@ export class ModalHelper {
observer.next(res);
}
observer.complete();
afterClose$.unsubscribe();
dragRef?.dispose();
});
});
}
Expand Down
27 changes: 26 additions & 1 deletion packages/theme/src/services/modal/modal.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,31 @@ describe('theme: ModalHelper', () => {
fixture.detectChanges();
}));
});
describe('#drag', () => {
it('should be working', fakeAsync(() => {
modal
.create(TestModalComponent, { ret: 'true' }, { drag: true, modalOptions: { nzTitle: 'test' } })
.subscribe();
fixture.detectChanges();
tick(1000);
fixture.detectChanges();
expect(document.querySelectorAll('.MODAL-DRAG').length).toBe(1);
}));
it('#handleCls', fakeAsync(() => {
modal
.create(
TestModalComponent,
{ ret: 'true' },
{ drag: { handleCls: '.handle' }, modalOptions: { nzTitle: 'test' } }
)
.subscribe();
fixture.detectChanges();
tick(1000);
fixture.detectChanges();
const handle = document.querySelector<HTMLDivElement>('.MODAL-DRAG-HANDLE');
expect(handle?.classList).toContain('handle');
}));
});
});

describe('#createStatic', () => {
Expand Down Expand Up @@ -113,7 +138,7 @@ describe('theme: ModalHelper', () => {
});

@Component({
template: ` <div id="modal{{ id }}">modal{{ id }}</div> `
template: ` <div id="modal{{ id }}" class="handle">modal{{ id }}</div> `
})
class TestModalComponent {
id = '';
Expand Down
4 changes: 4 additions & 0 deletions packages/theme/system/antd/_modal.less
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,7 @@
}
}
}

.MODAL-DRAG-HANDLE {
cursor: move;
}
2 changes: 1 addition & 1 deletion scripts/site/route-paths.txt
Original file line number Diff line number Diff line change
Expand Up @@ -334,4 +334,4 @@
/util/pipes-format/en
/util/pipes-format/zh
/util/token/en
/util/token/zh
/util/token/zh

0 comments on commit 3cd73f7

Please sign in to comment.