@douyinfe/semi-foundation 2.23.0-beta.0 → 2.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (180) hide show
  1. package/anchor/animation.scss +2 -2
  2. package/autoComplete/animation.scss +2 -2
  3. package/breadcrumb/animation.scss +2 -2
  4. package/button/animation.scss +26 -26
  5. package/carousel/animation.scss +2 -2
  6. package/cascader/animation.scss +2 -2
  7. package/cascader/cascader.scss +15 -0
  8. package/cascader/variables.scss +1 -0
  9. package/checkbox/animation.scss +4 -4
  10. package/checkbox/variables.scss +1 -1
  11. package/collapsible/animation.scss +2 -2
  12. package/datePicker/animation.scss +2 -2
  13. package/dropdown/animation.scss +1 -1
  14. package/dropdown/foundation.ts +16 -9
  15. package/dropdown/menuFoundation.ts +1 -12
  16. package/form/form.scss +3 -4
  17. package/form/rtl.scss +0 -1
  18. package/form/variables.scss +38 -35
  19. package/input/animation.scss +6 -6
  20. package/inputNumber/animation.scss +4 -4
  21. package/lib/cjs/anchor/anchor.css +1 -1
  22. package/lib/cjs/anchor/animation.scss +2 -2
  23. package/lib/cjs/autoComplete/animation.scss +2 -2
  24. package/lib/cjs/autoComplete/autoComplete.css +1 -1
  25. package/lib/cjs/breadcrumb/animation.scss +2 -2
  26. package/lib/cjs/breadcrumb/breadcrumb.css +1 -1
  27. package/lib/cjs/button/animation.scss +26 -26
  28. package/lib/cjs/button/button.css +7 -7
  29. package/lib/cjs/carousel/animation.scss +2 -2
  30. package/lib/cjs/carousel/carousel.css +6 -6
  31. package/lib/cjs/cascader/animation.scss +2 -2
  32. package/lib/cjs/cascader/cascader.css +13 -1
  33. package/lib/cjs/cascader/cascader.scss +15 -0
  34. package/lib/cjs/cascader/variables.scss +1 -0
  35. package/lib/cjs/checkbox/animation.scss +4 -4
  36. package/lib/cjs/checkbox/checkbox.css +2 -2
  37. package/lib/cjs/checkbox/variables.scss +1 -1
  38. package/lib/cjs/collapsible/animation.scss +2 -2
  39. package/lib/cjs/collapsible/collapsible.css +1 -1
  40. package/lib/cjs/datePicker/animation.scss +2 -2
  41. package/lib/cjs/dropdown/animation.scss +1 -1
  42. package/lib/cjs/dropdown/dropdown.css +1 -1
  43. package/lib/cjs/dropdown/foundation.d.ts +4 -3
  44. package/lib/cjs/dropdown/foundation.js +21 -8
  45. package/lib/cjs/dropdown/menuFoundation.d.ts +0 -1
  46. package/lib/cjs/dropdown/menuFoundation.js +0 -11
  47. package/lib/cjs/form/form.css +0 -2
  48. package/lib/cjs/form/form.scss +3 -4
  49. package/lib/cjs/form/rtl.scss +0 -1
  50. package/lib/cjs/form/variables.scss +38 -35
  51. package/lib/cjs/input/animation.scss +6 -6
  52. package/lib/cjs/input/input.css +2 -2
  53. package/lib/cjs/input/textarea.css +1 -1
  54. package/lib/cjs/inputNumber/animation.scss +4 -4
  55. package/lib/cjs/inputNumber/inputNumber.css +1 -1
  56. package/lib/cjs/navigation/animation.scss +2 -2
  57. package/lib/cjs/navigation/navigation.css +1 -1
  58. package/lib/cjs/pagination/animation.scss +4 -4
  59. package/lib/cjs/pagination/pagination.css +1 -1
  60. package/lib/cjs/radio/animation.scss +4 -4
  61. package/lib/cjs/radio/radio.css +4 -4
  62. package/lib/cjs/rating/animation.scss +2 -2
  63. package/lib/cjs/rating/rating.css +1 -1
  64. package/lib/cjs/scrollList/animation.scss +1 -1
  65. package/lib/cjs/scrollList/scrollList.css +1 -1
  66. package/lib/cjs/select/animation.scss +6 -6
  67. package/lib/cjs/select/select.css +2 -2
  68. package/lib/cjs/slider/animation.scss +2 -2
  69. package/lib/cjs/slider/slider.css +1 -1
  70. package/lib/cjs/steps/animation.scss +6 -6
  71. package/lib/cjs/steps/steps.css +7 -7
  72. package/lib/cjs/switch/animation.scss +1 -1
  73. package/lib/cjs/switch/switch.css +1 -1
  74. package/lib/cjs/table/animation.scss +1 -1
  75. package/lib/cjs/table/table.css +2 -2
  76. package/lib/cjs/tabs/animation.scss +8 -8
  77. package/lib/cjs/tabs/tabs.css +46 -6
  78. package/lib/cjs/tabs/tabs.scss +43 -2
  79. package/lib/cjs/tabs/variables.scss +20 -0
  80. package/lib/cjs/tagInput/animation.scss +4 -4
  81. package/lib/cjs/tagInput/tagInput.css +1 -1
  82. package/lib/cjs/timePicker/utils/animation.scss +4 -4
  83. package/lib/cjs/tooltip/constants.d.ts +1 -0
  84. package/lib/cjs/tooltip/constants.js +2 -2
  85. package/lib/cjs/tooltip/foundation.d.ts +21 -2
  86. package/lib/cjs/tooltip/foundation.js +360 -77
  87. package/lib/cjs/transfer/animation.scss +2 -2
  88. package/lib/cjs/transfer/transfer.css +1 -1
  89. package/lib/cjs/tree/animation.scss +2 -2
  90. package/lib/cjs/tree/tree.css +1 -1
  91. package/lib/es/anchor/anchor.css +1 -1
  92. package/lib/es/anchor/animation.scss +2 -2
  93. package/lib/es/autoComplete/animation.scss +2 -2
  94. package/lib/es/autoComplete/autoComplete.css +1 -1
  95. package/lib/es/breadcrumb/animation.scss +2 -2
  96. package/lib/es/breadcrumb/breadcrumb.css +1 -1
  97. package/lib/es/button/animation.scss +26 -26
  98. package/lib/es/button/button.css +7 -7
  99. package/lib/es/carousel/animation.scss +2 -2
  100. package/lib/es/carousel/carousel.css +6 -6
  101. package/lib/es/cascader/animation.scss +2 -2
  102. package/lib/es/cascader/cascader.css +13 -1
  103. package/lib/es/cascader/cascader.scss +15 -0
  104. package/lib/es/cascader/variables.scss +1 -0
  105. package/lib/es/checkbox/animation.scss +4 -4
  106. package/lib/es/checkbox/checkbox.css +2 -2
  107. package/lib/es/checkbox/variables.scss +1 -1
  108. package/lib/es/collapsible/animation.scss +2 -2
  109. package/lib/es/collapsible/collapsible.css +1 -1
  110. package/lib/es/datePicker/animation.scss +2 -2
  111. package/lib/es/dropdown/animation.scss +1 -1
  112. package/lib/es/dropdown/dropdown.css +1 -1
  113. package/lib/es/dropdown/foundation.d.ts +4 -3
  114. package/lib/es/dropdown/foundation.js +21 -8
  115. package/lib/es/dropdown/menuFoundation.d.ts +0 -1
  116. package/lib/es/dropdown/menuFoundation.js +1 -12
  117. package/lib/es/form/form.css +0 -2
  118. package/lib/es/form/form.scss +3 -4
  119. package/lib/es/form/rtl.scss +0 -1
  120. package/lib/es/form/variables.scss +38 -35
  121. package/lib/es/input/animation.scss +6 -6
  122. package/lib/es/input/input.css +2 -2
  123. package/lib/es/input/textarea.css +1 -1
  124. package/lib/es/inputNumber/animation.scss +4 -4
  125. package/lib/es/inputNumber/inputNumber.css +1 -1
  126. package/lib/es/navigation/animation.scss +2 -2
  127. package/lib/es/navigation/navigation.css +1 -1
  128. package/lib/es/pagination/animation.scss +4 -4
  129. package/lib/es/pagination/pagination.css +1 -1
  130. package/lib/es/radio/animation.scss +4 -4
  131. package/lib/es/radio/radio.css +4 -4
  132. package/lib/es/rating/animation.scss +2 -2
  133. package/lib/es/rating/rating.css +1 -1
  134. package/lib/es/scrollList/animation.scss +1 -1
  135. package/lib/es/scrollList/scrollList.css +1 -1
  136. package/lib/es/select/animation.scss +6 -6
  137. package/lib/es/select/select.css +2 -2
  138. package/lib/es/slider/animation.scss +2 -2
  139. package/lib/es/slider/slider.css +1 -1
  140. package/lib/es/steps/animation.scss +6 -6
  141. package/lib/es/steps/steps.css +7 -7
  142. package/lib/es/switch/animation.scss +1 -1
  143. package/lib/es/switch/switch.css +1 -1
  144. package/lib/es/table/animation.scss +1 -1
  145. package/lib/es/table/table.css +2 -2
  146. package/lib/es/tabs/animation.scss +8 -8
  147. package/lib/es/tabs/tabs.css +46 -6
  148. package/lib/es/tabs/tabs.scss +43 -2
  149. package/lib/es/tabs/variables.scss +20 -0
  150. package/lib/es/tagInput/animation.scss +4 -4
  151. package/lib/es/tagInput/tagInput.css +1 -1
  152. package/lib/es/timePicker/utils/animation.scss +4 -4
  153. package/lib/es/tooltip/constants.d.ts +1 -0
  154. package/lib/es/tooltip/constants.js +2 -2
  155. package/lib/es/tooltip/foundation.d.ts +21 -2
  156. package/lib/es/tooltip/foundation.js +360 -77
  157. package/lib/es/transfer/animation.scss +2 -2
  158. package/lib/es/transfer/transfer.css +1 -1
  159. package/lib/es/tree/animation.scss +2 -2
  160. package/lib/es/tree/tree.css +1 -1
  161. package/navigation/animation.scss +2 -2
  162. package/package.json +2 -2
  163. package/pagination/animation.scss +4 -4
  164. package/radio/animation.scss +4 -4
  165. package/rating/animation.scss +2 -2
  166. package/scrollList/animation.scss +1 -1
  167. package/select/animation.scss +6 -6
  168. package/slider/animation.scss +2 -2
  169. package/steps/animation.scss +6 -6
  170. package/switch/animation.scss +1 -1
  171. package/table/animation.scss +1 -1
  172. package/tabs/animation.scss +8 -8
  173. package/tabs/tabs.scss +43 -2
  174. package/tabs/variables.scss +20 -0
  175. package/tagInput/animation.scss +4 -4
  176. package/timePicker/utils/animation.scss +4 -4
  177. package/tooltip/constants.ts +1 -0
  178. package/tooltip/foundation.ts +322 -78
  179. package/transfer/animation.scss +2 -2
  180. package/tree/animation.scss +2 -2
