Skip to content

Commit

Permalink
feat: 模态弹窗添加最大化和退出最大化功能 (#320)
Browse files Browse the repository at this point in the history
  • Loading branch information
xuxzh authored Aug 8, 2023
1 parent e828814 commit 8456cba
Show file tree
Hide file tree
Showing 18 changed files with 313 additions and 122 deletions.
2 changes: 2 additions & 0 deletions devui/modal/demo/maximize/maximize.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<d-button (click)="openDialog()">open dialog</d-button>
<d-button bsStyle="common" (click)="openDialog('standard', false)">open dialog without animation</d-button>
54 changes: 54 additions & 0 deletions devui/modal/demo/maximize/maximize.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { Component } from '@angular/core';
import { DialogService } from 'ng-devui/modal';
import { ModalTestComponent } from '../modal-test.component';

@Component({
selector: 'd-maximize',
templateUrl: './maximize.component.html',
})
export class MaximizeComponent {
config = {
id: 'dialog-service',
width: '346px',
maxHeight: '600px',
title: 'Start Snapshot Version',
content: ModalTestComponent,
backdropCloseable: true,
onClose: () => console.log('on dialog closed'),
data: {
name: 'Tom',
age: 10,
address: 'Chengdu',
},
};

constructor(private dialogService: DialogService) {}

openDialog(dialogtype?: string, showAnimation?: boolean) {
const results = this.dialogService.open({
...this.config,
showMaximizeBtn: true,
dialogtype: dialogtype,
showAnimation: showAnimation,
buttons: [
{
cssClass: 'primary',
text: 'Ok',
disabled: false,
handler: ($event: Event) => {
results.modalInstance.hide();
},
},
{
id: 'btn-cancel',
cssClass: 'common',
text: 'Cancel',
handler: ($event: Event) => {
results.modalInstance.hide();
},
},
],
});
console.log(results.modalContentInstance);
}
}
7 changes: 7 additions & 0 deletions devui/modal/demo/modal-demo.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@
<d-basic demo></d-basic>
</d-codebox>
</div>
<div class="devui-demo-example" [dAnchor]="'maximize-dialog'">
<div class="devui-demo-title">{{ 'components.modal.maximizeDemo.title' | translate }}</div>
<div class="devui-demo-text">{{ 'components.modal.maximizeDemo.description' | translate }}</div>
<d-codebox id="basic" [sourceData]="maximizeSource">
<d-maximize demo></d-maximize>
</d-codebox>
</div>
<div class="devui-demo-example" [dAnchor]="'intercept-dialog-closed'">
<div class="devui-demo-title">{{ 'components.modal.hideDemo.title' | translate }}</div>
<div class="devui-demo-text">{{ 'components.modal.hideDemo.description' | translate }}</div>
Expand Down
9 changes: 8 additions & 1 deletion devui/modal/demo/modal-demo.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,20 @@ import { Subscription } from 'rxjs';
selector: 'd-modal-demo',
templateUrl: './modal-demo.component.html',
styles: [':host ::ng-deep d-button:not(first-child) { margin-left: 8px }'],
})
})
export class ModalDemoComponent implements OnInit, OnDestroy {
basicSource: Array<DevuiSourceData> = [
{ title: 'HTML', language: 'xml', code: require('./basic/basic.component.html?raw') },
{ title: 'TS', language: 'typescript', code: require('./basic/basic.component.ts?raw') },
{ title: 'Dialog HTML', language: 'xml', code: require('./modal-test.component.html?raw') },
{ title: 'Dialog TS', language: 'typescript', code: require('./modal-test.component.ts?raw') },
];
maximizeSource: Array<DevuiSourceData> = [
{ title: 'HTML', language: 'xml', code: require('./maximize/maximize.component.html?raw') },
{ title: 'TS', language: 'typescript', code: require('./maximize/maximize.component.ts?raw') },
{ title: 'Dialog HTML', language: 'xml', code: require('./modal-test.component.html?raw') },
{ title: 'Dialog TS', language: 'typescript', code: require('./modal-test.component.ts?raw') },
];
basicUpdateSource: Array<DevuiSourceData> = [
{ title: 'HTML', language: 'xml', code: require('./basic-update/basic-update.component.html?raw') },
{ title: 'TS', language: 'typescript', code: require('./basic-update/basic-update.component.ts?raw') },
Expand Down Expand Up @@ -102,6 +108,7 @@ export class ModalDemoComponent implements OnInit, OnDestroy {
setNavValues(values) {
this.navItems = [
{ dAnchorLink: 'standard-dialog', value: values['standard-dialog'] },
{ dAnchorLink: 'maximize-dialog', value: values['maximize-dialog'] },
{ dAnchorLink: 'custom-dialog', value: values['custom-dialog'] },
{ dAnchorLink: 'intercept-dialog-closed', value: values['intercept-dialog-closed'] },
{ dAnchorLink: 'message-hint', value: values['message-hint'] },
Expand Down
92 changes: 47 additions & 45 deletions devui/modal/demo/modal-demo.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { DDemoNavModule } from 'devui-commons/src/demo-nav/d-demo-nav.module';
import { AutofocusComponent } from './autofocus/autofocus.component';
import { BasicUpdateComponent } from './basic-update/basic-update.component';
import { BasicComponent } from './basic/basic.component';
import { MaximizeComponent } from './maximize/maximize.component';
import { CasesComponent } from './cases/cases.component';
import { ModalCasesComponent } from './cases/modal-cases.component';
import { CustomizeComponent } from './customize/customize.component';
Expand All @@ -33,53 +34,54 @@ import { TipsComponent } from './tips/tips.component';

@NgModule({
imports: [
FormsModule,
TranslateModule,
CommonModule,
ModalModule,
ButtonModule,
PopoverModule,
FormModule,
DevUICodeboxModule,
DevUIApiModule,
DDemoNavModule,
TextInputModule,
RouterModule.forChild([
{ path: '', redirectTo: 'demo', pathMatch: 'full' },
{
path: 'design',
component: ModalDesignComponent,
},
{ path: 'demo', component: ModalDemoComponent },
{
path: 'api',
component: DevUIApiComponent,
data: {
'zh-cn': require('!html-loader!markdown-loader!../doc/api-cn.md'),
'en-us': require('!html-loader!markdown-loader!../doc/api-en.md'),
},
},
FormsModule,
TranslateModule,
CommonModule,
ModalModule,
ButtonModule,
PopoverModule,
FormModule,
DevUICodeboxModule,
DevUIApiModule,
DDemoNavModule,
TextInputModule,
RouterModule.forChild([
{ path: '', redirectTo: 'demo', pathMatch: 'full' },
{
path: 'design',
component: ModalDesignComponent,
},
{ path: 'demo', component: ModalDemoComponent },
{
path: 'api',
component: DevUIApiComponent,
data: {
'zh-cn': require('!html-loader!markdown-loader!../doc/api-cn.md'),
'en-us': require('!html-loader!markdown-loader!../doc/api-en.md'),
},
},
]),
],
declarations: [
ModalDemoComponent,
ModalDesignComponent,
ModalTestComponent,
ModalAlertComponent,
ModalNoBtnComponent,
BasicComponent,
CustomizeComponent,
TipsComponent,
HideComponent,
ModalFormComponent,
AutofocusComponent,
TemplateComponent,
DialogContentComponent,
ModalContentComponent,
BasicUpdateComponent,
FixedWrapperComponent,
CasesComponent,
ModalCasesComponent
ModalDemoComponent,
ModalDesignComponent,
ModalTestComponent,
ModalAlertComponent,
ModalNoBtnComponent,
BasicComponent,
MaximizeComponent,
CustomizeComponent,
TipsComponent,
HideComponent,
ModalFormComponent,
AutofocusComponent,
TemplateComponent,
DialogContentComponent,
ModalContentComponent,
BasicUpdateComponent,
FixedWrapperComponent,
CasesComponent,
ModalCasesComponent,
],
})
})
export class ModalDemoModule {}
48 changes: 29 additions & 19 deletions devui/modal/dialog.service.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
import { DOCUMENT } from '@angular/common';
import {
ComponentFactoryResolver,
ComponentRef,
Inject,
Injectable,
Renderer2, RendererFactory2
} from '@angular/core';
import { ComponentFactoryResolver, ComponentRef, Inject, Injectable, Renderer2, RendererFactory2 } from '@angular/core';
import { OverlayContainerRef } from 'ng-devui/overlay-container';
import { DevConfigService } from 'ng-devui/utils';
import { assign, isUndefined } from 'lodash-es';
Expand All @@ -19,10 +13,13 @@ export class DialogService {
private renderer: Renderer2;
document: Document;

constructor(private componentFactoryResolver: ComponentFactoryResolver,
private overlayContainerRef: OverlayContainerRef, private rendererFactory: RendererFactory2,
private devConfigService: DevConfigService,
@Inject(DOCUMENT) private doc: any) {
constructor(
private componentFactoryResolver: ComponentFactoryResolver,
private overlayContainerRef: OverlayContainerRef,
private rendererFactory: RendererFactory2,
private devConfigService: DevConfigService,
@Inject(DOCUMENT) private doc: any
) {
this.renderer = this.rendererFactory.createRenderer(null, null);
this.document = this.doc;
}
Expand All @@ -48,6 +45,7 @@ export class DialogService {
componentFactoryResolver,
beforeHidden,
onClose,
onMaximize,
dialogtype = 'standard',
showCloseBtn = true,
draggable = true,
Expand All @@ -56,7 +54,8 @@ export class DialogService {
offsetY,
bodyScrollable = true,
contentTemplate,
escapable = true
escapable = true,
showMaximizeBtn = false,
}: IDialogOptions) {
const finalComponentFactoryResolver = componentFactoryResolver || this.componentFactoryResolver;

Expand Down Expand Up @@ -95,21 +94,25 @@ export class DialogService {
offsetX,
offsetY,
bodyScrollable,
escapable
escapable,
});

const modalContainerRef = modalRef.instance.modalContainerHost.viewContainerRef
.createComponent(finalComponentFactoryResolver.resolveComponentFactory(ModalContainerComponent), 0, injector);
assign(modalContainerRef.instance, { title, buttons, maxHeight, dialogtype, showCloseBtn });
const modalContainerRef = modalRef.instance.modalContainerHost.viewContainerRef.createComponent(
finalComponentFactoryResolver.resolveComponentFactory(ModalContainerComponent),
0,
injector
);
assign(modalContainerRef.instance, { title, buttons, maxHeight, dialogtype, showCloseBtn, showMaximizeBtn });

if (contentTemplate) {
assign(modalContainerRef.instance, { contentTemplate });
} else {
if (typeof content === 'string') {
assign(modalContainerRef.instance, { content, html });
} else {
this.contentRef = modalContainerRef.instance.modalContentHost.viewContainerRef
.createComponent(finalComponentFactoryResolver.resolveComponentFactory(content));
this.contentRef = modalContainerRef.instance.modalContentHost.viewContainerRef.createComponent(
finalComponentFactoryResolver.resolveComponentFactory(content)
);
assign(this.contentRef.instance, { data, dialogtype });
}
}
Expand All @@ -118,7 +121,14 @@ export class DialogService {
modalRef.instance.hide();
};

modalRef.instance.updateButtonOptions = buttonOptions => modalContainerRef.instance.updateButtonOptions(buttonOptions);
modalContainerRef.instance.onMaximize = () => {
modalRef.instance.maximize();
if (onMaximize) {
onMaximize(modalRef.instance.maximized);
}
};

modalRef.instance.updateButtonOptions = (buttonOptions) => modalContainerRef.instance.updateButtonOptions(buttonOptions);

modalRef.instance.onHidden = () => {
if (modalRef.instance.documentOverFlow) {
Expand Down
4 changes: 3 additions & 1 deletion devui/modal/modal-container.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,17 @@
id="d-modal-header"
[title]="title"
(closeEvent)="close($event)"
(maximizeEvent)="maximize($event)"
[dialogtype]="dialogtype"
[showMaximizeBtn]="showMaximizeBtn"
[showCloseBtn]="showCloseBtn"
></d-modal-header>
<div
class="modal-body devui-scrollbar"
[ngClass]="{
'flex-content': dialogtype === 'warning' || dialogtype === 'failed' || dialogtype === 'success' || dialogtype === 'info'
}"
[ngStyle]="{ maxHeight: maxHeight }"
[ngStyle]="{ maxHeight: maxHeight, 'overflow-y': 'auto' }"
>
<div
[ngClass]="{
Expand Down
27 changes: 18 additions & 9 deletions devui/modal/modal-container.component.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
import {
Component,
Input,
OnInit,
TemplateRef,
ViewChild
} from '@angular/core';
import { Component, Input, OnInit, TemplateRef, ViewChild } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
import { IButtonStyle } from 'ng-devui/button';
import { ModalComponent } from './modal.component';
Expand All @@ -14,12 +8,13 @@ import { ModalContentDirective } from './modal.directive';
templateUrl: './modal-container.component.html',
styleUrls: ['./modal-container.component.scss'],
preserveWhitespaces: false,
})
})
export class ModalContainerComponent implements OnInit {
@Input() maxHeight: string;
@Input() data: any;
@Input() title: string;
@Input() content: string | HTMLElement;
@Input() showMaximizeBtn: boolean;
@Input() buttons: Array<{
id?: string;
cssClass?: IButtonStyle;
Expand All @@ -31,10 +26,12 @@ export class ModalContainerComponent implements OnInit {
}>;
@Input() html: boolean;
@Input() onClose: ($event?: Event) => void;
@Input() onMaximize: (maximized: boolean) => void;
@ViewChild(ModalContentDirective, { static: true }) modalContentHost: ModalContentDirective;
@Input() dialogtype = 'standard';
@Input() showCloseBtn: boolean;
contentTemplate: TemplateRef<any>;
_oldMaxHeight: string;

constructor(private sanitizer: DomSanitizer, public modalInstance: ModalComponent) {}

Expand All @@ -48,9 +45,21 @@ export class ModalContainerComponent implements OnInit {
this.onClose(event);
}

maximize(maximized: boolean) {
if (this.onMaximize) {
this.onMaximize(maximized);
}
if (maximized) {
this._oldMaxHeight = this.maxHeight;
this.maxHeight = '100vh';
} else {
this.maxHeight = this._oldMaxHeight;
}
}

updateButtonOptions(buttonOptions = []) {
this.buttons = this.buttons.map((button, index) => {
return {...button, ...buttonOptions[index]};
return { ...button, ...buttonOptions[index] };
});
}
}
Loading

0 comments on commit 8456cba

Please sign in to comment.