Skip to main content
Version: Next 🚧

MultiWheelPicker

MultiWheelPicker puts several React Native WheelPickers side by side, sharing one selection band, the way iOS shows time and date wheels. TimePicker and DateWheelPicker are built on it. Use it for durations, heights, weights, currency + amount, or anything multi-column.

import { MultiWheelPicker } from '@elik56a/react-native-pickers';
Loading…
<MultiWheelPicker
  separator=":"
  columns={[
    { key: 'h', items: range(24), value: h, onChange: setH },
    { key: 'm', items: range(60), value: m, onChange: setM, loop: true },
    { key: 's', items: range(60), value: s, onChange: setS, loop: true },
  ]}
/>

Try the props​

variant
visibleItems
itemHeight
<MultiWheelPicker columns={columns} separator=":" />

Columns​

Each entry in columns is a WheelPicker's props (minus the shared ones below) plus layout keys:

type WheelColumn<T> = Omit<WheelPickerProps<T>, 'itemHeight' | 'visibleItems' | 'variant' | 'showIndicator' | 'theme'> & {
key: string; // React key, required
flex?: number; // flex weight, default 1
width?: number; // fixed width instead of flex
suffix?: string; // text after the column at the selection band, such as a unit
};

So every column has its own items, value, onChange, onValueChanging, loop, renderItem, keyboardInput, isEqual, textAlign, disabled, styles and so on. itemHeight, visibleItems, variant and theme are set once on the MultiWheelPicker so all columns line up.

Labels and separators​

separator is placed between every pair of columns. A string is rendered as bold text (style it with the separator slot), and any React node is rendered as-is. Pass a function to choose per gap: it gets the index of the column on the left and can return null to skip that gap.

Loading…
<>
  <MultiWheelPicker
    columns={[
      {
        key: 'ft',
        items: feet,
        value: ft,
        onChange: setFt,
        textAlign: 'right',
      },
      {
        key: 'in',
        items: inches,
        value: inch,
        onChange: setInch,
        textAlign: 'left',
      },
    ]}
  />
  <Text style={{ textAlign: 'center', color: '#6E685E' }}>
    {ft}′{inch}″ = {Math.round((ft * 12 + inch) * 2.54)} cm
  </Text>
</>

For a unit after each column, such as min, set the column's suffix instead: it's shown after the column at the selection band in the theme's secondary text color, and the separator slot styles it too. DurationPicker labels its wheels this way.

Column widths​

Use flex for proportional columns and width for fixed ones:

Loading…
<MultiWheelPicker
  variant="flat"
  columns={[
    {
      key: 'cur',
      items: ['USD', 'EUR', 'GBP', 'ILS'],
      value: cur,
      onChange: setCur,
      width: 90,
    },
    {
      key: 'amount',
      items: amounts,
      value: amount,
      onChange: setAmount,
      flex: 2,
    },
  ]}
/>

Dependent columns​

Columns are plain props, so derive one from another in render. Here the model list depends on the brand:

Loading…
<MultiWheelPicker
  columns={[
    {
      key: 'brand',
      items: Object.keys(models),
      value: brand,
      onChange: (b) => {
        setBrand(b);
        setModel(models[b][0]);
      },
    },
    {
      key: 'model',
      items: models[brand],
      value: model,
      onChange: setModel,
      flex: 1.4,
    },
  ]}
/>

Props​

PropTypeDefaultDescription
columnsWheelColumn[]requiredOne entry per wheel; see Columns.
separatorReactNode | ((leftIndex: number) => ReactNode)—Content between columns. Strings use the separator slot style.
itemHeightnumber40Row height shared by all columns.
visibleItemsnumber5Visible rows (odd) shared by all columns.
variant'3d' | 'flat''3d'Wheel style for all columns.
styleStyleProp<ViewStyle>—Outer container style.
stylesSlotStyles<MultiWheelSlot>—Slot styles, applied to every column (a column's own styles win).
themeDeepPartial<PickerTheme>—Theme override for all columns.
design'ios' | 'material' | 'web'from PickersProviderThe look to follow, over the provider's: iOS, Material or web.
testIDstring—Test ID on the container.

Slots​

SlotElement
containerOuter view
indicatorThe shared selection band
separatorString separators
item, itemText, selectedItemText, disabledItemTextForwarded to every column's wheel
type MultiWheelSlot = 'container' | 'indicator' | 'separator' | WheelPickerSlot;