react-native-multicolumn-modal-picker
Package dependencies
This package includes the @react-native-picker/picker
dependency, which is automatically installed. This allows you to use all functionalities without any additional steps or concerns about this dependency. If you already have this dependency in your project and its version is 2.5.0
or higher, this package will be compatible with it.
This package includes the prop-types
dependency, which is automatically installed. This allows you to use all functionalities without any additional steps or concerns about this dependency. If you already have this dependency in your project and its version is 15.8.0
or higher, this package will be compatible with it.
Prerequisites
This package is compatible with existing React Native projects, whether you’re using Expo
or pure React Native
. It has been tested and verified with react-native
version 0.72.5
and expo
version 49.0.8
. If you experience any issues when using it with other versions, please feel free to report it.
Description
react-native-multicolumn-modal-picker
It is a highly customizable React Native component for the iOS
platform. It allows you to configure up to 3 selection columns in the same picker. By default, it can be used as a simple selector.
Installation
Using npm
npm install react-native-multicolumn-modal-picker
This command installs the react-native-multicolumn-modal-picker
package in your current project using npm
.
Using yarn
yarn add react-native-multicolumn-modal-picker
This command installs the react-native-multicolumn-modal-picker
package in your current project using yarn
.
If you are using Expo
npx expo install react-native-multicolumn-modal-picker
This command is specific for Expo
projects. It installs the package react-native-multicolumn-modal-picker
and also automatically handles compatibility with the Expo
version. It’s important to use this command instead of npm install
or yarn add
when you’re working on an Expo
project.
Compatibility
Currently, this package is optimized for iOS
. Although it is compatible with Android
, I decided to restrict its use only to iOS
as it does not provide a good user experience on Android
. I’m considering improving this experience and making it fully functional on Android
too. Your opinion matters to me. Please spare a minute to share your thoughts here. Thank you for your patience!
Usage
import MultiColumnModalPicker from 'react-native-multicolumn-modal-picker';
You can use the MultiColumnModalPicker
component in your application as follows:
Examples
1. Basic Single Column Picker
import React, { useState } from "react";
import { View, Button, Text, StyleSheet } from "react-native";
import MultiColumnModalPicker from "react-native-multicolumn-modal-picker";
const App = () => {
const [visible, setVisible] = useState(false);
const [selectedValue, setSelectedValue] = useState(2);
const options = [
{ label: "Option 1", value: 1 },
{ label: "Option 2", value: 2 },
{ label: "Option 3", value: 3 },
];
return (
<View style={styles.container}>
<Text style={styles.title}>
This is an example of a Basic Single Column Picker
</Text>
<Text style={styles.selectedValue}>Selected value: {selectedValue}</Text>
<Button
title="Open selector"
onPress={() => {
setVisible(true);
}}
/>
<MultiColumnModalPicker
visible={visible}
column1={options}
selectedValue1={selectedValue}
onValueChange1={(value) => setSelectedValue(value)}
onClose={() => setVisible(!visible)}
/>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#E6E6E6",
},
title: {
fontSize: 24,
textAlign: "center",
},
selectedValue: {
fontSize: 18,
marginVertical: 10,
},
});
export default App;
2. Two columns picker
import React, { useState } from "react";
import { View, Button, Text, StyleSheet } from "react-native";
import MultiColumnModalPicker from "react-native-multicolumn-modal-picker";
// Component that implements a modal selector with two columns.
const App = () => {
// State variables for the visibility of the selector and the selected hour and minute
const [visible, setVisible] = useState(false);
const [selectedHour, setSelectedHour] = useState(null);
const [selectedMinute, setSelectedMinute] = useState(null);
const [formattedTime, setFormattedTime] = useState("");
// Arrays for the hours and minutes options in the selector
const hours = Array.from({ length: 24 }, (_, i) => ({
label: `${i}`.padStart(2, "0"),
value: `${i}`.padStart(2, "0"),
}));
const minutes = Array.from({ length: 60 }, (_, i) => ({
label: `${i}`.padStart(2, "0"),
value: `${i}`.padStart(2, "0"),
}));
// formatTime function converts the selected hour and minute into a time string.
const formatTime = (hour, minute) => {
let date = new Date();
date.setHours(hour);
date.setMinutes(minute);
return date.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
};
// In this case, action that is executed when pressing outside of the modal, since the accept button is not displayed in the example.
const onAccept = () => {
setFormattedTime(formatTime(selectedHour, selectedMinute));
};
return (
<View style={styles.container}>
<Text style={styles.title}>
This is an example of a Two-Column Picker
</Text>
{formattedTime && (
<Text style={styles.timeText}>
The selected time is: {formattedTime}
</Text>
)}
<Button title="Select Time" onPress={() => setVisible(true)} />
<MultiColumnModalPicker
visible={visible}
actionButtons="cancel"
column1={hours}
column2={minutes}
onValueChange1={(value) => setSelectedHour(value)}
onValueChange2={(value) => setSelectedMinute(value)}
selectedValue1={selectedHour}
selectedValue2={selectedMinute}
onClose={()=> setVisible(false)}
onAccept={onAccept}
// Custom styles
hPadding={80}
bgColor="#097CF6"
selectionHighlightColor="#0024FF"
cancelButtonBgColor="#2E7DD1"
cancelButtonTextStyle={{ color: "#F0F0F0" }}
/>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#F0F0F0",
},
title: {
fontSize: 22,
textAlign: "center",
marginBottom: 20,
},
timeText: {
marginBottom: 20,
fontSize: 18,
color: "#333333",
},
});
export default App;
3. Single column picker with search bar
import React, { useCallback, useState } from "react";
import { View, Button, Text, StyleSheet } from "react-native";
import MultiColumnModalPicker from "react-native-multicolumn-modal-picker";
const App = () => {
const [visible, setVisible] = useState(false);
const [selectedValue, setSelectedValue] = useState("+33");
const [selectedCountry, setSelectedCountry] = useState("France");
let options = [
{ label: "Australia", value: "+61" },
{ label: "Argentina", value: "+54" },
{ label: "Brazil", value: "+55" },
{ label: "Croatia", value: "+385" },
{ label: "England", value: "+44" },
{ label: "France", value: "+33" },
{ label: "Japan", value: "+81" },
{ label: "Morocco", value: "+212" },
{ label: "Netherlands", value: "+31" },
{ label: "Poland", value: "+48" },
{ label: "Portugal", value: "+351" },
{ label: "Senegal", value: "+221" },
{ label: "South Korea", value: "+82" },
{ label: "Spain", value: "+34" },
{ label: "Switzerland", value: "+41" },
{ label: "United States", value: "+1" },
];
// Create a mapping object from the values (phone codes) to the labels (country names), especially useful when the array is very large.
const countryByPhoneCode = options.reduce((map, option) => {
map[option.value] = option.label;
return map;
}, {});
// Get the label (country name) from the selected value (phone code).
const getCountry = useCallback(() => {
return countryByPhoneCode[selectedValue];
}, [selectedValue]);
return (
<View style={styles.container}>
<Text style={styles.title}>
This is an example of a Single Column Picker with Search Bar
</Text>
<Text style={styles.selectedValue}>
{selectedCountry} phone code: {selectedValue}
</Text>
<Button
title="Open selector"
onPress={() => {
setVisible(true);
}}
/>
<MultiColumnModalPicker
visible={visible}
searchBar
column1={options}
actionButtons="top"
rightInfo={selectedValue}
onValueChange1={(value) => setSelectedValue(value)}
selectedValue1={selectedValue}
onClose={() => setVisible(false)}
onAccept={() => setSelectedCountry(getCountry())}
/>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#111827",
},
title: {
fontSize: 22,
textAlign: "center",
marginBottom: 20,
color: "#E6E6E6",
},
selectedValue: {
fontSize: 18,
marginVertical: 10,
color: "#E6E6E6",
},
});
export default App;
Props
The MultiColumnModalPicker
component accepts the following props:
Example 1
Required Properties: These are essential for the component to function. The values shown here are based onRequired Properties | Type | Description | Usage |
---|---|---|---|
visible |
Boolean | Determines whether the modal is visible or not. | visible={visible} |
column1 |
Array | An array of objects with options for the first column. Each object must have a "label" property and a "value" property. | column1={options} |
selectedValue1 |
String/Number | The selected value in the first column. | selectedValue1 = {selectedValue} |
onValueChange1 |
Function | A function that is called when selected value in first column changes. | onValueChange1={(newValue) => setSelectedValue(newValue)} |
onClose |
Function | This property is crucial for closing the selector. It’s best to use onClose just for closing the modal without adding any extra actions, as it’s used both when accepting and cancelling. |
onClose={() => setVisible(!visible)} |
General Properties
-
onClose
: (Required), (Function) This property is crucial for closing the selector. It’s best to useonClose
just for closing the modal without adding any extra actions, as it’s used both when accepting and cancelling. -
visible
: (Required), (Boolean) Determines whether the modal is visible or not. -
actionButtons
(Optional), (String) Controls the visibility and position of the “Accept” and “Cancel” action buttons. The possible values are:-
"none"
: No action buttons are displayed. This is the default value. -
"cancel"
: Only the “Cancel” button is displayed at the bottom. -
"top"
: Both “Accept” and “Cancel” buttons are displayed at the top. -
"bottom"
: Both “Accept” and “Cancel” buttons are displayed at the bottom.
-
-
acceptButtonText
: (Optional), (String) Accept button label. Default is "Accept" -
cancelButtonText
: (Optional), (String) Cancel button label. Default is "Cancel" -
onAccept
: (Optional), (Function) This function is triggered when the user confirms a selection by pressing the accept button or touching outside of the picker. The inherent logical actions are managed automatically. If this function is defined, it will be added to the existing behavior, not overwrite it. -
onCancel
: (Optional), (Function) A function that is called when the user cancels the selection by pressing the cancel button or the physical back button. The inherent logical actions are managed automatically. If this function is defined, it will be added to the existing behavior, not overwrite it. -
rightInfo
: (Optional), (String) Text displayed on the right side of the selector. It’s suggested to avoid using with hPadding for best results. This is a guideline, not a rule. -
title
: (Optional), (String) Title of picker.
Column 1 Related Properties
-
column1
: (Required), (Array) An array of objects with options for first column. Each object must have a ‘label’ property and a ‘value’ property. -
onValueChange1
: (Required), (Function) A function that is called when selected value in first column changes. -
selectedValue1
: (Required), (String/Number) The selected value in first column. Initialization required upon usage.
column2
, column1
is required
Column 2 Related Properties. To define -
column2
: (Optional), (Array) An array of objects with options for second column. Each object must have a ‘label’ property and a ‘value’ property. -
onValueChange2
: (Required ifcolumn2
is defined), (Function) A function that is called when selected value in second column changes. -
selectedValue2
: (Required ifcolumn2
is defined), (String/Number) The selected value in second column. Initialization required upon usage.
column3
, both column1
and column2
are required
Column 3 Related Properties. To define -
column3
: (Optional), (Array) An array of objects with options for third column. Each object must have a ‘label’ property and a ‘value’ property. -
onValueChange3
: (Required ifcolumn3
is defined), (Function) A function that is called when selected value in third column changes. -
selectedValue3
: (Required ifcolumn3
is defined), (String/Number) The selected value in third column. Initialization required upon usage.
column1
Search Bar Related Properties. The use of the Search Bar is completely optional. It can only be used in conjunction with a single column picker. The Search Bar should be combined with -
searchBar
: (Optional),(Boolean) Indicates whether the search bar is displayed or not. (Please note that the search bar can only be used when the selector has a single column, specifically withcolumn1
.) -
searchBoxStyle
: (Optional),(JSX style object) Determines the style of the search bar. Accepts standard React Native style properties. -
searchPlaceholder
: (Optional),(String) Placeholder of the search bar. The default value is "Search here". -
searchElementsColor
: (Optional), (String) Defines the color of both the search bar placeholder and the clear button within the search bar. Accepts standard React Native color values. -
searchTextStyle
: (Optional),(JSX style object) Determines the text style of the search bar. Accepts standard React Native style properties.
Style Related Properties
-
acceptButtonTextStyle
: (Optional), (JSX style object) Style of the accept button text. Accepts standard React Native style properties. -
actionButtonsBorderColor
: (Optional), (String) This property sets the border color of the action buttons. It is only applicable whenactionButtons
is set to“top”
or“bottom”
. Accepts standard React Native color values. -
bgColor
: (Optional), (String) Background color of modal. Accepts standard React Native color values. -
cancelButtonBgColor
: (Optional), (String) This property sets the background color of the “cancel button” that appears at the bottom of the picker. Accepts standard React Native color values. -
cancelButtonTextStyle
: (Optional), (JSX style object) Style of the cancel button text. Accepts standard React Native style properties. -
hPadding
: (Optional), (Number > 0) Adds extra horizontal space around the picker. -
itemStyle
: (Optional), (JSX style object) Style of the picker items. Accepts standard React Native style properties. -
rightInfoTextStyle
: (Optional), (JSX style object) Style of text for additional information to right side of modal. Accepts standard React Native style properties. -
selectionHighlightColor
: (Optional), (String) Color of the selection highlight. Accepts standard React Native color values. -
titleStyle
: (Optional), (JSX style object) Style of the title text. Accepts standard React Native style properties.
Contributing
Contributions are welcome to react-native-multicolumn-modal-picker
.
If you have an idea for a new feature or have discovered a bug, please open an issue or participate in a discussion.
Don't forget to add a title and a description explaining the issue you're trying to solve and your proposed solution.
Screenshots or gifs are helpful to add to the repository for reviews.
Do you like this package?
Thank you for using my package! Your support is greatly appreciated and it motivates me to continue improving and adding new features. If you find my package useful, please consider giving it a ⭐ on GitHub. This lets me know that I’m on the right track and encourages me to keep going.
Changelog
For a detailed list of changes in each version, please refer to the CHANGELOG
Author
Río
Feel free to Contact me.
License
The library is released under the MIT license. For more details see LICENSE