iOS-like wheel picker for React with smooth inertia scrolling and infinite loop support.
pnpm dlx shadcn@latest add https://chanhdai.com/r/wheel-picker.json
<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/blog/react-wheel-picker#examples
Props for the WheelPickerWrapper
component:
Prop | Type | Default | Description |
---|---|---|---|
className | string | - | CSS class name for wrapper |
children | React.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) |
classNames | WheelPickerClassNames | - | Custom class names for styling |
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;
};