Skip to content

Drum Picker

motion

A spinning wheel for picking one option. It coasts when flicked and always lands on a row.

atlas-l
atlas-m
atlas-s
atlas-mini
coder-l
vision-m
judge-xl
embed-v3
local/32b
local/8b
Selected model
atlas-m
Context200k
Input / 1M tokens$0.80
p50 latency, ms410
Drag, scroll, or use ↑ ↓

Install

$ npx shadcn@latest add https://spotcheckui.com/r/drum-picker.json

Also installs motion.

Usage

"use client"

import { useState } from "react"
import { DrumPicker } from "@/components/spotcheck/drum-picker"

const options = [
  { value: "atlas-l", label: "atlas-l" },
  { value: "atlas-m", label: "atlas-m" },
  { value: "atlas-s", label: "atlas-s" },
]

const [model, setModel] = useState("atlas-m")

<DrumPicker label="Model" options={options} value={model} onValueChange={setModel} />

Leave out value and pass defaultValue if you don't need to control it. It's a listbox, so screen readers hear each option as the wheel lands.

Scrolling past it

The mouse wheel turns the drum until it reaches the first or last row, then the page scrolls again.

The drum is the one place Spotcheck sets touch-action: none, because it drags up and down and so can't share vertical swipes with the page. It applies to the wheel only. Below the md breakpoint the picker keeps a 48px gutter on its right, so a thumb always has somewhere to scroll the page. Keep that gutter if you change the padding.

The flick

Dragging and throwing come from the use-flick hook, which coverflow also uses. It works in items rather than pixels, caps the throw and springs to the nearest item.

Props

  • label * RequiredstringDefault —Names the list for screen readers.
  • options * RequiredDrumOption[]Default —
  • valuestringDefault —The chosen option's value, when you control it.
  • defaultValuestringDefault —The starting value, when the picker manages itself.
  • onValueChange(value: string) => voidDefault —Runs when the wheel lands on a different row.
  • classNamestringDefault —Added to the outer element.

Keyboard

↑ ↓Move one row
HomeJump to the first row
EndJump to the last row

Reduced motion

The wheel jumps to the row with no spin or coasting.