diff --git a/README.md b/README.md index da4a3c9..1be925f 100644 --- a/README.md +++ b/README.md @@ -103,49 +103,53 @@ export default function App() { ### `DropdownProps` -| Prop | Type | Description | -| --------------------- | ----------------------------------------------------------------- | ---------------------------------------------- | -| `value` | `string` | The currently selected value. | -| `onSelect` | `(value: string) => void` | Callback function to handle value selection. | -| `options` | `Option[]` | Array of options for the dropdown. | -| `menuUpIcon` | `JSX.Element` | Custom icon for menu up state. | -| `menuDownIcon` | `JSX.Element` | Custom icon for menu down state. | -| `maxMenuHeight` | `number` | Maximum height of the dropdown menu. | -| `menuContentStyle` | `ViewStyle` | Style for the dropdown menu content. | -| `CustomDropdownItem` | `(props: DropdownItemProps) => JSX.Element` | Custom component for dropdown item. | -| `CustomDropdownInput` | `(props: DropdownInputProps) => JSX.Element` | Custom component for dropdown input. | -| `CustomMenuHeader` | `(props: DropdownHeaderProps) => JSX.Element` | Custom component for the dropdown menu header. | -| `Touchable` | `ForwardRefExoticComponent>` | Custom touchable component for the dropdown. | -| `testID` | `string` | Test ID for the dropdown component. | -| `menuTestID` | `string` | Test ID for the dropdown menu. | -| `placeholder` | `string` | Placeholder text for the dropdown input. | -| `label` | `TextInputLabelProp` | Label for the dropdown input. | -| `mode` | `'flat' \| 'outlined'` | Mode for the dropdown input. | -| `disabled` | `boolean` | Whether the dropdown is disabled. | -| `error` | `boolean` | Whether the dropdown has an error. | +| Prop | Type | Description | +| --------------------- | ----------------------------------------------------------------- | ---------------------------------------------------- | +| `testID` | `string` | Test ID for the dropdown component. | +| `menuTestID` | `string` | Test ID for the dropdown menu. | +| `value` | `string` | The currently selected value. | +| `onSelect` | `(value: string) => void` | Callback function to handle value selection. | +| `options` | `Option[]` | Array of options for the dropdown. | +| `menuUpIcon` | `JSX.Element` | Custom icon for menu up state. | +| `menuDownIcon` | `JSX.Element` | Custom icon for menu down state. | +| `maxMenuHeight` | `number` | Maximum height of the dropdown menu. | +| `menuContentStyle` | `ViewStyle` | Style for the dropdown menu content. | +| `CustomDropdownItem` | `(props: DropdownItemProps) => JSX.Element` | Custom component for dropdown item. | +| `CustomDropdownInput` | `(props: DropdownInputProps) => JSX.Element` | Custom component for dropdown input. | +| `CustomMenuHeader` | `(props: DropdownHeaderProps) => JSX.Element` | Custom component for the dropdown menu header. | +| `Touchable` | `ForwardRefExoticComponent>` | Custom touchable component for the dropdown. | +| `placeholder` | `string` | Placeholder text for the dropdown input. | +| `label` | `TextInputLabelProp` | Label for the dropdown input. | +| `mode` | `'flat' \| 'outlined'` | Mode for the dropdown input. | +| `disabled` | `boolean` | Whether the dropdown is disabled. | +| `error` | `boolean` | Whether the dropdown has an error. | +| `hideMenuHeader` | `boolean` | Hide menu header component (default: false). | +| `statusBarHeight` | `number` | Additional top margin for the status bar on Android. | ### `MultiSelectDropdownProps` -| Prop | Type | Description | -| -------------------------------- | ----------------------------------------------------------------- | ------------------------------------------------- | -| `value` | `string[]` | The currently selected values. | -| `onSelect` | `(value: string[]) => void` | Callback function to handle value selection. | -| `options` | `Option[]` | Array of options for the dropdown. | -| `menuUpIcon` | `JSX.Element` | Custom icon for menu up state. | -| `menuDownIcon` | `JSX.Element` | Custom icon for menu down state. | -| `Touchable` | `ForwardRefExoticComponent>` | Custom touchable component for the dropdown. | -| `maxMenuHeight` | `number` | Maximum height of the dropdown menu. | -| `menuContentStyle` | `ViewStyle` | Style for the dropdown menu content. | -| `CustomMultiSelectDropdownItem` | `(props: MultiSelectDropdownItemProps) => JSX.Element` | Custom component for multi-select dropdown item. | -| `CustomMultiSelectDropdownInput` | `(props: DropdownInputProps) => JSX.Element` | Custom component for multi-select dropdown input. | -| `CustomMenuHeader` | `(props: DropdownHeaderProps) => JSX.Element` | Custom component for the dropdown menu header. | -| `testID` | `string` | Test ID for the dropdown component. | -| `menuTestID` | `string` | Test ID for the dropdown menu. | -| `placeholder` | `string` | Placeholder text for the dropdown input. | -| `label` | `TextInputLabelProp` | Label for the dropdown input. | -| `mode` | `'flat' \| 'outlined'` | Mode for the dropdown input. | -| `disabled` | `boolean` | Whether the dropdown is disabled. | -| `error` | `boolean` | Whether the dropdown has an error. | +| Prop | Type | Description | +| -------------------------------- | ----------------------------------------------------------------- | ---------------------------------------------------- | +| `testID` | `string` | Test ID for the dropdown component. | +| `menuTestID` | `string` | Test ID for the dropdown menu. | +| `value` | `string[]` | The currently selected values. | +| `onSelect` | `(value: string[]) => void` | Callback function to handle value selection. | +| `options` | `Option[]` | Array of options for the dropdown. | +| `menuUpIcon` | `JSX.Element` | Custom icon for menu up state. | +| `menuDownIcon` | `JSX.Element` | Custom icon for menu down state. | +| `Touchable` | `ForwardRefExoticComponent>` | Custom touchable component for the dropdown. | +| `maxMenuHeight` | `number` | Maximum height of the dropdown menu. | +| `menuContentStyle` | `ViewStyle` | Style for the dropdown menu content. | +| `CustomMultiSelectDropdownItem` | `(props: MultiSelectDropdownItemProps) => JSX.Element` | Custom component for multi-select dropdown item. | +| `CustomMultiSelectDropdownInput` | `(props: DropdownInputProps) => JSX.Element` | Custom component for multi-select dropdown input. | +| `CustomMenuHeader` | `(props: DropdownHeaderProps) => JSX.Element` | Custom component for the dropdown menu header. | +| `placeholder` | `string` | Placeholder text for the dropdown input. | +| `label` | `TextInputLabelProp` | Label for the dropdown input. | +| `mode` | `'flat' \| 'outlined'` | Mode for the dropdown input. | +| `disabled` | `boolean` | Whether the dropdown is disabled. | +| `error` | `boolean` | Whether the dropdown has an error. | +| `hideMenuHeader` | `boolean` | Hide menu header component (default: false). | +| `statusBarHeight` | `number` | Additional top margin for the status bar on Android. | ## Methods diff --git a/docs/README.md b/docs/README.md index 87c9a51..87c70b3 100644 --- a/docs/README.md +++ b/docs/README.md @@ -288,49 +288,53 @@ const styles = StyleSheet.create({ ### `DropdownProps` -| Prop | Type | Description | -| --------------------- | ----------------------------------------------------------------- | ---------------------------------------------- | -| `value` | `string` | The currently selected value. | -| `onSelect` | `(value: string) => void` | Callback function to handle value selection. | -| `options` | `Option[]` | Array of options for the dropdown. | -| `menuUpIcon` | `JSX.Element` | Custom icon for menu up state. | -| `menuDownIcon` | `JSX.Element` | Custom icon for menu down state. | -| `maxMenuHeight` | `number` | Maximum height of the dropdown menu. | -| `menuContentStyle` | `ViewStyle` | Style for the dropdown menu content. | -| `CustomDropdownItem` | `(props: DropdownItemProps) => JSX.Element` | Custom component for dropdown item. | -| `CustomDropdownInput` | `(props: DropdownInputProps) => JSX.Element` | Custom component for dropdown input. | -| `CustomMenuHeader` | `(props: DropdownHeaderProps) => JSX.Element` | Custom component for the dropdown menu header. | -| `Touchable` | `ForwardRefExoticComponent>` | Custom touchable component for the dropdown. | -| `testID` | `string` | Test ID for the dropdown component. | -| `menuTestID` | `string` | Test ID for the dropdown menu. | -| `placeholder` | `string` | Placeholder text for the dropdown input. | -| `label` | `TextInputLabelProp` | Label for the dropdown input. | -| `mode` | `'flat' \| 'outlined'` | Mode for the dropdown input. | -| `disabled` | `boolean` | Whether the dropdown is disabled. | -| `error` | `boolean` | Whether the dropdown has an error. | +| Prop | Type | Description | +| --------------------- | ----------------------------------------------------------------- | ---------------------------------------------------- | +| `testID` | `string` | Test ID for the dropdown component. | +| `menuTestID` | `string` | Test ID for the dropdown menu. | +| `value` | `string` | The currently selected value. | +| `onSelect` | `(value: string) => void` | Callback function to handle value selection. | +| `options` | `Option[]` | Array of options for the dropdown. | +| `menuUpIcon` | `JSX.Element` | Custom icon for menu up state. | +| `menuDownIcon` | `JSX.Element` | Custom icon for menu down state. | +| `maxMenuHeight` | `number` | Maximum height of the dropdown menu. | +| `menuContentStyle` | `ViewStyle` | Style for the dropdown menu content. | +| `CustomDropdownItem` | `(props: DropdownItemProps) => JSX.Element` | Custom component for dropdown item. | +| `CustomDropdownInput` | `(props: DropdownInputProps) => JSX.Element` | Custom component for dropdown input. | +| `CustomMenuHeader` | `(props: DropdownHeaderProps) => JSX.Element` | Custom component for the dropdown menu header. | +| `Touchable` | `ForwardRefExoticComponent>` | Custom touchable component for the dropdown. | +| `placeholder` | `string` | Placeholder text for the dropdown input. | +| `label` | `TextInputLabelProp` | Label for the dropdown input. | +| `mode` | `'flat' \| 'outlined'` | Mode for the dropdown input. | +| `disabled` | `boolean` | Whether the dropdown is disabled. | +| `error` | `boolean` | Whether the dropdown has an error. | +| `hideMenuHeader` | `boolean` | Hide menu header component (default: false). | +| `statusBarHeight` | `number` | Additional top margin for the status bar on Android. | ### `MultiSelectDropdownProps` -| Prop | Type | Description | -| -------------------------------- | ----------------------------------------------------------------- | ------------------------------------------------- | -| `value` | `string[]` | The currently selected values. | -| `onSelect` | `(value: string[]) => void` | Callback function to handle value selection. | -| `options` | `Option[]` | Array of options for the dropdown. | -| `menuUpIcon` | `JSX.Element` | Custom icon for menu up state. | -| `menuDownIcon` | `JSX.Element` | Custom icon for menu down state. | -| `Touchable` | `ForwardRefExoticComponent>` | Custom touchable component for the dropdown. | -| `maxMenuHeight` | `number` | Maximum height of the dropdown menu. | -| `menuContentStyle` | `ViewStyle` | Style for the dropdown menu content. | -| `CustomMultiSelectDropdownItem` | `(props: MultiSelectDropdownItemProps) => JSX.Element` | Custom component for multi-select dropdown item. | -| `CustomMultiSelectDropdownInput` | `(props: DropdownInputProps) => JSX.Element` | Custom component for multi-select dropdown input. | -| `CustomMenuHeader` | `(props: DropdownHeaderProps) => JSX.Element` | Custom component for the dropdown menu header. | -| `testID` | `string` | Test ID for the dropdown component. | -| `menuTestID` | `string` | Test ID for the dropdown menu. | -| `placeholder` | `string` | Placeholder text for the dropdown input. | -| `label` | `TextInputLabelProp` | Label for the dropdown input. | -| `mode` | `'flat' \| 'outlined'` | Mode for the dropdown input. | -| `disabled` | `boolean` | Whether the dropdown is disabled. | -| `error` | `boolean` | Whether the dropdown has an error. | +| Prop | Type | Description | +| -------------------------------- | ----------------------------------------------------------------- | ---------------------------------------------------- | +| `testID` | `string` | Test ID for the dropdown component. | +| `menuTestID` | `string` | Test ID for the dropdown menu. | +| `value` | `string[]` | The currently selected values. | +| `onSelect` | `(value: string[]) => void` | Callback function to handle value selection. | +| `options` | `Option[]` | Array of options for the dropdown. | +| `menuUpIcon` | `JSX.Element` | Custom icon for menu up state. | +| `menuDownIcon` | `JSX.Element` | Custom icon for menu down state. | +| `Touchable` | `ForwardRefExoticComponent>` | Custom touchable component for the dropdown. | +| `maxMenuHeight` | `number` | Maximum height of the dropdown menu. | +| `menuContentStyle` | `ViewStyle` | Style for the dropdown menu content. | +| `CustomMultiSelectDropdownItem` | `(props: MultiSelectDropdownItemProps) => JSX.Element` | Custom component for multi-select dropdown item. | +| `CustomMultiSelectDropdownInput` | `(props: DropdownInputProps) => JSX.Element` | Custom component for multi-select dropdown input. | +| `CustomMenuHeader` | `(props: DropdownHeaderProps) => JSX.Element` | Custom component for the dropdown menu header. | +| `placeholder` | `string` | Placeholder text for the dropdown input. | +| `label` | `TextInputLabelProp` | Label for the dropdown input. | +| `mode` | `'flat' \| 'outlined'` | Mode for the dropdown input. | +| `disabled` | `boolean` | Whether the dropdown is disabled. | +| `error` | `boolean` | Whether the dropdown has an error. | +| `hideMenuHeader` | `boolean` | Hide menu header component (default: false). | +| `statusBarHeight` | `number` | Additional top margin for the status bar on Android. | ## Methods diff --git a/src/dropdown.tsx b/src/dropdown.tsx index 42a8add..3f6c29e 100644 --- a/src/dropdown.tsx +++ b/src/dropdown.tsx @@ -1,4 +1,4 @@ -import { ScrollView, View } from 'react-native'; +import { Platform, ScrollView, StatusBar, View } from 'react-native'; import { Menu, TextInput, TouchableRipple } from 'react-native-paper'; import DropdownItem from './dropdown-item'; import DropdownInput from './dropdown-input'; @@ -9,6 +9,8 @@ import DropdownHeader from './dropdown-header'; function Dropdown(props: DropdownProps, ref: React.Ref) { const { + testID, + menuTestID, options, mode, placeholder, @@ -16,16 +18,18 @@ function Dropdown(props: DropdownProps, ref: React.Ref) { menuUpIcon = , menuDownIcon = , value, - onSelect, maxMenuHeight, menuContentStyle, - CustomDropdownItem = DropdownItem, - CustomDropdownInput = DropdownInput, + statusBarHeight = Platform.OS === 'android' + ? StatusBar.currentHeight + : undefined, + hideMenuHeader = false, Touchable = TouchableRipple, disabled = false, error = false, - testID, - menuTestID, + onSelect, + CustomDropdownItem = DropdownItem, + CustomDropdownInput = DropdownInput, CustomMenuHeader = DropdownHeader, } = props; const selectedLabel = options.find((option) => option.value === value)?.label; @@ -61,6 +65,7 @@ function Dropdown(props: DropdownProps, ref: React.Ref) { onDismiss={toggleMenu} style={menuStyle} elevation={5} + statusBarHeight={statusBarHeight} keyboardShouldPersistTaps={'handled'} anchor={ ) { contentStyle={[contentStyle, menuContentStyle]} testID={menuTestID} > - + {!hideMenuHeader && ( + + )} {options.map((option, index) => { return ( diff --git a/src/multi-select-dropdown.tsx b/src/multi-select-dropdown.tsx index 6d4a82f..eed4d3e 100644 --- a/src/multi-select-dropdown.tsx +++ b/src/multi-select-dropdown.tsx @@ -1,5 +1,5 @@ import { forwardRef, useCallback, useImperativeHandle, useMemo } from 'react'; -import { ScrollView, View } from 'react-native'; +import { Platform, ScrollView, StatusBar, View } from 'react-native'; import { Menu, TextInput, TouchableRipple } from 'react-native-paper'; import DropdownInput from './dropdown-input'; import MultiSelectDropdownItem from './multi-select-dropdown-item'; @@ -12,6 +12,8 @@ function MultiSelectDropdown( ref: React.Ref ) { const { + testID, + menuTestID, options, mode, placeholder, @@ -19,16 +21,18 @@ function MultiSelectDropdown( menuUpIcon = , menuDownIcon = , value = [], - onSelect, menuContentStyle = { paddingVertical: 0 }, maxMenuHeight, - CustomMultiSelectDropdownItem = MultiSelectDropdownItem, - CustomMultiSelectDropdownInput = DropdownInput, + statusBarHeight = Platform.OS === 'android' + ? StatusBar.currentHeight + : undefined, + hideMenuHeader = false, Touchable = TouchableRipple, disabled = false, error = false, - testID, - menuTestID, + onSelect, + CustomMultiSelectDropdownItem = MultiSelectDropdownItem, + CustomMultiSelectDropdownInput = DropdownInput, CustomMenuHeader = DropdownHeader, } = props; @@ -72,6 +76,7 @@ function MultiSelectDropdown( onDismiss={toggleMenu} style={menuStyle} elevation={5} + statusBarHeight={statusBarHeight} keyboardShouldPersistTaps={'handled'} anchor={ - + {!hideMenuHeader && ( + + )} {options.map((option, index) => { return ( diff --git a/src/types.ts b/src/types.ts index 89b4e84..b80de7d 100644 --- a/src/types.ts +++ b/src/types.ts @@ -19,44 +19,48 @@ export type Option = { }; export type DropdownProps = { + testID?: string; + menuTestID?: string; value?: string; - onSelect?: (value?: string) => void; options: Option[]; menuUpIcon?: JSX.Element; menuDownIcon?: JSX.Element; maxMenuHeight?: number; menuContentStyle?: ViewStyle; - CustomMenuHeader?: (props: DropdownHeaderProps) => JSX.Element; - CustomDropdownItem?: (props: DropdownItemProps) => JSX.Element; - CustomDropdownInput?: (props: DropdownInputProps) => JSX.Element; + hideMenuHeader?: boolean; + statusBarHeight?: number; Touchable?: ForwardRefExoticComponent< PressableProps & React.RefAttributes >; - testID?: string; - menuTestID?: string; + onSelect?: (value?: string) => void; + CustomMenuHeader?: (props: DropdownHeaderProps) => JSX.Element; + CustomDropdownItem?: (props: DropdownItemProps) => JSX.Element; + CustomDropdownInput?: (props: DropdownInputProps) => JSX.Element; } & Pick< TextInputProps, 'placeholder' | 'label' | 'mode' | 'disabled' | 'error' >; export type MultiSelectDropdownProps = { + testID?: string; + menuTestID?: string; value?: string[]; - onSelect?: (value: string[]) => void; options: Option[]; menuUpIcon?: JSX.Element; menuDownIcon?: JSX.Element; - CustomMenuHeader?: (props: DropdownHeaderProps) => JSX.Element; + maxMenuHeight?: number; + menuContentStyle?: ViewStyle; + hideMenuHeader?: boolean; + statusBarHeight?: number; Touchable?: ForwardRefExoticComponent< PressableProps & React.RefAttributes >; - maxMenuHeight?: number; - menuContentStyle?: ViewStyle; + onSelect?: (value: string[]) => void; + CustomMenuHeader?: (props: DropdownHeaderProps) => JSX.Element; CustomMultiSelectDropdownItem?: ( props: MultiSelectDropdownItemProps ) => JSX.Element; CustomMultiSelectDropdownInput?: (props: DropdownInputProps) => JSX.Element; - testID?: string; - menuTestID?: string; } & Pick< TextInputProps, 'placeholder' | 'label' | 'mode' | 'disabled' | 'error'