1- import React , { useState , useMemo , useRef } from 'react' ;
1+ import React , { useState , useMemo , useRef , useEffect } from 'react' ;
22import { Animated , StyleSheet , LayoutChangeEvent , Dimensions , ViewStyle } from 'react-native' ;
33import MaskLayer , { MaskLayerProps } from '../MaskLayer' ;
44import { Theme } from '../theme' ;
55import { useTheme } from '@shopify/restyle' ;
66
7- let MainWidth = Dimensions . get ( 'window' ) . width ;
8- let MainHeight = Dimensions . get ( 'window' ) . height ;
7+ const MainWidth = Dimensions . get ( 'window' ) . width ;
8+ const MainHeight = Dimensions . get ( 'window' ) . height ;
99
1010export interface ModalProps extends MaskLayerProps {
1111 placement ?: 'top' | 'right' | 'bottom' | 'left' ;
@@ -16,27 +16,14 @@ export interface ModalProps extends MaskLayerProps {
1616const Modal = ( props : ModalProps = { } ) => {
1717 const { onClosed, visible, children, placement = 'bottom' , containerStyle, ...otherProps } = props ;
1818 const theme = useTheme < Theme > ( ) ;
19- const AnimatedOpacity : Animated . Value = useRef ( new Animated . Value ( 0 ) ) . current ;
20- // const [display] = useState<'none' | 'flex'>('none');
21- let [ layoutHeight , setLayoutHeight ] = useState ( 0 ) ;
22- let [ layoutWidth , setLayoutWidth ] = useState ( 0 ) ;
19+ const AnimatedOpacity = useRef ( new Animated . Value ( 0 ) ) . current ;
20+ const [ layoutHeight , setLayoutHeight ] = useState ( 0 ) ;
21+ const [ layoutWidth , setLayoutWidth ] = useState ( 0 ) ;
2322 const [ translateValue ] = useState ( new Animated . Value ( 0 ) ) ;
2423 const isVertical = / ^ ( t o p | b o t t o m ) $ / . test ( placement ) ;
2524 const isHorizontal = / ^ ( l e f t | r i g h t ) $ / . test ( placement ) ;
26- function onDismiss ( ) {
27- onClosed && onClosed ( ) ;
28- }
29- function measureContainer ( event : LayoutChangeEvent ) {
30- const { height, width } = event . nativeEvent . layout ;
31- if ( ! layoutHeight && isVertical ) {
32- setLayoutHeight ( height ) ;
33- }
34- if ( ! layoutWidth && isHorizontal ) {
35- setLayoutWidth ( width ) ;
36- }
37- }
3825
39- useMemo ( ( ) => {
26+ useEffect ( ( ) => {
4027 function getTransformSize ( ) {
4128 if ( placement === 'top' ) {
4229 return - layoutHeight ;
@@ -56,20 +43,18 @@ const Modal = (props: ModalProps = {}) => {
5643 if ( ! result ) return ;
5744 if ( visible ) {
5845 translateValue . setValue ( result ) ;
59- // AnimatedOpacity
60- Animated . timing ( AnimatedOpacity , {
61- toValue : 1 ,
62- duration : 0 ,
63- useNativeDriver : false ,
64- } ) . start ( ( { finished } ) => {
65- Animated . parallel ( [
66- Animated . spring ( translateValue , {
67- toValue : 0 ,
68- overshootClamping : true ,
69- useNativeDriver : true ,
70- } ) ,
71- ] ) . start ( ) ;
72- } ) ;
46+ Animated . parallel ( [
47+ Animated . timing ( AnimatedOpacity , {
48+ toValue : 1 ,
49+ duration : 0 ,
50+ useNativeDriver : false ,
51+ } ) ,
52+ Animated . spring ( translateValue , {
53+ toValue : 0 ,
54+ overshootClamping : true ,
55+ useNativeDriver : true ,
56+ } ) ,
57+ ] ) . start ( ) ;
7358 }
7459 if ( ! visible ) {
7560 Animated . parallel ( [
@@ -78,10 +63,15 @@ const Modal = (props: ModalProps = {}) => {
7863 overshootClamping : true ,
7964 useNativeDriver : true ,
8065 } ) ,
66+ Animated . timing ( AnimatedOpacity , {
67+ toValue : 0 ,
68+ duration : 0 ,
69+ useNativeDriver : false ,
70+ } ) ,
8171 ] ) . start ( ) ;
8272 }
83- // eslint-disable-next-line react-hooks/exhaustive-deps
84- } , [ visible , layoutHeight , layoutWidth ] ) ;
73+ } , [ visible , layoutHeight , layoutWidth , placement , translateValue , AnimatedOpacity ] ) ;
74+
8575 const translateStyle = { } as {
8676 translateY : Animated . Value ;
8777 translateX : Animated . Value ;
@@ -92,19 +82,25 @@ const Modal = (props: ModalProps = {}) => {
9282 if ( isHorizontal ) {
9383 translateStyle . translateX = translateValue ;
9484 }
95- const child = React . useMemo (
85+
86+ const child = useMemo (
9687 ( ) => (
9788 < Animated . View
9889 style = { [ styles . content , placement && styles [ placement ] , { opacity : AnimatedOpacity } , containerStyle ] }
9990 >
10091 < Animated . View
101- onLayout = { measureContainer }
92+ onLayout = { ( event : LayoutChangeEvent ) => {
93+ const { height, width } = event . nativeEvent . layout ;
94+ if ( ! layoutHeight && isVertical ) {
95+ setLayoutHeight ( height ) ;
96+ }
97+ if ( ! layoutWidth && isHorizontal ) {
98+ setLayoutWidth ( width ) ;
99+ }
100+ } }
102101 style = { [
103102 styles . content ,
104103 placement && styles [ placement ] ,
105- // !layoutHeight && isVertical ? { display: display } : {},
106- // !layoutWidth && isHorizontal ? { display: display } : {},
107- // // getTransformStyle(),
108104 {
109105 transform : [ translateStyle ] ,
110106 backgroundColor : theme . colors . mask || '#fff' ,
@@ -117,10 +113,22 @@ const Modal = (props: ModalProps = {}) => {
117113 </ Animated . View >
118114 </ Animated . View >
119115 ) ,
120- [ children ] ,
116+ [
117+ children ,
118+ AnimatedOpacity ,
119+ containerStyle ,
120+ isHorizontal ,
121+ isVertical ,
122+ layoutHeight ,
123+ layoutWidth ,
124+ placement ,
125+ theme . colors . mask ,
126+ translateStyle ,
127+ ] ,
121128 ) ;
129+
122130 return (
123- < MaskLayer { ...otherProps } visible = { visible } onDismiss = { onDismiss } >
131+ < MaskLayer { ...otherProps } visible = { visible } onDismiss = { onClosed } >
124132 { child }
125133 </ MaskLayer >
126134 ) ;
0 commit comments