placements.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.default = getPlacements;
  6. exports.getOverflowOptions = getOverflowOptions;
  7. var _placementArrow = require("../style/placementArrow");
  8. function getOverflowOptions(placement, arrowOffset, arrowWidth, autoAdjustOverflow) {
  9. if (autoAdjustOverflow === false) {
  10. return {
  11. adjustX: false,
  12. adjustY: false
  13. };
  14. }
  15. const overflow = autoAdjustOverflow && typeof autoAdjustOverflow === 'object' ? autoAdjustOverflow : {};
  16. const baseOverflow = {};
  17. switch (placement) {
  18. case 'top':
  19. case 'bottom':
  20. baseOverflow.shiftX = arrowOffset.arrowOffsetHorizontal * 2 + arrowWidth;
  21. baseOverflow.shiftY = true;
  22. baseOverflow.adjustY = true;
  23. break;
  24. case 'left':
  25. case 'right':
  26. baseOverflow.shiftY = arrowOffset.arrowOffsetVertical * 2 + arrowWidth;
  27. baseOverflow.shiftX = true;
  28. baseOverflow.adjustX = true;
  29. break;
  30. }
  31. const mergedOverflow = Object.assign(Object.assign({}, baseOverflow), overflow);
  32. // Support auto shift
  33. if (!mergedOverflow.shiftX) {
  34. mergedOverflow.adjustX = true;
  35. }
  36. if (!mergedOverflow.shiftY) {
  37. mergedOverflow.adjustY = true;
  38. }
  39. return mergedOverflow;
  40. }
  41. const PlacementAlignMap = {
  42. left: {
  43. points: ['cr', 'cl']
  44. },
  45. right: {
  46. points: ['cl', 'cr']
  47. },
  48. top: {
  49. points: ['bc', 'tc']
  50. },
  51. bottom: {
  52. points: ['tc', 'bc']
  53. },
  54. topLeft: {
  55. points: ['bl', 'tl']
  56. },
  57. leftTop: {
  58. points: ['tr', 'tl']
  59. },
  60. topRight: {
  61. points: ['br', 'tr']
  62. },
  63. rightTop: {
  64. points: ['tl', 'tr']
  65. },
  66. bottomRight: {
  67. points: ['tr', 'br']
  68. },
  69. rightBottom: {
  70. points: ['bl', 'br']
  71. },
  72. bottomLeft: {
  73. points: ['tl', 'bl']
  74. },
  75. leftBottom: {
  76. points: ['br', 'bl']
  77. }
  78. };
  79. const ArrowCenterPlacementAlignMap = {
  80. topLeft: {
  81. points: ['bl', 'tc']
  82. },
  83. leftTop: {
  84. points: ['tr', 'cl']
  85. },
  86. topRight: {
  87. points: ['br', 'tc']
  88. },
  89. rightTop: {
  90. points: ['tl', 'cr']
  91. },
  92. bottomRight: {
  93. points: ['tr', 'bc']
  94. },
  95. rightBottom: {
  96. points: ['bl', 'cr']
  97. },
  98. bottomLeft: {
  99. points: ['tl', 'bc']
  100. },
  101. leftBottom: {
  102. points: ['br', 'cl']
  103. }
  104. };
  105. const DisableAutoArrowList = new Set(['topLeft', 'topRight', 'bottomLeft', 'bottomRight', 'leftTop', 'leftBottom', 'rightTop', 'rightBottom']);
  106. function getPlacements(config) {
  107. const {
  108. arrowWidth,
  109. autoAdjustOverflow,
  110. arrowPointAtCenter,
  111. offset,
  112. borderRadius,
  113. visibleFirst
  114. } = config;
  115. const halfArrowWidth = arrowWidth / 2;
  116. const placementMap = {};
  117. // Dynamic offset
  118. const arrowOffset = (0, _placementArrow.getArrowOffsetToken)({
  119. contentRadius: borderRadius,
  120. limitVerticalRadius: true
  121. });
  122. Object.keys(PlacementAlignMap).forEach(key => {
  123. const template = arrowPointAtCenter && ArrowCenterPlacementAlignMap[key] || PlacementAlignMap[key];
  124. const placementInfo = Object.assign(Object.assign({}, template), {
  125. offset: [0, 0],
  126. dynamicInset: true
  127. });
  128. placementMap[key] = placementInfo;
  129. // Disable autoArrow since design is fixed position
  130. if (DisableAutoArrowList.has(key)) {
  131. placementInfo.autoArrow = false;
  132. }
  133. // Static offset
  134. switch (key) {
  135. case 'top':
  136. case 'topLeft':
  137. case 'topRight':
  138. placementInfo.offset[1] = -halfArrowWidth - offset;
  139. break;
  140. case 'bottom':
  141. case 'bottomLeft':
  142. case 'bottomRight':
  143. placementInfo.offset[1] = halfArrowWidth + offset;
  144. break;
  145. case 'left':
  146. case 'leftTop':
  147. case 'leftBottom':
  148. placementInfo.offset[0] = -halfArrowWidth - offset;
  149. break;
  150. case 'right':
  151. case 'rightTop':
  152. case 'rightBottom':
  153. placementInfo.offset[0] = halfArrowWidth + offset;
  154. break;
  155. }
  156. if (arrowPointAtCenter) {
  157. switch (key) {
  158. case 'topLeft':
  159. case 'bottomLeft':
  160. placementInfo.offset[0] = -arrowOffset.arrowOffsetHorizontal - halfArrowWidth;
  161. break;
  162. case 'topRight':
  163. case 'bottomRight':
  164. placementInfo.offset[0] = arrowOffset.arrowOffsetHorizontal + halfArrowWidth;
  165. break;
  166. case 'leftTop':
  167. case 'rightTop':
  168. placementInfo.offset[1] = -arrowOffset.arrowOffsetHorizontal * 2 + halfArrowWidth;
  169. break;
  170. case 'leftBottom':
  171. case 'rightBottom':
  172. placementInfo.offset[1] = arrowOffset.arrowOffsetHorizontal * 2 - halfArrowWidth;
  173. break;
  174. }
  175. }
  176. // Overflow
  177. placementInfo.overflow = getOverflowOptions(key, arrowOffset, arrowWidth, autoAdjustOverflow);
  178. // VisibleFirst
  179. if (visibleFirst) {
  180. placementInfo.htmlRegion = 'visibleFirst';
  181. }
  182. });
  183. return placementMap;
  184. }