react-native-wheel-picker

repository·main·Indexed 43 days ago

https://github.com/quidone/react-native-wheel-picker

A high-performance wheel picker for iOS and Android in React Native. Version 1.7.1 provides a unified API with native animations, virtualization for large datasets, and specialized components like DatePicker. It includes a Picker Control API for synchronizing multiple pickers and supports haptic feedback via an optional feedback package.

Tokens
11.1K
Snippets
38
Records
52
Agent score
54%

What's inside react-native-wheel-picker

  1. How Picker Control synchronizes multiple WheelPickers

    main

    Picker Control is used to synchronize multiple WheelPicker components (e.g., inside a DatePicker). It ensures that onValueChanged and onValueChanging events are synchronized and that all connected pickers accept a value change even if they are still spinning.

    To implement synchronization:

    1. Use usePickerControl to create a control object.
    2. Wrap your WheelPicker components with the withPickerControl HOC.
    3. Pass the control object and a unique pickerName to the HOC.

    Available hooks for side effects:

    • useOnPickerValueChangedEffect: Called when the value has been changed (during the inactive state of all WheelPickers).
    • useOnPickerValueChangingEffect: Called when any of the connected WheelPickers changes.
  2. Add native feedback to WheelPicker

    main

    To provide a more native feel, you can trigger haptic feedback and sounds during picker interaction. This is achieved by using the @quidone/react-native-wheel-picker-feedback package and calling triggerSoundAndImpact() within the onValueChanging callback of the WheelPicker.

    // ...
    import WheelPickerFeedback from '@quidone/react-native-wheel-picker-feedback';
    
    const App = () => {
      return (
        <WheelPicker
          onValueChanging={() => {
            WheelPickerFeedback.triggerSoundAndImpact();
          }}
        />
      );
    };
  3. Use the DatePicker component

    main

    The DatePicker component provides a specialized wheel picker interface for selecting dates.

    Simple Usage

    Pass a date string in YYYY-MM-DD format and use onDateChanged to handle updates.

    Customized Usage

    You can customize the rendering of date components (Date, Month, Year) by providing custom render functions. The component uses a render prop pattern where you can access dateNodes to manually map and render the individual picker nodes.

    // Simple Case
    import React, {useState} from 'react';
    import {DatePicker} from '@quidone/react-native-wheel-picker';
    
    const App = () => {
      const [date, setDate] = useState('2025-02-02');
    
      return (
        <DatePicker
          date={date} // required format YYYY-MM-DD
          onDateChanged={({date}) => setDate(date)}
        />
      );
    };
    
    // Customized Case
    import React, {useState} from 'react';
    import {useStableCallback} from '@rozhkov/react-useful-hooks';
    import {DatePicker} from '@quidone/react-native-wheel-picker';
    
    const CustomizedDatePicker = () => {
      const [date, setDate] = useState('2025-02-02');
    
      const onDateChanged = useStableCallback(({date}: {date: string}) => {
        setDate(date);
      });
    
      return (
        <DatePicker
          date={date}
          onDateChanged={onDateChanged}
          renderDate={() => <DatePicker.Date />}
          renderMonth={() => <DatePicker.Month />}
          renderYear={() => <DatePicker.Year />}
        >
          {({dateNodes}) => {
            return dateNodes.map((x) => x.node);
          }}
        </DatePicker>
      );
    };
  4. Manage multiple pickers with Picker Control

    main

    When you need to coordinate multiple pickers (e.g., a range selector or a complex form), use the Picker Control API. This allows you to manage the state of several pickers through a single controller.

    Workflow:

    1. Wrap your WheelPicker with withPickerControl to create a ControlPicker component.
    2. Initialize a controller using usePickerControl<T>(), where T is a map of your picker names to their respective item types.
    3. Use useOnPickerValueChangedEffect to react to changes across the controlled pickers.
    4. Use useOnPickerValueChangingEffect to intercept or react to values while they are in the process of changing.
    5. Pass the control and a unique pickerName to each ControlPicker instance.
    import React, {useState} from 'react';
    import WheelPicker, {
      type PickerItem,
      useOnPickerValueChangedEffect,
      useOnPickerValueChangingEffect,
      usePickerControl,
      withPickerControl,
    } from '@quidone/react-native-wheel-picker';
    import {View} from 'react-native';
    
    const ControlPicker = withPickerControl(WheelPicker);
    
    type ControlPickersMap = {
      value1: {item: PickerItem<number>};
      value2: {item: PickerItem<number>};
    };
    
    const data = Array.from({length: 100}, (_, index) => ({value: index}));
    
    const App = () => {
      const [value, setValue] = useState({value1: 0, value2: 0});
    
      const pickerControl = usePickerControl<ControlPickersMap>();
    
      useOnPickerValueChangedEffect(pickerControl, (event) => {
        setValue({
          value1: event.pickers.value1.item.value,
          value2: event.pickers.value2.item.value,
        });
      });
    
      useOnPickerValueChangingEffect(pickerControl, (event) => {
        // some logic
      });
    
      return (
        <View style={{flexDirection: 'row', justifyContent: 'space-around'}}>
          <ControlPicker
            control={pickerControl}
            pickerName={'value1'}
            data={data}
            value={value.value1}
            width={100}
            enableScrollByTapOnItem={true}
          />
          <ControlPicker
            control={pickerControl}
            pickerName={'value2'}
            data={data}
            value={value.value2}
            width={100}
            enableScrollByTapOnItem={true}
          />
        </View>
      );
    };
  5. Use the WheelPicker component

    main

    The WheelPicker is a flexible component for creating wheel-style selection interfaces. It works without a native side, using native animations for performance.

    Key props:

    • data: An array of items to display. Each item should ideally have a value and label.
    • value: The currently selected value.
    • onValueChanged: Callback function triggered when the selection changes. It receives an object containing the selected item.
    • enableScrollByTapOnItem: Boolean to allow scrolling to an item when it is tapped.
    import React, {useState} from 'react';
    import WheelPicker from '@quidone/react-native-wheel-picker';
    
    const data = [...Array(100).keys()].map((index) => ({
      value: index,
      label: index.toString(),
    }))
    
    const App = () => {
      const [value, setValue] = useState(0);
      return (
        <WheelPicker
          data={data}
          value={value}
          onValueChanged={({item: {value}}) => setValue(value)}
          enableScrollByTapOnItem={true}
        />
      );
    };
    
    export default App;
  6. Picker Control API

    main

    Tools for synchronizing multiple pickers.

    Hooks

    • usePickerControl: Creates a control object for connecting multiple pickers.
    • useOnPickerValueChangedEffect: Called when the value has been changed (inactive state of all WheelPickers).
    • useOnPickerValueChangingEffect: Called when any of the connected WheelPickers changes.

    HOC

    • withPickerControl: Connects a WheelPicker to a control object. Requires the following props:
      • control: The control object from usePickerControl.
      • pickerName: A unique string name for the picker within the group.
  7. Use withVirtualized HOC

    main

    To improve performance with large datasets, use the withVirtualized Higher-Order Component (HOC) to return a virtualized version of the WheelPicker.

    import WheelPicker, {withVirtualized} from '@quidone/react-native-wheel-picker';
    
    const VirtualizedWheelPicker = withVirtualized(WheelPicker);
  8. DatePicker API Reference

    main

    The DatePicker is a specialized component for date selection. It supports localization and provides subcomponents for custom layouts.

    <DatePicker
      date="2023-01-01"
      onDateChanged={(date) => console.log(date)}
      minDate="2020-01-01"
      maxDate="2025-12-31"
      locale="en"
    />
  9. WheelPicker API Reference

    main

    The WheelPicker component is the core component for creating wheel-style selection pickers. It accepts a variety of props for data, styling, and event handling.

    <WheelPicker
      data={['Item 1', 'Item 2', 'Item 3']}
      value={'Item 1'}
      itemHeight={50}
      visibleItemCount={5}
      onValueChanged={(value) => console.log(value)}
      renderItem={({ item }) => <Text>{item}</Text>}
    />
  10. DatePicker Props and Subcomponents

    main

    Props

    PropTypeDescription
    datestringCurrent date in 'YYYY-MM-DD' format.
    onDateChangedfunctionCallback fired when date selection is confirmed.
    minDatestringMinimum selectable date in 'YYYY-MM-DD' format.
    maxDatestringMaximum selectable date in 'YYYY-MM-DD' format.
    localestringLocale for date formatting. Default is 'en'.
    renderDatefunctionCustom renderer for the date component.
    renderMonthfunctionCustom renderer for the month component.
    renderYearfunctionCustom renderer for the year component.
    childrenfunctionRender prop for customizing component layout.

    Note: DatePicker also accepts all common WheelPicker props like itemHeight, visibleItemCount, and readOnly.

    Subcomponents

    Use these for custom layouts:

    • DatePicker.Date: Day WheelPicker
    • DatePicker.Month: Month WheelPicker
    • DatePicker.Year: Year WheelPicker