Skip to content

Scrub Number Field

A numeric input whose label you drag to scrub, with pointer lock and precision modifiers.

DOM + CSS1 dep1 file · 5 KB TSX

Prominimaleditorial
Preview

Props

1

The source is part of Pro

$27/month or $179 once. See Pro

Requires lucide-react
"use client";

import { useCallback, useRef, useState } from "react";
import { MoveHorizontal } from "lucide-react";

export function ScrubNumberField({
  label = "Blur radius",
  step = 1,
  suffix = "px",
  min = 0,
  max = 400,
  defaultValue = 24,
  onCommit,
}: {
  label?: string;
  step?: number;
  suffix?: string;
  min?: number;

  // ---------------------------------------------------------------
  // Full source available with a viberdy Pro subscription.
  // https://viberdy.dev/pricing
  // ---------------------------------------------------------------
}
Details

About this component

Design tools have had scrubbable number fields for decades and the web mostly still has spinners with four-pixel arrows. The mechanism is pointer lock: on pointerdown the cursor is hidden and movement deltas keep arriving after the pointer would have run off the screen, so a single gesture can cover the whole range. Response is deliberately non-linear, so small movements are precise and committed ones are fast. Three details separate this from a naive implementation. Movement under pointer lock is unfiltered and on some Windows acceleration profiles arrives in bursts, so every event is clamped before use — without that a twitch can throw the value hundreds of units. Pointer lock can also simply be refused, since it needs a genuine gesture and is disallowed in several contexts, which makes the unlocked delta path mandatory rather than a fallback nicety. And the live value never touches React state during the drag: it is written to a ref and into the DOM directly, with a single commit on release, because a state update per pointermove re-renders on every pixel of travel. The field itself stays an ordinary text input, so typing, selection and screen-reader access all still work.

Curator’s note

The ±60px movement clamp is the line between a professional scrubber and one that occasionally throws the value across the range.

Pairs well with

Pro