UNPKG

4.62 kBJavaScriptView Raw
1"use strict";
2
3var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
5exports.__esModule = true;
6exports.default = usePopperMarginModifiers;
7
8var _react = require("react");
9
10var _hasClass = _interopRequireDefault(require("dom-helpers/hasClass"));
11
12var _ThemeProvider = require("./ThemeProvider");
13
14function getMargins(element) {
15 var styles = window.getComputedStyle(element);
16 var top = parseFloat(styles.marginTop) || 0;
17 var right = parseFloat(styles.marginRight) || 0;
18 var bottom = parseFloat(styles.marginBottom) || 0;
19 var left = parseFloat(styles.marginLeft) || 0;
20 return {
21 top: top,
22 right: right,
23 bottom: bottom,
24 left: left
25 };
26}
27
28function usePopperMarginModifiers() {
29 var overlayRef = (0, _react.useRef)(null);
30 var margins = (0, _react.useRef)(null);
31 var arrowMargins = (0, _react.useRef)(null);
32 var popoverClass = (0, _ThemeProvider.useBootstrapPrefix)(undefined, 'popover');
33 var dropdownMenuClass = (0, _ThemeProvider.useBootstrapPrefix)(undefined, 'dropdown-menu');
34 var callback = (0, _react.useCallback)(function (overlay) {
35 if (!overlay || !((0, _hasClass.default)(overlay, popoverClass) || (0, _hasClass.default)(overlay, dropdownMenuClass))) return;
36 margins.current = getMargins(overlay);
37 overlay.style.margin = '0';
38 overlayRef.current = overlay;
39 }, [popoverClass, dropdownMenuClass]);
40 var offset = (0, _react.useMemo)(function () {
41 return {
42 name: 'offset',
43 options: {
44 offset: function offset(_ref) {
45 var placement = _ref.placement;
46 if (!margins.current) return [0, 0];
47 var _margins$current = margins.current,
48 top = _margins$current.top,
49 left = _margins$current.left,
50 bottom = _margins$current.bottom,
51 right = _margins$current.right;
52
53 switch (placement.split('-')[0]) {
54 case 'top':
55 return [0, bottom];
56
57 case 'left':
58 return [0, right];
59
60 case 'bottom':
61 return [0, top];
62
63 case 'right':
64 return [0, left];
65
66 default:
67 return [0, 0];
68 }
69 }
70 }
71 };
72 }, [margins]);
73 var arrow = (0, _react.useMemo)(function () {
74 return {
75 name: 'arrow',
76 options: {
77 padding: function padding() {
78 // The options here are used for Popper 2.8.4 and up.
79 // For earlier version, padding is handled in popoverArrowMargins below.
80 if (!arrowMargins.current) {
81 return 0;
82 }
83
84 var _arrowMargins$current = arrowMargins.current,
85 top = _arrowMargins$current.top,
86 right = _arrowMargins$current.right;
87 var padding = top || right;
88 return {
89 top: padding,
90 left: padding,
91 right: padding,
92 bottom: padding
93 };
94 }
95 }
96 };
97 }, [arrowMargins]); // Converts popover arrow margin to arrow modifier padding
98
99 var popoverArrowMargins = (0, _react.useMemo)(function () {
100 return {
101 name: 'popoverArrowMargins',
102 enabled: true,
103 phase: 'main',
104 fn: function fn() {
105 return undefined;
106 },
107 requiresIfExists: ['arrow'],
108 effect: function effect(_ref2) {
109 var state = _ref2.state;
110
111 if (!overlayRef.current || !state.elements.arrow || !(0, _hasClass.default)(overlayRef.current, popoverClass)) {
112 return undefined;
113 }
114
115 if (state.modifiersData['arrow#persistent']) {
116 // @popperjs/core <= 2.8.3 uses arrow#persistent to pass padding to arrow modifier.
117 var _getMargins = getMargins(state.elements.arrow),
118 top = _getMargins.top,
119 right = _getMargins.right;
120
121 var padding = top || right;
122 state.modifiersData['arrow#persistent'].padding = {
123 top: padding,
124 left: padding,
125 right: padding,
126 bottom: padding
127 };
128 } else {
129 // @popperjs/core >= 2.8.4 gets the padding from the arrow modifier options,
130 // so we'll get the margins here, and let the arrow modifier above pass
131 // it to popper.
132 arrowMargins.current = getMargins(state.elements.arrow);
133 }
134
135 state.elements.arrow.style.margin = '0';
136 return function () {
137 if (state.elements.arrow) state.elements.arrow.style.margin = '';
138 };
139 }
140 };
141 }, [popoverClass]);
142 return [callback, [offset, arrow, popoverArrowMargins]];
143}
144
145module.exports = exports["default"];
\No newline at end of file