123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- import React from "react";
- import ReactDOM from "react-dom";
- import { createPortal } from "react-dom";
- import { isBrowser } from "../Utils/utils";
-
- import styles from "./Modal.less";
-
- export interface ModalProps {
- visible: boolean;
- onCancel: (e: any) => void;
- container?: HTMLElement;
- }
-
- export class Modal extends React.PureComponent<ModalProps> {
- static hasShowWarning = false;
-
- render() {
- if (!isBrowser()) return null; // 服务端无需渲染下列代码,渲染也会出错
- const DEFAULT_CONTAINER: HTMLElement | null = document.getElementById(
- "container"
- );
- const { children, visible, onCancel, container } = this.props;
- let finalMountContainer: HTMLElement;
- if (!container) {
- if (!DEFAULT_CONTAINER) {
- if (!Modal.hasShowWarning) {
- Modal.hasShowWarning = true;
- }
- finalMountContainer = document.body;
- } else {
- if (!Modal.hasShowWarning) {
- Modal.hasShowWarning = true;
- }
- finalMountContainer = DEFAULT_CONTAINER;
- }
- } else {
- finalMountContainer = container;
- }
- return (
- visible &&
- createPortal(
- <div className={styles.wrapper}>
- <div className={styles.overlay} onClick={onCancel} />
- <div className={styles.container}>{children}</div>
- </div>,
- finalMountContainer
- )
- );
- }
- }
-
- export interface ModalCMDOptions {
- children: any;
- container?: HTMLElement;
- options?: {
- mask?: true;
- };
- }
-
- export interface ModalCMDRecord {
- modalInstance: HTMLElement;
- }
-
- export class ModalCMD {
- static currentModal: ModalCMDRecord[] = [];
-
- constructor() {
- ModalCMD.currentModal = [];
- }
-
- private static recordModal(record: ModalCMDRecord) {
- ModalCMD.currentModal.push(record);
- }
-
- private static delModal() {
- return ModalCMD.currentModal.pop();
- }
-
- static show({ children, container }: ModalCMDOptions) {
- const modalInstance = document.createElement("div");
- let targetMountDom = container ? container : document.body;
- targetMountDom.appendChild(modalInstance);
- ReactDOM.render(
- <>
- <div
- style={{
- position: "fixed",
- top: 0,
- bottom: 0,
- left: 0,
- right: 0,
- zIndex: 1000
- }}
- >
- <div
- style={{
- position: "absolute",
- top: 0,
- bottom: 0,
- left: 0,
- right: 0,
- background: "rgba(0,0,0,1)",
- opacity: 0.6,
- zIndex: -1
- }}
- onClick={() => {
- ModalCMD.hide(ModalCMD.currentModal.length);
- }}
- />
-
- <div
- style={{
- position: "absolute",
- top: "50%",
- left: "50%",
- transform: "translate(-50%, -50%)"
- }}
- >
- {children}
- </div>
- </div>
- </>,
- modalInstance
- );
- this.recordModal({
- modalInstance
- });
- }
-
- static hide(targetId?: string | number) {
- const popModalRecord: ModalCMDRecord | undefined = this.delModal();
- if (popModalRecord && popModalRecord.modalInstance) {
- ReactDOM.unmountComponentAtNode(popModalRecord.modalInstance);
- const { parentNode } = popModalRecord.modalInstance;
- parentNode && parentNode.removeChild(popModalRecord.modalInstance);
- }
- }
- }
-
- export default Modal;
|