Phoundry UI

NumberInput

Numeric input with increment/decrement buttons, min/max clamping, step control, and keyboard arrow support. Hold-to-repeat on buttons for fast value changes.

import { NumberInput } from 'phoundry-ui';

Basic

Value: 42
Show code
<NumberInput value={qty} onchange={(v) => qty = v} />

With Min / Max

Clamped 0–10: 5
Show code
<NumberInput value={qty} onchange={(v) => qty = v} min={0} max={10} />

Custom Step

Step 0.25: 0
Show code
<NumberInput value={price} onchange={(v) => price = v} step={0.25} min={0} />

Sizes

sm
md
Show code
<NumberInput value={v} onchange={set} size="sm" />
<NumberInput value={v} onchange={set} size="md" />

Disabled

Steppers are inert and the field does not accept edits.

Show code
<NumberInput value={qty} onchange={set} disabled />

Button Layout

vertical (default)
horizontal
Show code
<NumberInput value={v} onchange={set} /> <!-- vertical (default) -->
<NumberInput value={v} onchange={set} buttonLayout="horizontal" />

Props

PropTypeDefaultDescription
value requirednumberCurrent numeric value
onchange required(value: number) => voidCalled when value changes
min numberMinimum allowed value
max numberMaximum allowed value
step number1Increment / decrement step
size 'sm' | 'md''sm'Wrapper height aligned to Button `sm` / `md` control scale
width string'w-24'Tailwind width class for the wrapper
buttonLayout 'vertical' | 'horizontal''vertical'Button arrangement: vertical (stacked on right) or horizontal (left/right)
disabled booleanfalseDisables the input and buttons
class stringAdditional CSS classes
id stringHTML id attribute
name stringHTML name attribute for forms
element HTMLInputElementBindable reference to the underlying input element
…rest HTMLAttributes<input>Additional attributes forwarded to the inner `<input>` (e.g. `aria-label`, `autocomplete`).

Usage tips

  • Hold down the +/- buttons for continuous increment — useful for large ranges.
  • Arrow Up / Arrow Down keys work when the input is focused.
  • Use width to control the wrapper size — defaults to w-24 which works well for most counters.
  • Always set min and max when the domain has natural bounds to prevent invalid values.
  • Non-numeric manual input resolves to min when set, otherwise 0 — validate in your form layer if you need stricter behavior.