diff --git a/packages/mosaic-dev/modal/module.ts b/packages/mosaic-dev/modal/module.ts index 34d080751..699651745 100644 --- a/packages/mosaic-dev/modal/module.ts +++ b/packages/mosaic-dev/modal/module.ts @@ -57,6 +57,12 @@ export class ModalDemoComponent { }); } + createModalComponent() { + const modalRef = this.modalService.open({ + mcComponent: McModalFullCustomComponent + }); + } + createLongModal() { const modal = this.modalService.create({ @@ -163,15 +169,50 @@ export class McModalCustomComponent { } } +@Component({ + selector: 'mc-modal-full-custom-component', + template: ` + + Modal Title + + + +

{{ title }}

+

{{ subtitle }}

+

+ Get Modal instance in component + +

+
+ +
+ + +
+ ` +}) +export class McModalFullCustomComponent { + @Input() title: string; + @Input() subtitle: string; + + constructor(private modal: McModalRef) { } + + destroyModal() { + this.modal.destroy({ data: 'this the result data' }); + } +} + @NgModule({ declarations: [ ModalDemoComponent, McModalCustomComponent, - McModalLongCustomComponent + McModalLongCustomComponent, + McModalFullCustomComponent ], entryComponents: [ McModalCustomComponent, - McModalLongCustomComponent + McModalLongCustomComponent, + McModalFullCustomComponent ], imports: [ BrowserModule, diff --git a/packages/mosaic-dev/modal/template.html b/packages/mosaic-dev/modal/template.html index 3b6d8bcfe..ca64aa169 100644 --- a/packages/mosaic-dev/modal/template.html +++ b/packages/mosaic-dev/modal/template.html @@ -42,3 +42,6 @@ mcCancelText="Cancel" [mcZIndex]="1001" mcTitle="Non-service html modal">This is a non-service html modal + +

Modal with looong component

+ diff --git a/packages/mosaic/modal/README.md b/packages/mosaic/modal/README.md index e69de29bb..ab06b9944 100644 --- a/packages/mosaic/modal/README.md +++ b/packages/mosaic/modal/README.md @@ -0,0 +1,34 @@ +The dialog is currently divided into 3 modes - `default`, `confirm box`, `custom`. + + +#### Using service to create Confirm Mode + +```ts +showConfirm() { + this.modalService.success({ + mcContent : 'Save changes made to the request "All assets with Windows"?', + mcOkText : 'Save', + mcCancelText: 'Cancel', + mcOnOk : () => console.log('OK') + }); +} +``` + +#### Using service to open modal Custom Mode + +```ts +let dialogRef = modalService.open({ + mcComponent: CustomComponent +}); +``` + +```ts +@Component({/* ... */}) +export class CustomComponent { + constructor(private dialogRef: McModalRef) { } + + closeDialog() { + this.modal.destroy({ data: 'this the result data' }); + } +} +``` \ No newline at end of file diff --git a/packages/mosaic/modal/modal.component.html b/packages/mosaic/modal/modal.component.html index 957f2101e..8eda1ff7c 100644 --- a/packages/mosaic/modal/modal.component.html +++ b/packages/mosaic/modal/modal.component.html @@ -38,12 +38,19 @@ [ngTemplateOutlet]="tplContentDefault"> + + + + + +
diff --git a/packages/mosaic/modal/modal.component.ts b/packages/mosaic/modal/modal.component.ts index fe4bfd4a4..36efcc4b6 100644 --- a/packages/mosaic/modal/modal.component.ts +++ b/packages/mosaic/modal/modal.component.ts @@ -52,6 +52,9 @@ export class McModalComponent extends McModalRef // tslint:disable-next-line:no-any @Input() mcModalType: ModalType = 'default'; + + // The instance of component opened into the dialog. + @Input() mcComponent: Type; // If not specified, will use @Input() mcContent: string | TemplateRef<{}> | Type; // available when mcContent is a component @@ -117,7 +120,7 @@ export class McModalComponent extends McModalRef @Input() @Output() mcOnCancel: EventEmitter | OnClickCallback = new EventEmitter(); - @ViewChild('modalContainer', {static: false}) modalContainer: ElementRef; + @ViewChild('modalContainer', { static: true }) modalContainer: ElementRef; @ViewChild('bodyContainer', { read: ViewContainerRef, static: false}) bodyContainer: ViewContainerRef; // Only aim to focus the ok button that needs to be auto focused @ViewChild('autoFocusButtonOk', { read: ElementRef, static: false}) autoFocusButtonOk: ElementRef; @@ -184,6 +187,11 @@ export class McModalComponent extends McModalRef this.mcFooter = this.formatModalButtons(this.mcFooter as IModalButtonOptions[]); } + + if (this.isComponent(this.mcComponent)) { + this.createDynamicComponent(this.mcComponent as Type); + } + // Place the modal dom to elsewhere this.container = typeof this.mcGetContainer === 'function' ? this.mcGetContainer() : this.mcGetContainer; if (this.container instanceof HTMLElement) { @@ -479,8 +487,6 @@ export class McModalComponent extends McModalRef // Do the first change detection immediately // (or we do detection at ngAfterViewInit, multi-changes error will be thrown) this.contentComponentRef.changeDetectorRef.detectChanges(); - - } // Update transform-origin to the last click position on document diff --git a/packages/mosaic/modal/modal.directive.ts b/packages/mosaic/modal/modal.directive.ts new file mode 100644 index 000000000..7cefcc6f9 --- /dev/null +++ b/packages/mosaic/modal/modal.directive.ts @@ -0,0 +1,26 @@ +import { Directive } from '@angular/core'; + + +@Directive({ + selector: `[mc-modal-title], mc-modal-title, [mcModalTitle]`, + host: { + class: 'mc-modal-header mc-modal-title' + } +}) +export class McModalTitle {} + +@Directive({ + selector: `[mc-modal-body], mc-modal-body, [mcModalBody]`, + host: { + class: 'mc-modal-body' + } +}) +export class McModalBody {} + +@Directive({ + selector: `[mc-modal-footer], mc-modal-footer, [mcModalFooter]`, + host: { + class: 'mc-modal-footer' + } +}) +export class McModalFooter {} diff --git a/packages/mosaic/modal/modal.module.ts b/packages/mosaic/modal/modal.module.ts index a73aa4d85..450f31d17 100644 --- a/packages/mosaic/modal/modal.module.ts +++ b/packages/mosaic/modal/modal.module.ts @@ -8,13 +8,25 @@ import { McIconModule } from '@ptsecurity/mosaic/icon'; import { CssUnitPipe } from './css-unit.pipe'; import { McModalControlService } from './modal-control.service'; import { McModalComponent } from './modal.component'; +import { McModalBody, McModalFooter, McModalTitle } from './modal.directive'; import { McModalService } from './modal.service'; @NgModule({ imports: [CommonModule, OverlayModule, A11yModule, McButtonModule, McIconModule], - exports: [McModalComponent], - declarations: [McModalComponent, CssUnitPipe], + exports: [ + McModalComponent, + McModalTitle, + McModalBody, + McModalFooter + ], + declarations: [ + McModalComponent, + McModalTitle, + McModalBody, + McModalFooter, + CssUnitPipe + ], entryComponents: [McModalComponent], providers: [McModalControlService, McModalService] }) diff --git a/packages/mosaic/modal/modal.scss b/packages/mosaic/modal/modal.scss index 6b9c88ef1..991b18c42 100644 --- a/packages/mosaic/modal/modal.scss +++ b/packages/mosaic/modal/modal.scss @@ -82,25 +82,22 @@ .mc-modal-header { padding: 14px 16px; - + display: block; border-radius: 4px 4px 0 0; } .mc-modal-body { + display: block; padding: 16px 24px 24px 24px; - max-height: calc(100vh - 260px); - word-wrap: break-word; - overflow-y: auto; } .mc-modal-footer { + display: block; padding: 16px 16px; - border-radius: 0 0 4px 4px; - text-align: right; button + button { diff --git a/packages/mosaic/modal/modal.service.ts b/packages/mosaic/modal/modal.service.ts index 7c520c2a2..0742770a7 100644 --- a/packages/mosaic/modal/modal.service.ts +++ b/packages/mosaic/modal/modal.service.ts @@ -1,6 +1,6 @@ -import { Overlay, OverlayRef } from '@angular/cdk/overlay'; +import { ComponentType, Overlay, OverlayRef } from '@angular/cdk/overlay'; import { ComponentPortal } from '@angular/cdk/portal'; -import { ComponentRef, Injectable } from '@angular/core'; +import { ComponentRef, Injectable, TemplateRef } from '@angular/core'; import { ESCAPE } from '@ptsecurity/cdk/keycodes'; import { Observable } from 'rxjs'; import { filter } from 'rxjs/operators'; @@ -123,6 +123,13 @@ export class McModalService { return this.create(options); } + open(options: IModalOptionsForService = {}): McModalRef { + + options.mcModalType = 'custom'; + + return this.create(options); + } + success(options: IModalOptionsForService = {}): McModalRef { return this.simpleConfirm(options, 'success'); } diff --git a/packages/mosaic/modal/modal.type.ts b/packages/mosaic/modal/modal.type.ts index d0c2e10a6..cfdb2c48a 100644 --- a/packages/mosaic/modal/modal.type.ts +++ b/packages/mosaic/modal/modal.type.ts @@ -5,7 +5,7 @@ import { EventEmitter, TemplateRef, Type } from '@angular/core'; export type OnClickCallback = ((instance: T) => (false | void | {}) | Promise); // Different modal styles we have supported -export type ModalType = 'default' | 'confirm'; +export type ModalType = 'default' | 'confirm' | 'custom'; // Subtypes of Confirm Modal export type ConfirmType = 'confirm' | 'success' | 'warn'; @@ -21,6 +21,7 @@ export interface IModalOptions { mcStyle?: object; mcTitle?: string | TemplateRef<{}>; mcContent?: string | TemplateRef<{}> | Type; + mcComponent?: Type; // The instance of component opened into the dialog. mcComponentParams?: Partial; mcClosable?: boolean; mcMask?: boolean;