"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); exports.__esModule = true; exports.toModifierMap = toModifierMap; exports.toModifierArray = toModifierArray; exports["default"] = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose")); var _react = require("react"); var _useSafeState2 = _interopRequireDefault(require("@restart/hooks/useSafeState")); var _popper = require("./popper"); var initialPopperStyles = { position: 'absolute', top: '0', left: '0', opacity: '0', pointerEvents: 'none' }; var initialArrowStyles = {}; // until docjs supports type exports... function toModifierMap(modifiers) { var result = {}; if (!Array.isArray(modifiers)) { return modifiers || result; } // eslint-disable-next-line no-unused-expressions modifiers == null ? void 0 : modifiers.forEach(function (m) { result[m.name] = m; }); return result; } function toModifierArray(map) { if (map === void 0) { map = {}; } if (Array.isArray(map)) return map; return Object.keys(map).map(function (k) { map[k].name = k; return map[k]; }); } /** * Position an element relative some reference element using Popper.js * * @param referenceElement * @param popperElement * @param {object} options * @param {object=} options.modifiers Popper.js modifiers * @param {boolean=} options.enabled toggle the popper functionality on/off * @param {string=} options.placement The popper element placement relative to the reference element * @param {string=} options.strategy the positioning strategy * @param {boolean=} options.eventsEnabled have Popper listen on window resize events to reposition the element * @param {function=} options.onCreate called when the popper is created * @param {function=} options.onUpdate called when the popper is updated * * @returns {UsePopperState} The popper state */ function usePopper(referenceElement, popperElement, _temp) { var _ref = _temp === void 0 ? {} : _temp, _ref$enabled = _ref.enabled, enabled = _ref$enabled === void 0 ? true : _ref$enabled, _ref$placement = _ref.placement, placement = _ref$placement === void 0 ? 'bottom' : _ref$placement, _ref$strategy = _ref.strategy, strategy = _ref$strategy === void 0 ? 'absolute' : _ref$strategy, _ref$eventsEnabled = _ref.eventsEnabled, eventsEnabled = _ref$eventsEnabled === void 0 ? true : _ref$eventsEnabled, userModifiers = _ref.modifiers, popperOptions = (0, _objectWithoutPropertiesLoose2["default"])(_ref, ["enabled", "placement", "strategy", "eventsEnabled", "modifiers"]); var popperInstanceRef = (0, _react.useRef)(); var scheduleUpdate = (0, _react.useCallback)(function () { if (popperInstanceRef.current) { popperInstanceRef.current.update(); } }, []); var _useSafeState = (0, _useSafeState2["default"])((0, _react.useState)({ placement: placement, scheduleUpdate: scheduleUpdate, outOfBoundaries: false, styles: initialPopperStyles, arrowStyles: initialArrowStyles })), state = _useSafeState[0], setState = _useSafeState[1]; var updateModifier = (0, _react.useMemo)(function () { return { name: 'updateStateModifier', enabled: true, phase: 'afterWrite', requires: ['computeStyles'], fn: function fn(data) { var _data$state$modifiers, _data$state$styles, _data$state$styles2; setState({ scheduleUpdate: scheduleUpdate, outOfBoundaries: !!((_data$state$modifiers = data.state.modifiersData.hide) == null ? void 0 : _data$state$modifiers.isReferenceHidden), placement: data.state.placement, styles: (0, _extends2["default"])({}, (_data$state$styles = data.state.styles) == null ? void 0 : _data$state$styles.popper), arrowStyles: (0, _extends2["default"])({}, (_data$state$styles2 = data.state.styles) == null ? void 0 : _data$state$styles2.arrow), state: data.state }); } }; }, [scheduleUpdate, setState]); var modifiers = toModifierArray(userModifiers); var eventsModifier = modifiers.find(function (m) { return m.name === 'eventListeners'; }); if (!eventsModifier && eventsEnabled) { eventsModifier = { name: 'eventListeners', enabled: true }; modifiers = [].concat(modifiers, [eventsModifier]); } // A placement difference in state means popper determined a new placement // apart from the props value. By the time the popper element is rendered with // the new position Popper has already measured it, if the place change triggers // a size change it will result in a misaligned popper. So we schedule an update to be sure. (0, _react.useEffect)(function () { scheduleUpdate(); }, [state.placement, scheduleUpdate]); (0, _react.useEffect)(function () { if (!popperInstanceRef.current || !enabled) return; popperInstanceRef.current.setOptions({ placement: placement, strategy: strategy, modifiers: [].concat(modifiers, [updateModifier]) }); // intentionally NOT re-running on new modifiers // eslint-disable-next-line react-hooks/exhaustive-deps }, [strategy, placement, eventsModifier.enabled, updateModifier, enabled]); (0, _react.useEffect)(function () { if (!enabled || referenceElement == null || popperElement == null) { return undefined; } popperInstanceRef.current = (0, _popper.createPopper)(referenceElement, popperElement, (0, _extends2["default"])({}, popperOptions, { placement: placement, strategy: strategy, modifiers: [].concat(modifiers, [updateModifier]) })); return function () { if (popperInstanceRef.current != null) { popperInstanceRef.current.destroy(); popperInstanceRef.current = undefined; setState(function (s) { return (0, _extends2["default"])({}, s, { styles: initialPopperStyles, arrowStyles: initialArrowStyles }); }); } }; // This is only run once to _create_ the popper // eslint-disable-next-line react-hooks/exhaustive-deps }, [enabled, referenceElement, popperElement]); return state; } var _default = usePopper; exports["default"] = _default;