UNPKG

suomifi-ui-components

Version:
146 lines (143 loc) 5.32 kB
import { __rest, __spreadArray, __assign } from 'tslib'; import React, { useState, useRef, useEffect, useLayoutEffect, useMemo } from 'react'; import ReactDOM from 'react-dom'; import { useEnhancedEffect } from '../../utils/common/common.js'; import { HtmlDivWithRef } from '../../reset/HtmlDiv/HtmlDiv.js'; import { useFloating, flip, shift, size, autoUpdate } from '@floating-ui/react-dom'; import classnames from 'classnames'; var defaultProviderValue = { updatePopover: function updatePopover() { return null; }, popoverPlacement: 'bottom' }; var _a = /*#__PURE__*/React.createContext(defaultProviderValue), PopoverProvider = _a.Provider, PopoverConsumer = _a.Consumer; var Popover = function Popover(props) { var _a = props.placement, placement = _a === void 0 ? 'bottom' : _a, _b = props.allowFlip, allowFlip = _b === void 0 ? true : _b, _c = props.matchWidth, matchWidth = _c === void 0 ? true : _c, children = props.children, sourceRef = props.sourceRef, onClickOutside = props.onClickOutside, _d = props.portal, portal = _d === void 0 ? true : _d, className = props.className, passProps = __rest(props, ["placement", "allowFlip", "matchWidth", "children", "sourceRef", "onClickOutside", "portal", "className"]); var _e = useState(null), floatingElement = _e[0], setFloatingElement = _e[1]; var _f = useState(null), mountNode = _f[0], setMountNode = _f[1]; var _g = useState(false), isPositioned = _g[0], setIsPositioned = _g[1]; var portalRef = useRef(null); var _h = useFloating({ open: true, middleware: __spreadArray(__spreadArray(__spreadArray([], allowFlip ? [flip()] : [], true), [shift()], false), matchWidth ? [size({ apply: function apply(_a) { var rects = _a.rects, elements = _a.elements; var floatingEl = elements.floating; floatingEl.style.width = "".concat(rects.reference.width, "px"); } })] : [], true), whileElementsMounted: autoUpdate, placement: placement }), floatingUiRefs = _h.refs, floatingStyles = _h.floatingStyles, resolvedPlacement = _h.placement, update = _h.update; useEffect(function () { if (sourceRef.current) { floatingUiRefs.setReference(sourceRef.current); } }, [floatingUiRefs, sourceRef]); useEffect(function () { if (floatingElement) { floatingUiRefs.setFloating(floatingElement); } }, [floatingUiRefs, floatingElement]); useLayoutEffect(function () { if (floatingElement && floatingStyles.position) { requestAnimationFrame(function () { requestAnimationFrame(function () { setIsPositioned(true); }); }); } }, [floatingElement, floatingStyles.position]); var _j = useState(placement), consumerPlacement = _j[0], setConsumerPlacement = _j[1]; useEffect(function () { setConsumerPlacement(resolvedPlacement); }, [resolvedPlacement]); var providerValue = useMemo(function () { return { updatePopover: function updatePopover() { return update === null || update === void 0 ? void 0 : update(); }, popoverPlacement: consumerPlacement || placement }; }, [update, consumerPlacement, placement]); useEffect(function () { var globalClickHandler = function globalClickHandler(nativeEvent) { var _a, _b; if (!((_a = portalRef.current) === null || _a === void 0 ? void 0 : _a.contains(nativeEvent.target)) && !((_b = sourceRef === null || sourceRef === void 0 ? void 0 : sourceRef.current) === null || _b === void 0 ? void 0 : _b.contains(nativeEvent.target)) && !!onClickOutside) { onClickOutside(nativeEvent); } }; document.addEventListener('click', globalClickHandler, { capture: true }); return function () { document.removeEventListener('click', globalClickHandler, { capture: true }); }; }, [onClickOutside, sourceRef]); useEnhancedEffect(function () { setMountNode(window.document.body); }); if (portal && !mountNode) { return null; } if (portal && mountNode) { return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/ReactDOM.createPortal( /*#__PURE__*/React.createElement("div", { className: classnames('fi-portal', className), ref: setFloatingElement, style: __assign(__assign({}, floatingStyles), { visibility: isPositioned ? 'visible' : 'hidden' }), tabIndex: -1, role: "presentation" }, /*#__PURE__*/React.createElement(HtmlDivWithRef, __assign({ forwardedRef: portalRef }, passProps), /*#__PURE__*/React.createElement(PopoverProvider, { value: providerValue }, children))), mountNode)); } return /*#__PURE__*/React.createElement("div", { className: className, ref: setFloatingElement, style: __assign(__assign({}, floatingStyles), { visibility: isPositioned ? 'visible' : 'hidden' }), tabIndex: -1, role: "presentation" }, /*#__PURE__*/React.createElement(HtmlDivWithRef, __assign({ forwardedRef: portalRef }, passProps), /*#__PURE__*/React.createElement(PopoverProvider, { value: providerValue }, children))); }; export { Popover, PopoverConsumer }; //# sourceMappingURL=Popover.js.map