1.0.9 • Published 6 months ago

react-native-multicolumn-modal-picker v1.0.9

Weekly downloads
-
License
MIT
Repository
github
Last release
6 months ago

react-native-multicolumn-modal-picker

 npm    Static Badge    Static Badge    npm

Package dependencies

Static Badge    Static Badge

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:

Required Properties: These are essential for the component to function. The values shown here are based on Example 1

Required PropertiesTypeDescriptionUsage
visibleBooleanDetermines whether the modal is visible or not.visible={visible}
column1ArrayAn array of objects with options for the first column. Each object must have a "label" property and a "value" property.column1={options}
selectedValue1String/NumberThe selected value in the first column.selectedValue1 = {selectedValue}
onValueChange1FunctionA function that is called when selected value in first column changes.onValueChange1={(newValue) => setSelectedValue(newValue)}
onCloseFunctionThis 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 use onClose 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.

Column 2 Related Properties. To define column2 , column1 is required

  • 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 if column2 is defined), (Function) A function that is called when selected value in second column changes.
  • selectedValue2: (Required if column2 is defined), (String/Number) The selected value in second column. Initialization required upon usage.

Column 3 Related Properties. To define column3 , both column1 and column2 are required

  • 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 if column3 is defined), (Function) A function that is called when selected value in third column changes.
  • selectedValue3: (Required if column3 is defined), (String/Number) The selected value in third column. Initialization required upon usage.

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 column1

  • 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 with column1.)
  • 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 when actionButtons 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 :star: on GitHub. This lets me know that I’m on the right track and encourages me to keep going.

Give it a star!

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