# NumberInput

- Page: https://jiguang132.com/resources/astryx/docs/number-input
- Resource: Astryx (https://jiguang132.com/resources/astryx.md)
- All guides: https://jiguang132.com/resources/astryx/docs.md

A form input for numeric values with built-in validation, min/max constraints, and step controls. Use NumberInput for quantities, measurements, percentages, and similar inputs.

## Installation

```bash
npm install @astryxdesign/core@0.7.1 @astryxdesign/theme-neutral@0.7.1 @stylexjs/stylex@0.19.0
```

Requires React 19+, base CSS and a Theme provider. See [Setup](/resources/astryx/docs/getting-started).

## Number Input

A form input for numeric values with built-in validation, min/max constraints, and step controls. Use NumberInput for quantities, measurements, percentages, and similar inputs.

| Prop | Type | Default | Description |
|---|---|---|---|
| label * | string |  | Label text for the input (always rendered for accessibility). |
| value * | number \| null \| undefined |  | Current value of the input. |
| onChange * | (value: number) => void |  | Callback fired when a valid text edit commits on blur or Enter, or when a step or clear control changes the value. |
| size | 'sm' \| 'md' \| 'lg' | 'md' | Size variant. |
| isLabelHidden | boolean |  | Visually hide the label (still accessible to screen readers). |
| description | string |  | Description text displayed between the label and input. |
| isOptional | boolean |  | Whether the field is optional (mutually exclusive with isRequired). |
| onKeyDown | (e: KeyboardEvent<HTMLInputElement>) => void |  | Callback fired on keydown events on the input. |
| isRequired | boolean |  | Whether the field is required (mutually exclusive with isOptional). |
| isDisabled | boolean |  | Whether the input is disabled. |
| isReadOnly | boolean | false | Makes the input read-only: the value is shown at full opacity and still submits with the form, but cannot be edited. Unlike isDisabled, a read-only input is not dimmed and stays in the tab order. Stepping is off in every form while read-only: arrow keys, the wheel, and the number steppers. isDisabled takes precedence when both are set. |
| disabledMessage | string |  | Explains why the input is disabled. With isDisabled, shows a tooltip on hover/keyboard focus and keeps the input focusable via aria-disabled (the field becomes read-only). Use this instead of wrapping a disabled NumberInput in Tooltip. |
| placeholder | string |  | Placeholder text. |
| labelTooltip | string |  | Tooltip text to display in an info icon at the end of the label. |
| startIcon | IconType |  | Icon to display at the start of the input. See `astryx docs icons` for valid semantic names. |
| labelIcon | IconType |  | Icon to display before the label text. See `astryx docs icons` for valid semantic names. |
| status | {type: 'error' \| 'warning' \| 'success', message?: string} |  | Validation status with optional message. |
| statusVariant | 'attached' \| 'detached' \| 'tooltip' | 'attached' | How the status message is placed relative to the input. attached overlaps directly below the input (bordered treatment); detached floats below as a separate element with spacing; tooltip hides the message box and surfaces it in a tooltip on the status icon. |
| min | number \| null |  | Minimum value allowed. A smaller entry commits at this value on blur or Enter. |
| max | number \| null |  | Maximum value allowed. A larger entry commits at this value on blur or Enter. |
| step | number \| null | 1 | Step increment for the input. |
| formatValue | (value: number) => string |  | Formats the committed value while the input is not focused. The raw numeric value is shown on focus for editing and the formatted value is exposed through aria-valuetext. |
| isWheelEnabled | boolean | true | Whether scrolling the wheel over the focused input steps the value. Disable this when page scrolling should always take priority. |
| hasNumberSteppers | boolean | false | Shows increment and decrement buttons at the end of the input. |
| units | string \| null |  | Units text to display at the end of the input (e.g., "%" or "GB"). |
| isIntegerOnly | boolean |  | Only allow integer values (no floating point). |
| hasClear | boolean | false | Shows a clear (×) button when the input has a value. When true, the onChange callback also accepts null to signal the user cleared the input. |
| htmlName | string |  | HTML name attribute for form submissions. |
| autoComplete | string |  | HTML autocomplete attribute. |
| width | SizeValue |  | Width of the field (number = pixels, string used as-is, e.g. "100%"). Sizes the whole field (label, control, and status) so they stay aligned. |
| hasAutoFocus | boolean |  | Whether to focus the input on mount. |
| onFocus | (e: FocusEvent<HTMLInputElement>) => void |  | Callback fired when the input receives focus. |
| onBlur | (e: FocusEvent<HTMLInputElement>) => void |  | Callback fired when the input loses focus. |
| onEnter | () => void |  | Callback fired when the user presses the Enter key. |
| containerXstyle | StyleXStyles |  | StyleX styles for the field container (label, control, and status together). No effect inside InputGroup (style the InputGroup instead) or in a `horizontal-labels` FormLayout. Root `xstyle`, `className`, and `style` are not accepted. |
| containerClassName | string |  | Class name for the field container. Same targeting as `containerXstyle`. |
| containerStyle | CSSProperties |  | Inline styles for the field container. Same targeting as `containerXstyle`. |
| controlXstyle | StyleXStyles |  | StyleX styles for the visual control box: the element that paints the border and background and holds icons and end controls. Never the native input. |
| controlClassName | string |  | Class name for the visual control box. |
| controlStyle | CSSProperties |  | Inline styles for the visual control box. |

### Usage guidance

- Let people paste formatted numbers: a pasted 1,234,234,234 is read under the field's locale and commits as 1234234234 on blur. Typing is never intercepted.
- Set min, max, and step to guide users toward valid values.
- Show units (e.g. "%" or "GB") so users know what the number represents.
- Set isWheelEnabled={false} when the input appears in a scrolling surface where wheel gestures should always scroll the page.
- Avoid: Use NumberInput for free-form text that happens to contain numbers; use TextInput instead.
- Avoid: Set both isOptional and isRequired on the same field.
- Avoid: Wrap a disabled NumberInput in Tooltip to explain why it's disabled; disabled controls swallow the hover events the wrapper needs. Use the disabledMessage prop instead.

### Theming API

```json
{
  "targets": [
    {
      "className": "astryx-number-input",
      "visualProps": [
        "size",
        "status"
      ],
      "states": [
        "disabled",
        "readonly"
      ]
    }
  ],
  "derived": [
    {
      "property": "padding",
      "expand": "container"
    },
    {
      "property": "borderRadius",
      "vars": [
        "--_field-radius"
      ]
    }
  ]
}
```

### Anatomy

- **Label**: The label for the number input.
- **Description**: Additional description text below the label.
- **Icon**: An optional icon within the input.
- **Placeholder**: Placeholder text shown when the input is empty.
- **Number steppers**: Optional buttons that increment or decrement by the configured step.


## Examples

- Number Input: A number input for quantity entry.
- NumberInput — Clearable: Number input with a clear button, unit suffix, and min/max constraint
- NumberInput — Range Constrained: Number input with min/max boundaries and a helper description
- NumberInput — Status Variants: Number inputs showing error, warning, and success validation states
- NumberInput — With Units: Number input with a percentage unit suffix and valid range

---

Index of all JGuang resources: https://jiguang132.com/llms.txt
