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.

146 lines
4.8 KiB

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