You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
181 lines
5.6 KiB
181 lines
5.6 KiB
"use strict";
|
|
|
|
exports.__esModule = true;
|
|
exports.default = void 0;
|
|
|
|
var _react = require("react");
|
|
|
|
var _dequal = require("dequal");
|
|
|
|
var _useSafeState = _interopRequireDefault(require("@restart/hooks/useSafeState"));
|
|
|
|
var _popper = require("./popper");
|
|
|
|
const _excluded = ["enabled", "placement", "strategy", "modifiers"];
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
|
|
|
const disabledApplyStylesModifier = {
|
|
name: 'applyStyles',
|
|
enabled: false,
|
|
phase: 'afterWrite',
|
|
fn: () => undefined
|
|
}; // until docjs supports type exports...
|
|
|
|
const ariaDescribedByModifier = {
|
|
name: 'ariaDescribedBy',
|
|
enabled: true,
|
|
phase: 'afterWrite',
|
|
effect: ({
|
|
state
|
|
}) => () => {
|
|
const {
|
|
reference,
|
|
popper
|
|
} = state.elements;
|
|
|
|
if ('removeAttribute' in reference) {
|
|
const ids = (reference.getAttribute('aria-describedby') || '').split(',').filter(id => id.trim() !== popper.id);
|
|
if (!ids.length) reference.removeAttribute('aria-describedby');else reference.setAttribute('aria-describedby', ids.join(','));
|
|
}
|
|
},
|
|
fn: ({
|
|
state
|
|
}) => {
|
|
var _popper$getAttribute;
|
|
|
|
const {
|
|
popper,
|
|
reference
|
|
} = state.elements;
|
|
const role = (_popper$getAttribute = popper.getAttribute('role')) == null ? void 0 : _popper$getAttribute.toLowerCase();
|
|
|
|
if (popper.id && role === 'tooltip' && 'setAttribute' in reference) {
|
|
const ids = reference.getAttribute('aria-describedby');
|
|
|
|
if (ids && ids.split(',').indexOf(popper.id) !== -1) {
|
|
return;
|
|
}
|
|
|
|
reference.setAttribute('aria-describedby', ids ? `${ids},${popper.id}` : popper.id);
|
|
}
|
|
}
|
|
};
|
|
const EMPTY_MODIFIERS = [];
|
|
/**
|
|
* 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 {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, _ref = {}) {
|
|
let {
|
|
enabled = true,
|
|
placement = 'bottom',
|
|
strategy = 'absolute',
|
|
modifiers = EMPTY_MODIFIERS
|
|
} = _ref,
|
|
config = _objectWithoutPropertiesLoose(_ref, _excluded);
|
|
|
|
const prevModifiers = (0, _react.useRef)(modifiers);
|
|
const popperInstanceRef = (0, _react.useRef)();
|
|
const update = (0, _react.useCallback)(() => {
|
|
var _popperInstanceRef$cu;
|
|
|
|
(_popperInstanceRef$cu = popperInstanceRef.current) == null ? void 0 : _popperInstanceRef$cu.update();
|
|
}, []);
|
|
const forceUpdate = (0, _react.useCallback)(() => {
|
|
var _popperInstanceRef$cu2;
|
|
|
|
(_popperInstanceRef$cu2 = popperInstanceRef.current) == null ? void 0 : _popperInstanceRef$cu2.forceUpdate();
|
|
}, []);
|
|
const [popperState, setState] = (0, _useSafeState.default)((0, _react.useState)({
|
|
placement,
|
|
update,
|
|
forceUpdate,
|
|
attributes: {},
|
|
styles: {
|
|
popper: {},
|
|
arrow: {}
|
|
}
|
|
}));
|
|
const updateModifier = (0, _react.useMemo)(() => ({
|
|
name: 'updateStateModifier',
|
|
enabled: true,
|
|
phase: 'write',
|
|
requires: ['computeStyles'],
|
|
fn: ({
|
|
state
|
|
}) => {
|
|
const styles = {};
|
|
const attributes = {};
|
|
Object.keys(state.elements).forEach(element => {
|
|
styles[element] = state.styles[element];
|
|
attributes[element] = state.attributes[element];
|
|
});
|
|
setState({
|
|
state,
|
|
styles,
|
|
attributes,
|
|
update,
|
|
forceUpdate,
|
|
placement: state.placement
|
|
});
|
|
}
|
|
}), [update, forceUpdate, setState]);
|
|
const nextModifiers = (0, _react.useMemo)(() => {
|
|
if (!(0, _dequal.dequal)(prevModifiers.current, modifiers)) {
|
|
prevModifiers.current = modifiers;
|
|
}
|
|
|
|
return prevModifiers.current;
|
|
}, [modifiers]);
|
|
(0, _react.useEffect)(() => {
|
|
if (!popperInstanceRef.current || !enabled) return;
|
|
popperInstanceRef.current.setOptions({
|
|
placement,
|
|
strategy,
|
|
modifiers: [...nextModifiers, updateModifier, disabledApplyStylesModifier]
|
|
});
|
|
}, [strategy, placement, updateModifier, enabled, nextModifiers]);
|
|
(0, _react.useEffect)(() => {
|
|
if (!enabled || referenceElement == null || popperElement == null) {
|
|
return undefined;
|
|
}
|
|
|
|
popperInstanceRef.current = (0, _popper.createPopper)(referenceElement, popperElement, Object.assign({}, config, {
|
|
placement,
|
|
strategy,
|
|
modifiers: [...nextModifiers, ariaDescribedByModifier, updateModifier]
|
|
}));
|
|
return () => {
|
|
if (popperInstanceRef.current != null) {
|
|
popperInstanceRef.current.destroy();
|
|
popperInstanceRef.current = undefined;
|
|
setState(s => Object.assign({}, s, {
|
|
attributes: {},
|
|
styles: {
|
|
popper: {}
|
|
}
|
|
}));
|
|
}
|
|
}; // This is only run once to _create_ the popper
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, [enabled, referenceElement, popperElement]);
|
|
return popperState;
|
|
}
|
|
|
|
var _default = usePopper;
|
|
exports.default = _default; |