# NumberInput

> Numeric entry with stepper buttons and full spinbutton keyboard support.

Category: Forms · Status: stable · Package: @bindshq/stance-react@0.1.1 · Docs: https://stanceui.com/components/number-input

Use NumberInput for quantities with a meaningful range and step: licence seats, reminder intervals, prices. Values are clamped to min and max and rounded to the step precision when the field loses focus. For values picked from a visual range, consider Slider.

## Import

```tsx
import { NumberInput, FormField } from '@bindshq/stance-react';
```

Styles are imported once per app: `@bindshq/stance-tokens/css` and `@bindshq/stance-react/styles.css`.

## Examples

### Basic

```tsx
import { FormField, NumberInput } from '@bindshq/stance-react';

export function Basic() {
  return (
    <div style={{ width: '100%', maxWidth: 240 }}>
      <FormField label="Licence seats" description="Between 1 and 500.">
        <NumberInput defaultValue={25} min={1} max={500} />
      </FormField>
    </div>
  );
}
```

### Decimal steps and formatting

```tsx
import { FormField, NumberInput } from '@bindshq/stance-react';

export function Decimal() {
  const gbp = new Intl.NumberFormat('en-GB', { style: 'currency', currency: 'GBP' });
  return (
    <div style={{ width: '100%', maxWidth: 240 }}>
      <FormField label="Price per seat">
        <NumberInput defaultValue={4.5} min={0} step={0.5} format={(v) => gbp.format(v)} />
      </FormField>
    </div>
  );
}
```

### With affixes

```tsx
import { FormField, NumberInput } from '@bindshq/stance-react';

export function WithAffixes() {
  return (
    <div style={{ width: '100%', maxWidth: 240 }}>
      <FormField label="Send reminders every">
        <NumberInput defaultValue={3} min={1} max={30} suffix="days" />
      </FormField>
    </div>
  );
}
```

### Without stepper

```tsx
import { FormField, NumberInput } from '@bindshq/stance-react';

export function NoStepper() {
  return (
    <div style={{ width: '100%', maxWidth: 240 }}>
      <FormField label="Contract value">
        <NumberInput hideStepper prefix="£" defaultValue={12000} step={100} />
      </FormField>
    </div>
  );
}
```

## API reference

| Component | Prop | Type | Default | Description |
| --- | --- | --- | --- | --- |
| NumberInput | `value` | `number \| null` | None | Controlled value; null when empty. |
| NumberInput | `defaultValue` | `number \| null` | `null` | Initial value. |
| NumberInput | `onValueChange` | `(value: number \| null) => void` | None | Called with the committed number. |
| NumberInput | `min` | `number` | None | Minimum value. |
| NumberInput | `max` | `number` | None | Maximum value. |
| NumberInput | `step` | `number` | `1` | Increment for arrows and steppers. |
| NumberInput | `largeStep` | `number` | `10` | Multiplier for PageUp/PageDown. |
| NumberInput | `precision` | `number` | None | Decimal places; inferred from step. |
| NumberInput | `format` | `(value: number) => string` | None | Display formatter; also used for aria-valuetext. |
| NumberInput | `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | Control height. |
| NumberInput | `hideStepper` | `boolean` | `false` | Hide the increment/decrement buttons. |
| NumberInput | `prefix / suffix` | `ReactNode` | None | Content inside the field box. |
| NumberInput | `incrementLabel / decrementLabel` | `string` | `'Increase' / 'Decrease'` | Stepper button labels (localise these). |

## Accessibility

- Implements the WAI-ARIA spinbutton pattern: role="spinbutton" with aria-valuenow, aria-valuemin, aria-valuemax and aria-valuetext when formatted.
- Uses a text input with inputMode so mobile shows a numeric keypad without the native number input’s scroll-wheel and locale problems.
- Stepper buttons are mouse and touch affordances and are removed from the tab order; the keyboard uses arrow keys instead.

## Keyboard

| Keys | Action |
| --- | --- |
| `ArrowUp` `ArrowDown` | Increase or decrease by one step. |
| `PageUp` `PageDown` | Increase or decrease by a large step. |
| `Home` `End` | Jump to the minimum or maximum (when set). |
| `Enter` | Commit the typed value. |

## Related

- https://stanceui.com/components/input
- https://stanceui.com/components/slider
