UNPKG

3.69 kBJavaScriptView Raw
1import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
2import * as React from 'react';
3import { createPortal } from 'react-dom';
4import canUseDom from "rc-util/es/Dom/canUseDom";
5import { supportRef, useComposeRef } from "rc-util/es/ref";
6import OrderContext from "./Context";
7import useDom from "./useDom";
8import useScrollLocker from "./useScrollLocker";
9import { inlineMock } from "./mock";
10
11var getPortalContainer = function getPortalContainer(getContainer) {
12 if (getContainer === false) {
13 return false;
14 }
15
16 if (!canUseDom() || !getContainer) {
17 return null;
18 }
19
20 if (typeof getContainer === 'string') {
21 return document.querySelector(getContainer);
22 }
23
24 if (typeof getContainer === 'function') {
25 return getContainer();
26 }
27
28 return getContainer;
29};
30
31var Portal = /*#__PURE__*/React.forwardRef(function (props, ref) {
32 var open = props.open,
33 autoLock = props.autoLock,
34 getContainer = props.getContainer,
35 debug = props.debug,
36 _props$autoDestroy = props.autoDestroy,
37 autoDestroy = _props$autoDestroy === void 0 ? true : _props$autoDestroy,
38 children = props.children;
39
40 var _React$useState = React.useState(open),
41 _React$useState2 = _slicedToArray(_React$useState, 2),
42 mergedRender = _React$useState2[0],
43 setMergedRender = _React$useState2[1]; // ====================== Should Render ======================
44
45
46 React.useEffect(function () {
47 if (autoDestroy || open) {
48 setMergedRender(open);
49 }
50 }, [open, autoDestroy]); // ======================== Container ========================
51
52 var _React$useState3 = React.useState(function () {
53 return getPortalContainer(getContainer);
54 }),
55 _React$useState4 = _slicedToArray(_React$useState3, 2),
56 innerContainer = _React$useState4[0],
57 setInnerContainer = _React$useState4[1];
58
59 React.useEffect(function () {
60 var customizeContainer = getPortalContainer(getContainer); // Tell component that we check this in effect which is safe to be `null`
61
62 setInnerContainer(customizeContainer !== null && customizeContainer !== void 0 ? customizeContainer : null);
63 });
64
65 var _useDom = useDom(mergedRender && !innerContainer, debug),
66 _useDom2 = _slicedToArray(_useDom, 2),
67 defaultContainer = _useDom2[0],
68 queueCreate = _useDom2[1];
69
70 var mergedContainer = innerContainer !== null && innerContainer !== void 0 ? innerContainer : defaultContainer; // ========================= Locker ==========================
71
72 useScrollLocker(autoLock && open && canUseDom() && (mergedContainer === defaultContainer || mergedContainer === document.body)); // =========================== Ref ===========================
73
74 var childRef = null;
75
76 if (children && supportRef(children) && ref) {
77 var _ref = children;
78 childRef = _ref.ref;
79 }
80
81 var mergedRef = useComposeRef(childRef, ref); // ========================= Render ==========================
82 // Do not render when nothing need render
83 // When innerContainer is `undefined`, it may not ready since user use ref in the same render
84
85 if (!mergedRender || !canUseDom() || innerContainer === undefined) {
86 return null;
87 } // Render inline
88
89
90 var renderInline = mergedContainer === false || inlineMock();
91 var reffedChildren = children;
92
93 if (ref) {
94 reffedChildren = /*#__PURE__*/React.cloneElement(children, {
95 ref: mergedRef
96 });
97 }
98
99 return /*#__PURE__*/React.createElement(OrderContext.Provider, {
100 value: queueCreate
101 }, renderInline ? reffedChildren : /*#__PURE__*/createPortal(reffedChildren, mergedContainer));
102});
103
104if (process.env.NODE_ENV !== 'production') {
105 Portal.displayName = 'Portal';
106}
107
108export default Portal;
\No newline at end of file