diff --git a/package.json b/package.json index eb0c15a..3d2a9c7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-paper-dropdown", - "version": "2.0.7", + "version": "2.0.8", "description": "Dropdown component using React Native Paper TextInput and Menu, now also with multiselect", "source": "./src/index.tsx", "main": "./lib/commonjs/index.js", diff --git a/src/DropDown.tsx b/src/dropdown.tsx similarity index 69% rename from src/DropDown.tsx rename to src/dropdown.tsx index ac7b4d7..52adb3b 100644 --- a/src/DropDown.tsx +++ b/src/dropdown.tsx @@ -1,27 +1,12 @@ -import React, { - forwardRef, - useCallback, - useImperativeHandle, - useMemo, - useState, -} from 'react'; -import { - Keyboard, - ScrollView, - useWindowDimensions, - View, - LayoutChangeEvent, - LayoutRectangle, - ViewStyle, -} from 'react-native'; +import { ScrollView, View } from 'react-native'; import { Menu, TextInput, TouchableRipple } from 'react-native-paper'; import DropdownItem from './dropdown-item'; import DropdownInput from './dropdown-input'; import { DropdownProps, DropdownRef } from './types'; +import useDropdown from './use-dropdown'; +import { forwardRef, useImperativeHandle } from 'react'; function Dropdown(props: DropdownProps, ref: React.Ref) { - const [enable, setEnable] = useState(false); - const { height } = useWindowDimensions(); const { options, mode, @@ -31,7 +16,7 @@ function Dropdown(props: DropdownProps, ref: React.Ref) { menuDownIcon = , value, onSelect, - maxMenuHeight = height / 2.5, + maxMenuHeight, menuContentStyle, CustomDropdownItem = DropdownItem, CustomDropdownInput = DropdownInput, @@ -42,40 +27,22 @@ function Dropdown(props: DropdownProps, ref: React.Ref) { menuTestID, } = props; const selectedLabel = options.find((option) => option.value === value)?.label; - const [dropdownLayout, setDropdownLayout] = useState({ - x: 0, - y: 0, - height: 0, - width: 0, - }); + const { + enable, + setEnable, + toggleMenu, + onLayout, + menuStyle, + scrollViewStyle, + dropdownLayout, + } = useDropdown(maxMenuHeight); const rightIcon = enable ? menuUpIcon : menuDownIcon; - const toggleMenu = useCallback(() => { - Keyboard.dismiss(); - setEnable(!enable); - }, [enable]); - - const onLayout = useCallback( - ({ nativeEvent: { layout } }: LayoutChangeEvent) => { - setDropdownLayout(layout); - }, - [] - ); - - const menuStyle: ViewStyle = useMemo( - () => ({ - width: dropdownLayout.width, - }), - [dropdownLayout.width] - ); - useImperativeHandle(ref, () => ({ focus() { - Keyboard.dismiss(); setEnable(true); }, blur() { - Keyboard.dismiss(); setEnable(false); }, })); @@ -110,7 +77,7 @@ function Dropdown(props: DropdownProps, ref: React.Ref) { contentStyle={menuContentStyle} testID={menuTestID} > - + {options.map((option, index) => { return ( ) { - const [enable, setEnable] = useState(false); - const { height } = useWindowDimensions(); const { options, mode, @@ -34,8 +19,8 @@ function MultiSelectDropdown( menuDownIcon = , value = [], onSelect, - maxMenuHeight = height / 2.5, menuContentStyle, + maxMenuHeight, CustomMultiSelectDropdownItem = MultiSelectDropdownItem, CustomMultiSelectDropdownInput = DropdownInput, Touchable = TouchableRipple, @@ -53,40 +38,22 @@ function MultiSelectDropdown( .join(', '), [options, value] ); - const [dropdownLayout, setDropdownLayout] = useState({ - x: 0, - y: 0, - height: 0, - width: 0, - }); + const { + enable, + setEnable, + toggleMenu, + onLayout, + menuStyle, + scrollViewStyle, + dropdownLayout, + } = useDropdown(maxMenuHeight); const rightIcon = enable ? menuUpIcon : menuDownIcon; - const toggleMenu = useCallback(() => { - Keyboard.dismiss(); - setEnable(!enable); - }, [enable]); - - const onLayout = useCallback( - ({ nativeEvent: { layout } }: LayoutChangeEvent) => { - setDropdownLayout(layout); - }, - [] - ); - - const menuStyle: ViewStyle = useMemo( - () => ({ - width: dropdownLayout.width, - }), - [dropdownLayout.width] - ); - useImperativeHandle(ref, () => ({ focus() { - Keyboard.dismiss(); setEnable(true); }, blur() { - Keyboard.dismiss(); setEnable(false); }, })); @@ -121,7 +88,7 @@ function MultiSelectDropdown( } contentStyle={menuContentStyle} > - + {options.map((option, index) => { return ( ({ + x: 0, + y: 0, + height: 0, + width: 0, + }); + + const toggleMenu = useCallback(() => { + Keyboard.dismiss(); + setEnable((prev) => !prev); + }, []); + + const onLayout = useCallback( + ({ nativeEvent: { layout } }: LayoutChangeEvent) => { + setDropdownLayout(layout); + }, + [] + ); + + const menuStyle: ViewStyle = useMemo( + () => ({ + width: dropdownLayout.width, + }), + [dropdownLayout.width] + ); + + const scrollViewStyle: ViewStyle = useMemo( + () => ({ + maxHeight: finalMenuHeight, + }), + [finalMenuHeight] + ); + + return { + enable, + setEnable, + toggleMenu, + onLayout, + menuStyle, + scrollViewStyle, + dropdownLayout, + }; +} + +export default useDropdown;