DaiQiangReal 3 lat temu
rodzic
commit
c22ff2a9a6

+ 10 - 3
packages/semi-foundation/modal/modalFoundation.ts

@@ -13,6 +13,7 @@ export interface ModalAdapter extends DefaultAdapter<ModalProps, ModalState> {
     toggleHidden: (hidden: boolean, callback?: (hidden: boolean) => void) => void;
     notifyFullScreen: (isFullScreen: boolean) => void;
     getProps: () => ModalProps;
+    setShouldRender:(shouldRender:boolean)=>void;
 }
 
 export interface ModalProps {
@@ -60,6 +61,7 @@ export interface ModalProps {
 export interface ModalState {
     hidden: boolean;
     isFullScreen: boolean;
+    shouldRender:boolean
 }
 
 export default class ModalFoundation extends BaseFoundation<ModalAdapter> {
@@ -88,17 +90,22 @@ export default class ModalFoundation extends BaseFoundation<ModalAdapter> {
 
     afterHide() {
         this._adapter.enabledBodyScroll();
-    }
-
-    afterClose() {
         this._adapter.notifyClose();
     }
 
+    // afterClose() {
+    //     this._adapter.notifyClose();
+    // }
+
 
     toggleHidden = (hidden: boolean, callback?: (hidden: boolean) => void) => {
         this._adapter.toggleHidden(hidden, callback);
     };
 
+    setShouldRender=(shouldRender)=>{
+        this._adapter.setShouldRender(shouldRender);
+    }
+
     // // eslint-disable-next-line max-len
     // mergeMotionProp = (motion: Motion, prop: string, cb: () => void) => {
     //     const mergedMotion = typeof (motion) === 'undefined' || motion ? {

+ 2 - 0
packages/semi-ui/_cssAnimation/index.tsx

@@ -20,6 +20,7 @@ interface AnimationProps {
     animationState: "enter" | "leave"
     onAnimationEnd?: () => void;
     onAnimationStart?: () => void;
+    motion?:boolean;
 }
 
 interface AnimationState {
@@ -31,6 +32,7 @@ interface AnimationState {
 class CSSAnimation extends React.Component<AnimationProps, AnimationState> {
     constructor(props) {
         super(props);
+        
         this.state = {
             currentClassName: this.props.startClassName,
             extraStyle: {}

+ 43 - 22
packages/semi-ui/modal/Modal.tsx

@@ -17,6 +17,7 @@ import useModal from './useModal';
 import { ButtonProps } from '../button/Button';
 import { MotionObject } from "@douyinfe/semi-foundation/utils/type";
 import CSSAnimation from "@douyinfe/semi-ui/_cssAnimation";
+import { SideSheetReactProps } from "@douyinfe/semi-ui/sideSheet";
 
 export const destroyFns: any[] = [];
 export type ConfirmType = 'leftTop' | 'leftBottom' | 'rightTop' | 'rightBottom';
@@ -115,19 +116,21 @@ class Modal extends BaseComponent<ModalReactProps, ModalState> {
     private bodyOverflow: string;
     private scrollBarWidth: number;
     private originBodyWith: string;
-    private _active: boolean;
+    private _haveRendered: boolean;
 
     constructor(props: ModalReactProps) {
         super(props);
         this.state = {
             hidden: !props.visible,
             isFullScreen: props.fullScreen,
+            shouldRender:this.props.visible || (this.props.keepDOM && !this.props.lazyRender)
         };
         this.foundation = new ModalFoundation(this.adapter);
         this.modalRef = React.createRef();
         this.bodyOverflow = '';
         this.scrollBarWidth = 0;
         this.originBodyWith = '100%';
+
     }
 
     get adapter(): ModalAdapter {
@@ -169,6 +172,11 @@ class Modal extends BaseComponent<ModalReactProps, ModalState> {
                     this.setState({ isFullScreen });
                 }
             },
+            setShouldRender:(shouldRender)=>{
+                if (shouldRender!==this.state.shouldRender){
+                    this.setState({ shouldRender });
+                }
+            }
         };
     }
 
@@ -180,6 +188,15 @@ class Modal extends BaseComponent<ModalReactProps, ModalState> {
         }
 
 
+        if (props.visible && prevState.hidden) {
+            newState.hidden = false;
+        }
+
+        if (!props.visible && !props.motion && !prevState.hidden) {
+            newState.hidden = true;
+        }
+
+
         return newState;
     }
 
@@ -231,6 +248,7 @@ class Modal extends BaseComponent<ModalReactProps, ModalState> {
         }
     }
 
+
     componentDidUpdate(prevProps: ModalReactProps, prevState: ModalState, snapshot: any) {
         // hide => show
         if (!prevProps.visible && this.props.visible) {
@@ -241,8 +259,13 @@ class Modal extends BaseComponent<ModalReactProps, ModalState> {
             this.foundation.afterHide();
         }
 
+        const shouldRender = this.props.visible || (this.props.keepDOM && (!this.props.lazyRender || this._haveRendered));
+        if (shouldRender === true && this.state.shouldRender === false) {
+            this.foundation.setShouldRender(true);
+        }
+
         if (!this.props.motion) {
-            this.updateHiddenState();
+            this.updateState();
         }
     }
 
@@ -260,14 +283,15 @@ class Modal extends BaseComponent<ModalReactProps, ModalState> {
         this.foundation.handleOk(e);
     };
 
-    updateHiddenState = () => {
+    updateState = () => {
         const { visible } = this.props;
-        const { hidden } = this.state;
-        if (!visible && !hidden) {
-            this.foundation.toggleHidden(true, () => this.foundation.afterClose());
-        } else if (visible && this.state.hidden) {
-            this.foundation.toggleHidden(false);
+        if (!visible) {
+            this.foundation.toggleHidden(!visible);
+        } else if (visible) {
+            this.foundation.toggleHidden(!visible);
         }
+        const shouldRender = this.props.visible || (this.props.keepDOM && (!this.props.lazyRender || this._haveRendered));
+        this.foundation.setShouldRender(shouldRender);
     };
 
     renderFooter = (): ReactNode => {
@@ -360,14 +384,15 @@ class Modal extends BaseComponent<ModalReactProps, ModalState> {
         }
 
         const classList = cls(className, {
-            [`${cssClasses.DIALOG}-displayNone`]: keepDOM && this.state.hidden && !visible,
+            [`${cssClasses.DIALOG}-displayNone`]: keepDOM && this.state.hidden,
         });
         const maskClassName = motion ? cls({
             [`${cssClasses.DIALOG}-mask-animate-hide`]: !visible,
             [`${cssClasses.DIALOG}-mask-animate-show`]: visible
         }) : null;
 
-        if (!motion){
+        if (!motion && this.state.shouldRender){
+            this._haveRendered = true;
             return <ModalContent
                 {...restProps}
                 isFullScreen={this.state.isFullScreen}
@@ -382,13 +407,15 @@ class Modal extends BaseComponent<ModalReactProps, ModalState> {
 
             />;
         }
-
+        if (this.state.shouldRender){
+            this._haveRendered = true;
+        }
         return (
             <Portal style={wrapperStyle} getPopupContainer={getPopupContainer}>
                 <CSSAnimation animationState={visible?'enter':'leave'}
                     startClassName={visible?`${cssClasses.DIALOG}-content-animate-show`:`${cssClasses.DIALOG}-content-animate-hide`}
                     onAnimationEnd={()=>{
-                        this.updateHiddenState();
+                        this.updateState();
                     }}
                 >
                     {
@@ -396,12 +423,12 @@ class Modal extends BaseComponent<ModalReactProps, ModalState> {
                             return <CSSAnimation animationState={visible?'enter':'leave'}
                                 startClassName={visible?`${cssClasses.DIALOG}-mask-animate-show`:`${cssClasses.DIALOG}-mask-animate-hide`}
                                 onAnimationEnd={()=>{
-                                    this.updateHiddenState();
+                                    this.updateState();
                                 }}
                             >
                                 {
                                     ({ animationClassName:maskAnimationClassName, animationEventsNeedBind:maskAnimationEventsNeedBind })=>{
-                                        return <ModalContent
+                                        return this.state.shouldRender ? <ModalContent
                                             {...restProps}
                                             contentExtraProps={animationEventsNeedBind}
                                             maskExtraProps={maskAnimationEventsNeedBind}
@@ -416,7 +443,7 @@ class Modal extends BaseComponent<ModalReactProps, ModalState> {
                                             footer={renderFooter}
                                             onClose={this.handleCancel}
 
-                                        />;
+                                        />:<></>;
                                     }
                                 }
                             </CSSAnimation>;
@@ -433,13 +460,7 @@ class Modal extends BaseComponent<ModalReactProps, ModalState> {
             keepDOM,
             lazyRender,
         } = this.props;
-        this._active = this._active || visible;
-        const shouldRender = ((visible || keepDOM) && (!lazyRender || this._active)) || !this.state.hidden;
-        if (shouldRender) {
-            return this.renderDialog();
-        }
-
-        return null;
+        return this.renderDialog();
     }
 
 

+ 1 - 0
packages/semi-ui/sideSheet/index.tsx

@@ -172,6 +172,7 @@ export default class SideSheet extends BaseComponent<SideSheetReactProps, SideSh
         if (shouldRender === true && this.state.shouldRender === false) {
             this.foundation.setShouldRender(true);
         }
+
         if (prevState.hidden!==this.state.hidden){
             this.foundation.onVisibleChange(!this.state.hidden);
         }