Ruler slider
A tape of ticks that slides under a fixed needle, with momentum, snapping, and a rolling readout.
pnpm dlx shadcn@latest add @uiarc/ruler-sliderLive · keyboard ready
- Onboarding and profile flows that ask for body measurements or goals.
- Mobile-first inputs where dragging a scale is easier than typing.
- Wide ranges with fine steps that a short slider track cannot resolve.
- Use number-field when people know the exact number and prefer to type it.
- Use slider or elastic-slider when the value is relative, like volume.
- Use range-histogram-slider to pick a range.
Installation
Add Ruler slider with the shadcn CLI, or copy the source by hand.
pnpm dlx shadcn@latest add @uiarc/ruler-sliderAdds the component and its local dependencies, and installs motion. First time? Add the @uiarc registry to components.json, or use the full URL:
example.tsx
import { RulerSlider } from "@/components/arc/ruler-slider/ruler-slider"; export function HeightField() { const [height, setHeight] = useState(172); return ( <RulerSlider label="Height" unit="cm" min={120} max={220} value={height} onValueChange={setHeight} onValueCommit={saveHeight} /> );}RulerSlider
A precise value input shaped like a tape measure. A ruler of ticks slides under a fixed needle; drag it, flick it to coast onto a tick, tap to glide there, or scroll horizontally. The readout rolls each digit.
PropTypeDefaultDescription
labelRequiredstring–Visible label. It also names the control.valuenumber–Controlled value. Leave it out for uncontrolled use.defaultValuenumberminInitial value when uncontrolled.onValueChange(value: number) => void–Called whenever a tick passes the needle, including while coasting.onValueCommit(value: number) => void–Called once the tape comes to rest after a drag, flick, tap, scroll, or key.minnumber0Lowest value.maxnumber100Highest value.stepnumber1Value of one small tick. The tape always rests on a tick.largeStepnumber–Distance for PageUp, PageDown, and Shift with an arrow. Defaults to one labelled tick (step × majorEvery).majorEverynumber10Small ticks between labelled ticks.spacingnumber10Pixels between small ticks. Wider spacing gives finer control.format(value: number) => string–Formats the readout, the tick labels, and aria-valuetext.unitstring–Unit shown after the readout and spoken with the value, such as "cm".namestring–Submits the value with a form through a hidden input.disabledbooleanfalseBlocks input and removes the control from the tab order.classNamestring–Extra class on the root.- ArrowRightorArrowUp
- Moves one tick up.
- ArrowLeftorArrowDown
- Moves one tick down.
- Shift+ArroworPageUporPageDown
- Moves one labelled tick (largeStep).
- HomeorEnd
- Goes to min or max.
- The tape viewport is role="slider" with aria-valuemin, aria-valuemax, aria-valuenow, and aria-valuetext that includes the unit.
- It is labelled by the visible label through aria-labelledby.
- The rolling readout and needle are aria-hidden; the slider announces the value.
- Horizontal trackpad scrolling moves the tape; vertical scrolling is left to the page.
- Dragging moves the tape 1:1; a flick coasts with scroll-like deceleration and lands on a tick.
- Pulling past either end rubber-bands, and releasing pulls the tape home with the throw's speed.
- Taps and keys glide on a spring that keeps any speed already in the tape; grabbing a coasting tape catches it in place.
- Each digit of the readout rolls on its own column as ticks pass the needle.
- Reduced motion removes coasting, rubber-banding, and glides; the tape jumps to the nearest tick.
- The viewport fills its container and fades the tape at both edges; the needle stays centered at any width.
- Touch drags, flicks, and taps work the same as mouse; small moves under 4px count as a tap.
- Horizontal trackpad scrolling moves the tape without capturing vertical page scroll.
- Ticks are drawn with CSS gradients, not one element per tick, so long ranges stay cheap.
- Only labelled ticks are elements; keep (max - min) / (step × majorEvery) to a few hundred.
- Tape position is a motion value, so dragging and coasting do not re-render per frame.
Notes for AI
Give your coding assistant the Markdown reference instead of screenshots.
- Choose it for measurements and precise values on touch: height, weight, temperature, tip amount, zoom level.
- Set step to the precision you store and majorEvery so labelled ticks land on round numbers (10 for cm, 5 or 10 for kg).
- Increase spacing when people need finer control on small screens.
- Use onValueCommit for saves: onValueChange fires on every tick while the tape coasts.
The full library index for assistants is at /llms.txt.
Avatar uploadProComponentClick or drop a photo onto the avatar to crop it in place with drag, pinch and zoom. It uploads through a progress ring and settles, with clear errors and retry.Emoji pickerProComponentA full emoji picker with instant search, scroll-synced categories, skin tones, recently used emoji, and a virtualized, keyboard-navigable grid.
Wallet stackProComponentFan a stack of cards and lift one out to see its activity.
