UNPKG

3.99 kBJavaScriptView Raw
1"use client";
2
3import * as React from 'react';
4import { useEffect, useRef, useState } from 'react';
5import classNames from 'classnames';
6import BaseOverlay from '@restart/ui/Overlay';
7import useEventCallback from '@restart/hooks/useEventCallback';
8import useIsomorphicEffect from '@restart/hooks/useIsomorphicEffect';
9import useMergedRefs from '@restart/hooks/useMergedRefs';
10import useOverlayOffset from './useOverlayOffset';
11import Fade from './Fade';
12import safeFindDOMNode from './safeFindDOMNode';
13import { jsx as _jsx } from "react/jsx-runtime";
14function wrapRefs(props, arrowProps) {
15 const {
16 ref
17 } = props;
18 const {
19 ref: aRef
20 } = arrowProps;
21 props.ref = ref.__wrapped || (ref.__wrapped = r => ref(safeFindDOMNode(r)));
22 arrowProps.ref = aRef.__wrapped || (aRef.__wrapped = r => aRef(safeFindDOMNode(r)));
23}
24const Overlay = /*#__PURE__*/React.forwardRef(({
25 children: overlay,
26 transition = Fade,
27 popperConfig = {},
28 rootClose = false,
29 placement = 'top',
30 show: outerShow = false,
31 ...outerProps
32}, outerRef) => {
33 const popperRef = useRef({});
34 const [firstRenderedState, setFirstRenderedState] = useState(null);
35 const [ref, modifiers] = useOverlayOffset(outerProps.offset);
36 const mergedRef = useMergedRefs(outerRef, ref);
37 const actualTransition = transition === true ? Fade : transition || undefined;
38 const handleFirstUpdate = useEventCallback(state => {
39 setFirstRenderedState(state);
40 popperConfig == null ? void 0 : popperConfig.onFirstUpdate == null ? void 0 : popperConfig.onFirstUpdate(state);
41 });
42 useIsomorphicEffect(() => {
43 if (firstRenderedState && outerProps.target) {
44 // Must wait for target element to resolve before updating popper.
45 popperRef.current.scheduleUpdate == null ? void 0 : popperRef.current.scheduleUpdate();
46 }
47 }, [firstRenderedState, outerProps.target]);
48 useEffect(() => {
49 if (!outerShow) {
50 setFirstRenderedState(null);
51 }
52 }, [outerShow]);
53 return /*#__PURE__*/_jsx(BaseOverlay, {
54 ...outerProps,
55 ref: mergedRef,
56 popperConfig: {
57 ...popperConfig,
58 modifiers: modifiers.concat(popperConfig.modifiers || []),
59 onFirstUpdate: handleFirstUpdate
60 },
61 transition: actualTransition,
62 rootClose: rootClose,
63 placement: placement,
64 show: outerShow,
65 children: (overlayProps, {
66 arrowProps,
67 popper: popperObj,
68 show
69 }) => {
70 var _popperObj$state, _popperObj$state$modi;
71 wrapRefs(overlayProps, arrowProps);
72 // Need to get placement from popper object, handling case when overlay is flipped using 'flip' prop
73 const updatedPlacement = popperObj == null ? void 0 : popperObj.placement;
74 const popper = Object.assign(popperRef.current, {
75 state: popperObj == null ? void 0 : popperObj.state,
76 scheduleUpdate: popperObj == null ? void 0 : popperObj.update,
77 placement: updatedPlacement,
78 outOfBoundaries: (popperObj == null ? void 0 : (_popperObj$state = popperObj.state) == null ? void 0 : (_popperObj$state$modi = _popperObj$state.modifiersData.hide) == null ? void 0 : _popperObj$state$modi.isReferenceHidden) || false,
79 strategy: popperConfig.strategy
80 });
81 const hasDoneInitialMeasure = !!firstRenderedState;
82 if (typeof overlay === 'function') return overlay({
83 ...overlayProps,
84 placement: updatedPlacement,
85 show,
86 ...(!transition && show && {
87 className: 'show'
88 }),
89 popper,
90 arrowProps,
91 hasDoneInitialMeasure
92 });
93 return /*#__PURE__*/React.cloneElement(overlay, {
94 ...overlayProps,
95 placement: updatedPlacement,
96 arrowProps,
97 popper,
98 hasDoneInitialMeasure,
99 className: classNames(overlay.props.className, !transition && show && 'show'),
100 style: {
101 ...overlay.props.style,
102 ...overlayProps.style
103 }
104 });
105 }
106 });
107});
108Overlay.displayName = 'Overlay';
109export default Overlay;
\No newline at end of file