UNPKG

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