React Wheel Picker

Getting started

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

Installation

pnpm dlx shadcn add @ncdai/wheel-picker

Configure the shadcn MCP server (optional)

Enable AI assistants to understand your component registry:

pnpm dlx shadcn mcp init

Learn more about shadcn MCP server.

Example Prompts:

  • Create a wheel picker demo from the ncdai registry
  • Create a wheel picker form demo from the ncdai registry

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/components/react-wheel-picker#examples

API Reference

WheelPickerWrapper

Props for the WheelPickerWrapper component:

PropTypeDefaultDescription
classNamestring-CSS class name for wrapper
childrenReactNode(required)WheelPicker components

WheelPicker

Props for the WheelPicker component:

PropTypeDefaultDescription
optionsWheelPickerOption<T>[](required)Array of options to display in the wheel
valueT-Current value of the picker (controlled mode). Type matches the option values (string or number)
defaultValueT-Default value of the picker (uncontrolled mode). Type matches the option values (string or number)
onValueChange(value: T) => void-Callback fired when the selected value changes. Receives the selected option's value
infinitebooleanfalseEnable infinite scrolling
visibleCountnumber20Number of options visible on the wheel (must be multiple of 4)
dragSensitivitynumber3Sensitivity of the drag interaction (higher = more sensitive)
scrollSensitivitynumber5Sensitivity of the scroll interaction (higher = more sensitive)
optionItemHeightnumber30Height (in pixels) of each item in the picker list
classNamesWheelPickerClassNames-Custom class names for styling

Types

type WheelPickerValue = string | number;
type WheelPickerOption<T extends WheelPickerValue = string> = {
  /** Value that will be returned when this option is selected */
  value: T;
  /** The content displayed for this option */
  label: ReactNode;
  /** Optional text for type-ahead search (useful when label is a ReactNode). Defaults to label if string, otherwise value. */
  textValue?: 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;
};

Data Attributes

The following data attributes are available for CSS styling:

AttributeElementDescription
[data-rwp-wrapper]WrapperApplied to WheelPickerWrapper
[data-rwp]PickerApplied to WheelPicker root element
[data-rwp-options]Options containerApplied to the options list container
[data-rwp-option]Option itemApplied to each option item in the wheel
[data-rwp-highlight-wrapper]Highlight wrapperApplied to the highlight area wrapper
[data-rwp-highlight-list]Highlight listApplied to the highlight list container
[data-rwp-highlight-item]Highlight itemApplied to the highlighted option item
[data-rwp-focused]Highlight wrapperPresent on [data-rwp-highlight-wrapper] when the picker is focused

Data Slots

The following data-slot attributes are available for targeting specific elements:

SlotElementDescription
option-itemOption itemEach option item in the wheel
highlight-wrapperHighlight wrapperThe highlight area wrapper
highlight-itemHighlight itemThe highlighted option item