Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main'
Browse files Browse the repository at this point in the history
  • Loading branch information
cervisebas committed Jul 21, 2024
2 parents 2c0d2e2 + 9d5baad commit e169b9b
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 95 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
61 changes: 14 additions & 47 deletions src/DropDown.tsx → src/dropdown.tsx
Original file line number Diff line number Diff line change
@@ -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<DropdownRef>) {
const [enable, setEnable] = useState(false);
const { height } = useWindowDimensions();
const {
options,
mode,
Expand All @@ -31,7 +16,7 @@ function Dropdown(props: DropdownProps, ref: React.Ref<DropdownRef>) {
menuDownIcon = <TextInput.Icon icon={'menu-down'} pointerEvents="none" />,
value,
onSelect,
maxMenuHeight = height / 2.5,
maxMenuHeight,
menuContentStyle,
CustomDropdownItem = DropdownItem,
CustomDropdownInput = DropdownInput,
Expand All @@ -42,40 +27,22 @@ function Dropdown(props: DropdownProps, ref: React.Ref<DropdownRef>) {
menuTestID,
} = props;
const selectedLabel = options.find((option) => option.value === value)?.label;
const [dropdownLayout, setDropdownLayout] = useState<LayoutRectangle>({
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);
},
}));
Expand Down Expand Up @@ -110,7 +77,7 @@ function Dropdown(props: DropdownProps, ref: React.Ref<DropdownRef>) {
contentStyle={menuContentStyle}
testID={menuTestID}
>
<ScrollView style={{ maxHeight: maxMenuHeight }} bounces={false}>
<ScrollView style={scrollViewStyle} bounces={false}>
{options.map((option, index) => {
return (
<CustomDropdownItem
Expand Down
61 changes: 14 additions & 47 deletions src/multi-select-dropdown.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,15 @@
import React, {
forwardRef,
useCallback,
useImperativeHandle,
useMemo,
useState,
} from 'react';
import {
Keyboard,
ScrollView,
useWindowDimensions,
View,
LayoutChangeEvent,
LayoutRectangle,
ViewStyle,
} from 'react-native';
import { forwardRef, useImperativeHandle, useMemo } from 'react';
import { ScrollView, View } from 'react-native';
import { Menu, TextInput, TouchableRipple } from 'react-native-paper';
import DropdownInput from './dropdown-input';
import MultiSelectDropdownItem from './multi-select-dropdown-item';
import { DropdownRef, MultiSelectDropdownProps } from './types';
import useDropdown from './use-dropdown';

function MultiSelectDropdown(
props: MultiSelectDropdownProps,
ref: React.Ref<DropdownRef>
) {
const [enable, setEnable] = useState(false);
const { height } = useWindowDimensions();
const {
options,
mode,
Expand All @@ -34,8 +19,8 @@ function MultiSelectDropdown(
menuDownIcon = <TextInput.Icon icon={'menu-down'} pointerEvents="none" />,
value = [],
onSelect,
maxMenuHeight = height / 2.5,
menuContentStyle,
maxMenuHeight,
CustomMultiSelectDropdownItem = MultiSelectDropdownItem,
CustomMultiSelectDropdownInput = DropdownInput,
Touchable = TouchableRipple,
Expand All @@ -53,40 +38,22 @@ function MultiSelectDropdown(
.join(', '),
[options, value]
);
const [dropdownLayout, setDropdownLayout] = useState<LayoutRectangle>({
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);
},
}));
Expand Down Expand Up @@ -121,7 +88,7 @@ function MultiSelectDropdown(
}
contentStyle={menuContentStyle}
>
<ScrollView style={{ maxHeight: maxMenuHeight }} bounces={false}>
<ScrollView style={scrollViewStyle} bounces={false}>
{options.map((option, index) => {
return (
<CustomMultiSelectDropdownItem
Expand Down
59 changes: 59 additions & 0 deletions src/use-dropdown.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { useCallback, useState, useMemo } from 'react';
import {
Keyboard,
LayoutChangeEvent,
LayoutRectangle,
useWindowDimensions,
ViewStyle,
} from 'react-native';

function useDropdown(maxMenuHeight?: number, maxHeightFraction: number = 2.5) {
const [enable, setEnable] = useState(false);
const { height } = useWindowDimensions();
const finalMenuHeight = maxMenuHeight ?? height / maxHeightFraction;

const [dropdownLayout, setDropdownLayout] = useState<LayoutRectangle>({
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;

0 comments on commit e169b9b

Please sign in to comment.