react-bootstrap
Version:
Bootstrap 4 components built with React
107 lines (90 loc) • 3.35 kB
JavaScript
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
exports.__esModule = true;
exports.default = usePopperMarginModifiers;
var _react = require("react");
var _hasClass = _interopRequireDefault(require("dom-helpers/hasClass"));
var _ThemeProvider = require("./ThemeProvider");
function getMargins(element) {
var styles = window.getComputedStyle(element);
var top = parseFloat(styles.marginTop) || 0;
var right = parseFloat(styles.marginRight) || 0;
var bottom = parseFloat(styles.marginBottom) || 0;
var left = parseFloat(styles.marginLeft) || 0;
return {
top: top,
right: right,
bottom: bottom,
left: left
};
}
function usePopperMarginModifiers() {
var overlayRef = (0, _react.useRef)(null);
var margins = (0, _react.useRef)(null);
var popoverClass = (0, _ThemeProvider.useBootstrapPrefix)(undefined, 'popover');
var dropdownMenuClass = (0, _ThemeProvider.useBootstrapPrefix)(undefined, 'dropdown-menu');
var callback = (0, _react.useCallback)(function (overlay) {
if (!overlay || !((0, _hasClass.default)(overlay, popoverClass) || (0, _hasClass.default)(overlay, dropdownMenuClass))) return;
margins.current = getMargins(overlay);
overlay.style.margin = '0';
overlayRef.current = overlay;
}, [popoverClass, dropdownMenuClass]);
var offset = (0, _react.useMemo)(function () {
return {
name: 'offset',
options: {
offset: function offset(_ref) {
var placement = _ref.placement;
if (!margins.current) return [0, 0];
var _margins$current = margins.current,
top = _margins$current.top,
left = _margins$current.left,
bottom = _margins$current.bottom,
right = _margins$current.right;
switch (placement.split('-')[0]) {
case 'top':
return [0, bottom];
case 'left':
return [0, right];
case 'bottom':
return [0, top];
case 'right':
return [0, left];
default:
return [0, 0];
}
}
}
};
}, [margins]); // Converts popover arrow margin to arrow modifier padding
var popoverArrowMargins = (0, _react.useMemo)(function () {
return {
name: 'popoverArrowMargins',
enabled: true,
phase: 'main',
requiresIfExists: ['arrow'],
effect: function effect(_ref2) {
var state = _ref2.state;
if (!overlayRef.current || !state.elements.arrow || !(0, _hasClass.default)(overlayRef.current, popoverClass) || !state.modifiersData['arrow#persistent']) {
return undefined;
}
var _getMargins = getMargins(state.elements.arrow),
top = _getMargins.top,
right = _getMargins.right;
var padding = top || right;
state.modifiersData['arrow#persistent'].padding = {
top: padding,
left: padding,
right: padding,
bottom: padding
};
state.elements.arrow.style.margin = '0';
return function () {
if (state.elements.arrow) state.elements.arrow.style.margin = '';
};
}
};
}, [popoverClass]);
return [callback, [offset, popoverArrowMargins]];
}
module.exports = exports["default"];
;