import type { ReactNode } from 'react'; import React, { useCallback, useEffect } from 'react'; import type { LayoutChangeEvent, StyleProp, ViewProps, ViewStyle, } from 'react-native'; import { LayoutAnimation, Platform, UIManager } from 'react-native'; import { usePrevious } from '../../utils/hooks'; import { StyledChildWrapper, StyledHiddenWrapper, StyledWrapper, } from './StyledCollapse'; export interface CollapseProps extends ViewProps { /* * The collapse's content. */ children: ReactNode; /** * Whether the component is open or closed. */ open?: boolean; /** * Additional style. */ style?: StyleProp; /** * Testing id of the component. */ testID?: string; } if (Platform.OS === 'android') { if (UIManager.setLayoutAnimationEnabledExperimental) { UIManager.setLayoutAnimationEnabledExperimental(true); } } const Collapse = ({ open = false, children, testID, style, onLayout, }: CollapseProps) => { const [contentHeight, setContentHeight] = React.useState(0); const [componentMounted, setComponentMounted] = React.useState(false); const previousOpenState = usePrevious(open); useEffect(() => { if ( ((open !== previousOpenState && previousOpenState !== undefined) || open) && componentMounted ) { LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut); } }, [open, previousOpenState, contentHeight]); const fetchMaxHeight = useCallback(({ height }: { height: number }) => { setContentHeight(height); }, []); const onCollapseLayout = useCallback((e: LayoutChangeEvent) => { setComponentMounted(true); onLayout?.(e); }, []); return ( fetchMaxHeight(event.nativeEvent.layout)} style={style} > {children} ); }; export default Collapse;