React Wheel Picker
GitHub

Getting started

iOS-like wheel picker for React with smooth inertia scrolling and infinite loop support.

Installation

If you're using shadcn/ui, please refer to the guide: https://chanhdai.com/blog/react-wheel-picker

pnpm add @ncdai/react-wheel-picker

Anatomy

The wheel picker consists of two main components:

WheelPickerWrapper

The wrapper component that contains one or more wheel pickers. It provides the container structure and handles the layout of multiple wheels.

<WheelPickerWrapper>
  <WheelPicker />
  <WheelPicker />
  <WheelPicker />
</WheelPickerWrapper>

WheelPicker

The core component that renders a single wheel of options. Each wheel picker consists of:

<WheelPicker
  options={[
    { label: "React", value: "react" },
    { label: "Vue", value: "vue" },
    { label: "Angular", value: "angular" },
  ]}
/>

Usage

Import the default styles

Add the core CSS to your app's entry point (e.g., src/app/layout.tsx, src/main.tsx, or src/index.tsx):

import "@ncdai/react-wheel-picker/dist/style.css";

This CSS includes only basic layout. Use classNames to customize visuals (see below).

Use the component

import {
  WheelPicker,
  WheelPickerWrapper,
  type WheelPickerOption,
  type WheelPickerClassNames,
} from "@ncdai/react-wheel-picker";
 
const options: WheelPickerOption[] = [
  {
    label: "React",
    value: "react",
  },
  {
    label: "Vue",
    value: "vue",
  },
  {
    label: "Angular",
    value: "angular",
  },
  {
    label: "Svelte",
    value: "svelte",
  },
];
 
const classNames: WheelPickerClassNames = {
  optionItem: "text-zinc-400",
  highlightWrapper: "bg-zinc-100 text-zinc-950",
};
 
export function WheelPickerDemo() {
  return (
    <WheelPickerWrapper className="max-w-56 rounded-md border border-zinc-200 bg-white shadow-xs">
      <WheelPicker options={options} classNames={classNames} />
    </WheelPickerWrapper>
  );
}

API

WheelPicker

Props for the WheelPicker component:

PropTypeDefaultDescription
optionsWheelPickerOption[](required)Array of options to display in the wheel
valuestring-Current value of the picker (controlled mode)
defaultValuestring-Default value of the picker (uncontrolled mode)
onValueChange(value: string) => void-Callback fired when the selected value changes
infinitebooleanfalseEnable infinite scrolling
visibleCountnumber20Number of options visible on the wheel (must be multiple of 4)
dragSensitivitynumber3Sensitivity of the drag interaction (higher = more sensitive)
classNamesWheelPickerClassNames-Custom class names for styling

WheelPickerWrapper

Props for the WheelPickerWrapper component:

PropTypeDefaultDescription
classNamestring-CSS class name for wrapper
childrenReact.ReactNode(required)WheelPicker components

Types

type WheelPickerOption = {
  /** Value that will be returned when this option is selected */
  value: string;
  /** Text label displayed for this option */
  label: string;
};
 
type WheelPickerClassNames = {
  /** Class name for individual option items */
  optionItem?: string;
  /** Class name for the wrapper of the highlighted area */
  highlightWrapper?: string;
  /** Class name for the highlighted item */
  highlightItem?: string;
};