@@ -51,6 +51,14 @@ export default class Tooltip extends BaseFoundation {
51
51
  const content = this.getProp('content');
52
52
  const trigger = this.getProp('trigger');
53
53
  const clickTriggerToHide = this.getProp('clickTriggerToHide');
54
+ const {
55
+ visible
56
+ } = this.getStates();
57
+
58
+ if (visible) {
59
+ return;
60
+ }
61
+
54
62
  this.clearDelayTimer();
55
63
  /**
56
64
  * If you emit an event in setState callback, you need to place the event listener function before setState to execute.
@@ -66,9 +74,11 @@ export default class Tooltip extends BaseFoundation {
66
74
  this._togglePortalVisible(true);
67
75
  });
68
76
 
69
- const position = this.calcPosition(null, null, null, false);
77
+ this._adapter.insertPortal(content, {
78
+ left: -9999,
79
+ top: -9999
80
+ }); // offscreen rendering
70
81
 
71
- this._adapter.insertPortal(content, position);
72
82
 
73
83
  if (trigger === 'custom') {
74
84
  // eslint-disable-next-line
@@ -114,17 +124,32 @@ export default class Tooltip extends BaseFoundation {
114
124
  containerRect = (_isEmpty(containerRect) ? _this._adapter.getPopupContainerRect() : containerRect) || Object.assign({}, defaultRect);
115
125
  wrapperRect = (_isEmpty(wrapperRect) ? _this._adapter.getWrapperBounding() : wrapperRect) || Object.assign({}, defaultRect); // console.log('containerRect: ', containerRect, 'triggerRect: ', triggerRect, 'wrapperRect: ', wrapperRect);
116
126
 
117
- let style = _this.calcPosStyle(triggerRect, wrapperRect, containerRect);
127
+ let style = _this.calcPosStyle({
128
+ triggerRect,
129
+ wrapperRect,
130
+ containerRect
131
+ });
118
132
 
119
133
  let position = _this.getProp('position');
120
134
 
121
135
  if (_this.getProp('autoAdjustOverflow')) {
122
136
  // console.log('style: ', style, '\ntriggerRect: ', triggerRect, '\nwrapperRect: ', wrapperRect);
123
- const adjustedPos = _this.adjustPosIfNeed(position, style, triggerRect, wrapperRect, containerRect);
137
+ const {
138
+ position: adjustedPos,
139
+ isHeightOverFlow,
140
+ isWidthOverFlow
141
+ } = _this.adjustPosIfNeed(position, style, triggerRect, wrapperRect, containerRect);
124
142
 
125
- if (position !== adjustedPos) {
143
+ if (position !== adjustedPos || isHeightOverFlow || isWidthOverFlow) {
126
144
  position = adjustedPos;
127
- style = _this.calcPosStyle(triggerRect, wrapperRect, containerRect, position);
145
+ style = _this.calcPosStyle({
146
+ triggerRect,
147
+ wrapperRect,
148
+ containerRect,
149
+ position,
150
+ spacing: null,
151
+ isOverFlow: [isHeightOverFlow, isWidthOverFlow]
152
+ });
128
153
  }
129
154
  }
130
155
 
@@ -262,6 +287,29 @@ export default class Tooltip extends BaseFoundation {
262
287
  this._adapter.unregisterResizeHandler(this.onResize);
263
288
  }
264
289
 
290
+ _adjustPos() {
291
+ let position = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
292
+ let isVertical = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
293
+ let adjustType = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'reverse';
294
+ let concatPos = arguments.length > 3 ? arguments[3] : undefined;
295
+
296
+ switch (adjustType) {
297
+ case 'reverse':
298
+ return this._reversePos(position, isVertical);
299
+
300
+ case 'expand':
301
+ // only happens when position is top/bottom/left/right
302
+ return this._expandPos(position, concatPos);
303
+
304
+ case 'reduce':
305
+ // only happens when position other than top/bottom/left/right
306
+ return this._reducePos(position);
307
+
308
+ default:
309
+ return this._reversePos(position, isVertical);
310
+ }
311
+ }
312
+
265
313
  _reversePos() {
266
314
  let position = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
267
315
  let isVertical = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
@@ -281,6 +329,19 @@ export default class Tooltip extends BaseFoundation {
281
329
  return position;
282
330
  }
283
331
 
332
+ _expandPos() {
333
+ let position = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
334
+ let concatPos = arguments.length > 1 ? arguments[1] : undefined;
335
+ return position.concat(concatPos);
336
+ }
337
+
338
+ _reducePos() {
339
+ let position = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
340
+ // if cur position consists of two directions, remove the last position
341
+ const found = ['Top', 'Bottom', 'Left', 'Right'].find(pos => position.endsWith(pos));
342
+ return found ? position.replace(found, '') : position;
343
+ }
344
+
284
345
  clearDelayTimer() {
285
346
  if (this._timer) {
286
347
  clearTimeout(this._timer);
@@ -441,12 +502,16 @@ export default class Tooltip extends BaseFoundation {
441
502
  return null;
442
503
  }
443
504
 
444
- calcPosStyle(triggerRect, wrapperRect, containerRect, position, spacing) {
445
- triggerRect = (_isEmpty(triggerRect) ? triggerRect : this._adapter.getTriggerBounding()) || Object.assign({}, defaultRect);
446
- containerRect = (_isEmpty(containerRect) ? containerRect : this._adapter.getPopupContainerRect()) || Object.assign({}, defaultRect);
447
- wrapperRect = (_isEmpty(wrapperRect) ? wrapperRect : this._adapter.getWrapperBounding()) || Object.assign({}, defaultRect); // eslint-disable-next-line
505
+ calcPosStyle(props) {
506
+ const {
507
+ spacing,
508
+ isOverFlow
509
+ } = props;
510
+ const triggerRect = (_isEmpty(props.triggerRect) ? props.triggerRect : this._adapter.getTriggerBounding()) || Object.assign({}, defaultRect);
511
+ const containerRect = (_isEmpty(props.containerRect) ? props.containerRect : this._adapter.getPopupContainerRect()) || Object.assign({}, defaultRect);
512
+ const wrapperRect = (_isEmpty(props.wrapperRect) ? props.wrapperRect : this._adapter.getWrapperBounding()) || Object.assign({}, defaultRect); // eslint-disable-next-line
448
513
 
449
- position = position != null ? position : this.getProp('position'); // eslint-disable-next-line
514
+ const position = props.position != null ? props.position : this.getProp('position'); // eslint-disable-next-line
450
515
 
451
516
  const SPACING = spacing != null ? spacing : this.getProp('spacing');
452
517
  const {
@@ -476,79 +541,112 @@ export default class Tooltip extends BaseFoundation {
476
541
  const middleY = triggerRect.top + triggerRect.height / 2;
477
542
  const offsetXWithArrow = positionOffsetX + horizontalArrowWidth / 2;
478
543
  const offsetYWithArrow = positionOffsetY + verticalArrowHeight / 2;
544
+ const heightDifference = wrapperRect.height - containerRect.height;
545
+ const widthDifference = wrapperRect.width - containerRect.width;
546
+ const offsetHeight = heightDifference > 0 ? heightDifference : 0;
547
+ const offsetWidth = widthDifference > 0 ? widthDifference : 0;
548
+ const isHeightOverFlow = isOverFlow && isOverFlow[0];
549
+ const isWidthOverFlow = isOverFlow && isOverFlow[1];
550
+ const isTriggerNearLeft = middleX - containerRect.left < containerRect.right - middleX;
551
+ const isTriggerNearTop = middleY - containerRect.top < containerRect.bottom - middleY;
479
552
 
480
553
  switch (position) {
481
554
  case 'top':
482
- left = middleX;
483
- top = triggerRect.top - SPACING;
555
+ // left = middleX;
556
+ // top = triggerRect.top - SPACING;
557
+ left = isWidthOverFlow ? isTriggerNearLeft ? containerRect.left + wrapperRect.width / 2 : containerRect.right - wrapperRect.width / 2 + offsetWidth : middleX;
558
+ top = isHeightOverFlow ? containerRect.bottom + offsetHeight : triggerRect.top - SPACING;
484
559
  translateX = -0.5;
485
560
  translateY = -1;
486
561
  break;
487
562
 
488
563
  case 'topLeft':
489
- left = pointAtCenter ? middleX - offsetXWithArrow : triggerRect.left;
490
- top = triggerRect.top - SPACING;
564
+ // left = pointAtCenter ? middleX - offsetXWithArrow : triggerRect.left;
565
+ // top = triggerRect.top - SPACING;
566
+ left = isWidthOverFlow ? containerRect.left : pointAtCenter ? middleX - offsetXWithArrow : triggerRect.left;
567
+ top = isHeightOverFlow ? containerRect.bottom + offsetHeight : triggerRect.top - SPACING;
491
568
  translateY = -1;
492
569
  break;
493
570
 
494
571
  case 'topRight':
495
- left = pointAtCenter ? middleX + offsetXWithArrow : triggerRect.right;
496
- top = triggerRect.top - SPACING;
572
+ // left = pointAtCenter ? middleX + offsetXWithArrow : triggerRect.right;
573
+ // top = triggerRect.top - SPACING;
574
+ left = isWidthOverFlow ? containerRect.right + offsetWidth : pointAtCenter ? middleX + offsetXWithArrow : triggerRect.right;
575
+ top = isHeightOverFlow ? containerRect.bottom + offsetHeight : triggerRect.top - SPACING;
497
576
  translateY = -1;
498
577
  translateX = -1;
499
578
  break;
500
579
 
501
580
  case 'left':
502
- left = triggerRect.left - SPACING;
503
- top = middleY;
581
+ // left = triggerRect.left - SPACING;
582
+ // top = middleY;
583
+ // left = isWidthOverFlow? containerRect.right - SPACING : triggerRect.left - SPACING;
584
+ left = isWidthOverFlow ? containerRect.right + offsetWidth - SPACING + offsetXWithArrow : triggerRect.left - SPACING;
585
+ top = isHeightOverFlow ? isTriggerNearTop ? containerRect.top + wrapperRect.height / 2 : containerRect.bottom - wrapperRect.height / 2 + offsetHeight : middleY;
504
586
  translateX = -1;
505
587
  translateY = -0.5;
506
588
  break;
507
589
 
508
590
  case 'leftTop':
509
- left = triggerRect.left - SPACING;
510
- top = pointAtCenter ? middleY - offsetYWithArrow : triggerRect.top;
591
+ // left = triggerRect.left - SPACING;
592
+ // top = pointAtCenter ? middleY - offsetYWithArrow : triggerRect.top;
593
+ left = isWidthOverFlow ? containerRect.right + offsetWidth - SPACING + offsetXWithArrow : triggerRect.left - SPACING;
594
+ top = isHeightOverFlow ? containerRect.top : pointAtCenter ? middleY - offsetYWithArrow : triggerRect.top;
511
595
  translateX = -1;
512
596
  break;
513
597
 
514
598
  case 'leftBottom':
515
- left = triggerRect.left - SPACING;
516
- top = pointAtCenter ? middleY + offsetYWithArrow : triggerRect.bottom;
599
+ // left = triggerRect.left - SPACING;
600
+ // top = pointAtCenter ? middleY + offsetYWithArrow : triggerRect.bottom;
601
+ left = isWidthOverFlow ? containerRect.right + offsetWidth - SPACING + offsetXWithArrow : triggerRect.left - SPACING;
602
+ top = isHeightOverFlow ? containerRect.bottom + offsetHeight : pointAtCenter ? middleY + offsetYWithArrow : triggerRect.bottom;
517
603
  translateX = -1;
518
604
  translateY = -1;
519
605
  break;
520
606
 
521
607
  case 'bottom':
522
- left = middleX;
523
- top = triggerRect.top + triggerRect.height + SPACING;
608
+ // left = middleX;
609
+ // top = triggerRect.top + triggerRect.height + SPACING;
610
+ left = isWidthOverFlow ? isTriggerNearLeft ? containerRect.left + wrapperRect.width / 2 : containerRect.right - wrapperRect.width / 2 + offsetWidth : middleX;
611
+ top = isHeightOverFlow ? containerRect.top + offsetYWithArrow - SPACING : triggerRect.top + triggerRect.height + SPACING;
524
612
  translateX = -0.5;
525
613
  break;
526
614
 
527
615
  case 'bottomLeft':
528
- left = pointAtCenter ? middleX - offsetXWithArrow : triggerRect.left;
529
- top = triggerRect.bottom + SPACING;
616
+ // left = pointAtCenter ? middleX - offsetXWithArrow : triggerRect.left;
617
+ // top = triggerRect.bottom + SPACING;
618
+ left = isWidthOverFlow ? containerRect.left : pointAtCenter ? middleX - offsetXWithArrow : triggerRect.left;
619
+ top = isHeightOverFlow ? containerRect.top + offsetYWithArrow - SPACING : triggerRect.top + triggerRect.height + SPACING;
530
620
  break;
531
621
 
532
622
  case 'bottomRight':
533
- left = pointAtCenter ? middleX + offsetXWithArrow : triggerRect.right;
534
- top = triggerRect.bottom + SPACING;
623
+ // left = pointAtCenter ? middleX + offsetXWithArrow : triggerRect.right;
624
+ // top = triggerRect.bottom + SPACING;
625
+ left = isWidthOverFlow ? containerRect.right + offsetWidth : pointAtCenter ? middleX + offsetXWithArrow : triggerRect.right;
626
+ top = isHeightOverFlow ? containerRect.top + offsetYWithArrow - SPACING : triggerRect.top + triggerRect.height + SPACING;
535
627
  translateX = -1;
536
628
  break;
537
629
 
538
630
  case 'right':
539
- left = triggerRect.right + SPACING;
540
- top = middleY;
631
+ // left = triggerRect.right + SPACING;
632
+ // top = middleY;
633
+ left = isWidthOverFlow ? containerRect.left - SPACING + offsetXWithArrow : triggerRect.right + SPACING;
634
+ top = isHeightOverFlow ? isTriggerNearTop ? containerRect.top + wrapperRect.height / 2 : containerRect.bottom - wrapperRect.height / 2 + offsetHeight : middleY;
541
635
  translateY = -0.5;
542
636
  break;
543
637
 
544
638
  case 'rightTop':
545
- left = triggerRect.right + SPACING;
546
- top = pointAtCenter ? middleY - offsetYWithArrow : triggerRect.top;
639
+ // left = triggerRect.right + SPACING;
640
+ // top = pointAtCenter ? middleY - offsetYWithArrow : triggerRect.top;
641
+ left = isWidthOverFlow ? containerRect.left - SPACING + offsetXWithArrow : triggerRect.right + SPACING;
642
+ top = isHeightOverFlow ? containerRect.top : pointAtCenter ? middleY - offsetYWithArrow : triggerRect.top;
547
643
  break;
548
644
 
549
645
  case 'rightBottom':
550
- left = triggerRect.right + SPACING;
551
- top = pointAtCenter ? middleY + offsetYWithArrow : triggerRect.bottom;
646
+ // left = triggerRect.right + SPACING;
647
+ // top = pointAtCenter ? middleY + offsetYWithArrow : triggerRect.bottom;
648
+ left = isWidthOverFlow ? containerRect.left - SPACING + offsetXWithArrow : triggerRect.right + SPACING;
649
+ top = isHeightOverFlow ? containerRect.bottom + offsetHeight : pointAtCenter ? middleY + offsetYWithArrow : triggerRect.bottom;
552
650
  translateY = -1;
553
651
  break;
554
652
 
@@ -655,12 +753,53 @@ export default class Tooltip extends BaseFoundation {
655
753
 
656
754
  isLR() {
657
755
  let position = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
658
- return position.indexOf('left') === 0 || position.indexOf('right') === 0;
756
+ return position.includes('left') || position.includes('right');
659
757
  }
660
758
 
661
759
  isTB() {
662
760
  let position = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
663
- return position.indexOf('top') === 0 || position.indexOf('bottom') === 0;
761
+ return position.includes('top') || position.includes('bottom');
762
+ }
763
+
764
+ isReverse(rowSpace, reverseSpace, size) {
765
+ // 原空间不足,反向空间足够
766
+ // Insufficient original space, enough reverse space
767
+ return rowSpace < size && reverseSpace > size;
768
+ }
769
+
770
+ isOverFlow(rowSpace, reverseSpace, size) {
771
+ // 原空间且反向空间都不足
772
+ // The original space and the reverse space are not enough
773
+ return rowSpace < size && reverseSpace < size;
774
+ }
775
+
776
+ isHalfOverFlow(posSpace, negSpace, size) {
777
+ // 正半空间或者负半空间不足,即表示有遮挡,需要偏移
778
+ // Insufficient positive half space or negative half space means that there is occlusion and needs to be offset
779
+ return posSpace < size || negSpace < size;
780
+ }
781
+
782
+ isHalfAllEnough(posSpace, negSpace, size) {
783
+ // 正半空间和负半空间都足够,即表示可以从 topLeft/topRight 变成 top
784
+ // Both positive and negative half-spaces are sufficient, which means you can change from topLeft/topRight to top
785
+ return posSpace >= size || negSpace >= size;
786
+ }
787
+
788
+ getReverse(viewOverFlow, containerOverFlow, shouldReverseView, shouldReverseContainer) {
789
+ /**
790
+ * 基于视口和容器一起判断,以下几种情况允许从原方向转到反方向,以判断是否应该由top->bottom为例子
791
+ *
792
+ * 1. 视口上下空间不足 且 容器上空间❌下空间✅
793
+ * 2. 视口上空间❌下空间✅ 且 容器上下空间不足
794
+ * 3. 视口上空间❌下空间✅ 且 容器上空间❌下空间✅
795
+ *
796
+ * Based on the judgment of the viewport and the container, the following situations are allowed to turn from the original direction to the opposite direction
797
+ * to judge whether it should be top->bottom as an example
798
+ * 1. There is insufficient space above and below the viewport and the space above the container ❌ the space below ✅
799
+ * 2. The space above the viewport ❌ the space below ✅ and the space above and below the container is insufficient
800
+ * 3. Viewport upper space ❌ lower space✅ and container upper space ❌ lower space✅
801
+ */
802
+ return viewOverFlow && shouldReverseContainer || shouldReverseView && containerOverFlow || shouldReverseView && shouldReverseContainer;
664
803
  } // place the dom correctly
