Skip to content
weftGitHub

NumberField

A number you can type or step, with arrow keys and two buttons.

SourcePackage @weft-js/warp

Preview

tsx
import { NumberField } from '@weft-js/warp'export function Basic() {  return (    <NumberField label="Retries" defaultValue={3} min={0} max={10} />  )}const min = 60_000

Installation

npm install @weft-js/warp

Usage

tsx
import { NumberField } from '@weft-js/warp'<NumberField label="Retries" defaultValue={3} min={0} max={10} />

Sizes

size matches the other fields in a form.

tsx
import { NumberField, Stack } from '@weft-js/warp'export function Sizes() {  return (    <Stack gap="group">      <NumberField label="Small" size="sm" defaultValue={3} min={0} max={10} />      <NumberField label="Medium" defaultValue={3} min={0} max={10} />      <NumberField label="Large" size="lg" defaultValue={3} min={0} max={10} />    </Stack>  )}const min = 60_000

Fractions and a unit

A fractional step moves by that much. suffix names the unit.

tsx
import { NumberField } from '@weft-js/warp'export function Decimal() {  return (    <NumberField label="CPU per copy" defaultValue={0.5} min={0.25} max={8} step={0.25} suffix="vCPU" />  )}const min = 60_000

Money

prefix shows the currency. Page Up and Page Down move ten steps at a time.

tsx
import { NumberField } from '@weft-js/warp'export function Money() {  return (    <NumberField label="Monthly budget" defaultValue={1500} min={0} step={50} prefix="$" hint="We email you at 80%." />  )}const min = 60_000

Hint, error, read-only, disabled

Read-only and disabled turn the steppers off too.

tsx
import { Grid, NumberField, Stack, Text } from '@weft-js/warp'export function States() {  return (    <Grid cols={2} gap="group">      <Cell name="Empty"><NumberField label="Retries" min={0} max={10} /></Cell>      <Cell name="Hint"><NumberField label="Retries" defaultValue={3} min={0} max={10} hint="0 turns retries off." /></Cell>      <Cell name="Invalid"><NumberField label="Retries" defaultValue={10} min={0} max={10} error="Ten retries can hide a real failure." /></Cell>      <Cell name="Read-only"><NumberField label="Retries" defaultValue={3} readonly /></Cell>      <Cell name="Disabled"><NumberField label="Retries" defaultValue={3} disabled /></Cell>    </Grid>  )}const min = 60_000const Cell = (p: { name: string; children?: unknown }) => (  <Stack gap="tight">    <Text role="caption" subtle>{p.name}</Text>    {p.children}  </Stack>)

Buying seats

Use min and max to limit the count, and read value to work out a total.

tsx
import { state } from '@weft-js/core'import { NumberField, Stack, Text } from '@weft-js/warp'export function Seats() {  const seats = state<number | null>(8)  return (    <Stack gap="related">      <NumberField label="Seats" value={seats} min={1} max={50} hint="$12 a seat, each month." />      <Text subtle>Total: ${(seats.value ?? 0) * 12} a month</Text>    </Stack>  )}const min = 60_000

When to use

Use it for

  • An exact number, like seats or a retry count

Reach for something else

  • Slider, when a rough value is enough

Accessibility

↑↓
Steps up or down
PageUpPageDown
Steps by ten
HomeEnd
Jumps to the bound, when there is one

API Reference

PropTypeDefaultDescription
labelstring—The accessible name, drawn as the floating border label (or above, classic). Required.
hintunknown—One line of help under the control.
errorunknown—Shown instead of the hint; marks the field invalid.
iconIconRef—Leading icon: it sweeps with the border.
prefixunknown—Text or an element inside the field before the value, such as $.
suffixunknown—Text or an element inside the field after the value, such as kg.
variant"floating" | "classic"—floating (default, or the app's warp({ fields })) · classic: the label above.
appearance"line"—line: only a bottom line under the value, no box or fill. The boxed field otherwise.
size"sm" | "md" | "lg"'md'Control size. md by default.
clearablebooleanfalseA clear button (shown once there is a value).
counternumber—Maximum length, shown as a counter.
idstring—The element id. One is made for you if you leave it out.
disabledbooleanfalseTurns it off, and takes it out of the tab order.
readonlybooleanfalseShows the value and lets it be selected and copied, but not changed.
valuenumber | State<number | null> | null—The current value, when you own the state.
defaultValuenumber | null—The starting value, when the component owns the state.
minnumber—The lowest it can step to.
maxnumber—The highest it can step to.
stepnumber1How far one press moves it.
namestring—The name it posts under in a form.
requiredbooleanfalseThe form will not submit without it.
EventTypeDefaultDescription
onInput((e: InputEvent & { currentTarget: HTMLInputElement & HTMLTextAreaElemen…—Called on each keystroke.
onValueChange((v: number | null, reason: ChangeReason) => void)—Called with each new value, and whether a pointer, a key or code made the change.

Parts

Every element carries a stable name, so you can style it from your own CSS: [data-scope="number-field"] [data-part="step"]

stepstepsinput

RelatedInputSlider