import React, { Component } from "react"; import { tBaseStore } from "../../store"; import ModalBase from "./ModalBase"; import { emptyFunc } from "./configs"; import { ModalPortalProps, ModalPortalState, ModalProps } from "./types"; let modal: ModalPortal; export class ModalPortal extends Component { id = 0; constructor(props: ModalPortalProps) { super(props); this.id = 0; this.state = { stack: [] }; modal = this as ModalPortal; } static get ref() { return modal; } static get size() { return modal.state.stack.length; } static show(children: any, props: ModalProps) { return modal.show({ children, ...props }); } static update(key: string, props: ModalProps) { modal.update(key, props); } static dismiss(key: string) { modal.dismiss(key); } static dismissAll() { modal.dismissAll(); } get current() { return this.state.stack.pop()?.key; } generateKey = () => { return `tlm-${this.id++}`; }; getIndex = (key: string) => { return this.state.stack.findIndex((i) => i.key === key); }; getProps = (props: ModalProps) => { const key = props.key || this.generateKey(); return { visible: true, ...props, key }; }; show = (props: ModalProps) => { const mergedProps = this.getProps(props); this.setState(({ stack }) => { return { stack: stack.concat(mergedProps) }; }); return mergedProps.key; }; update = (key: string, props: ModalProps) => { const mergedProps = this.getProps({ ...props, key }); this.setState(({ stack }) => { const index = this.getIndex(key); stack[index] = { ...stack[index], ...mergedProps }; return { stack }; }); }; dismiss = (key = this.current) => { if (!key) return; const props = { ...this.state.stack[this.getIndex(key)], visible: false }; this.update(key, props); }; dismissAll = () => { this.state.stack.forEach(({ key }) => this.dismiss(key)); }; dismissHandler = (key: string) => { const { onClosed = emptyFunc } = this.state.stack[this.getIndex(key)] || {}; this.setState(({ stack }) => { return { stack: stack.filter((i) => i.key !== key) }; }, onClosed); }; renderModal = ({ ...props }) => { return ( this.dismissHandler(props.key)} /> ); }; render() { const { stack } = this.state; tBaseStore.setTotalModal(stack.length); tBaseStore.setAndroidInputMode( stack.length ? "resize" : tBaseStore.inputType ); return stack.map(this.renderModal); } }