---
title: NumberInput
description: A numeric field with step buttons, clamping, and precision.
category: Form
status: beta
since: 0.3.7
tags: [number, input, form]
syncStatus: reviewed
verified: true
---

## Usage

### Range and Precision
`min` / `max` set the range, `step` the increment, and `precision` the decimal places.
::::TuffDemoWrapper{demo="NumberInputNumberInputDemo" code-lang="vue"}
---
code: |
  <script setup lang="ts">
  import { ref } from 'vue'

  const percentage = ref(35)
  </script>

  <template>
    <TxNumberInput v-model="percentage" :min="0" :max="100" :step="5" :precision="0" />
  </template>
---
::::

### Best Practices

- Pass explicit `min`, `max`, and `step` for percentages, quotas, and pagination.
- Handle decimals with `precision` instead of rounding in the consumer after every event.
- Set `controls=false` in dense table filters, where typing is faster.
- Treat `null` as unset in validation and API mapping.

## API Reference

### Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `modelValue` / `v-model` | `number \| null` | `null` | The number; `null` when the field is empty. |
| `min` | `number` | - | Minimum value. |
| `max` | `number` | - | Maximum value. |
| `step` | `number` | `1` | Increment of the step buttons and the native input. |
| `precision` | `number` | - | Decimal places to keep. |
| `placeholder` | `string` | `''` | Placeholder text. |
| `disabled` | `boolean` | `false` | Disables the field and the buttons. |
| `readonly` | `boolean` | `false` | Makes the field read-only and blocks stepping. |
| `controls` | `boolean` | `true` | Shows the decrease and increase buttons. |
| `decreaseLabel` | `string` | `'Decrease value'` | The decrease button's `aria-label`; pass a localized string. |
| `increaseLabel` | `string` | `'Increase value'` | The increase button's `aria-label`; pass a localized string. |

### Events

| Event | Params | Description |
|------|--------|-------------|
| `update:modelValue` | `(value: number \| null)` | Fires with the normalized value. |
| `change` | `(value: number \| null)` | Fires together with `update:modelValue`. |
| `focus` | `(event: FocusEvent)` | The native focus event. |
| `blur` | `(event: FocusEvent)` | The native blur event; the field re-normalizes on blur. |

### Exposed Methods

| Name | Description |
|------|-------------|
| `focus()` | Focuses the native input. |
| `blur()` | Blurs the native input. |
| `inputRef` | Ref to the native input. |

## Overview

- Empty input normalizes to `null`.
- Typed values clamp to `min` / `max` on blur, step results right away; `precision` rounds after clamping.
- Unparseable text left at blur falls back to the current value, or `null` if there is none.
- `controls=false` hides the step buttons and keeps the native numeric field.
- `readonly` and `disabled` both block stepping; `disabled` also disables the field.

## Technologies

- Attrs other than `class` / `style` go to the native input.
- Source: `packages/tuffex/packages/components/src/number-input/`.

<TuffDocSourceLink />
