iOS-like wheel picker for React with smooth inertia scrolling and infinite loop support.
pnpm dlx shadcn add @ncdai/wheel-picker
Enable AI assistants to understand your component registry:
pnpm dlx shadcn mcp init
Learn more about shadcn MCP server.
Example Prompts:
<WheelPickerWrapper>
<WheelPicker />
<WheelPicker />
<WheelPicker />
</WheelPickerWrapper>The wheel picker consists of two main components:
The wrapper component that contains one or more wheel pickers. It provides the container structure and handles the layout of multiple wheels.
The core component that renders a single wheel of options. Each wheel picker consists of:
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>
);
}You can find usage examples in the Examples section at: https://chanhdai.com/components/react-wheel-picker#examples
Props for the WheelPickerWrapper component:
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | CSS class name for wrapper |
children | ReactNode | (required) | WheelPicker components |
Props for the WheelPicker component:
| Prop | Type | Default | Description |
|---|---|---|---|
options | WheelPickerOption[] | (required) | Array of options to display in the wheel |
value | string | - | Current value of the picker (controlled mode) |
defaultValue | string | - | Default value of the picker (uncontrolled mode) |
onValueChange | (value: string) => void | - | Callback fired when the selected value changes |
infinite | boolean | false | Enable infinite scrolling |
visibleCount | number | 20 | Number of options visible on the wheel (must be multiple of 4) |
dragSensitivity | number | 3 | Sensitivity of the drag interaction (higher = more sensitive) |
scrollSensitivity | number | 5 | Sensitivity of the scroll interaction (higher = more sensitive) |
optionItemHeight | number | 30 | Height (in pixels) of each item in the picker list |
classNames | WheelPickerClassNames | - | Custom class names for styling |
type WheelPickerOption = {
/** Value that will be returned when this option is selected */
value: string;
/** The content displayed for this option */
label: ReactNode;
};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;
};