Unit Input

Notices when a number makes far more sense in another unit (70 cm is likely inches) and offers a one-tap conversion.

StopsHeight saved in the wrong unit

Installation

pnpm dlx shadcn@latest add https://bollard-ui.vercel.app/r/unit-input.json

The files land in your project. They're yours to edit.

Usage

unit-input-usage.tsx
import { UnitInput } from "@/components/ui/unit-input"

<UnitInput label="Height" preset="height" defaultValue="70" />

What it catches

  • Values outside the usual range for the unit but inside another's
  • Feet-and-inches notation (5'9", 5 ft 9 in, 5.9)
  • Body temperature in the wrong scale
  • Conversion rounded to the target unit's precision

Props

UnitInput props
PropTypeDefault
label* (required)

Visible label.

string—
hint

Helper text shown under the field while there is nothing to warn about.

string—
preset* (required)

A built-in preset or your own units and plausible ranges.

keyof typeof UNIT_PRESETS | UnitPreset—
ranges

Override plausible ranges per unit id, e.g. `{ cm: [45, 120] }` for children.

Record<string, [number, number]>—
value

Controlled text of the number.

string—
defaultValue

Initial text when uncontrolled.

string""
onValueChange

Called with the number's text on every change.

(value: string) => void—
unit

Controlled unit id.

string—
defaultUnit

Unit selected initially; defaults to the first unit.

string—
onUnitChange

Called when the unit changes, including from a one-tap switch.

(unit: string) => void—
onMeasurementChange

Called with the number, its unit and the value in the preset's base unit, or null.

(measurement: { value: number; unit: string; base: number } | null) => void—
delay

Pause in ms before warnings appear while typing. Leaving the field shows them at once.

number700
keepLabel

Accessible label of the button that keeps the value as typed.

string"Keep it as typed"
messages

Override any other visible string.

Partial<typeof UNIT_INPUT_MESSAGES>—

* required. Also accepts the native props of <input> (className, aria-*, data-*…), passed through to it.

Accessibility

  • Visible <label>; unit picker has an aria-label
  • aria-invalid with suggestions in a polite live region via aria-describedby
  • Keep-as-typed dismiss has an aria-label

Only what the source does. Test with your own screen reader and content before shipping.

Limitations

  • Plausibility ranges are presets you can override; unusual real values can be flagged
  • Converts between the units in the preset only

What it stops

Height saved in the wrong unit

Also known as

units · unit converter · cm inches · kg lbs · height · weight · temperature · measurements

Field type

Dependencies

Pairs well with