UNPKG

@kiwicom/orbit-components

Version:

Orbit-components is a React component library which provides developers with the easiest possible way of building Kiwi.com's products.

150 lines (149 loc) 5.02 kB
"use strict"; "use client"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default; var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default; exports.__esModule = true; exports.default = void 0; var React = _interopRequireWildcard(require("react")); var _react2 = require("@floating-ui/react"); var _useStateWithTimeout = _interopRequireDefault(require("../hooks/useStateWithTimeout")); var _placements = require("../common/placements"); var _ContentWrapper = _interopRequireDefault(require("./components/ContentWrapper")); var _useRandomId = _interopRequireDefault(require("../hooks/useRandomId")); var _handleKeyDown = _interopRequireDefault(require("../utils/handleKeyDown")); const Popover = ({ children, renderInPortal = true, opened, zIndex, content, onClose, id, onOpen, offset, placement = _placements.PLACEMENTS.BOTTOM_START, fixed, lockScrolling = true, noFlip, labelClose = "Close", renderTimeout = 0, allowOverflow, noPadding, width, maxHeight, actions, overlapped, dataTest, ariaLabel, ariaLabelledby, role = "dialog", tabIndex, triggerRole }) => { const ref = React.useRef(null); const popoverId = (0, _useRandomId.default)(); const overlayId = (0, _useRandomId.default)(); const [shown, setShown, setShownWithTimeout, clearShownTimeout] = (0, _useStateWithTimeout.default)(false, renderTimeout); const [render, setRender, setRenderWithTimeout, clearRenderTimeout] = (0, _useStateWithTimeout.default)(false, renderTimeout); const resolveCallback = React.useCallback(state => { if (onClose && !state) onClose(); if (onOpen && state) onOpen(); }, [onClose, onOpen]); const closePopover = React.useCallback(() => { // If open prop is present ignore custom handler if (typeof opened === "undefined") { setShown(false); clearShownTimeout(); resolveCallback(false); setRenderWithTimeout(false); } else if (onClose) onClose(); }, [setShown, clearShownTimeout, onClose, opened, resolveCallback, setRenderWithTimeout]); const handleEsc = React.useCallback(ev => { if (ev.key === "Escape") { closePopover(); } }, [closePopover]); const handleOut = React.useCallback(ev => { ev?.stopPropagation(); if (ev && ref.current && !ref.current.contains(ev.target)) { closePopover(); } }, [closePopover]); const handleClick = React.useCallback(() => { // If open prop is present ignore custom handler if (typeof opened === "undefined") { if (shown) { setShown(false); clearShownTimeout(); setRenderWithTimeout(false); resolveCallback(false); } else { setRender(true); clearRenderTimeout(); setShownWithTimeout(true); resolveCallback(true); } } else if (opened) { resolveCallback(false); } else if (!opened) { resolveCallback(true); } }, [clearRenderTimeout, clearShownTimeout, opened, resolveCallback, setRender, setRenderWithTimeout, setShown, setShownWithTimeout, shown]); React.useEffect(() => { if (opened || shown) { document.addEventListener("keydown", handleEsc); } if (typeof opened !== "undefined") { if (opened) { setRender(true); clearRenderTimeout(); setShownWithTimeout(true); } else { setShown(false); clearShownTimeout(); setRenderWithTimeout(false); } } return () => { document.removeEventListener("keydown", handleEsc); }; }, [shown, handleEsc, opened, clearRenderTimeout, clearShownTimeout, setRender, setShown, setShownWithTimeout, setRenderWithTimeout]); const popover = /*#__PURE__*/React.createElement(_ContentWrapper.default, { shown: shown, id: id || popoverId, overlayId: overlayId, labelClose: labelClose, dataTest: dataTest, zIndex: zIndex, overlapped: overlapped, fixed: fixed, noFlip: noFlip, allowOverflow: allowOverflow, lockScrolling: lockScrolling, noPadding: noPadding, actions: actions, width: width, maxHeight: maxHeight, offset: offset, referenceElement: ref.current, onClose: handleOut, placement: placement, ariaLabel: ariaLabel, ariaLabelledby: ariaLabelledby, role: role }, content); return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", { className: "relative inline-block focus:outline-offset-1", ref: ref, role: triggerRole || "button", tabIndex: tabIndex ? Number(tabIndex) : 0, onClick: handleClick, onKeyDown: (0, _handleKeyDown.default)(handleClick), "aria-controls": shown ? id || popoverId : undefined, "aria-haspopup": role, "aria-expanded": shown }, children), render && (renderInPortal ? /*#__PURE__*/React.createElement(_react2.FloatingPortal, { id: "popovers" }, popover) : popover)); }; var _default = exports.default = Popover;