npm install unit-field Examples
Drag the labels to scrub. Arrow keys for fine control, shift for large steps.
Grouped fields for spacing values.
Live value updates on drag, committed value fires on release.
Font size, line height, and letter spacing.
Aa Bb Cc
Usage
Install
Add unit-field to your project. Works with any React 18+ or 19+ setup.
npm install unit-fieldBasic field
Compose a numeric field with a draggable label and input. Format and parse control how values are displayed and read back.
import { UnitField } from 'unit-field';
import { useState } from 'react';
function WidthField() {
const [width, setWidth] = useState(100);
return (
<UnitField.Root
value={width}
onValueChange={setWidth}
min={0}
max={1000}
format={(v) => `${v}px`}
parse={(v) => parseInt(v)}
>
<UnitField.DragArea>W</UnitField.DragArea>
<UnitField.Input aria-label="Width" />
</UnitField.Root>
);
}Drag to scrub
The drag area supports sensitivity control and Shift for large steps. Arrow keys, Home, End, Page Up/Down all work out of the box.
<UnitField.Root
value={rotation}
onValueChange={setRotation}
min={-360}
max={360}
step={1}
largeStep={15}
format={(v) => `${v}°`}
parse={(v) => parseInt(v)}
>
<UnitField.DragArea sensitivity={2}>
Rotate
</UnitField.DragArea>
<UnitField.Input aria-label="Rotation" />
</UnitField.Root>Committed values
Use onValueCommitted to distinguish between live scrubbing updates and final committed values — perfect for undo history or saving state.
<UnitField.Root
value={fontSize}
onValueChange={setFontSize}
onValueCommitted={(v) => {
// Fires on Enter, blur, or drag end
saveFontSize(v);
}}
min={8}
max={120}
format={(v) => `${v}px`}
parse={(v) => parseInt(v)}
>
<UnitField.DragArea>Size</UnitField.DragArea>
<UnitField.Input aria-label="Font size" />
</UnitField.Root>