suiss/ui · Component
Wheel Picker
A scrolling, 3D-curved wheel of options, like the iOS picker, for choosing values such as dates and times.
Wheel Picker is an open-source component from suiss/ui for React, React Native, SwiftUI and Jetpack Compose. The @esuiss/ui CLI copies its source into your project, so you own the code.
WheelPicker is the frame: it draws the highlighted selection band across the middle and lays out one or more WheelPickerColumn wheels side by side. Each column is a scrolling list of WheelPickerItem options that snap to the center, and rows curve away and fade as they move from the middle.
A column selects the item that comes to rest in the center after scrolling, or the item that's clicked. Use a wheel picker for touch-friendly choices from ordered lists, especially several related columns such as day, hour and minute. For a compact dropdown, use Select.
Installation
CLI
Works in any project with a components.json. See Installation for the one-line registry setup. Or use the suiss/ui CLI:
Manual
-
Add the
cnhelper. -
Copy the source into
components/ui/wheel-picker.tsx:
- Update the import paths to match your project.
Usage
Each column manages its own value. Use defaultValue on WheelPickerColumn for an uncontrolled column, or value with onValueChange to control it. Give every WheelPickerItem a unique string value; its children are the visible label.
Set disabled on items that can't be chosen. Scrolling skips past them to the nearest enabled item, and the keyboard steps over them.
Examples
Disabled items
Disables booked time slots so scrolling, keys and clicks skip them.
Date time
Combines controlled day, hour and minute columns into a date and time picker.
API Reference
WheelPicker
The frame that holds the columns and draws the selection band.
Also accepts the props of React.ComponentProps<"div">.
WheelPickerColumn
A scrolling, snapping wheel that holds one selected value.
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | - | The selected value, for controlled use. |
defaultValue | string | - | The initial value when uncontrolled. |
onValueChange | (value: string) => void | - | Called when the column settles on a new value. |
Also accepts the props of React.ComponentProps<"div">, WheelPickerColumnProps.
WheelPickerItem
A single option in a column.
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | Required | The string value this item selects; it must be unique in its column. |
disabled | boolean | false | Prevents the item from being selected. |
Also accepts the props of React.ComponentProps<"div">.
Accessibility
- Each column has the
listboxrole and is focusable; name it witharia-label. Items areoptionelements witharia-selected, and the column points to the selected item witharia-activedescendant. - With a column focused, the up and down arrow keys move to the previous or next enabled item,
Page UpandPage Downmove by five, andHomeandEndjump to the first and last enabled items. - Disabled items set
aria-disabledand ignore clicks. - When reduced motion is preferred, the column scrolls to new values without smooth scrolling.
Notes
- Row height comes from
--wheel-picker-item-height(--spacing(8)by default), set onWheelPicker; the column shows about seven rows. - The curve is driven by scroll-driven animations where
ViewTimelineis supported, and by a scroll handler elsewhere. - Parts carry
data-slotattributes:wheel-picker,wheel-picker-columnandwheel-picker-item. Items setdata-value,data-selectedanddata-disabled. - The selection band uses
bg-secondary.

WheelPicker lays out one or more WheelPickerColumn components side by side behind a shared highlight band. Each column is a snapping ScrollView; items above and below the center are scaled, moved and faded with React Native Animated interpolations to look like a rotating wheel.
Use it for times, dates and other values picked from a short, ordered list, often in a sheet or popover.
Installation
The CLI also adds what it builds on: Text.
Manual
- Install the dependencies:
-
Add the pieces it builds on: Text, and the primitives
components/primitives/use-render.tsx,components/primitives/wheel-picker.tsx. -
Copy the source into
components/ui/wheel-picker.tsx:
- Update the import paths to match your project.
- Install the dependencies:
-
Add the pieces it builds on: Text, and the primitives
components/primitives/use-render.tsx,components/primitives/wheel-picker.tsx. -
Copy the source into
components/ui/wheel-picker.tsx:
- Update the import paths to match your project.
-
Add the pieces it builds on: Text, and the primitives
components/primitives/use-render.tsx,components/primitives/wheel-picker.tsx. -
Copy the source into
components/ui/wheel-picker.tsx:
- Update the import paths to match your project.
-
Target iOS 17 or later.
-
Add the Swift package to your app:
- Copy the theme files every view uses:
- Copy the source and every file it uses:
- Add the files to your app target.
- Set
minSdkto 24 or higher and add the dependencies:
- Copy the theme files every view uses:
- Copy the source and every file it uses:
- Update the
com.esuiss.uipackage names to match your project.
Usage
Give each column a defaultValue, or value with onValueChange, and fill it with WheelPickerItem components that each have a unique value. Plain string or number children are wrapped in single-line Text.
The value is set when scrolling settles or when an item is pressed. Disabled items are skipped: if the wheel stops on one, it moves to the nearest enabled item.
Combine several columns for compound values such as day, hour and minute, and use className on columns and items to control width and alignment. Set itemHeight on WheelPicker to change the row height.
Examples
Disabled items
A time list where booked slots are disabled and skipped.

Date time
Controlled day, hour and minute columns combined into one value.

API Reference
WheelPicker
Root row of columns with the selection highlight.
Also accepts the props of React.ComponentProps<typeof WheelPickerPrimitive.Root>.
WheelPickerColumn
Snapping scroll column that holds one value.
Also accepts the props of React.ComponentProps<typeof WheelPickerPrimitive.Column>.
WheelPickerItem
Single row in a column.
Also accepts the props of React.ComponentProps<typeof WheelPickerPrimitive.Item>.
Accessibility
- Each column has the
adjustablerole and announces the selected item's label as its value. - VoiceOver and TalkBack users swipe up or down to move to the next or previous enabled item.
- Give each column an
accessibilityLabel, such asHourorMinute. - The highlight band is hidden from screen readers.
Notes
- A selection haptic plays when the value changes, if a haptics adapter is provided through the haptics context.
- The highlight uses
bg-secondary; items usetext-xl text-foregroundwith tabular numbers andtext-muted-foregroundwhen disabled. - Light and dark colors follow the system appearance.


