Input Number

Stable v1.0.2

A number input with proper min/max limits, step buttons, and prefix/suffix text, so people can't type something the form is just going to reject anyway.

Interactive Playground

Every prop, wired live. Adjust boundaries, adornments, and stepper behavior and watch the code snippet update in real time.

Label & Content
Top
State & Validation
Boundaries & Step
Buttons & Orientation
Vertical
Stepper Icons
Adornments
Appearance
Small (sm)
Advanced
None
Live Source Code
<InputNumber
  v-model="value"
  id="custom-quantity-id"
  label="Playground Value"
  placeholder="Enter a value..."
  :min="0"
  :max="100"
/>

Controls & Boundaries

The component enforces strict validation. If a user types a number outside the min and max bounds, it will auto-correct on blur.

Template
<InputNumber
  label="Item Quantity"
  v-model="quantity"
  :min="0"
  :max="10"
/>

<!-- Handles floating point precision cleanly -->
<InputNumber
  label="Weight Modifier"
  v-model="weight"
  :step="0.25"
/>

Prefixes & Suffixes

Ideal for financial rate matrices or capacity quotas. Use prefix for currencies and suffix for measurements.

$
TEU
%
Template
<!-- Prefix -->
<InputNumber label="Base Rate" prefix="$" v-model="rate" />

<!-- Suffix -->
<InputNumber label="Capacity" suffix="TEU" v-model="capacity" />

<!-- Hide Spinners -->
<InputNumber label="Quota" suffix="%" :showButtons="false" v-model="quota" />

Validation & States

Identical to BaseInputText, the error prop transforms the input and maps over arrays to display multiple validation requirements.

Value cannot be negative for this record.
$
Rate must be higher than the base carrier cost ($750).
Cannot apply standard margins to this specific route.
Template
<script setup>
const rateErrors = ref([
  'Rate must be higher than the base carrier cost ($750).',
  'Cannot apply standard margins to this specific route.'
])
</script>

<template>
  <!-- Pass the array directly to the error prop -->
  <InputNumber
    label="Complex Validation (Array)"
    prefix="$"
    v-model="rateErrorValue"
    :error="rateErrors"
  />
</template>

Input Sizing

The integrated spinners and text sizes scale perfectly across all four layout constraints.

Template
<!-- Dense layout inputs -->
<InputNumber label="Extra Small" size="xs" v-model="val1" />
<InputNumber label="Small" size="sm" v-model="val2" />

<!-- Standard layout inputs -->
<InputNumber label="Medium" size="md" v-model="val3" />
<InputNumber label="Large" size="lg" v-model="val4" />

Stepper Icons & Orientation

Use orientation to flank the field with a horizontal +/- stepper instead of the default stacked spinners, and override incrementIcon / decrementIcon to swap in any lucide: icon for either button.

Template
<!-- Horizontal stepper (default +/- icons) -->
<InputNumber label="Quantity" orientation="horizontal" :min="0" v-model="quantity" />

<!-- Override the icons, default vertical layout -->
<InputNumber
  label="Adjustment"
  v-model="adjustment"
  incrementIcon="lucide:plus"
  decrementIcon="lucide:minus"
/>

<!-- Combine orientation with custom icons -->
<InputNumber
  label="Progress"
  orientation="horizontal"
  incrementIcon="lucide:chevron-right"
  decrementIcon="lucide:chevron-left"
  :min="0"
  :max="100"
  v-model="progress"
/>

API Reference

Props

Name
Type / Signature
Default
Description
modelValue
number | null
undefined
The numeric value, bound via v-model.
id
string
undefined
Overrides the auto-generated element id (useId()), e.g. for an external <label for> or test hooks.
label
string
undefined
Top or left-aligned input label.
labelPosition
"top" | "left"
"top"
Alignment of the label relative to the input field.
required
boolean
false
Marks the field as required and renders an asterisk next to the label.
placeholder
string
undefined
Text shown when the input is empty.
disabled
boolean
false
Disables user interaction and grays out the component.
error
string | boolean | string[]
false
Applies red error styling and displays error message(s) below the input.
min
number
undefined
Lower bound the value is clamped to.
max
number
undefined
Upper bound the value is clamped to.
step
number
1
Amount incremented/decremented per click or hold tick.
showButtons
boolean
true
Shows the increment/decrement spinner buttons.
orientation
"vertical" | "horizontal"
"vertical"
Stacks the spinners vertically, or flanks the input with them horizontally.
incrementIcon
string
undefined
Overrides the increment button icon (any lucide: identifier).
decrementIcon
string
undefined
Overrides the decrement button icon (any lucide: identifier).
prefix
string
undefined
Static text rendered before the value, e.g. '$'.
suffix
string
undefined
Static text rendered after the value, e.g. 'kg'.
size
"xs" | "sm" | "md" | "lg" | "xl"
"sm"
Dimensional size of the component.
keyfilter
string | RegExp
undefined
Restricts which characters can be typed into the field.

Events

Event Name
Payload Signature
Description
@focus
(event: FocusEvent)
Fired when the input receives focus.
@blur
(event: FocusEvent)
Fired when the input loses focus.
@input
(value: number | null | undefined)
Fired on every keystroke or spinner click.
@change
(value: number | null | undefined)
Fired when the value commits.