Skip to content

No.316 · Forms· New

Scrub Number

The number field from design tools. Drag the label sideways to scrub (Shift for ten times, Alt for a tenth), nudge with the arrow keys, or type arithmetic straight into the box: 12*4, (100-8)/2, +=8. Values clamp with a flash at the edge they hit.

The prompt

Copy this text

Automatic copying is unavailable. Copy the selected text using your device’s copy command.

Written for the variant you picked above: Light

Build a compact number field of the kind used in design-tool inspectors, plus a ScrubGroup that lays several out as a panel ('Frame': X, Y, W, H, rotation, corner radius, opacity), driving a live preview. Each field is a 30px-tall, 6px-radius well on a slightly darker grey than the panel, in Inter 12px with tabular numbers: a short handle on the left ('X', 'W', '↻'), the value, and a muted unit on the right ('°', '%'). Hover adds a hairline ring; focus or scrubbing turns it accent blue. The panel is white with a 10px radius, a hairline border, a soft shadow and a small uppercase muted title. The handle is a scrub control: press and drag sideways and the value changes by one step every 3px of movement, ten steps with Shift and a tenth with Alt, using movementX with pointer lock where the browser allows it so a scrub can continue past the screen edge. While scrubbing the handle turns blue and a 3px row of tick marks along the field's bottom edge slides with the value. Hitting min or max clamps the value and briefly flashes a 3px accent bar on that side. The box accepts arithmetic, read by a small recursive-descent parser (never eval): numbers, + − × ÷ (and x between numbers), parentheses, units typed at the end, and relative forms '+=8', '-=8', '*=2', '/=2' applied to the current value. Enter commits and reselects, Escape reverts, blur commits; anything unreadable shakes the field with a red ring and leaves the value unchanged. Selected variant — Light (light): Palette for this theme (Light): --scrubn-accent #2f6fe4; --scrubn-bad #c4321c; --scrubn-field #f3f3f1; --scrubn-ink #1c1c1a; --scrubn-line rgb(28 28 26 / 0.12); --scrubn-muted #77756f; --scrubn-panel #ffffff. Treat these as the root colour tokens, one value per role, and name them to suit your code. Select it with the theme option set to "light". Keep every dimension, spacing value, state and motion from the brief unchanged, and keep text at 4.5:1 contrast or better on these surfaces. This selection takes precedence over references to other themes or options in the general brief. Implement this selected appearance; do not add a variant picker or alternative appearances unless requested. Implementation requirements: Use React and TypeScript. Keep the component self-contained, with uniquely scoped CSS and no animation libraries. Include required imports, styles and font setup in the result. Interaction: Drag the handle to scrub; ↑/↓ change by one step (Shift ×10, Alt ×0.1); type a number or expression and press Enter. onChange receives the clamped, rounded value. Precision and step are per field. Motion: Focus and hover rings fade over 140ms; the edge flash runs 320ms; an unreadable entry shakes 3px each way over 300ms. All of it is removed with reduced motion or motion={false}; the values still change. Accessibility: The handle is the input's label, so each field has a full spoken name ('Rotation') even when the handle shows a symbol. A description explains the keys, the arithmetic and the allowed range; a rejected entry sets aria-invalid and says the value is unchanged. Scrubbing is optional: everything it does is available from the keyboard. Responsive behavior: Fields fill their grid cell; the group's column count is a prop and the preview demo stacks the panel under the canvas on narrow screens. Touch: Drag the handle with a finger to scrub; tap the value to type with the decimal keypad. Preserve keyboard access, visible focus and reduced-motion behavior. Keep fictional demo data and simulated service calls in a separate usage example; expose callbacks for real actions and recover from rejected requests. Keep usage-example links inside the demo: use local buttons or prevent navigation. Demonstration links must not navigate to Vitrine routes or open other pages; preserve real URL support in the reusable component itself. Verify the result at narrow and wide viewport sizes, with keyboard input and reduced motion enabled.

Notes

Interaction
Drag the handle to scrub; ↑/↓ change by one step (Shift ×10, Alt ×0.1); type a number or expression and press Enter. onChange receives the clamped, rounded value. Precision and step are per field.
Motion
Focus and hover rings fade over 140ms; the edge flash runs 320ms; an unreadable entry shakes 3px each way over 300ms. All of it is removed with reduced motion or motion={false}; the values still change.
Accessibility
The handle is the input's label, so each field has a full spoken name ('Rotation') even when the handle shows a symbol. A description explains the keys, the arithmetic and the allowed range; a rejected entry sets aria-invalid and says the value is unchanged. Scrubbing is optional: everything it does is available from the keyboard.
Responsive
Fields fill their grid cell; the group's column count is a prop and the preview demo stacks the panel under the canvas on narrow screens.
On touch
Drag the handle with a finger to scrub; tap the value to type with the decimal keypad.

Featured

363 components