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.

64 lines
3.4 KiB

2 months ago
  1. import getClippingRect from "../dom-utils/getClippingRect.js";
  2. import getDocumentElement from "../dom-utils/getDocumentElement.js";
  3. import getBoundingClientRect from "../dom-utils/getBoundingClientRect.js";
  4. import computeOffsets from "./computeOffsets.js";
  5. import rectToClientRect from "./rectToClientRect.js";
  6. import { clippingParents, reference, popper, bottom, top, right, basePlacements, viewport } from "../enums.js";
  7. import { isElement } from "../dom-utils/instanceOf.js";
  8. import mergePaddingObject from "./mergePaddingObject.js";
  9. import expandToHashMap from "./expandToHashMap.js"; // eslint-disable-next-line import/no-unused-modules
  10. export default function detectOverflow(state, options) {
  11. if (options === void 0) {
  12. options = {};
  13. }
  14. var _options = options,
  15. _options$placement = _options.placement,
  16. placement = _options$placement === void 0 ? state.placement : _options$placement,
  17. _options$strategy = _options.strategy,
  18. strategy = _options$strategy === void 0 ? state.strategy : _options$strategy,
  19. _options$boundary = _options.boundary,
  20. boundary = _options$boundary === void 0 ? clippingParents : _options$boundary,
  21. _options$rootBoundary = _options.rootBoundary,
  22. rootBoundary = _options$rootBoundary === void 0 ? viewport : _options$rootBoundary,
  23. _options$elementConte = _options.elementContext,
  24. elementContext = _options$elementConte === void 0 ? popper : _options$elementConte,
  25. _options$altBoundary = _options.altBoundary,
  26. altBoundary = _options$altBoundary === void 0 ? false : _options$altBoundary,
  27. _options$padding = _options.padding,
  28. padding = _options$padding === void 0 ? 0 : _options$padding;
  29. var paddingObject = mergePaddingObject(typeof padding !== 'number' ? padding : expandToHashMap(padding, basePlacements));
  30. var altContext = elementContext === popper ? reference : popper;
  31. var popperRect = state.rects.popper;
  32. var element = state.elements[altBoundary ? altContext : elementContext];
  33. var clippingClientRect = getClippingRect(isElement(element) ? element : element.contextElement || getDocumentElement(state.elements.popper), boundary, rootBoundary, strategy);
  34. var referenceClientRect = getBoundingClientRect(state.elements.reference);
  35. var popperOffsets = computeOffsets({
  36. reference: referenceClientRect,
  37. element: popperRect,
  38. strategy: 'absolute',
  39. placement: placement
  40. });
  41. var popperClientRect = rectToClientRect(Object.assign({}, popperRect, popperOffsets));
  42. var elementClientRect = elementContext === popper ? popperClientRect : referenceClientRect; // positive = overflowing the clipping rect
  43. // 0 or negative = within the clipping rect
  44. var overflowOffsets = {
  45. top: clippingClientRect.top - elementClientRect.top + paddingObject.top,
  46. bottom: elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom,
  47. left: clippingClientRect.left - elementClientRect.left + paddingObject.left,
  48. right: elementClientRect.right - clippingClientRect.right + paddingObject.right
  49. };
  50. var offsetData = state.modifiersData.offset; // Offsets can be applied only to the popper element
  51. if (elementContext === popper && offsetData) {
  52. var offset = offsetData[placement];
  53. Object.keys(overflowOffsets).forEach(function (key) {
  54. var multiply = [right, bottom].indexOf(key) >= 0 ? 1 : -1;
  55. var axis = [top, bottom].indexOf(key) >= 0 ? 'y' : 'x';
  56. overflowOffsets[key] += offset[axis] * multiply;
  57. });
  58. }
  59. return overflowOffsets;
  60. }