UNPKG

@niku/react-native-dropdown-select

Version:
113 lines (106 loc) 3.89 kB
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { Animated, Easing, FlatList, InteractionManager, Platform, TouchableWithoutFeedback, View } from 'react-native'; import { useSafeAreaFrame, useSafeAreaInsets } from 'react-native-safe-area-context'; import { DROPDOWN_MIN_WIDTH } from '../constants'; import { isDropdownOptionItem } from '../utils'; import { styles } from './styles'; const DropdownModalContent = ({ visible, onDismiss, onDismissed, dropdownContainerStyle, renderItem, options, loading, loadingComponent, buttonLayout, position }) => { /** * Animation */ const animationValue = useRef(new Animated.Value(0)).current; const show = useCallback(() => { InteractionManager.runAfterInteractions(() => { Animated.timing(animationValue, { toValue: 1, duration: 250, useNativeDriver: false }).start(); }); }, [animationValue]); const hide = useCallback(() => { InteractionManager.runAfterInteractions(() => { Animated.timing(animationValue, { toValue: 0, duration: 250, useNativeDriver: false }).start(result => { if (result.finished) { onDismissed && onDismissed(); } }); }); }, [animationValue, onDismissed]); useEffect(() => { visible ? show() : hide(); }, [visible]); /** * Dropdown Position */ const frame = useSafeAreaFrame(); const insets = useSafeAreaInsets(); const [dropdownContainerHeight, setDropdownContainerHeight] = useState(0); const measureDropdownContainer = useCallback(e => { setDropdownContainerHeight(e.nativeEvent.layout.height); }, []); const dropdownContainerPositionStyles = useMemo(() => { const top = buttonLayout.y + buttonLayout.height; const left = buttonLayout.x; const width = buttonLayout.width > DROPDOWN_MIN_WIDTH ? buttonLayout.width : DROPDOWN_MIN_WIDTH; let positionStyles = { top: top - (Platform.OS === 'ios' || frame.y > 0 ? 0 : insets.top), left: left, width }; if (position === 'top') { positionStyles.top = buttonLayout.y - dropdownContainerHeight + (Platform.OS === 'ios' || frame.y > 0 ? 0 : insets.top); } return positionStyles; }, [buttonLayout, dropdownContainerHeight, position, frame, insets]); /** * Animation translate */ const dropdownContainerTranslateY = animationValue.interpolate({ inputRange: [0, 1], outputRange: [position === 'bottom' ? -dropdownContainerHeight / 2 : dropdownContainerHeight / 2, 0], easing: Easing.linear, extrapolate: 'clamp' }); return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(TouchableWithoutFeedback, { style: styles.backdrop, onPress: onDismiss }, /*#__PURE__*/React.createElement(View, { style: styles.backdrop })), /*#__PURE__*/React.createElement(Animated.View, { onLayout: measureDropdownContainer, style: [styles.dropdownContainer, dropdownContainerPositionStyles, position === 'top' ? styles.dropdownContainerPositionTop : {}, { transform: [{ translateY: dropdownContainerTranslateY }, { scaleY: animationValue }], opacity: animationValue }, dropdownContainerStyle] }, /*#__PURE__*/React.createElement(FlatList, { renderItem: renderItem, data: options, keyExtractor: (item, index) => { var _item$value; return isDropdownOptionItem(item) ? (_item$value = item.value) === null || _item$value === void 0 ? void 0 : _item$value.toString() : (typeof item.label === 'string' ? item.label : index) + '-' + item.options.length; }, ListFooterComponent: () => /*#__PURE__*/React.createElement(React.Fragment, null, loading && loadingComponent) }))); }; export default DropdownModalContent; //# sourceMappingURL=index.js.map