# NumberInput (React Native)

> Locale-aware numbers, currency and percent with − and + steppers that repeat when held.

GramproKit for React Native · Forms · Beta · Source: https://kit.gramproindia.com/native/docs/number-input

> **Beta:** React Native support is in beta. APIs may change or break between prereleases (npm tag `native`).

_Interactive demo:_ [open the live example](https://kit.gramproindia.com/native/docs/number-input). The example's source:

```tsx
import { useState } from "react";
import { Text } from "react-native";
import { NumberInput } from "@/component-lib/number-input";
import { useKitTheme } from "@/component-lib/shared/native";
import { Section } from "./layout"; // Section and Row: page layout for the demo

export function NumberInputDemo() {
  const { tokens } = useKitTheme();
  const [amount, setAmount] = useState<number | null>(1234567.5);
  return (
    <>
      <Section title="NumberInput · locales">
        <NumberInput
          label="Amount (en-IN, INR)"
          locale="en-IN"
          format="currency"
          currency="INR"
          decimals={2}
          value={amount}
          onValueChange={setAmount}
          step={100}
          clearable
        />
        <Text style={{ color: tokens.muted, fontSize: tokens.fontSize - 2 }}>Value: {String(amount)}</Text>
        <NumberInput label="Betrag (de-DE)" locale="de-DE" decimals={2} defaultValue={9876.5} />
        <NumberInput label="Discount" format="percent" step={0.05} min={0} max={1} defaultValue={0.15} />
      </Section>

      <Section title="NumberInput · limits and states">
        <NumberInput
          label="Quantity"
          description="1 to 10. Hold + or − to repeat."
          min={1}
          max={10}
          decimals={0}
          defaultValue={1}
          required
        />
        <NumberInput label="Weight" trailing="kg" step={0.1} defaultValue={72.5} snapToStep />
        <NumberInput label="Seats" defaultValue={4} error="Only 3 seats left." />
        <NumberInput label="Locked" defaultValue={42} readOnly />
        <NumberInput label="Disabled" defaultValue={7} disabled size="sm" />
      </Section>
    </>
  );
}
```

## Install

```bash
npx @grampro/kit@native add NumberInput
```

## Usage

```tsx
import { NumberInput } from "@/component-lib/number-input";

<NumberInput label="Amount" format="currency" currency="INR" locale="en-IN" min={0} step={100} />
```

## Props

### NumberInputProps

| Prop | Type | Description |
|---|---|---|
| `value` | `number \| null` | The number, or `null` for an empty field (controlled). |
| `defaultValue` | `number \| null` |   |
| `onValueChange` | `(value: number \| null) => void` | Fires with the parsed number, or `null` when the field is emptied. |
| `min` | `number` | Smallest accepted value, applied on blur by default (see `clampBehavior`). |
| `max` | `number` | Largest accepted value, applied the same way as `min`. |
| `step` | `number` | How much one stepper press moves. Default 1. |
| `largeStep` | `number` | Kept for API parity; touch has no Page Up / Page Down. Default ten steps. |
| `snapToStep` | `boolean` | Round every committed value onto the step grid, counting from `min`. |
| `decimals` | `number` | Fraction digits to show, and to round to. |
| `locale` | `string` | BCP 47 tag deciding the separators and digits, for reading and showing. |
| `format` | `NumberStyle` | Default `decimal`. `percent` shows 0.45 as 45%, as `Intl` does. |
| `currency` | `string` | ISO 4217 code, for `format="currency"`. |
| `useGrouping` | `boolean` | Thousands separators while the field is not being edited. Default true. |
| `clampBehavior` | `ClampBehavior` | When a value outside the limits is pulled back. Default `blur`. |
| `stepper` | `boolean` | The − and + buttons. Default true. |
| `clearable` | `boolean` | A button that empties the field. |
| `label` | `ReactNode` |   |
| `description` | `ReactNode` |   |
| `error` | `ReactNode` | The validation message; also marks the field invalid. |
| `size` | `NumberSize` | Default `md`. |
| `leading` | `ReactNode` | Before the number: a currency symbol, a unit. |
| `trailing` | `ReactNode` | After the number: a unit, a suffix. |
| `disabled` | `boolean` |   |
| `readOnly` | `boolean` |   |
| `required` | `boolean` | Marks the label with an asterisk. |
| `style` | `Styleable<ViewStyle>` |   |
| `styles` | `Partial<{ root: Styleable<ViewStyle>; label: Styleable<TextStyle>; control: Styleable<V…` |   |
| `localeText` | `Partial<NumberInputLocaleText>` |   |

Also accepts the props of `Omit< TextInputProps, "value" | "defaultValue" | "style" | "editable" | "onChangeText" | "keyboardType" | "inputMode" >`.

## Native and web

- Screen readers adjust it with increment and decrement actions (`role="spinbutton"`).
- Uses the same Intl parsing and formatting as the web, which Hermes supports.
- Web version: [NumberInput on the web](https://kit.gramproindia.com/numberinput).
