123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
- import * as React from 'react';
- import { createPortal } from 'react-dom';
- import canUseDom from "rc-util/es/Dom/canUseDom";
- import warning from "rc-util/es/warning";
- import { supportRef, useComposeRef } from "rc-util/es/ref";
- import OrderContext from "./Context";
- import useDom from "./useDom";
- import useScrollLocker from "./useScrollLocker";
- import { inlineMock } from "./mock";
- var getPortalContainer = function getPortalContainer(getContainer) {
- if (getContainer === false) {
- return false;
- }
- if (!canUseDom() || !getContainer) {
- return null;
- }
- if (typeof getContainer === 'string') {
- return document.querySelector(getContainer);
- }
- if (typeof getContainer === 'function') {
- return getContainer();
- }
- return getContainer;
- };
- var Portal = /*#__PURE__*/React.forwardRef(function (props, ref) {
- var open = props.open,
- autoLock = props.autoLock,
- getContainer = props.getContainer,
- debug = props.debug,
- _props$autoDestroy = props.autoDestroy,
- autoDestroy = _props$autoDestroy === void 0 ? true : _props$autoDestroy,
- children = props.children;
- var _React$useState = React.useState(open),
- _React$useState2 = _slicedToArray(_React$useState, 2),
- shouldRender = _React$useState2[0],
- setShouldRender = _React$useState2[1];
- var mergedRender = shouldRender || open;
- // ========================= Warning =========================
- if (process.env.NODE_ENV !== 'production') {
- warning(canUseDom() || !open, "Portal only work in client side. Please call 'useEffect' to show Portal instead default render in SSR.");
- }
- // ====================== Should Render ======================
- React.useEffect(function () {
- if (autoDestroy || open) {
- setShouldRender(open);
- }
- }, [open, autoDestroy]);
- // ======================== Container ========================
- var _React$useState3 = React.useState(function () {
- return getPortalContainer(getContainer);
- }),
- _React$useState4 = _slicedToArray(_React$useState3, 2),
- innerContainer = _React$useState4[0],
- setInnerContainer = _React$useState4[1];
- React.useEffect(function () {
- var customizeContainer = getPortalContainer(getContainer);
- // Tell component that we check this in effect which is safe to be `null`
- setInnerContainer(customizeContainer !== null && customizeContainer !== void 0 ? customizeContainer : null);
- });
- var _useDom = useDom(mergedRender && !innerContainer, debug),
- _useDom2 = _slicedToArray(_useDom, 2),
- defaultContainer = _useDom2[0],
- queueCreate = _useDom2[1];
- var mergedContainer = innerContainer !== null && innerContainer !== void 0 ? innerContainer : defaultContainer;
- // ========================= Locker ==========================
- useScrollLocker(autoLock && open && canUseDom() && (mergedContainer === defaultContainer || mergedContainer === document.body));
- // =========================== Ref ===========================
- var childRef = null;
- if (children && supportRef(children) && ref) {
- var _ref = children;
- childRef = _ref.ref;
- }
- var mergedRef = useComposeRef(childRef, ref);
- // ========================= Render ==========================
- // Do not render when nothing need render
- // When innerContainer is `undefined`, it may not ready since user use ref in the same render
- if (!mergedRender || !canUseDom() || innerContainer === undefined) {
- return null;
- }
- // Render inline
- var renderInline = mergedContainer === false || inlineMock();
- var reffedChildren = children;
- if (ref) {
- reffedChildren = /*#__PURE__*/React.cloneElement(children, {
- ref: mergedRef
- });
- }
- return /*#__PURE__*/React.createElement(OrderContext.Provider, {
- value: queueCreate
- }, renderInline ? reffedChildren : /*#__PURE__*/createPortal(reffedChildren, mergedContainer));
- });
- if (process.env.NODE_ENV !== 'production') {
- Portal.displayName = 'Portal';
- }
- export default Portal;
|