React Wheel Picker

Getting started

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

Installation

pnpm dlx shadcn@latest add https://chanhdai.com/r/wheel-picker.json

Anatomy

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

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.

WheelPicker

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

  • A container with a 3D perspective
  • A scrollable list of options
  • A highlight area that indicates the selected option
  • A mask that creates the fade effect at the top and bottom

Usage

import {
  WheelPicker,
  WheelPickerWrapper,
  type WheelPickerOption,
} from "@/components/wheel-picker";
const options: WheelPickerOption[] = [
  {
    label: "Next.js",
    value: "nextjs",
  },
  {
    label: "Vite",
    value: "vite",
  },
  // ...
];
 
export function WheelPickerDemo() {
  const [value, setValue] = useState("nextjs");
 
  return (
    <WheelPickerWrapper>
      <WheelPicker options={options} value={value} onValueChange={setValue} />
    </WheelPickerWrapper>
  );
}

Examples

You can find usage examples in the Examples section at: https://chanhdai.com/blog/react-wheel-picker#examples

API Reference

WheelPickerWrapper

Props for the WheelPickerWrapper component:

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

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

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;
};

Built by ncdai. The source code is available on GitHub.