UNPKG

rsuite

Version:

A suite of react components

116 lines (115 loc) 3.37 kB
'use client'; import _extends from "@babel/runtime/helpers/esm/extends"; import React, { useState, useRef, useCallback } from 'react'; import classNames from 'classnames'; import Fade from "../../Animation/Fade.js"; import Position, { getPositionStyle } from "./Position.js"; import { useOverlay } from "./OverlayProvider.js"; import { useRootClose } from "../hooks/index.js"; import { mergeRefs, mergeStyles } from "../utils/index.js"; /** * Overlay is a powerful component that helps you create floating components. * @private */ const Overlay = /*#__PURE__*/React.forwardRef((props, ref) => { const { overlayContainer } = useOverlay(); const { container = overlayContainer, containerPadding, placement, rootClose, children, childrenProps, transition: Transition = Fade, open, preventOverflow, triggerTarget, onClose, onExited, onExit, onExiting, onEnter, onEntering, onEntered, followCursor, cursorPosition } = props; const [exited, setExited] = useState(!open); const overlayTarget = useRef(null); if (open) { if (exited) setExited(false); } else if (!Transition && !exited) { setExited(true); } const mountOverlay = open || Transition && !exited; const handleExited = useCallback(args => { setExited(true); onExited === null || onExited === void 0 || onExited(args); }, [onExited]); useRootClose(onClose, { triggerTarget, overlayTarget, disabled: !rootClose || !mountOverlay }); if (!mountOverlay) { return null; } const positionProps = { container, containerPadding, triggerTarget, placement, preventOverflow, followCursor, cursorPosition }; const renderChildWithPosition = (transitionProps, transitionRef) => { const { className } = transitionProps || {}; return /*#__PURE__*/React.createElement(Position, _extends({}, positionProps, transitionProps, { ref: mergeRefs(ref, transitionRef) }), (positionChildProps, childRef) => { // Position will return coordinates and className const { left, top } = positionChildProps; // Components returned by function children need to control their own positioning information. For example: Picker if (typeof children === 'function') { return children({ className, //dataAttributes, ...positionChildProps, ...childrenProps }, mergeRefs(childRef, overlayTarget)); } const childElement = children; const childStyles = mergeStyles(getPositionStyle(left, top), childElement.props.style); return /*#__PURE__*/React.cloneElement(childElement, { ...childrenProps, ...childElement.props, className: classNames(childElement.props.className, className), style: childStyles, ref: mergeRefs(childRef, overlayTarget) }); }); }; if (Transition) { return /*#__PURE__*/React.createElement(Transition, { in: open, transitionAppear: true, onExit: onExit, onExiting: onExiting, onExited: handleExited, onEnter: onEnter, onEntering: onEntering, onEntered: onEntered }, renderChildWithPosition); } return renderChildWithPosition(); }); Overlay.displayName = 'Overlay'; export default Overlay;