665
804
 
666
805
 
@@ -670,8 +809,15 @@ export default class Tooltip extends BaseFoundation {
670
809
  innerHeight
671
810
  } = window;
672
811
  const {
673
- spacing
812
+ spacing,
813
+ margin
674
814
  } = this.getProps();
815
+ const marginLeft = typeof margin === 'number' ? margin : margin.marginLeft;
816
+ const marginTop = typeof margin === 'number' ? margin : margin.marginTop;
817
+ const marginRight = typeof margin === 'number' ? margin : margin.marginRight;
818
+ const marginBottom = typeof margin === 'number' ? margin : margin.marginBottom;
819
+ let isHeightOverFlow = false;
820
+ let isWidthOverFlow = false;
675
821
 
676
822
  if (wrapperRect.width > 0 && wrapperRect.height > 0) {
677
823
  // let clientLeft = left + translateX * wrapperRect.width - containerRect.scrollLeft;
@@ -694,187 +840,324 @@ export default class Tooltip extends BaseFoundation {
694
840
  const restClientBottom = innerHeight - clientBottom;
695
841
  const widthIsBigger = wrapperRect.width > triggerRect.width;
696
842
  const heightIsBigger = wrapperRect.height > triggerRect.height; // The wrapperR ect.top|bottom equivalent cannot be directly used here for comparison, which is easy to cause jitter
697
-
698
- const shouldReverseTop = clientTop < wrapperRect.height + spacing && restClientBottom > wrapperRect.height + spacing;
699
- const shouldReverseLeft = clientLeft < wrapperRect.width + spacing && restClientRight > wrapperRect.width + spacing;
700
- const shouldReverseBottom = restClientBottom < wrapperRect.height + spacing && clientTop > wrapperRect.height + spacing;
701
- const shouldReverseRight = restClientRight < wrapperRect.width + spacing && clientLeft > wrapperRect.width + spacing;
843
+ // 基于视口的微调判断
844
+ // Fine-tuning judgment based on viewport
845
+
846
+ const shouldViewReverseTop = clientTop - marginTop < wrapperRect.height + spacing && restClientBottom - marginBottom > wrapperRect.height + spacing;
847
+ const shouldViewReverseLeft = clientLeft - marginLeft < wrapperRect.width + spacing && restClientRight - marginRight > wrapperRect.width + spacing;
848
+ const shouldViewReverseBottom = restClientBottom - marginBottom < wrapperRect.height + spacing && clientTop - marginTop > wrapperRect.height + spacing;
849
+ const shouldViewReverseRight = restClientRight - marginRight < wrapperRect.width + spacing && clientLeft - marginLeft > wrapperRect.width + spacing;
850
+ const shouldViewReverseTopOver = restClientTop - marginBottom < wrapperRect.height + spacing && clientBottom - marginTop > wrapperRect.height + spacing;
851
+ const shouldViewReverseBottomOver = clientBottom - marginTop < wrapperRect.height + spacing && restClientTop - marginBottom > wrapperRect.height + spacing;
852
+ const shouldViewReverseTopSide = restClientTop < wrapperRect.height && clientBottom > wrapperRect.height;
853
+ const shouldViewReverseBottomSide = clientBottom < wrapperRect.height && restClientTop > wrapperRect.height;
854
+ const shouldViewReverseLeftSide = restClientLeft < wrapperRect.width && clientRight > wrapperRect.width;
855
+ const shouldViewReverseRightSide = clientRight < wrapperRect.width && restClientLeft > wrapperRect.width;
702
856
  const shouldReverseTopOver = restClientTop < wrapperRect.height + spacing && clientBottom > wrapperRect.height + spacing;
703
857
  const shouldReverseBottomOver = clientBottom < wrapperRect.height + spacing && restClientTop > wrapperRect.height + spacing;
704
- const shouldReverseTopSide = restClientTop < wrapperRect.height && clientBottom > wrapperRect.height;
705
- const shouldReverseBottomSide = clientBottom < wrapperRect.height && restClientTop > wrapperRect.height;
706
- const shouldReverseLeftSide = restClientLeft < wrapperRect.width && clientRight > wrapperRect.width;
707
- const shouldReverseRightSide = clientRight < wrapperRect.width && restClientLeft > wrapperRect.width;
708
858
  const shouldReverseLeftOver = restClientLeft < wrapperRect.width && clientRight > wrapperRect.width;
709
- const shouldReverseRightOver = clientRight < wrapperRect.width && restClientLeft > wrapperRect.width;
859
+ const shouldReverseRightOver = clientRight < wrapperRect.width && restClientLeft > wrapperRect.width; // 基于容器的微调判断
860
+ // Fine-tuning judgment based on container
861
+
862
+ const clientTopInContainer = clientTop - containerRect.top;
863
+ const clientLeftInContainer = clientLeft - containerRect.left;
864
+ const clientBottomInContainer = clientTopInContainer + triggerRect.height;
865
+ const clientRightInContainer = clientLeftInContainer + triggerRect.width;
866
+ const restClientBottomInContainer = containerRect.bottom - clientBottom;
867
+ const restClientRightInContainer = containerRect.right - clientRight;
868
+ const restClientTopInContainer = restClientBottomInContainer + triggerRect.height;
869
+ const restClientLeftInContainer = restClientRightInContainer + triggerRect.width; // 当原空间不足,反向空间足够时,可以反向。
870
+ // When the original space is insufficient and the reverse space is sufficient, the reverse can be performed.
871
+
872
+ const shouldContainerReverseTop = this.isReverse(clientTopInContainer - marginTop, restClientBottomInContainer - marginBottom, wrapperRect.height + spacing);
873
+ const shouldContainerReverseLeft = this.isReverse(clientLeftInContainer - marginLeft, restClientRightInContainer - marginRight, wrapperRect.width + spacing);
874
+ const shouldContainerReverseBottom = this.isReverse(restClientBottomInContainer - marginBottom, clientTopInContainer - marginTop, wrapperRect.height + spacing);
875
+ const shouldContainerReverseRight = this.isReverse(restClientRightInContainer - marginRight, clientLeftInContainer - marginLeft, wrapperRect.width + spacing);
876
+ const shouldContainerReverseTopOver = this.isReverse(restClientTopInContainer - marginBottom, clientBottomInContainer - marginTop, wrapperRect.height + spacing);
877
+ const shouldContainerReverseBottomOver = this.isReverse(clientBottomInContainer - marginTop, restClientTopInContainer - marginBottom, wrapperRect.height + spacing);
878
+ const shouldContainerReverseTopSide = this.isReverse(restClientTopInContainer, clientBottomInContainer, wrapperRect.height);
879
+ const shouldContainerReverseBottomSide = this.isReverse(clientBottomInContainer, restClientTopInContainer, wrapperRect.height);
880
+ const shouldContainerReverseLeftSide = this.isReverse(restClientLeftInContainer, clientRightInContainer, wrapperRect.width);
881
+ const shouldContainerReverseRightSide = this.isReverse(clientRightInContainer, restClientLeftInContainer, wrapperRect.width);
882
+ const halfHeight = triggerRect.height / 2;
883
+ const halfWidth = triggerRect.width / 2; // 视口, 原空间与反向空间是否都不足判断
884
+ // Viewport, whether the original space and the reverse space are insufficient to judge
885
+
886
+ const isViewYOverFlow = this.isOverFlow(clientTop - marginTop, restClientBottom - marginBottom, wrapperRect.height + spacing);
887
+ const isViewXOverFlow = this.isOverFlow(clientLeft - marginLeft, restClientRight - marginRight, wrapperRect.width + spacing);
888
+ const isViewYOverFlowSide = this.isOverFlow(clientBottom - marginTop, restClientTop - marginBottom, wrapperRect.height + spacing);
889
+ const isViewXOverFlowSide = this.isOverFlow(clientRight - marginLeft, restClientLeft - marginRight, wrapperRect.width + spacing);
890
+ const isViewYOverFlowSideHalf = this.isHalfOverFlow(clientBottom - halfHeight, restClientTop - halfHeight, wrapperRect.height / 2);
891
+ const isViewXOverFlowSideHalf = this.isHalfOverFlow(clientRight - halfWidth, restClientLeft - halfWidth, wrapperRect.width / 2);
892
+ const isViewYEnoughSideHalf = this.isHalfAllEnough(clientBottom - halfHeight, restClientTop - halfHeight, wrapperRect.height / 2);
893
+ const isViewXEnoughSideHalf = this.isHalfAllEnough(clientRight - halfWidth, restClientLeft - halfWidth, wrapperRect.width / 2); // 容器, 原空间与反向空间是否都不足判断
894
+ // container, whether the original space and the reverse space are insufficient to judge
895
+
896
+ const isContainerYOverFlow = this.isOverFlow(clientTopInContainer - marginTop, restClientBottomInContainer - marginBottom, wrapperRect.height + spacing);
897
+ const isContainerXOverFlow = this.isOverFlow(clientLeftInContainer - marginLeft, restClientRightInContainer - marginRight, wrapperRect.width + spacing);
898
+ const isContainerYOverFlowSide = this.isOverFlow(clientBottomInContainer - marginTop, restClientTopInContainer - marginBottom, wrapperRect.height + spacing);
899
+ const isContainerXOverFlowSide = this.isOverFlow(clientRightInContainer - marginLeft, restClientLeftInContainer - marginRight, wrapperRect.width + spacing);
900
+ const isContainerYOverFlowSideHalf = this.isHalfOverFlow(clientBottomInContainer - halfHeight, restClientTopInContainer - halfHeight, wrapperRect.height / 2);
901
+ const isContainerXOverFlowSideHalf = this.isHalfOverFlow(clientRightInContainer - halfWidth, restClientLeftInContainer - halfWidth, wrapperRect.width / 2);
902
+ const isContainerYEnoughSideHalf = this.isHalfAllEnough(clientBottomInContainer - halfHeight, restClientTopInContainer - halfHeight, wrapperRect.height / 2);
903
+ const isContainerXEnoughSideHalf = this.isHalfAllEnough(clientRightInContainer - halfWidth, restClientLeftInContainer - halfWidth, wrapperRect.width / 2); // 综合 viewport + container 判断微调,即视口 + 容器都放置不行时才能考虑位置调整
904
+ // Comprehensive viewport + container judgment fine-tuning, that is, the position adjustment can only be considered when the viewport + container cannot be placed.
905
+
906
+ const shouldReverseTop = this.getReverse(isViewYOverFlow, isContainerYOverFlow, shouldViewReverseTop, shouldContainerReverseTop);
907
+ const shouldReverseLeft = this.getReverse(isViewXOverFlow, isContainerXOverFlow, shouldViewReverseLeft, shouldContainerReverseLeft);
908
+ const shouldReverseBottom = this.getReverse(isViewYOverFlow, isContainerYOverFlow, shouldViewReverseBottom, shouldContainerReverseBottom);
909
+ const shouldReverseRight = this.getReverse(isViewXOverFlow, isContainerXOverFlow, shouldViewReverseRight, shouldContainerReverseRight); // const shouldReverseTopOver = this.getReverse(isViewYOverFlowSide, isContainerYOverFlowSide, shouldViewReverseTopOver, shouldContainerReverseTopOver);
910
+ // const shouldReverseBottomOver = this.getReverse(isViewYOverFlowSide, isContainerYOverFlowSide, shouldViewReverseBottomOver, shouldContainerReverseBottomOver);
911
+
912
+ const shouldReverseTopSide = this.getReverse(isViewYOverFlowSide, isContainerYOverFlowSide, shouldViewReverseTopSide, shouldContainerReverseTopSide);
913
+ const shouldReverseBottomSide = this.getReverse(isViewYOverFlowSide, isContainerYOverFlowSide, shouldViewReverseBottomSide, shouldContainerReverseBottomSide);
914
+ const shouldReverseLeftSide = this.getReverse(isViewXOverFlowSide, isContainerXOverFlowSide, shouldViewReverseLeftSide, shouldContainerReverseLeftSide);
915
+ const shouldReverseRightSide = this.getReverse(isViewXOverFlowSide, isContainerXOverFlowSide, shouldViewReverseRightSide, shouldContainerReverseRightSide);
916
+ const isYOverFlowSideHalf = isViewYOverFlowSideHalf && isContainerYOverFlowSideHalf;
917
+ const isXOverFlowSideHalf = isViewXOverFlowSideHalf && isContainerXOverFlowSideHalf;
710
918
 
711
919
  switch (position) {
712
920
  case 'top':
713
921
  if (shouldReverseTop) {
714
- position = this._reversePos(position, true);
922
+ position = this._adjustPos(position, true);
923
+ }
924
+
925
+ if (isXOverFlowSideHalf && (shouldReverseLeftSide || shouldReverseRightSide)) {
926
+ position = this._adjustPos(position, true, 'expand', shouldReverseLeftSide ? 'Right' : 'Left');
715
927
  }
716
928
 
717
929
  break;
718
930
 
719
931
  case 'topLeft':
720
932
  if (shouldReverseTop) {
721
- position = this._reversePos(position, true);
933
+ position = this._adjustPos(position, true);
722
934
  }
723
935
 
724
936
  if (shouldReverseLeftSide && widthIsBigger) {
725
- position = this._reversePos(position);
937
+ position = this._adjustPos(position, true);
938
+ }
939
+
940
+ if (isWidthOverFlow && (isViewXEnoughSideHalf || isContainerXEnoughSideHalf)) {
941
+ position = this._adjustPos(position, true, 'reduce');
726
942
  }
727
943
 
728
944
  break;
729
945
 
730
946
  case 'topRight':
731
947
  if (shouldReverseTop) {
732
- position = this._reversePos(position, true);
948
+ position = this._adjustPos(position, true);
733
949
  }
734
950
 
735
951
  if (shouldReverseRightSide && widthIsBigger) {
736
- position = this._reversePos(position);
952
+ position = this._adjustPos(position);
953
+ }
954
+
955
+ if (isWidthOverFlow && (isViewXEnoughSideHalf || isContainerXEnoughSideHalf)) {
956
+ position = this._adjustPos(position, true, 'reduce');
737
957
  }
738
958
 
739
959
  break;
740
960
 
741
961
  case 'left':
742
962
  if (shouldReverseLeft) {
743
- position = this._reversePos(position);
963
+ position = this._adjustPos(position);
964
+ }
965
+
966
+ if (isYOverFlowSideHalf && (shouldReverseTopSide || shouldReverseBottomSide)) {
967
+ position = this._adjustPos(position, false, 'expand', shouldReverseTopSide ? 'Bottom' : 'Top');
744
968
  }
745
969
 
746
970
  break;
747
971
 
748
972
  case 'leftTop':
749
973
  if (shouldReverseLeft) {
750
- position = this._reversePos(position);
974
+ position = this._adjustPos(position);
751
975
  }
752
976
 
753
977
  if (shouldReverseTopSide && heightIsBigger) {
754
- position = this._reversePos(position, true);
978
+ position = this._adjustPos(position, true);
979
+ }
980
+
981
+ if (isHeightOverFlow && (isViewYEnoughSideHalf || isContainerYEnoughSideHalf)) {
982
+ position = this._adjustPos(position, false, 'reduce');
755
983
  }
756
984
 
757
985
  break;
758
986
 
759
987
  case 'leftBottom':
760
988
  if (shouldReverseLeft) {
761
- position = this._reversePos(position);
989
+ position = this._adjustPos(position);
762
990
  }
763
991
 
764
992
  if (shouldReverseBottomSide && heightIsBigger) {
765
- position = this._reversePos(position, true);
993
+ position = this._adjustPos(position, true);
994
+ }
995
+
996
+ if (isHeightOverFlow && (isViewYEnoughSideHalf || isContainerYEnoughSideHalf)) {
997
+ position = this._adjustPos(position, false, 'reduce');
766
998
  }
767
999
 
768
1000
  break;
769
1001
 
770
1002
  case 'bottom':
771
1003
  if (shouldReverseBottom) {
772
- position = this._reversePos(position, true);
1004
+ position = this._adjustPos(position, true);
1005
+ }
1006
+
1007
+ if (isXOverFlowSideHalf && (shouldReverseLeftSide || shouldReverseRightSide)) {
1008
+ position = this._adjustPos(position, true, 'expand', shouldReverseLeftSide ? 'Right' : 'Left');
773
1009
  }
774
1010
 
775
1011
  break;
776
1012
 
777
1013
  case 'bottomLeft':
778
1014
  if (shouldReverseBottom) {
779
- position = this._reversePos(position, true);
1015
+ position = this._adjustPos(position, true);
780
1016
  }
781
1017
 
782
1018
  if (shouldReverseLeftSide && widthIsBigger) {
783
- position = this._reversePos(position);
1019
+ position = this._adjustPos(position);
1020
+ }
1021
+
1022
+ if (isWidthOverFlow && (isViewXEnoughSideHalf || isContainerXEnoughSideHalf)) {
1023
+ position = this._adjustPos(position, true, 'reduce');
784
1024
  }
785
1025
 
786
1026
  break;
787
1027
 
788
1028
  case 'bottomRight':
789
1029
  if (shouldReverseBottom) {
790
- position = this._reversePos(position, true);
1030
+ position = this._adjustPos(position, true);
791
1031
  }
792
1032
 
793
1033
  if (shouldReverseRightSide && widthIsBigger) {
794
- position = this._reversePos(position);
1034
+ position = this._adjustPos(position);
1035
+ }
1036
+
1037
+ if (isWidthOverFlow && (isViewXEnoughSideHalf || isContainerXEnoughSideHalf)) {
1038
+ position = this._adjustPos(position, true, 'reduce');
795
1039
  }
796
1040
 
797
1041
  break;
798
1042
 
799
1043
  case 'right':
800
1044
  if (shouldReverseRight) {
801
- position = this._reversePos(position);
1045
+ position = this._adjustPos(position);
1046
+ }
1047
+
1048
+ if (isYOverFlowSideHalf && (shouldReverseTopSide || shouldReverseBottomSide)) {
1049
+ position = this._adjustPos(position, false, 'expand', shouldReverseTopSide ? 'Bottom' : 'Top');
802
1050
  }
803
1051
 
804
1052
  break;
805
1053
 
806
1054
  case 'rightTop':
807
1055
  if (shouldReverseRight) {
808
- position = this._reversePos(position);
1056
+ position = this._adjustPos(position);
809
1057
  }
810
1058
 
811
1059
  if (shouldReverseTopSide && heightIsBigger) {
812
- position = this._reversePos(position, true);
1060
+ position = this._adjustPos(position, true);
1061
+ }
1062
+
1063
+ if (isHeightOverFlow && (isViewYEnoughSideHalf || isContainerYEnoughSideHalf)) {
1064
+ position = this._adjustPos(position, false, 'reduce');
813
1065
  }
814
1066
 
815
1067
  break;
816
1068
 
817
1069
  case 'rightBottom':
818
1070
  if (shouldReverseRight) {
819
- position = this._reversePos(position);
1071
+ position = this._adjustPos(position);
820
1072
  }
821
1073
 
822
1074
  if (shouldReverseBottomSide && heightIsBigger) {
823
- position = this._reversePos(position, true);
1075
+ position = this._adjustPos(position, true);
1076
+ }
1077
+
1078
+ if (isHeightOverFlow && (isViewYEnoughSideHalf || isContainerYEnoughSideHalf)) {
1079
+ position = this._adjustPos(position, false, 'reduce');
824
1080
  }
825
1081
 
826
1082
  break;
827
1083
 
828
1084
  case 'leftTopOver':
829
1085
  if (shouldReverseTopOver) {
830
- position = this._reversePos(position, true);
1086
+ position = this._adjustPos(position, true);
831
1087
  }
832
1088
 
833
1089
  if (shouldReverseLeftOver) {
834
- position = this._reversePos(position);
1090
+ position = this._adjustPos(position);
835
1091
  }
836
1092
 
837
1093
  break;
838
1094
 
839
1095
  case 'leftBottomOver':
840
1096
  if (shouldReverseBottomOver) {
841
- position = this._reversePos(position, true);
1097
+ position = this._adjustPos(position, true);
842
1098
  }
843
1099
 
844
1100
  if (shouldReverseLeftOver) {
845
- position = this._reversePos(position);
1101
+ position = this._adjustPos(position);
846
1102
  }
847
1103
 
848
1104
  break;
849
1105
 
850
1106
  case 'rightTopOver':
851
1107
  if (shouldReverseTopOver) {
852
- position = this._reversePos(position, true);
1108
+ position = this._adjustPos(position, true);
853
1109
  }
854
1110
 
855
1111
  if (shouldReverseRightOver) {
856
- position = this._reversePos(position);
1112
+ position = this._adjustPos(position);
857
1113
  }
858
1114
 
859
1115
  break;
860
1116
 
861
1117
  case 'rightBottomOver':
862
1118
  if (shouldReverseBottomOver) {
863
- position = this._reversePos(position, true);
1119
+ position = this._adjustPos(position, true);
864
1120
  }
865
1121
 
866
1122
  if (shouldReverseRightOver) {
867
- position = this._reversePos(position);
1123
+ position = this._adjustPos(position);
868
1124
  }
869
1125
 
870
1126
  break;
871
1127
 
872
1128
  default:
873
1129
  break;
1130
+ } // 判断溢出 Judgment overflow
1131
+ // 上下方向 top and bottom
1132
+
1133
+
1134
+ if (this.isTB(position)) {
1135
+ isHeightOverFlow = isViewYOverFlow && isContainerYOverFlow;
1136
+
1137
+ if (position === 'top' || position === 'bottom') {
1138
+ isWidthOverFlow = isViewXOverFlowSideHalf && isContainerXOverFlowSideHalf;
1139
+ } else {
1140
+ isWidthOverFlow = isViewXOverFlowSide && isContainerXOverFlowSide;
1141
+ }
1142
+ } // 左右方向 left and right
1143
+
1144
+
1145
+ if (this.isLR(position)) {
1146
+ isWidthOverFlow = isViewXOverFlow && isContainerXOverFlow;
1147
+
1148
+ if (position === 'left' || position === 'right') {
1149
+ isHeightOverFlow = isViewYOverFlowSideHalf && isContainerYOverFlowSideHalf;
1150
+ } else {
1151
+ isHeightOverFlow = isViewYOverFlowSide && isContainerYOverFlowSide;
1152
+ }
874
1153
  }
875
1154
  }
876
1155
 
877
- return position;
1156
+ return {
1157
+ position,
1158
+ isHeightOverFlow,
1159
+ isWidthOverFlow
1160
+ };
878
1161
  }
879
1162
 
880
1163
  _bindScrollEvent() {