All files / src/modal ModalShow.tsx

7.14% Statements 1/14
0% Branches 0/2
0% Functions 0/6
8.33% Lines 1/12

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70                                                                                                              9x                            
import React, {
  useEffect,
  useState,
  forwardRef,
  useImperativeHandle,
} from "react";
import ReactDOM, { unmountComponentAtNode } from "react-dom";
import { Modal, ModalProps } from "./ModalMain";
import { ConfigProvider } from "../configprovider";
import { Omit } from "../_type";
 
export interface ModalShowOptions
  extends Omit<ModalProps, "visible" | "onExited"> {}
 
export interface ModalShowHandle {
  /**
   * 关闭并销毁当前对话框
   */
  destroy: () => void;
}
 
/**
 * API 方式唤起一个对话框内容
 */
export function show(options: ModalShowOptions): ModalShowHandle {
  const el = document.createElement("div");
 
  const instanceRef = React.createRef<ModalShowInstance>();
 
  ReactDOM.render(
    <ConfigProvider>
      <ModalShow
        {...options}
        ref={instanceRef}
        onExited={() => unmountComponentAtNode(el)}
      />
    </ConfigProvider>,
    el
  );
 
  return {
    destroy: () => {
      if (instanceRef.current) {
        instanceRef.current.setVisible(false);
      }
    },
  };
}
 
interface ModalShowProps extends Omit<ModalProps, "visible"> {}
 
interface ModalShowInstance {
  setVisible: React.Dispatch<React.SetStateAction<boolean>>;
}
 
const ModalShow = forwardRef(function ModalShow(
  props: ModalShowProps,
  ref: React.Ref<ModalShowInstance>
) {
  const [visible, setVisible] = useState(false);
 
  // 渲染之后,马上显示
  useEffect(() => setVisible(true), []);
 
  // 实例 ref 到外部
  useImperativeHandle(ref, () => ({ setVisible }));
 
  return <Modal {...props} visible={visible} />;
});