diff --git a/example/storybook/stories/components/composites/Transitions/SlideWrapped.tsx b/example/storybook/stories/components/composites/Transitions/SlideWrapped.tsx index 110bd50c8..486dce825 100644 --- a/example/storybook/stories/components/composites/Transitions/SlideWrapped.tsx +++ b/example/storybook/stories/components/composites/Transitions/SlideWrapped.tsx @@ -19,6 +19,7 @@ export const Example = () => { h="100%" // alignItems="flex-start" justifyContent="center" + // overflow={'hidden'} > diff --git a/src/components/composites/Actionsheet/ActionsheetContent.tsx b/src/components/composites/Actionsheet/ActionsheetContent.tsx index 0449a7a91..e6e8fd78d 100644 --- a/src/components/composites/Actionsheet/ActionsheetContent.tsx +++ b/src/components/composites/Actionsheet/ActionsheetContent.tsx @@ -16,11 +16,20 @@ const ActionsheetContent = ( 'ActionsheetContent', props ); + + // useEffect(() => { + // console.log('action sheet content'); + // }, []); + + // return null; const { handleClose } = React.useContext(ModalContext); const { hideDragIndicator } = React.useContext(ActionSheetContext); const pan = React.useRef(new Animated.ValueXY()).current; const sheetHeight = React.useRef(0); + // useEffect(() => { + + // }, []) const panResponder = React.useRef( PanResponder.create({ onStartShouldSetPanResponder: () => true, @@ -42,6 +51,14 @@ const ActionsheetContent = ( duration: 150, useNativeDriver: true, }).start(handleClose); + + setTimeout(() => { + Animated.spring(pan, { + toValue: { x: 0, y: 0 }, + overshootClamping: true, + useNativeDriver: true, + }).start(); + }); } else { Animated.spring(pan, { toValue: { x: 0, y: 0 }, @@ -56,6 +73,8 @@ const ActionsheetContent = ( if (useHasResponsiveProps(props)) { return null; } + + // console.log('action sheet render '); return ( { - const [animationExited, setAnimationExited] = React.useState(!visible); + // const [animationExited, setAnimationExited] = React.useState(!visible); const { setExited } = React.useContext(ExitAnimationContext); //TODO: refactor for responsive prop @@ -16,19 +16,17 @@ const PresenceTransition = ( return null; } - if (!visible && animationExited) { - return null; - } + // if (!visible && animationExited) { + // return null; + // } return ( { if (state === 'exited') { - setAnimationExited(true); setExited(true); } else { - setAnimationExited(false); setExited(false); } onTransitionComplete && onTransitionComplete(state); diff --git a/src/components/composites/Transitions/Transition.tsx b/src/components/composites/Transitions/Transition.tsx index d6df57f8a..796f9f18a 100644 --- a/src/components/composites/Transitions/Transition.tsx +++ b/src/components/composites/Transitions/Transition.tsx @@ -1,6 +1,6 @@ +/* eslint-disable react-hooks/exhaustive-deps */ import React, { forwardRef } from 'react'; import { Animated } from 'react-native'; -import { useHasResponsiveProps } from '../../../hooks/useHasResponsiveProps'; import type { ISupportedTransitions, ITransitionConfig, @@ -80,6 +80,7 @@ export const Transition = forwardRef( ) => { const animateValue = React.useRef(new Animated.Value(0)).current; + const [displayState, setDisplayState] = React.useState('flex'); const Component = React.useMemo(() => { if (as) { return Animated.createAnimatedComponent(as); @@ -87,112 +88,139 @@ export const Transition = forwardRef( return Animated.View; }, [as]); - const [animationState, setAnimationState] = React.useState( - visible ? 'entering' : 'exited' - ); + const [animationState, setAnimationState] = React.useState(''); const prevVisible = React.useRef(visible); - React.useEffect( - function startEntryTransition() { + // React.useEffect(() => { + + // }, [visible]); + + React.useEffect(() => { + if (animationState === 'entering' || animationState === 'exiting') { + // setDisplayState('flex'); + + // if (animationState === 'entering') { + // setTimeout(() => { + setDisplayState('flex'); + // }); + // return; + // } + + // setTimeout(() => { const entryTransition = { ...defaultTransitionConfig, ...animate?.transition, }; + const exitTransition = { + ...defaultTransitionConfig, + ...exit?.transition, + }; - if (visible) { - Animated.sequence([ - // @ts-ignore - delay is present in defaultTransitionConfig - Animated.delay(entryTransition.delay), - Animated[entryTransition.type ?? 'timing'](animateValue, { - toValue: 1, - useNativeDriver: true, - ...entryTransition, - }), - ]).start(() => { + const startAnimation = animationState === 'entering' ? 1 : 0; + + const transition = startAnimation ? entryTransition : exitTransition; + + // console.log( + // 'Transition state', + // transition, + // animationState, + // defaultTransitionConfig + // ); + Animated.sequence([ + // @ts-ignore - delay is present in defaultTransitionConfig + Animated.delay(transition.delay), + Animated[transition.type ?? 'timing'](animateValue, { + toValue: startAnimation, + useNativeDriver: true, + ...transition, + }), + ]).start(() => { + if (animationState === 'entering') { setAnimationState('entered'); - }); - } - }, - [visible, onTransitionComplete, animateValue, animate] - ); + } else if (animationState === 'exiting') { + setAnimationState('exited'); + setTimeout(() => { + setDisplayState('none'); + }); + } + }); + // }); + } + + if (animationState === 'exited') { + onTransitionComplete && onTransitionComplete('exited'); + // setDisplayState('none'); + + // setInitialState({ ...exit }); + } else if (animationState === 'entered') { + onTransitionComplete && onTransitionComplete('entered'); + // setInitialState({ ...initial }); + } + // if (animationState === 'entering') { + // // + // } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [animationState, onTransitionComplete]); React.useEffect(() => { - // Exit request + // if (!visible) { if (prevVisible.current !== visible && !visible) { setAnimationState('exiting'); } + + if (visible) { + setAnimationState('entering'); + } prevVisible.current = visible; + // } }, [visible]); - React.useEffect( - function startExitTransition() { - const exitTransition = { - ...defaultTransitionConfig, - ...exit?.transition, - }; - - if (animationState === 'exiting') { - Animated.sequence([ - // @ts-ignore - delay is present in defaultTransitionConfig - Animated.delay(exitTransition.delay), - Animated[exitTransition.type ?? 'timing'](animateValue, { - toValue: 0, - useNativeDriver: true, - ...exitTransition, - }), - ]).start(() => { - setAnimationState('exited'); - }); - } - }, - [ - exit, - onTransitionComplete, - setAnimationState, - animationState, - animateValue, - ] - ); - // If exit animation is present and state is exiting, we replace 'initial' with 'exit' animation - initial = - animationState === 'exiting' && exit + + // const initialState = { ...defaultStyles, ...initial }; + const initialState = + animationState === 'exited' && exit ? { ...defaultStyles, ...exit } : { ...defaultStyles, ...initial }; + // const initialState = { ...defaultStyles, ...initial }; + + // initial = + // animationState === 'exited' + // ? { ...defaultStyles, ...exit } + // : { ...defaultStyles, ...initial }; - animate = { ...defaultStyles, ...animate }; + const animateState = { ...defaultStyles, ...animate }; + // const [initialState, setInitialState] = React.useState({ + // ...defaultStyles, + // ...initial, + // }); + // console.log('Initial state ', initial); + + // const [animateState] = React.useState({ ...defaultStyles, ...animate }); const styles = React.useMemo(() => { + // console.log('display state here', initial); return [ getAnimatedStyles(animateValue)( - initial as ISupportedTransitions, - animate as ISupportedTransitions + initialState as ISupportedTransitions, + animateState as ISupportedTransitions ), style, ]; }, [animateValue, initial, animate, style]); - React.useEffect(() => { - if (animationState === 'exited') { - onTransitionComplete && onTransitionComplete('exited'); - } else if (animationState === 'entered') { - onTransitionComplete && onTransitionComplete('entered'); - } - }, [animationState, onTransitionComplete]); - //TODO: refactor for responsive prop - if (useHasResponsiveProps(rest)) { - return null; - } - return ( {children} diff --git a/src/components/composites/Transitions/types.tsx b/src/components/composites/Transitions/types.tsx index f03e4e844..4e804e5df 100644 --- a/src/components/composites/Transitions/types.tsx +++ b/src/components/composites/Transitions/types.tsx @@ -81,6 +81,8 @@ export interface ITransitionProps extends ViewProps { * Determines whether to start the animation */ visible?: boolean; + + animationExited?: boolean; children?: any; as?: any; } diff --git a/src/components/primitives/Overlay/Overlay.tsx b/src/components/primitives/Overlay/Overlay.tsx index 0a14ab83f..836e5a8da 100644 --- a/src/components/primitives/Overlay/Overlay.tsx +++ b/src/components/primitives/Overlay/Overlay.tsx @@ -28,9 +28,9 @@ export function Overlay({ callback: onRequestClose ? onRequestClose : () => {}, }); - if (exited && !isOpen) { - return null; - } + // if (exited && !isOpen) { + // return null; + // } // Android handles multiple Modal in RN and is better for accessibility as it shifts accessibility focus on mount, however it may not needed in case of tooltips, toast where one doesn't need to shift accessibility focus if (Platform.OS === 'android' && useRNModalOnAndroid) { @@ -44,11 +44,17 @@ export function Overlay({ } // Since OverlayContainer mounts children in NativeBaseProvider using Context, we need to pass the context by wrapping children + + // return <> {children}; return ( - + {children} + + // ); }