"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); exports.__esModule = true; exports["default"] = usePopper; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _popper = _interopRequireDefault(require("popper.js")); var _react = require("react"); var initialPopperStyles = { position: 'absolute', top: '0', left: '0', opacity: '0', pointerEvents: 'none' }; var initialArrowStyles = {}; /** * Position an element relative some reference element using Popper.js * * @param {HTMLElement} referenceElement The element * @param {HTMLElement} 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 {Boolean} options.positionFixed use fixed positioning * @param {Boolean} options.eventsEnabled have Popper listen on window resize events to reposition the element */ 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$positionFixed = _ref.positionFixed, positionFixed = _ref$positionFixed === void 0 ? false : _ref$positionFixed, _ref$eventsEnabled = _ref.eventsEnabled, eventsEnabled = _ref$eventsEnabled === void 0 ? true : _ref$eventsEnabled, _ref$modifiers = _ref.modifiers, modifiers = _ref$modifiers === void 0 ? {} : _ref$modifiers; var popperInstanceRef = (0, _react.useRef)(); var hasArrow = !!(modifiers.arrow && modifiers.arrow.element); var scheduleUpdate = (0, _react.useCallback)(function () { if (popperInstanceRef.current) { popperInstanceRef.current.scheduleUpdate(); } }, []); var _useState = (0, _react.useState)({ placement: placement, scheduleUpdate: scheduleUpdate, outOfBoundaries: false, styles: initialPopperStyles, arrowStyles: initialArrowStyles }), state = _useState[0], setState = _useState[1]; // 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]); /** Toggle Events */ (0, _react.useEffect)(function () { if (popperInstanceRef.current) { // eslint-disable-next-line no-unused-expressions eventsEnabled ? popperInstanceRef.current.enableEventListeners() : popperInstanceRef.current.disableEventListeners(); } }, [eventsEnabled]); (0, _react.useEffect)(function () { if (!enabled || referenceElement == null || popperElement == null) { return undefined; } var arrow = modifiers.arrow && (0, _extends2["default"])({}, modifiers.arrow, { element: modifiers.arrow.element }); popperInstanceRef.current = new _popper["default"](referenceElement, popperElement, { placement: placement, positionFixed: positionFixed, modifiers: (0, _extends2["default"])({}, modifiers, { arrow: arrow, applyStyle: { enabled: false }, updateStateModifier: { enabled: true, order: 900, fn: function fn(data) { setState({ scheduleUpdate: scheduleUpdate, styles: (0, _extends2["default"])({ position: data.offsets.popper.position }, data.styles), arrowStyles: data.arrowStyles, outOfBoundaries: data.hide, placement: data.placement }); } } }) }); return function () { if (popperInstanceRef.current !== null) { popperInstanceRef.current.destroy(); popperInstanceRef.current = null; } }; // intentionally NOT re-running on new modifiers // eslint-disable-next-line react-hooks/exhaustive-deps }, [enabled, placement, positionFixed, referenceElement, popperElement, hasArrow]); return state; } module.exports = exports.default;