File

src/app/modules/shared/components/modal-wrapper/modal-wrapper.component.ts

Implements

OnInit OnDestroy

Metadata

Index

Properties
Methods
Inputs
Outputs

Constructor

constructor(matDialog: MatDialog, overlay: Overlay)
Parameters :
Name Type Optional
matDialog MatDialog No
overlay Overlay No

Inputs

config
Type : IMatDialogConfig

Outputs

dismiss
Type : EventEmitter

Methods

Public deny
deny()
Returns : void
Private getDefaultConfig
getDefaultConfig()
Returns : MatDialogConfig
Private getDialogConfig
getDialogConfig()
Returns : MatDialogConfig
ngOnDestroy
ngOnDestroy()
Returns : void
ngOnInit
ngOnInit()
Returns : void
Private open
open(templateRef: TemplateRef, options: MatDialogConfig)
Parameters :
Name Type Optional
templateRef TemplateRef<any> No
options MatDialogConfig No
Returns : MatDialogRef<any>
Private setElementStyle
setElementStyle(element: HTMLElement)
Parameters :
Name Type Optional
element HTMLElement No
Returns : (styleProperty: string, styleValue: string) => void
Private subscribeToDialogDismiss
subscribeToDialogDismiss()
Returns : void

Properties

Public modal
Type : MatDialogRef<>
Private modalContent
Type : any
Decorators :
@ContentChild(ModalContentDirective, {static: true})
import { Component, ContentChild, OnInit, Directive, TemplateRef, Input, Output, EventEmitter, OnDestroy } from '@angular/core';
import { MatDialog, MatDialogConfig, MatDialogRef } from '@angular/material/dialog';
import { v4 as UUID } from 'uuid';
import { Overlay } from '@angular/cdk/overlay';


const modalSizeToMinWidthMapping = {
  small: '30rem',
  normal: '45rem',
  large: '56.5rem'
};

type ModalSize = keyof typeof modalSizeToMinWidthMapping;
interface AdditionalConfig {
  size: string;
}
type IMatDialogConfig = MatDialogConfig & AdditionalConfig;

@Directive({
  selector: '[sbModalContent]'
})
export class ModalContentDirective {
  constructor(private templateRef: TemplateRef<any>) { }
}

/**
 * @description Wrapper component to turn semantic modals into Material UI Modals
 * @export
 * @class ModalWrapperComponent
 * @implements {OnInit}
 */
@Component({
  selector: 'app-modal-wrapper',
  template: ''
})
export class ModalWrapperComponent implements OnInit, OnDestroy {

  @Input() config: IMatDialogConfig;
  @ContentChild(ModalContentDirective, { static: true }) private modalContent: any;
  @Output() dismiss = new EventEmitter();
  public modal: MatDialogRef<unknown>;

  private getDefaultConfig(): MatDialogConfig {
    return { disableClose: true };
  }

  constructor(private matDialog: MatDialog, private overlay: Overlay) { }

  private getDialogConfig(): MatDialogConfig {
    const { size: modalSize = 'normal', id = UUID(), data = {}, scrollStrategy = this.overlay.scrollStrategies.reposition(), ...config } = this.config || {};
    return {
      id,
      ...this.getDefaultConfig(),
      ...config,
      data: { id, ...data },
      // scrollStrategy
    };
  }

  private open(templateRef: TemplateRef<any>, options: MatDialogConfig): MatDialogRef<any> {
    this.setElementStyle(document.body)('overflow', 'hidden');
    this.setElementStyle(document.documentElement)('overflow', 'hidden');
    return this.matDialog.open(templateRef, options);
  }

  public deny() {
    this.modal && this.modal.close();
  }

  private subscribeToDialogDismiss() {
    this.modal && this.modal.afterClosed().subscribe(event => {
      this.setElementStyle(document.body)('overflow', 'auto');
      this.setElementStyle(document.documentElement)('overflow', 'inherit');
      this.dismiss.emit(event);
    });
  }

  ngOnInit(): void {
    const config = this.getDialogConfig();
    this.modal = this.open(this.modalContent.templateRef, config);
    this.subscribeToDialogDismiss();
  }

  ngOnDestroy() {
    this.deny();
  }

  private setElementStyle(element: HTMLElement) {
    return (styleProperty: string, styleValue: string) => {
      element.style[styleProperty] = styleValue;
    };
  }
}




Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""