UNPKG

4.91 kBJavaScriptView Raw
1import getOppositePlacement from "../utils/getOppositePlacement.js";
2import getBasePlacement from "../utils/getBasePlacement.js";
3import getOppositeVariationPlacement from "../utils/getOppositeVariationPlacement.js";
4import detectOverflow from "../utils/detectOverflow.js";
5import computeAutoPlacement from "../utils/computeAutoPlacement.js";
6import { bottom, top, start, right, left, auto } from "../enums.js";
7import getVariation from "../utils/getVariation.js"; // eslint-disable-next-line import/no-unused-modules
8
9function getExpandedFallbackPlacements(placement) {
10 if (getBasePlacement(placement) === auto) {
11 return [];
12 }
13
14 var oppositePlacement = getOppositePlacement(placement);
15 return [getOppositeVariationPlacement(placement), oppositePlacement, getOppositeVariationPlacement(oppositePlacement)];
16}
17
18function flip(_ref) {
19 var state = _ref.state,
20 options = _ref.options,
21 name = _ref.name;
22
23 if (state.modifiersData[name]._skip) {
24 return;
25 }
26
27 var _options$mainAxis = options.mainAxis,
28 checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis,
29 _options$altAxis = options.altAxis,
30 checkAltAxis = _options$altAxis === void 0 ? true : _options$altAxis,
31 specifiedFallbackPlacements = options.fallbackPlacements,
32 padding = options.padding,
33 boundary = options.boundary,
34 rootBoundary = options.rootBoundary,
35 altBoundary = options.altBoundary,
36 _options$flipVariatio = options.flipVariations,
37 flipVariations = _options$flipVariatio === void 0 ? true : _options$flipVariatio,
38 allowedAutoPlacements = options.allowedAutoPlacements;
39 var preferredPlacement = state.options.placement;
40 var basePlacement = getBasePlacement(preferredPlacement);
41 var isBasePlacement = basePlacement === preferredPlacement;
42 var fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipVariations ? [getOppositePlacement(preferredPlacement)] : getExpandedFallbackPlacements(preferredPlacement));
43 var placements = [preferredPlacement].concat(fallbackPlacements).reduce(function (acc, placement) {
44 return acc.concat(getBasePlacement(placement) === auto ? computeAutoPlacement(state, {
45 placement: placement,
46 boundary: boundary,
47 rootBoundary: rootBoundary,
48 padding: padding,
49 flipVariations: flipVariations,
50 allowedAutoPlacements: allowedAutoPlacements
51 }) : placement);
52 }, []);
53 var referenceRect = state.rects.reference;
54 var popperRect = state.rects.popper;
55 var checksMap = new Map();
56 var makeFallbackChecks = true;
57 var firstFittingPlacement = placements[0];
58
59 for (var i = 0; i < placements.length; i++) {
60 var placement = placements[i];
61
62 var _basePlacement = getBasePlacement(placement);
63
64 var isStartVariation = getVariation(placement) === start;
65 var isVertical = [top, bottom].indexOf(_basePlacement) >= 0;
66 var len = isVertical ? 'width' : 'height';
67 var overflow = detectOverflow(state, {
68 placement: placement,
69 boundary: boundary,
70 rootBoundary: rootBoundary,
71 altBoundary: altBoundary,
72 padding: padding
73 });
74 var mainVariationSide = isVertical ? isStartVariation ? right : left : isStartVariation ? bottom : top;
75
76 if (referenceRect[len] > popperRect[len]) {
77 mainVariationSide = getOppositePlacement(mainVariationSide);
78 }
79
80 var altVariationSide = getOppositePlacement(mainVariationSide);
81 var checks = [];
82
83 if (checkMainAxis) {
84 checks.push(overflow[_basePlacement] <= 0);
85 }
86
87 if (checkAltAxis) {
88 checks.push(overflow[mainVariationSide] <= 0, overflow[altVariationSide] <= 0);
89 }
90
91 if (checks.every(function (check) {
92 return check;
93 })) {
94 firstFittingPlacement = placement;
95 makeFallbackChecks = false;
96 break;
97 }
98
99 checksMap.set(placement, checks);
100 }
101
102 if (makeFallbackChecks) {
103 // `2` may be desired in some cases – research later
104 var numberOfChecks = flipVariations ? 3 : 1;
105
106 var _loop = function _loop(_i) {
107 var fittingPlacement = placements.find(function (placement) {
108 var checks = checksMap.get(placement);
109
110 if (checks) {
111 return checks.slice(0, _i).every(function (check) {
112 return check;
113 });
114 }
115 });
116
117 if (fittingPlacement) {
118 firstFittingPlacement = fittingPlacement;
119 return "break";
120 }
121 };
122
123 for (var _i = numberOfChecks; _i > 0; _i--) {
124 var _ret = _loop(_i);
125
126 if (_ret === "break") break;
127 }
128 }
129
130 if (state.placement !== firstFittingPlacement) {
131 state.modifiersData[name]._skip = true;
132 state.placement = firstFittingPlacement;
133 state.reset = true;
134 }
135} // eslint-disable-next-line import/no-unused-modules
136
137
138export default {
139 name: 'flip',
140 enabled: true,
141 phase: 'main',
142 fn: flip,
143 requiresIfExists: ['offset'],
144 data: {
145 _skip: false
146 }
147};
\No newline at end of file