Skip to content
GetUrUI

Drum Picker

Pro
.md

Touch-style 3D drum picker with any number of columns: rows tilt by their distance from the centre, and drags or flicks glide with momentum before snapping to a value.

pickerwheeltime pickeriosselect3dmomentumsnapdrum

Installation

Pro installs use your private registry token. Add the @geturui-pro registry once — setup guide. The command works after you get Pro.

$npx shadcn@latest add @geturui-pro/wheel-picker

Usage

usage.tsx
1"use client";
2import * as React from "react";
3import { WheelPicker, type WheelColumn } from "@/components/ui/wheel-picker";
4
5const pad = (n: number) => String(n).padStart(2, "0");
6const columns: WheelColumn[] = [
7  { key: "hour", label: "Hour", align: "right", options: Array.from({ length: 12 }, (_, i) => ({ value: String(i + 1), label: String(i + 1) })) },
8  { key: "minute", label: "Minute", options: Array.from({ length: 60 }, (_, i) => ({ value: pad(i), label: pad(i) })) },
9  { key: "period", label: "AM or PM", align: "left", options: [{ value: "AM", label: "AM" }, { value: "PM", label: "PM" }] },
10];
11
12export function AlarmTime() {
13  const [time, setTime] = React.useState({ hour: "7", minute: "30", period: "AM" });
14  return <WheelPicker aria-label="Alarm time" columns={columns} value={time} onValueChange={setTime} />;
15}

Props

PropTypeDefaultDescription
columns*{ key: string; label: string; options: { value: string; label: string }[]; width?: number; align?: "left" | "center" | "right" }[]—One wheel per column. label names the wheel for assistive tech.
valueRecord<string, string>—Controlled selection keyed by column key.
defaultValueRecord<string, string>first option of each columnSelection on mount when uncontrolled.
onValueChange(value: Record<string, string>) => void—Called as soon as a wheel picks its landing row.
itemHeightnumber36Row height in px; the wheel radius and height derive from it.
aria-labelstring—Names the group of wheels.
classNamestring—Classes for the picker surface.

Accessibility

  • Each wheel is a focusable role="spinbutton" with aria-valuenow and aria-valuetext set to the visible label.
  • Up and Down step one row, Page Up and Page Down jump five, Home and End go to the ends.
  • Mouse wheel and trackpad scroll the wheel without scrolling the page; tapping a row selects it.
  • With reduced motion the wheel snaps with a short tween instead of a momentum spring.

Related