diff --git a/src/components/Dropdown/index.tsx b/src/components/Dropdown/index.tsx index 9c6a599..d5c2869 100644 --- a/src/components/Dropdown/index.tsx +++ b/src/components/Dropdown/index.tsx @@ -30,6 +30,7 @@ import { View, ViewStyle, StatusBar, + Animated, } from 'react-native'; import { useDetectDevice } from '../../toolkits'; import { useDeviceOrientation } from '../../useDeviceOrientation'; @@ -98,6 +99,7 @@ const DropdownComponent: ( closeModalWhenSelectedItem = true, excludeItems = [], excludeSearchItems = [], + animationDuration = 300, } = props; const ref = useRef(null); @@ -108,6 +110,7 @@ const DropdownComponent: ( const [position, setPosition] = useState(); const [keyboardHeight, setKeyboardHeight] = useState(0); const [searchText, setSearchText] = useState(''); + const [modalAnimatedHeight] = useState(new Animated.Value(0)); const { width: W, height: H } = Dimensions.get('window'); const styleContainerVertical: ViewStyle = useMemo(() => { @@ -164,6 +167,11 @@ const DropdownComponent: ( if (!disable) { _measure(); setVisible(true); + Animated.timing(modalAnimatedHeight, { + toValue: 1, + duration: animationDuration, + useNativeDriver: false, + }).start(); if (onFocus) { onFocus(); } @@ -177,12 +185,18 @@ const DropdownComponent: ( const eventClose = useCallback(() => { if (!disable) { - setVisible(false); + Animated.timing(modalAnimatedHeight, { + toValue: 0, + duration: animationDuration, + useNativeDriver: false, + }).start(() => { + setVisible(false); + }); if (onBlur) { onBlur(); } } - }, [disable, onBlur]); + }, [disable, modalAnimatedHeight, animationDuration, onBlur]); const font = useCallback(() => { if (fontFamily) { @@ -320,7 +334,6 @@ const DropdownComponent: ( } _measure(); - setVisible(visibleStatus); if (data) { const filterData = excludeData(data); @@ -328,10 +341,23 @@ const DropdownComponent: ( } if (visibleStatus) { + setVisible(true); + Animated.timing(modalAnimatedHeight, { + toValue: 1, + duration: animationDuration, + useNativeDriver: false, + }).start(); if (onFocus) { onFocus(); } } else { + Animated.timing(modalAnimatedHeight, { + toValue: 0, + duration: animationDuration, + useNativeDriver: false, + }).start(() => { + setVisible(false); + }); if (onBlur) { onBlur(); } @@ -347,6 +373,7 @@ const DropdownComponent: ( disable, keyboardHeight, visible, + modalAnimatedHeight, _measure, data, searchText, @@ -701,18 +728,22 @@ const DropdownComponent: ( isFull && styles.fullScreen, ])} > - {_renderList(isTopPosition)} - + @@ -727,6 +758,7 @@ const DropdownComponent: ( search, position, keyboardHeight, + modalAnimatedHeight, maxHeight, minHeight, dropdownPosition, diff --git a/src/components/Dropdown/model.ts b/src/components/Dropdown/model.ts index a32bba5..ac9814c 100644 --- a/src/components/Dropdown/model.ts +++ b/src/components/Dropdown/model.ts @@ -58,6 +58,7 @@ export interface DropdownProps { closeModalWhenSelectedItem?: boolean; excludeItems?: T[]; excludeSearchItems?: T[]; + animationDuration?: number; onChange: (item: T) => void; renderLeftIcon?: (visible?: boolean) => JSX.Element | null | undefined; renderRightIcon?: (visible?: boolean) => JSX.Element | null | undefined;