ScrubField
A compact numeric field whose label is the drag handle.
Usage
Basic
An integer, a percentage, and a half step.
Loading demo...
Best Practices
- Keep labels short (
W,H,Radius); the label is the drag handle. - Let the host decide
active, usually "value differs from the preset", compared against data rather than a constant. - Use
clampOn="blur"in forms people type into; keep the default'input'in inspectors with a live preview. - Use
TxSliderto pick a value by position on a track, andTxNumberInputfor a form field with stepper buttons.
API Reference
Props
| Name | Type | Default | Description |
|---|---|---|---|
modelValue | number | — | The current value (controlled). |
label | string | — | Short label that doubles as the drag handle. |
min / max | number | — | Bounds; dragging, arrow keys, and typing all clamp to them. |
step | number | 1 | Step size; a fractional step keeps its decimals. |
suffix | string | — | Unit after the value, such as %. |
active | boolean | false | Tints the field as changed; the host decides what counts as changed. |
disabled | boolean | false | Disables dragging, arrow keys, and typing. |
pixelsPerStep | number | 2 | Pointer travel that advances one step. |
shiftMultiplier | number | 10 | Arrow-key multiplier while Shift is held. |
clampOn | 'input' | 'blur' | 'input' | When typed text is clamped: on every keystroke or on blur. |
ariaLabel | string | — | Accessible name for the handle; falls back to label. |
valueLabel | string | '{label} value' | Accessible name for the input. |
Events
| Event | Payload | Description |
|---|---|---|
update:modelValue | (value: number) | Fires when the value changes; never repeats an identical value. |
change | (value: number) | Fires together with update:modelValue. |
scrubStart / scrubEnd | — | Start and end of a drag, cancellation included. |
Exposed Methods
| Method | Description |
|---|---|
focus() | Focuses the drag handle. |
focusInput() | Focuses the number input. |
Overview
- Drag: move sideways on the label; every
pixelsPerSteppixels advance onestep, measured from the gesture's start, with no track. Escape during a drag restores the starting value. - Keyboard: ↑ → increase, ↓ ← decrease, Shift multiplies by
shiftMultiplier, and Home / End jump to the bounds. - Typing: the value is a native
<input>;clampOn="blur"keeps the typed text until blur. Escape reverts the text. - The handle is a
role="slider"witharia-valuenow/aria-valuemin/aria-valuemax/aria-orientation, plusaria-valuetextwhensuffixis set; the input is a second control with its own accessible name. - The handle sets
touch-action: pan-y, leaving vertical gestures to page scroll;pointercancelandlostpointercaptureboth end a drag. - Under reduced motion, the only state transition is switched off.
Technologies
- Travel is quantised, not the result:
round(distance / pixelsPerStep) * step, so fractional steps work and an off-grid starting value is not snapped. - Source:
packages/tuffex/packages/components/src/scrub-field/. - Adapted from Beautiful UI (https://www.beautifului.dev), © 2026 Shane Levine, MIT.
查看源码
packages/tuffex/packages/components/src/scrub-field/index.ts