@douyinfe/semi-foundation 2.21.0 → 2.22.0-alpha.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.
@@ -28,7 +28,7 @@ export default class ModalContentFoundation extends BaseFoundation<ModalContentA
28
28
  destroy(): void;
29
29
  handleDialogMouseDown(): void;
30
30
  handleMaskMouseUp(): void;
31
- handleKeyDown(e: any): void;
31
+ handleKeyDown: (e: any) => void;
32
32
  handleKeyDownEventListenerMount(): void;
33
33
  handleKeyDownEventListenerUnmount(): void;
34
34
  getMouseState(): void;
@@ -14,6 +14,18 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
14
14
  class ModalContentFoundation extends _foundation.default {
15
15
  constructor(adapter) {
16
16
  super(Object.assign(Object.assign({}, ModalContentFoundation.defaultAdapter), adapter));
17
+
18
+ this.handleKeyDown = e => {
19
+ const {
20
+ closeOnEsc
21
+ } = this.getProps();
22
+
23
+ if (closeOnEsc && e.keyCode === _keyCode.default.ESC) {
24
+ e.stopPropagation();
25
+ this.close(e);
26
+ return;
27
+ }
28
+ };
17
29
  }
18
30
 
19
31
  destroy() {
@@ -30,18 +42,6 @@ class ModalContentFoundation extends _foundation.default {
30
42
  this._adapter.notifyDialogMouseUp();
31
43
  }
32
44
 
33
- handleKeyDown(e) {
34
- const {
35
- closeOnEsc
36
- } = this.getProps();
37
-
38
- if (closeOnEsc && e.keyCode === _keyCode.default.ESC) {
39
- e.stopPropagation();
40
- this.close(e);
41
- return;
42
- }
43
- }
44
-
45
45
  handleKeyDownEventListenerMount() {
46
46
  this._adapter.addKeyDownEventListener();
47
47
  }
@@ -18,5 +18,6 @@ declare const numbers: {
18
18
  readonly MOUSE_ENTER_DELAY: 50;
19
19
  readonly MOUSE_LEAVE_DELAY: 50;
20
20
  readonly SPACING: 8;
21
+ readonly MARGIN: 0;
21
22
  };
22
23
  export { cssClasses, strings, numbers };
@@ -28,7 +28,7 @@ const numbers = {
28
28
  DEFAULT_Z_INDEX: 1060,
29
29
  MOUSE_ENTER_DELAY: 50,
30
30
  MOUSE_LEAVE_DELAY: 50,
31
- SPACING: 8 // Values are consistent with spacing-tight in scss
32
-
31
+ SPACING: 8,
32
+ MARGIN: 0
33
33
  };
34
34
  exports.numbers = numbers;
@@ -69,6 +69,7 @@ export default class Tooltip<P = Record<string, any>, S = Record<string, any>> e
69
69
  _bindResizeEvent(): void;
70
70
  _unBindResizeEvent(): void;
71
71
  _reversePos(position?: string, isVertical?: boolean): string;
72
+ _adjustPos(position?: string, shouldReverseArr?: boolean[], isVertical?: boolean): string;
72
73
  clearDelayTimer(): void;
73
74
  _generateEvent(types: ArrayElement<typeof strings.TRIGGER_SET>): {
74
75
  triggerEventSet: {
@@ -83,7 +84,7 @@ export default class Tooltip<P = Record<string, any>, S = Record<string, any>> e
83
84
  _togglePortalVisible(isVisible: boolean): void;
84
85
  _roundPixel(pixel: number): number;
85
86
  calcTransformOrigin(position: Position, triggerRect: DOMRect, translateX: number, translateY: number): string;
86
- calcPosStyle(triggerRect: DOMRect, wrapperRect: DOMRect, containerRect: PopupContainerDOMRect, position?: Position, spacing?: number): Record<string, string | number>;
87
+ calcPosStyle(triggerRect: DOMRect, wrapperRect: DOMRect, containerRect: PopupContainerDOMRect, position?: Position, spacing?: number, isOverFlow?: [boolean, boolean]): Record<string, string | number>;
87
88
  /**
88
89
  * 耦合的东西比较多,稍微罗列一下:
89
90
  *
@@ -100,7 +101,15 @@ export default class Tooltip<P = Record<string, any>, S = Record<string, any>> e
100
101
  calcPosition: (triggerRect?: DOMRect, wrapperRect?: DOMRect, containerRect?: PopupContainerDOMRect, shouldUpdatePos?: boolean) => Record<string, string | number>;
101
102
  isLR(position?: string): boolean;
102
103
  isTB(position?: string): boolean;
103
- adjustPosIfNeed(position: Position | string, style: Record<string, any>, triggerRect: DOMRect, wrapperRect: DOMRect, containerRect: PopupContainerDOMRect): string;
104
+ isReverse(rowSpace: number, reverseSpace: number, size: number): boolean;
105
+ isOverFlow(rowSpace: number, reverseSpace: number, size: number): boolean;
106
+ isHalfOverFlow(posSpace: number, negSpace: number, size: number): boolean;
107
+ getReverse(viewOvf: boolean, cntrOvf: boolean, shouldRevView: boolean, shouldRevCntr: boolean): boolean;
108
+ adjustPosIfNeed(position: Position | string, style: Record<string, any>, triggerRect: DOMRect, wrapperRect: DOMRect, containerRect: PopupContainerDOMRect): {
109
+ position: string;
110
+ isHeightOverFlow: boolean;
111
+ isWidthOverFlow: boolean;
112
+ };
104
113
  delayHide: () => void;
105
114
  hide: () => void;
106
115
  _bindScrollEvent(): void;
@@ -130,11 +130,15 @@ class Tooltip extends _foundation.default {
130
130
 
131
131
  if (_this.getProp('autoAdjustOverflow')) {
132
132
  // console.log('style: ', style, '\ntriggerRect: ', triggerRect, '\nwrapperRect: ', wrapperRect);
133
- const adjustedPos = _this.adjustPosIfNeed(position, style, triggerRect, wrapperRect, containerRect);
133
+ const {
134
+ position: adjustedPos,
135
+ isHeightOverFlow,
136
+ isWidthOverFlow
137
+ } = _this.adjustPosIfNeed(position, style, triggerRect, wrapperRect, containerRect);
134
138
 
135
- if (position !== adjustedPos) {
139
+ if (position !== adjustedPos || isHeightOverFlow || isWidthOverFlow) {
136
140
  position = adjustedPos;
137
- style = _this.calcPosStyle(triggerRect, wrapperRect, containerRect, position);
141
+ style = _this.calcPosStyle(triggerRect, wrapperRect, containerRect, position, null, [isHeightOverFlow, isWidthOverFlow]);
138
142
  }
139
143
  }
140
144
 
@@ -314,6 +318,28 @@ class Tooltip extends _foundation.default {
314
318
  return position;
315
319
  }
316
320
 
321
+ _adjustPos() {
322
+ let position = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
323
+ let shouldReverseArr = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [true, false];
324
+ let isVertical = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
325
+
326
+ if (isVertical) {
327
+ if (shouldReverseArr[0]) {
328
+ return position.concat('Right'); // top -> topRight
329
+ } else if (shouldReverseArr[1]) {
330
+ return position.concat('Left'); // top -> topLeft
331
+ }
332
+ } else {
333
+ if (shouldReverseArr[0]) {
334
+ return position.concat('Bottom'); // left -> leftBottom
335
+ } else if (shouldReverseArr[1]) {
336
+ return position.concat('Top'); // left -> leftTop
337
+ }
338
+ }
339
+
340
+ return position;
341
+ }
342
+
317
343
  clearDelayTimer() {
318
344
  if (this._timer) {
319
345
  clearTimeout(this._timer);
@@ -474,7 +500,7 @@ class Tooltip extends _foundation.default {
474
500
  return null;
475
501
  }
476
502
 
477
- calcPosStyle(triggerRect, wrapperRect, containerRect, position, spacing) {
503
+ calcPosStyle(triggerRect, wrapperRect, containerRect, position, spacing, isOverFlow) {
478
504
  triggerRect = ((0, _isEmpty2.default)(triggerRect) ? triggerRect : this._adapter.getTriggerBounding()) || Object.assign({}, defaultRect);
479
505
  containerRect = ((0, _isEmpty2.default)(containerRect) ? containerRect : this._adapter.getPopupContainerRect()) || Object.assign({}, defaultRect);
480
506
  wrapperRect = ((0, _isEmpty2.default)(wrapperRect) ? wrapperRect : this._adapter.getWrapperBounding()) || Object.assign({}, defaultRect); // eslint-disable-next-line
@@ -505,79 +531,112 @@ class Tooltip extends _foundation.default {
505
531
  const middleY = triggerRect.top + triggerRect.height / 2;
506
532
  const offsetXWithArrow = positionOffsetX + horizontalArrowWidth / 2;
507
533
  const offsetYWithArrow = positionOffsetY + verticalArrowHeight / 2;
534
+ const heightDifference = wrapperRect.height - containerRect.height;
535
+ const widthDifference = wrapperRect.width - containerRect.width;
536
+ const offsetHeight = heightDifference > 0 ? heightDifference : 0;
537
+ const offsetWidth = widthDifference > 0 ? widthDifference : 0;
538
+ const isHeightOverFlow = isOverFlow && isOverFlow[0];
539
+ const isWitdhOverFlow = isOverFlow && isOverFlow[1];
540
+ const isTriggerNearLeft = middleX - containerRect.left < containerRect.right - middleX;
541
+ const isTriggerNearTop = middleY - containerRect.top < containerRect.bottom - middleY;
508
542
 
509
543
  switch (position) {
510
544
  case 'top':
511
- left = middleX;
512
- top = triggerRect.top - SPACING;
545
+ // left = middleX;
546
+ // top = triggerRect.top - SPACING;
547
+ left = isWitdhOverFlow ? isTriggerNearLeft ? containerRect.left + wrapperRect.width / 2 : containerRect.right - wrapperRect.width / 2 + offsetWidth : middleX;
548
+ top = isHeightOverFlow ? containerRect.bottom - SPACING + offsetHeight : triggerRect.top - SPACING;
513
549
  translateX = -0.5;
514
550
  translateY = -1;
515
551
  break;
516
552
 
517
553
  case 'topLeft':
518
- left = pointAtCenter ? middleX - offsetXWithArrow : triggerRect.left;
519
- top = triggerRect.top - SPACING;
554
+ // left = pointAtCenter ? middleX - offsetXWithArrow : triggerRect.left;
555
+ // top = triggerRect.top - SPACING;
556
+ left = isWitdhOverFlow ? containerRect.left : pointAtCenter ? middleX - offsetXWithArrow : triggerRect.left;
557
+ top = isHeightOverFlow ? containerRect.bottom - SPACING + offsetHeight : triggerRect.top - SPACING;
520
558
  translateY = -1;
521
559
  break;
522
560
 
523
561
  case 'topRight':
524
- left = pointAtCenter ? middleX + offsetXWithArrow : triggerRect.right;
525
- top = triggerRect.top - SPACING;
562
+ // left = pointAtCenter ? middleX + offsetXWithArrow : triggerRect.right;
563
+ // top = triggerRect.top - SPACING;
564
+ left = isWitdhOverFlow ? containerRect.right + offsetWidth : pointAtCenter ? middleX + offsetXWithArrow : triggerRect.right;
565
+ top = isHeightOverFlow ? containerRect.bottom - SPACING + offsetHeight : triggerRect.top - SPACING;
526
566
  translateY = -1;
527
567
  translateX = -1;
528
568
  break;
529
569
 
530
570
  case 'left':
531
- left = triggerRect.left - SPACING;
532
- top = middleY;
571
+ // left = triggerRect.left - SPACING;
572
+ // top = middleY;
573
+ // left = isWitdhOverFlow? containerRect.right - SPACING : triggerRect.left - SPACING;
574
+ left = isWitdhOverFlow ? containerRect.right + offsetWidth - SPACING : triggerRect.left - SPACING;
575
+ top = isHeightOverFlow ? isTriggerNearTop ? containerRect.top + wrapperRect.height / 2 : containerRect.bottom - wrapperRect.height / 2 + offsetHeight : middleY;
533
576
  translateX = -1;
534
577
  translateY = -0.5;
535
578
  break;
536
579
 
537
580
  case 'leftTop':
538
- left = triggerRect.left - SPACING;
539
- top = pointAtCenter ? middleY - offsetYWithArrow : triggerRect.top;
581
+ // left = triggerRect.left - SPACING;
582
+ // top = pointAtCenter ? middleY - offsetYWithArrow : triggerRect.top;
583
+ left = isWitdhOverFlow ? containerRect.right + offsetWidth - SPACING : triggerRect.left - SPACING;
584
+ top = isHeightOverFlow ? containerRect.top : pointAtCenter ? middleY - offsetYWithArrow : triggerRect.top;
540
585
  translateX = -1;
541
586
  break;
542
587
 
543
588
  case 'leftBottom':
544
- left = triggerRect.left - SPACING;
545
- top = pointAtCenter ? middleY + offsetYWithArrow : triggerRect.bottom;
589
+ // left = triggerRect.left - SPACING;
590
+ // top = pointAtCenter ? middleY + offsetYWithArrow : triggerRect.bottom;
591
+ left = isWitdhOverFlow ? containerRect.right + offsetWidth - SPACING : triggerRect.left - SPACING;
592
+ top = isHeightOverFlow ? containerRect.bottom + offsetHeight : pointAtCenter ? middleY + offsetYWithArrow : triggerRect.bottom;
546
593
  translateX = -1;
547
594
  translateY = -1;
548
595
  break;
549
596
 
550
597
  case 'bottom':
551
- left = middleX;
552
- top = triggerRect.top + triggerRect.height + SPACING;
598
+ // left = middleX;
599
+ // top = triggerRect.top + triggerRect.height + SPACING;
600
+ left = isWitdhOverFlow ? isTriggerNearLeft ? containerRect.left + wrapperRect.width / 2 : containerRect.right - wrapperRect.width / 2 + offsetWidth : middleX;
601
+ top = isHeightOverFlow ? containerRect.top - SPACING + offsetYWithArrow : triggerRect.top + triggerRect.height + SPACING;
553
602
  translateX = -0.5;
554
603
  break;
555
604
 
556
605
  case 'bottomLeft':
557
- left = pointAtCenter ? middleX - offsetXWithArrow : triggerRect.left;
558
- top = triggerRect.bottom + SPACING;
606
+ // left = pointAtCenter ? middleX - offsetXWithArrow : triggerRect.left;
607
+ // top = triggerRect.bottom + SPACING;
608
+ left = isWitdhOverFlow ? containerRect.left : pointAtCenter ? middleX - offsetXWithArrow : triggerRect.left;
609
+ top = isHeightOverFlow ? containerRect.top + offsetYWithArrow - SPACING : triggerRect.top + triggerRect.height + SPACING;
559
610
  break;
560
611
 
561
612
  case 'bottomRight':
562
- left = pointAtCenter ? middleX + offsetXWithArrow : triggerRect.right;
563
- top = triggerRect.bottom + SPACING;
613
+ // left = pointAtCenter ? middleX + offsetXWithArrow : triggerRect.right;
614
+ // top = triggerRect.bottom + SPACING;
615
+ left = isWitdhOverFlow ? containerRect.right + offsetWidth : pointAtCenter ? middleX + offsetXWithArrow : triggerRect.right;
616
+ top = isHeightOverFlow ? containerRect.top + offsetYWithArrow - SPACING : triggerRect.top + triggerRect.height + SPACING;
564
617
  translateX = -1;
565
618
  break;
566
619
 
567
620
  case 'right':
568
- left = triggerRect.right + SPACING;
569
- top = middleY;
621
+ // left = triggerRect.right + SPACING;
622
+ // top = middleY;
623
+ left = isWitdhOverFlow ? containerRect.left - SPACING + offsetXWithArrow : triggerRect.right + SPACING;
624
+ top = isHeightOverFlow ? isTriggerNearTop ? containerRect.top + wrapperRect.height / 2 : containerRect.bottom - wrapperRect.height / 2 + offsetHeight : middleY;
570
625
  translateY = -0.5;
571
626
  break;
572
627
 
573
628
  case 'rightTop':
574
- left = triggerRect.right + SPACING;
575
- top = pointAtCenter ? middleY - offsetYWithArrow : triggerRect.top;
629
+ // left = triggerRect.right + SPACING;
630
+ // top = pointAtCenter ? middleY - offsetYWithArrow : triggerRect.top;
631
+ left = isWitdhOverFlow ? containerRect.left - SPACING + offsetXWithArrow : triggerRect.right + SPACING;
632
+ top = isHeightOverFlow ? containerRect.top : pointAtCenter ? middleY - offsetYWithArrow : triggerRect.top;
576
633
  break;
577
634
 
578
635
  case 'rightBottom':
579
- left = triggerRect.right + SPACING;
580
- top = pointAtCenter ? middleY + offsetYWithArrow : triggerRect.bottom;
636
+ // left = triggerRect.right + SPACING;
637
+ // top = pointAtCenter ? middleY + offsetYWithArrow : triggerRect.bottom;
638
+ left = isWitdhOverFlow ? containerRect.left - SPACING + offsetXWithArrow : triggerRect.right + SPACING;
639
+ top = isHeightOverFlow ? containerRect.bottom + offsetHeight : pointAtCenter ? middleY + offsetYWithArrow : triggerRect.bottom;
581
640
  translateY = -1;
582
641
  break;
583
642
 
@@ -684,12 +743,35 @@ class Tooltip extends _foundation.default {
684
743
 
685
744
  isLR() {
686
745
  let position = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
687
- return position.indexOf('left') === 0 || position.indexOf('right') === 0;
746
+ return position.includes('left') || position.includes('right');
688
747
  }
689
748
 
690
749
  isTB() {
691
750
  let position = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
692
- return position.indexOf('top') === 0 || position.indexOf('bottom') === 0;
751
+ return position.includes('top') || position.includes('bottom');
752
+ }
753
+
754
+ isReverse(rowSpace, reverseSpace, size) {
755
+ // 原空间不足,反向空间足够
756
+ return rowSpace < size && reverseSpace > size;
757
+ }
758
+
759
+ isOverFlow(rowSpace, reverseSpace, size) {
760
+ // 原空间且反向空间都不足
761
+ return rowSpace < size && reverseSpace < size;
762
+ }
763
+
764
+ isHalfOverFlow(posSpace, negSpace, size) {
765
+ // 正半空间或者负半空间不足,即表示有遮挡,需要偏移
766
+ return posSpace < size || negSpace < size;
767
+ }
768
+
769
+ getReverse(viewOvf, cntrOvf, shouldRevView, shouldRevCntr) {
770
+ // 基于视口和容器一起判断,以下几种情况允许从原方向转到反方向,以判断是否应该由top->bottom为例子
771
+ // 1. 视口上下空间不足 且 容器上空间❌下空间✅
772
+ // 2. 视口上空间❌下空间✅ 且 容器上下空间不足
773
+ // 3. 视口上空间❌下空间✅ 且 容器上空间❌下空间✅
774
+ return viewOvf && shouldRevCntr || shouldRevView && cntrOvf || shouldRevView && shouldRevCntr;
693
775
  } // place the dom correctly
694
776
 
695
777
 
@@ -701,6 +783,8 @@ class Tooltip extends _foundation.default {
701
783
  const {
702
784
  spacing
703
785
  } = this.getProps();
786
+ let isHeightOverFlow = false;
787
+ let isWidthOverFlow = false;
704
788
 
705
789
  if (wrapperRect.width > 0 && wrapperRect.height > 0) {
706
790
  // let clientLeft = left + translateX * wrapperRect.width - containerRect.scrollLeft;
@@ -723,19 +807,90 @@ class Tooltip extends _foundation.default {
723
807
  const restClientBottom = innerHeight - clientBottom;
724
808
  const widthIsBigger = wrapperRect.width > triggerRect.width;
725
809
  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
726
-
727
- const shouldReverseTop = clientTop < wrapperRect.height + spacing && restClientBottom > wrapperRect.height + spacing;
728
- const shouldReverseLeft = clientLeft < wrapperRect.width + spacing && restClientRight > wrapperRect.width + spacing;
729
- const shouldReverseBottom = restClientBottom < wrapperRect.height + spacing && clientTop > wrapperRect.height + spacing;
730
- const shouldReverseRight = restClientRight < wrapperRect.width + spacing && clientLeft > wrapperRect.width + spacing;
731
- const shouldReverseTopOver = restClientTop < wrapperRect.height + spacing && clientBottom > wrapperRect.height + spacing;
732
- const shouldReverseBottomOver = clientBottom < wrapperRect.height + spacing && restClientTop > wrapperRect.height + spacing;
733
- const shouldReverseTopSide = restClientTop < wrapperRect.height && clientBottom > wrapperRect.height;
734
- const shouldReverseBottomSide = clientBottom < wrapperRect.height && restClientTop > wrapperRect.height;
735
- const shouldReverseLeftSide = restClientLeft < wrapperRect.width && clientRight > wrapperRect.width;
736
- const shouldReverseRightSide = clientRight < wrapperRect.width && restClientLeft > wrapperRect.width;
810
+ // 基于视口的微调判断
811
+
812
+ const shouldViewReverseTop = clientTop < wrapperRect.height + spacing && restClientBottom > wrapperRect.height + spacing;
813
+ const shouldViewReverseLeft = clientLeft < wrapperRect.width + spacing && restClientRight > wrapperRect.width + spacing;
814
+ const shouldViewReverseBottom = restClientBottom < wrapperRect.height + spacing && clientTop > wrapperRect.height + spacing;
815
+ const shouldViewReverseRight = restClientRight < wrapperRect.width + spacing && clientLeft > wrapperRect.width + spacing;
816
+ const shouldViewReverseTopOver = restClientTop < wrapperRect.height + spacing && clientBottom > wrapperRect.height + spacing;
817
+ const shouldViewReverseBottomOver = clientBottom < wrapperRect.height + spacing && restClientTop > wrapperRect.height + spacing;
818
+ const shouldViewReverseTopSide = restClientTop < wrapperRect.height && clientBottom > wrapperRect.height;
819
+ const shouldViewReverseBottomSide = clientBottom < wrapperRect.height && restClientTop > wrapperRect.height;
820
+ const shouldViewReverseLeftSide = restClientLeft < wrapperRect.width && clientRight > wrapperRect.width;
821
+ const shouldViewReverseRightSide = clientRight < wrapperRect.width && restClientLeft > wrapperRect.width;
737
822
  const shouldReverseLeftOver = restClientLeft < wrapperRect.width && clientRight > wrapperRect.width;
738
- const shouldReverseRightOver = clientRight < wrapperRect.width && restClientLeft > wrapperRect.width;
823
+ const shouldReverseRightOver = clientRight < wrapperRect.width && restClientLeft > wrapperRect.width; // 基于容器的微调判断
824
+
825
+ const clientTopInCntr = clientTop - containerRect.top;
826
+ const clientLeftInCntr = clientLeft - containerRect.left;
827
+ const clientBottomInCntr = clientTopInCntr + triggerRect.height;
828
+ const clientRightInCntr = clientLeftInCntr + triggerRect.width;
829
+ const restClientBottomInCntr = containerRect.bottom - clientBottom;
830
+ const restClientRightInCntr = containerRect.right - clientRight;
831
+ const restClientTopInCntr = restClientBottomInCntr + triggerRect.height;
832
+ const restClientLeftInCntr = restClientRightInCntr + triggerRect.width; // 当原空间不足,反向空间足够时,可以反向。
833
+
834
+ const shouldCntrReverseTop = this.isReverse(clientTopInCntr, restClientBottomInCntr, wrapperRect.height + spacing);
835
+ const shouldCntrReverseLeft = this.isReverse(clientLeftInCntr, restClientRightInCntr, wrapperRect.width + spacing);
836
+ const shouldCntrReverseBottom = this.isReverse(restClientBottomInCntr, clientTopInCntr, wrapperRect.height + spacing);
837
+ const shouldCntrReverseRight = this.isReverse(restClientRightInCntr, clientLeftInCntr, wrapperRect.width + spacing);
838
+ const shouldCntrReverseTopOver = this.isReverse(restClientTopInCntr, clientBottomInCntr, wrapperRect.height + spacing);
839
+ const shouldCntrReverseBottomOver = this.isReverse(clientBottomInCntr, restClientTopInCntr, wrapperRect.height + spacing);
840
+ const shouldCntrReverseTopSide = this.isReverse(restClientTopInCntr, clientBottomInCntr, wrapperRect.height);
841
+ const shouldCntrReverseBottomSide = this.isReverse(clientBottomInCntr, restClientTopInCntr, wrapperRect.height);
842
+ const shouldCntrReverseLeftSide = this.isReverse(restClientLeftInCntr, clientRightInCntr, wrapperRect.width);
843
+ const shouldCntrReverseRightSide = this.isReverse(clientRightInCntr, restClientLeftInCntr, wrapperRect.width);
844
+ const halfHeight = triggerRect.height / 2;
845
+ const halfWidth = triggerRect.width / 2; // 视口, 原空间与反向空间是否都不足判断
846
+
847
+ const isViewYOvf = this.isOverFlow(clientTop, restClientBottom, wrapperRect.height + spacing);
848
+ const isViewXOvf = this.isOverFlow(clientLeft, restClientRight, wrapperRect.width + spacing);
849
+ const isViewYOvfSide = this.isOverFlow(clientBottom, restClientTop, wrapperRect.height + spacing);
850
+ const isViewXOvfSide = this.isOverFlow(clientRight, restClientLeft, wrapperRect.width + spacing);
851
+ const isViewYOvfSideHalf = this.isHalfOverFlow(clientBottom - halfHeight, restClientTop - halfHeight, wrapperRect.height / 2);
852
+ const isViewXOvfSideHalf = this.isHalfOverFlow(clientRight - halfWidth, restClientLeft - halfWidth, wrapperRect.width / 2); // 容器, 原空间与反向空间是否都不足判断
853
+
854
+ const isCntrYOvf = this.isOverFlow(clientTopInCntr, restClientBottomInCntr, wrapperRect.height + spacing);
855
+ const isCntrXOvf = this.isOverFlow(clientLeftInCntr, restClientRightInCntr, wrapperRect.width + spacing);
856
+ const isCntrYOvfSide = this.isOverFlow(clientBottomInCntr, restClientTopInCntr, wrapperRect.height + spacing);
857
+ const isCntrXOvfSide = this.isOverFlow(clientRightInCntr, restClientLeftInCntr, wrapperRect.width + spacing);
858
+ const isCntrYOvfSideHalf = this.isHalfOverFlow(clientBottomInCntr - halfHeight, restClientTopInCntr - halfHeight, wrapperRect.height / 2);
859
+ const isCntrXOvfSideHalf = this.isHalfOverFlow(clientRightInCntr - halfWidth, restClientLeftInCntr - halfWidth, wrapperRect.width / 2); // 综合 viewport + container 判断微调,即视口 + 容器都放置不行时才能考虑位置调整
860
+
861
+ const shouldReverseTop = this.getReverse(isViewYOvf, isCntrYOvf, shouldViewReverseTop, shouldCntrReverseTop);
862
+ const shouldReverseLeft = this.getReverse(isViewXOvf, isCntrXOvf, shouldViewReverseLeft, shouldCntrReverseLeft);
863
+ const shouldReverseBottom = this.getReverse(isViewYOvf, isCntrYOvf, shouldViewReverseBottom, shouldCntrReverseBottom);
864
+ const shouldReverseRight = this.getReverse(isViewXOvf, isCntrXOvf, shouldViewReverseRight, shouldCntrReverseRight);
865
+ const shouldReverseTopOver = this.getReverse(isViewYOvfSide, isCntrYOvfSide, shouldViewReverseTopOver, shouldCntrReverseTopOver);
866
+ const shouldReverseBottomOver = this.getReverse(isViewYOvfSide, isCntrYOvfSide, shouldViewReverseBottomOver, shouldCntrReverseBottomOver);
867
+ const shouldReverseTopSide = this.getReverse(isViewYOvfSide, isCntrYOvfSide, shouldViewReverseTopSide, shouldCntrReverseTopSide);
868
+ const shouldReverseBottomSide = this.getReverse(isViewYOvfSide, isCntrYOvfSide, shouldViewReverseBottomSide, shouldCntrReverseBottomSide);
869
+ const shouldReverseLeftSide = this.getReverse(isViewXOvfSide, isCntrXOvfSide, shouldViewReverseLeftSide, shouldCntrReverseLeftSide);
870
+ const shouldReverseRightSide = this.getReverse(isViewXOvfSide, isCntrXOvfSide, shouldViewReverseRightSide, shouldCntrReverseRightSide);
871
+ console.log('shouldReverseBottom', shouldReverseBottom, shouldViewReverseBottom, shouldCntrReverseBottom); // 判断溢出
872
+ // 上下方向
873
+
874
+ if (this.isTB(position)) {
875
+ isHeightOverFlow = isViewYOvf && isCntrYOvf;
876
+
877
+ if (position === 'top' || position === 'bottom') {
878
+ isWidthOverFlow = isViewXOvfSideHalf && isCntrXOvfSideHalf;
879
+ } else {
880
+ isWidthOverFlow = isViewXOvfSide && isCntrXOvfSide;
881
+ }
882
+ } // 左右方向
883
+
884
+
885
+ if (this.isLR(position)) {
886
+ isWidthOverFlow = isViewXOvf && isCntrXOvf;
887
+
888
+ if (position === 'left' || position === 'right') {
889
+ isHeightOverFlow = isViewYOvfSideHalf && isCntrYOvfSideHalf;
890
+ } else {
891
+ isHeightOverFlow = isViewYOvfSide && isCntrYOvfSide;
892
+ }
893
+ }
739
894
 
740
895
  switch (position) {
741
896
  case 'top':
@@ -743,6 +898,10 @@ class Tooltip extends _foundation.default {
743
898
  position = this._reversePos(position, true);
744
899
  }
745
900
 
901
+ if (shouldReverseLeftSide || shouldReverseRightSide) {
902
+ position = this._adjustPos(position, [shouldReverseLeftSide, shouldReverseRightSide], true);
903
+ }
904
+
746
905
  break;
747
906
 
748
907
  case 'topLeft':
@@ -772,6 +931,10 @@ class Tooltip extends _foundation.default {
772
931
  position = this._reversePos(position);
773
932
  }
774
933
 
934
+ if (shouldReverseTopSide || shouldReverseBottomSide) {
935
+ position = this._adjustPos(position, [shouldReverseTopSide, shouldReverseBottomSide]);
936
+ }
937
+
775
938
  break;
776
939
 
777
940
  case 'leftTop':
@@ -801,6 +964,10 @@ class Tooltip extends _foundation.default {
801
964
  position = this._reversePos(position, true);
802
965
  }
803
966
 
967
+ if (shouldReverseLeftSide || shouldReverseRightSide) {
968
+ position = this._adjustPos(position, [shouldReverseLeftSide, shouldReverseRightSide], true);
969
+ }
970
+
804
971
  break;
805
972
 
806
973
  case 'bottomLeft':
@@ -830,6 +997,10 @@ class Tooltip extends _foundation.default {
830
997
  position = this._reversePos(position);
831
998
  }
832
999
 
1000
+ if (shouldReverseTopSide || shouldReverseBottomSide) {
1001
+ position = this._adjustPos(position, [shouldReverseTopSide, shouldReverseBottomSide]);
1002
+ }
1003
+
833
1004
  break;
834
1005
 
835
1006
  case 'rightTop':
@@ -903,7 +1074,11 @@ class Tooltip extends _foundation.default {
903
1074
  }
904
1075
  }
905
1076
 
906
- return position;
1077
+ return {
1078
+ position,
1079
+ isHeightOverFlow,
1080
+ isWidthOverFlow
1081
+ };
907
1082
  }
908
1083
 
909
1084
  _bindScrollEvent() {
@@ -28,7 +28,7 @@ export default class ModalContentFoundation extends BaseFoundation<ModalContentA
28
28
  destroy(): void;
29
29
  handleDialogMouseDown(): void;
30
30
  handleMaskMouseUp(): void;
31
- handleKeyDown(e: any): void;
31
+ handleKeyDown: (e: any) => void;
32
32
  handleKeyDownEventListenerMount(): void;
33
33
  handleKeyDownEventListenerUnmount(): void;
34
34
  getMouseState(): void;
@@ -3,6 +3,18 @@ import KeyCode from '../utils/keyCode';
3
3
  export default class ModalContentFoundation extends BaseFoundation {
4
4
  constructor(adapter) {
5
5
  super(Object.assign(Object.assign({}, ModalContentFoundation.defaultAdapter), adapter));
6
+
7
+ this.handleKeyDown = e => {
8
+ const {
9
+ closeOnEsc
10
+ } = this.getProps();
11
+
12
+ if (closeOnEsc && e.keyCode === KeyCode.ESC) {
13
+ e.stopPropagation();
14
+ this.close(e);
15
+ return;
16
+ }
17
+ };
6
18
  }
7
19
 
8
20
  destroy() {
@@ -19,18 +31,6 @@ export default class ModalContentFoundation extends BaseFoundation {
19
31
  this._adapter.notifyDialogMouseUp();
20
32
  }
21
33
 
22
- handleKeyDown(e) {
23
- const {
24
- closeOnEsc
25
- } = this.getProps();
26
-
27
- if (closeOnEsc && e.keyCode === KeyCode.ESC) {
28
- e.stopPropagation();
29
- this.close(e);
30
- return;
31
- }
32
- }
33
-
34
34
  handleKeyDownEventListenerMount() {
35
35
  this._adapter.addKeyDownEventListener();
36
36
  }
@@ -18,5 +18,6 @@ declare const numbers: {
18
18
  readonly MOUSE_ENTER_DELAY: 50;
19
19
  readonly MOUSE_LEAVE_DELAY: 50;
20
20
  readonly SPACING: 8;
21
+ readonly MARGIN: 0;
21
22
  };
22
23
  export { cssClasses, strings, numbers };
@@ -18,7 +18,7 @@ const numbers = {
18
18
  DEFAULT_Z_INDEX: 1060,
19
19
  MOUSE_ENTER_DELAY: 50,
20
20
  MOUSE_LEAVE_DELAY: 50,
21
- SPACING: 8 // Values are consistent with spacing-tight in scss
22
-
21
+ SPACING: 8,
22
+ MARGIN: 0
23
23
  };
24
24
  export { cssClasses, strings, numbers };
@@ -69,6 +69,7 @@ export default class Tooltip<P = Record<string, any>, S = Record<string, any>> e
69
69
  _bindResizeEvent(): void;
70
70
  _unBindResizeEvent(): void;
71
71
  _reversePos(position?: string, isVertical?: boolean): string;
72
+ _adjustPos(position?: string, shouldReverseArr?: boolean[], isVertical?: boolean): string;
72
73
  clearDelayTimer(): void;
73
74
  _generateEvent(types: ArrayElement<typeof strings.TRIGGER_SET>): {
74
75
  triggerEventSet: {
@@ -83,7 +84,7 @@ export default class Tooltip<P = Record<string, any>, S = Record<string, any>> e
83
84
  _togglePortalVisible(isVisible: boolean): void;
84
85
  _roundPixel(pixel: number): number;
85
86
  calcTransformOrigin(position: Position, triggerRect: DOMRect, translateX: number, translateY: number): string;
86
- calcPosStyle(triggerRect: DOMRect, wrapperRect: DOMRect, containerRect: PopupContainerDOMRect, position?: Position, spacing?: number): Record<string, string | number>;
87
+ calcPosStyle(triggerRect: DOMRect, wrapperRect: DOMRect, containerRect: PopupContainerDOMRect, position?: Position, spacing?: number, isOverFlow?: [boolean, boolean]): Record<string, string | number>;
87
88
  /**
88
89
  * 耦合的东西比较多,稍微罗列一下:
89
90
  *
@@ -100,7 +101,15 @@ export default class Tooltip<P = Record<string, any>, S = Record<string, any>> e
100
101
  calcPosition: (triggerRect?: DOMRect, wrapperRect?: DOMRect, containerRect?: PopupContainerDOMRect, shouldUpdatePos?: boolean) => Record<string, string | number>;
101
102
  isLR(position?: string): boolean;
102
103
  isTB(position?: string): boolean;
103
- adjustPosIfNeed(position: Position | string, style: Record<string, any>, triggerRect: DOMRect, wrapperRect: DOMRect, containerRect: PopupContainerDOMRect): string;
104
+ isReverse(rowSpace: number, reverseSpace: number, size: number): boolean;
105
+ isOverFlow(rowSpace: number, reverseSpace: number, size: number): boolean;
106
+ isHalfOverFlow(posSpace: number, negSpace: number, size: number): boolean;
107
+ getReverse(viewOvf: boolean, cntrOvf: boolean, shouldRevView: boolean, shouldRevCntr: boolean): boolean;
108
+ adjustPosIfNeed(position: Position | string, style: Record<string, any>, triggerRect: DOMRect, wrapperRect: DOMRect, containerRect: PopupContainerDOMRect): {
109
+ position: string;
110
+ isHeightOverFlow: boolean;
111
+ isWidthOverFlow: boolean;
112
+ };
104
113
  delayHide: () => void;
105
114
  hide: () => void;
106
115
  _bindScrollEvent(): void;