Browse Source

Merge pull request #2461 from DouyinFE/fix_tooltip_quick_move

Fix tooltip quick move
代强 1 year ago
parent
commit
5e6c8f961b

+ 1 - 0
.eslintrc.js

@@ -62,6 +62,7 @@ module.exports = {
             plugins: ['react', 'jest', 'react-hooks', 'import', '@typescript-eslint', 'semi-design'],
             rules: {
                 // 因为历史原因,现有项目基本全部是4个空格
+                "arrow-spacing": ["error", { "before": true, "after": true }],
                 indent: 'off',
                 'comma-spacing': ["error", {"before": false, "after": true}],
                 'no-multi-spaces': ["error", {ignoreEOLComments: true}],

+ 18 - 14
packages/semi-foundation/tooltip/foundation.ts

@@ -67,7 +67,8 @@ export interface TooltipAdapter<P = Record<string, any>, S = Record<string, any>
     notifyEscKeydown(event: any): void;
     getTriggerNode(): any;
     setId(): void;
-    getTriggerDOM(): HTMLElement|null
+    getTriggerDOM(): HTMLElement|null;
+    getAnimatingState(): boolean
 }
 
 export type Position = ArrayElement<typeof strings.POSITION_SET>;
@@ -180,7 +181,7 @@ export default class Tooltip<P = Record<string, any>, S = Record<string, any>> e
     _reducePos(position = '') {
         // if cur position consists of two directions, remove the last position
         const found = ['Top', 'Bottom', 'Left', 'Right'].find(pos => position.endsWith(pos));
-        return found ? position.replace(found, ''): position;
+        return found ? position.replace(found, '') : position;
     }
 
     clearDelayTimer() {
@@ -311,6 +312,9 @@ export default class Tooltip<P = Record<string, any>, S = Record<string, any>> e
     };
 
     show = () => {
+        if (this._adapter.getAnimatingState()) {
+            return;
+        }
         const content = this.getProp('content');
         const trigger = this.getProp('trigger');
 
@@ -334,7 +338,7 @@ export default class Tooltip<P = Record<string, any>, S = Record<string, any>> e
             this.calcPosition();
         });
 
