floating-ui.utils.mjs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. /**
  2. * Custom positioning reference element.
  3. * @see https://floating-ui.com/docs/virtual-elements
  4. */
  5. const sides = ['top', 'right', 'bottom', 'left'];
  6. const alignments = ['start', 'end'];
  7. const placements = /*#__PURE__*/sides.reduce((acc, side) => acc.concat(side, side + "-" + alignments[0], side + "-" + alignments[1]), []);
  8. const min = Math.min;
  9. const max = Math.max;
  10. const round = Math.round;
  11. const floor = Math.floor;
  12. const createCoords = v => ({
  13. x: v,
  14. y: v
  15. });
  16. const oppositeSideMap = {
  17. left: 'right',
  18. right: 'left',
  19. bottom: 'top',
  20. top: 'bottom'
  21. };
  22. const oppositeAlignmentMap = {
  23. start: 'end',
  24. end: 'start'
  25. };
  26. function clamp(start, value, end) {
  27. return max(start, min(value, end));
  28. }
  29. function evaluate(value, param) {
  30. return typeof value === 'function' ? value(param) : value;
  31. }
  32. function getSide(placement) {
  33. return placement.split('-')[0];
  34. }
  35. function getAlignment(placement) {
  36. return placement.split('-')[1];
  37. }
  38. function getOppositeAxis(axis) {
  39. return axis === 'x' ? 'y' : 'x';
  40. }
  41. function getAxisLength(axis) {
  42. return axis === 'y' ? 'height' : 'width';
  43. }
  44. const yAxisSides = /*#__PURE__*/new Set(['top', 'bottom']);
  45. function getSideAxis(placement) {
  46. return yAxisSides.has(getSide(placement)) ? 'y' : 'x';
  47. }
  48. function getAlignmentAxis(placement) {
  49. return getOppositeAxis(getSideAxis(placement));
  50. }
  51. function getAlignmentSides(placement, rects, rtl) {
  52. if (rtl === void 0) {
  53. rtl = false;
  54. }
  55. const alignment = getAlignment(placement);
  56. const alignmentAxis = getAlignmentAxis(placement);
  57. const length = getAxisLength(alignmentAxis);
  58. let mainAlignmentSide = alignmentAxis === 'x' ? alignment === (rtl ? 'end' : 'start') ? 'right' : 'left' : alignment === 'start' ? 'bottom' : 'top';
  59. if (rects.reference[length] > rects.floating[length]) {
  60. mainAlignmentSide = getOppositePlacement(mainAlignmentSide);
  61. }
  62. return [mainAlignmentSide, getOppositePlacement(mainAlignmentSide)];
  63. }
  64. function getExpandedPlacements(placement) {
  65. const oppositePlacement = getOppositePlacement(placement);
  66. return [getOppositeAlignmentPlacement(placement), oppositePlacement, getOppositeAlignmentPlacement(oppositePlacement)];
  67. }
  68. function getOppositeAlignmentPlacement(placement) {
  69. return placement.replace(/start|end/g, alignment => oppositeAlignmentMap[alignment]);
  70. }
  71. const lrPlacement = ['left', 'right'];
  72. const rlPlacement = ['right', 'left'];
  73. const tbPlacement = ['top', 'bottom'];
  74. const btPlacement = ['bottom', 'top'];
  75. function getSideList(side, isStart, rtl) {
  76. switch (side) {
  77. case 'top':
  78. case 'bottom':
  79. if (rtl) return isStart ? rlPlacement : lrPlacement;
  80. return isStart ? lrPlacement : rlPlacement;
  81. case 'left':
  82. case 'right':
  83. return isStart ? tbPlacement : btPlacement;
  84. default:
  85. return [];
  86. }
  87. }
  88. function getOppositeAxisPlacements(placement, flipAlignment, direction, rtl) {
  89. const alignment = getAlignment(placement);
  90. let list = getSideList(getSide(placement), direction === 'start', rtl);
  91. if (alignment) {
  92. list = list.map(side => side + "-" + alignment);
  93. if (flipAlignment) {
  94. list = list.concat(list.map(getOppositeAlignmentPlacement));
  95. }
  96. }
  97. return list;
  98. }
  99. function getOppositePlacement(placement) {
  100. return placement.replace(/left|right|bottom|top/g, side => oppositeSideMap[side]);
  101. }
  102. function expandPaddingObject(padding) {
  103. return {
  104. top: 0,
  105. right: 0,
  106. bottom: 0,
  107. left: 0,
  108. ...padding
  109. };
  110. }
  111. function getPaddingObject(padding) {
  112. return typeof padding !== 'number' ? expandPaddingObject(padding) : {
  113. top: padding,
  114. right: padding,
  115. bottom: padding,
  116. left: padding
  117. };
  118. }
  119. function rectToClientRect(rect) {
  120. const {
  121. x,
  122. y,
  123. width,
  124. height
  125. } = rect;
  126. return {
  127. width,
  128. height,
  129. top: y,
  130. left: x,
  131. right: x + width,
  132. bottom: y + height,
  133. x,
  134. y
  135. };
  136. }
  137. export { alignments, clamp, createCoords, evaluate, expandPaddingObject, floor, getAlignment, getAlignmentAxis, getAlignmentSides, getAxisLength, getExpandedPlacements, getOppositeAlignmentPlacement, getOppositeAxis, getOppositeAxisPlacements, getOppositePlacement, getPaddingObject, getSide, getSideAxis, max, min, placements, rectToClientRect, round, sides };