Browse Source

fix: fix tooltip animation in react18 #1225 (#1227)

Co-authored-by: shijia.me <[email protected]>
走鹃 3 years ago
parent
commit
73401f34e4
2 changed files with 23 additions and 14 deletions
  1. 14 7
      packages/semi-ui/_cssAnimation/index.tsx
  2. 9 7
      packages/semi-ui/tooltip/index.tsx

+ 14 - 7
packages/semi-ui/_cssAnimation/index.tsx

@@ -12,17 +12,18 @@ interface AnimationEventsNeedBind {
 interface AnimationProps {
     startClassName?: string;
     endClassName?: string;
-    children: ({}: {
+    children: ({ }: {
         animationClassName: string;
         animationStyle: CSSProperties;
         animationEventsNeedBind: AnimationEventsNeedBind;
         isAnimating: boolean
     }) => ReactNode;
     animationState: "enter" | "leave";
-    onAnimationEnd?: (stoppedByAnother:boolean) => void;
+    onAnimationEnd?: (stoppedByAnother: boolean) => void;
     onAnimationStart?: () => void;
     motion?: boolean;
-    replayKey?: string
+    replayKey?: string;
+    fillMode?: "backwards" | "both" | "forwards" | "none"
 }
 
 interface AnimationState {
@@ -44,7 +45,9 @@ class CSSAnimation extends React.Component<AnimationProps, AnimationState> {
 
         this.state = {
             currentClassName: this.props.startClassName,
-            extraStyle: {},
+            extraStyle: {
+                animationFillMode: this.props.fillMode,
+            },
             isAnimating: true
         };
     }
@@ -55,7 +58,7 @@ class CSSAnimation extends React.Component<AnimationProps, AnimationState> {
         // In order to make the component side do not need to manually call the next life cycle function when there is no animation,
         // so when there is no animation , it is logically (and only logically) regarded as an animation with a duration of 0.
         this.props.onAnimationStart?.();
-        if (!this.props.motion){
+        if (!this.props.motion) {
             this.props.onAnimationEnd?.(false);
             this.setState({ isAnimating: false });
         }
@@ -69,7 +72,9 @@ class CSSAnimation extends React.Component<AnimationProps, AnimationState> {
         if (changedKeys.includes("startClassName") || changedKeys.includes('replayKey') || changedKeys.includes("motion")) {
             this.setState({
                 currentClassName: this.props.startClassName,
-                extraStyle: {},
+                extraStyle: {
+                    animationFillMode: this.props.fillMode,
+                },
                 isAnimating: true
             }, () => {
                 this.props.onAnimationStart?.();
@@ -91,7 +96,9 @@ class CSSAnimation extends React.Component<AnimationProps, AnimationState> {
     handleAnimationEnd = () => {
         this.setState({
             currentClassName: this.props.endClassName,
-            extraStyle: {},
+            extraStyle: {
+                animationFillMode: this.props.fillMode,
+            },
             isAnimating: false
         }, () => {
             this.props.onAnimationEnd?.(false);

+ 9 - 7
packages/semi-ui/tooltip/index.tsx

@@ -77,7 +77,7 @@ export interface TooltipProps extends BaseProps {
     wrapperId?: string;
     preventScroll?: boolean;
     disableFocusListener?: boolean;
-    afterClose?:()=>void
+    afterClose?: () => void
 }
 interface TooltipState {
     visible: boolean;
@@ -563,22 +563,24 @@ export default class Tooltip extends BaseComponent<TooltipProps, TooltipState> {
         const portalInnerStyle = omit(containerStyle, motion ? ['transformOrigin'] : undefined);
         const transformOrigin = get(containerStyle, 'transformOrigin');
         const inner =
-            <CSSAnimation animationState={transitionState as "enter"|"leave"}
+            <CSSAnimation
+                fillMode="forwards"
+                animationState={transitionState as "enter" | "leave"}
                 motion={motion && isPositionUpdated}
-                startClassName={transitionState==='enter'?`${prefix}-animation-show`:`${prefix}-animation-hide`}
-                onAnimationEnd={()=>{
-                    if (transitionState === 'leave'){
+                startClassName={transitionState === 'enter' ? `${prefix}-animation-show` : `${prefix}-animation-hide`}
+                onAnimationEnd={() => {
+                    if (transitionState === 'leave') {
                         this.didLeave();
                         this.props.afterClose?.();
                     }
                 }}>
                 {
-                    ({ animationStyle, animationClassName, animationEventsNeedBind })=>{
+                    ({ animationStyle, animationClassName, animationEventsNeedBind }) => {
                         return <div
 
                             className={classNames(className, animationClassName)}
                             style={{
-                                opacity: isPositionUpdated?'1':"0",
+                                opacity: isPositionUpdated ? '1' : "0",
                                 ...animationStyle,
                                 transformOrigin,
                                 ...style,