-        if (trigger==="hover") {
+        if (trigger === "hover") {
             const checkTriggerIsHover = () => {
                 const triggerDOM = this._adapter.getTriggerDOM();
                 if (trigger && !triggerDOM?.matches?.(":hover")) {
@@ -474,13 +478,13 @@ export default class Tooltip<P = Record<string, any>, S = Record<string, any>> e
         const isWrapperWidthOverflow = wrapperRect.width > innerWidth;
         const scaled = Math.abs(wrapperRect?.width - this._adapter.getContainer()?.clientWidth) > 1;
         if (scaled) {
-            SPACING = SPACING * wrapperRect.width/this._adapter.getContainer().clientWidth;
+            SPACING = SPACING * wrapperRect.width / this._adapter.getContainer().clientWidth;
         }
         switch (position) {
             case 'top':
                 // left = middleX;
                 // top = triggerRect.top - SPACING;
-                left = isWidthOverFlow ? (isTriggerNearLeft ? containerRect.left + wrapperRect.width / 2 : containerRect.right - wrapperRect.width / 2 + offsetWidth): middleX + ANO_SPACING;
+                left = isWidthOverFlow ? (isTriggerNearLeft ? containerRect.left + wrapperRect.width / 2 : containerRect.right - wrapperRect.width / 2 + offsetWidth) : middleX + ANO_SPACING;
                 top = isHeightOverFlow ? containerRect.bottom + offsetHeight : triggerRect.top - SPACING;
                 translateX = -0.5;
                 translateY = -1;
@@ -505,7 +509,7 @@ export default class Tooltip<P = Record<string, any>, S = Record<string, any>> e
                 // top = middleY;
                 // left = isWidthOverFlow? containerRect.right - SPACING : triggerRect.left - SPACING;
                 left = isWidthOverFlow ? containerRect.right + offsetWidth - SPACING + offsetXWithArrow : triggerRect.left - SPACING;
-                top = isHeightOverFlow ? (isTriggerNearTop ? containerRect.top + wrapperRect.height / 2 : containerRect.bottom - wrapperRect.height / 2 + offsetHeight): middleY + ANO_SPACING;
+                top = isHeightOverFlow ? (isTriggerNearTop ? containerRect.top + wrapperRect.height / 2 : containerRect.bottom - wrapperRect.height / 2 + offsetHeight) : middleY + ANO_SPACING;
                 translateX = -1;
                 translateY = -0.5;
                 break;
@@ -519,22 +523,22 @@ export default class Tooltip<P = Record<string, any>, S = Record<string, any>> e
             case 'leftBottom':
                 // left = triggerRect.left - SPACING;
                 // top = pointAtCenter ? middleY + offsetYWithArrow : triggerRect.bottom;
-                left = isWidthOverFlow ? containerRect.right + offsetWidth - SPACING + offsetXWithArrow: triggerRect.left - SPACING;
-                top = isHeightOverFlow ? containerRect.bottom + offsetHeight: (pointAtCenter ? middleY + offsetYWithArrow + ANO_SPACING : triggerRect.bottom + ANO_SPACING);
+                left = isWidthOverFlow ? containerRect.right + offsetWidth - SPACING + offsetXWithArrow : triggerRect.left - SPACING;
+                top = isHeightOverFlow ? containerRect.bottom + offsetHeight : (pointAtCenter ? middleY + offsetYWithArrow + ANO_SPACING : triggerRect.bottom + ANO_SPACING);
                 translateX = -1;
                 translateY = -1;
                 break;
             case 'bottom':
                 // left = middleX;
                 // top = triggerRect.top + triggerRect.height + SPACING;
-                left = isWidthOverFlow ? (isTriggerNearLeft ? containerRect.left + wrapperRect.width / 2 : containerRect.right - wrapperRect.width / 2 + offsetWidth): middleX + ANO_SPACING;
-                top = isHeightOverFlow ? containerRect.top + offsetYWithArrow - SPACING: triggerRect.top + triggerRect.height + SPACING;
+                left = isWidthOverFlow ? (isTriggerNearLeft ? containerRect.left + wrapperRect.width / 2 : containerRect.right - wrapperRect.width / 2 + offsetWidth) : middleX + ANO_SPACING;
+                top = isHeightOverFlow ? containerRect.top + offsetYWithArrow - SPACING : triggerRect.top + triggerRect.height + SPACING;
                 translateX = -0.5;
                 break;
             case 'bottomLeft':
                 // left = pointAtCenter ? middleX - offsetXWithArrow : triggerRect.left;
                 // top = triggerRect.bottom + SPACING;
-                left = isWidthOverFlow ? (isWrapperWidthOverflow ? containerRect.left : containerRect.right - wrapperRect.width ) : (pointAtCenter ? middleX - offsetXWithArrow + ANO_SPACING: triggerRect.left + ANO_SPACING);
+                left = isWidthOverFlow ? (isWrapperWidthOverflow ? containerRect.left : containerRect.right - wrapperRect.width ) : (pointAtCenter ? middleX - offsetXWithArrow + ANO_SPACING : triggerRect.left + ANO_SPACING);
                 top = isHeightOverFlow ? containerRect.top + offsetYWithArrow - SPACING : triggerRect.top + triggerRect.height + SPACING;
                 break;
             case 'bottomRight':
@@ -596,11 +600,11 @@ export default class Tooltip<P = Record<string, any>, S = Record<string, any>> e
         top = top - containerRect.top;
 
         if (scaled) {
-            left /= wrapperRect.width/this._adapter.getContainer().clientWidth;
+            left /= wrapperRect.width / this._adapter.getContainer().clientWidth;
         }
 
         if (scaled) {
-            top /= wrapperRect.height/this._adapter.getContainer().clientHeight;
+            top /= wrapperRect.height / this._adapter.getContainer().clientHeight;
         }
 
         /**
@@ -820,7 +824,7 @@ export default class Tooltip<P = Record<string, any>, S = Record<string, any>> e
             const shouldViewReverseLeft = clientLeft - marginLeft < wrapperRect.width + spacing && restClientRight - marginRight > wrapperRect.width + spacing;
             const shouldViewReverseBottom = restClientBottom - marginBottom < wrapperRect.height + spacing && clientTop - marginTop > wrapperRect.height + spacing;
             const shouldViewReverseRight = restClientRight - marginRight < wrapperRect.width + spacing && clientLeft - marginLeft > wrapperRect.width + spacing;
-            const shouldViewReverseTopOver = restClientTop - marginBottom< wrapperRect.height + spacing && clientBottom - marginTop> wrapperRect.height + spacing;
+            const shouldViewReverseTopOver = restClientTop - marginBottom < wrapperRect.height + spacing && clientBottom - marginTop > wrapperRect.height + spacing;
             const shouldViewReverseBottomOver = clientBottom - marginTop < wrapperRect.height + spacing && restClientTop - marginBottom > wrapperRect.height + spacing;
 
             const shouldViewReverseTopSide = restClientTop < wrapperRect.height + ano_spacing && clientBottom > wrapperRect.height + ano_spacing;

+ 2 - 2
packages/semi-ui/tooltip/__test__/tooltip.test.js

@@ -295,14 +295,14 @@ describe(`Tooltip`, () => {
     });
 
   it(`test click outside handler`, async () => {
-    const containerId = `container`;
-
+    const containerId = `container`
     const demo = mount(
       <div style={{ height: 480, width: 320 }}>
         <div id={containerId}>Hello Semi</div>
         <Tooltip
           content='Content'
           trigger='click'
+          motion={false}
         >
           <Button >Click here</Button>
         </Tooltip>

+ 6 - 3
packages/semi-ui/tooltip/index.tsx

@@ -198,7 +198,7 @@ export default class Tooltip extends BaseComponent<TooltipProps, TooltipState> {
     containerPosition: string;
     foundation: TooltipFoundation;
     context: ContextValue;
-
+    isAnimating: boolean = false;
     constructor(props: TooltipProps) {
         super(props);
         this.state = {
@@ -240,6 +240,7 @@ export default class Tooltip extends BaseComponent<TooltipProps, TooltipState> {
             on: (...args: any[]) => this.eventManager.on(...args),
             // @ts-ignore
             off: (...args: any[]) => this.eventManager.off(...args),
+            getAnimatingState: () => this.isAnimating,
             insertPortal: (content: TooltipProps['content'], { position, ...containerStyle }: { position: Position }) => {
                 this.setState(
                     {
@@ -458,7 +459,7 @@ export default class Tooltip extends BaseComponent<TooltipProps, TooltipState> {
             setId: () => {
                 this.setState({ id: getUuidShort() });
             },
-            getTriggerDOM: ()=>{
+            getTriggerDOM: () => {
                 if (this.triggerEl.current) {
                     return ReactDOM.findDOMNode(this.triggerEl.current as ReactInstance) as HTMLElement;
                 } else {
@@ -473,7 +474,7 @@ export default class Tooltip extends BaseComponent<TooltipProps, TooltipState> {
         this.mounted = true;
         this.getPopupContainer = this.props.getPopupContainer || this.context.getPopupContainer || defaultGetContainer;
         this.foundation.init();
-        runAfterTicks(()=>{
+        runAfterTicks(() => {
             let triggerEle = this.triggerEl.current;
             if (triggerEle) {
                 if (!(triggerEle instanceof HTMLElement)) {
@@ -652,8 +653,10 @@ export default class Tooltip extends BaseComponent<TooltipProps, TooltipState> {
                 animationState={transitionState as "enter" | "leave"}
                 motion={motion && isPositionUpdated}
                 startClassName={transitionState === 'enter' ? `${prefix}-animation-show` : `${prefix}-animation-hide`}
+                onAnimationStart={() => this.isAnimating = true}
                 onAnimationEnd={() => {
                     if (transitionState === 'leave') {
+                        this.isAnimating = false;
                         this.didLeave();
                         this.props.afterClose?.();
                     }

+ 20 - 0
syncRegistry.sh

@@ -0,0 +1,20 @@
+#!/bin/bash
+
+## 提示用户输入URL
+read -p "请输入同步的源(例如: registry.npmjs.org): " url
+#
+## 使用python -m webbrowser访问输入的URL
+python -m webbrowser https://$url/sync/@douyinfe/semi-ui
+python -m webbrowser https://$url/sync/@douyinfe/semi-foundation
+python -m webbrowser https://$url/sync/@douyinfe/semi-animation
+python -m webbrowser https://$url/sync/@douyinfe/semi-animation-react
+python -m webbrowser https://$url/sync/@douyinfe/semi-animation-styled
+python -m webbrowser https://$url/sync/@douyinfe/semi-icons
+python -m webbrowser https://$url/sync/@douyinfe/semi-icons-lab
+python -m webbrowser https://$url/sync/@douyinfe/semi-illustrations
+python -m webbrowser https://$url/sync/@douyinfe/semi-next
+python -m webbrowser https://$url/sync/@douyinfe/semi-rspack-plugin
+python -m webbrowser https://$url/sync/@douyinfe/semi-scss-compile
+python -m webbrowser https://$url/sync/@douyinfe/semi-theme-default
+python -m webbrowser https://$url/sync/@douyinfe/semi-webpack-plugin
+