Forms
InputNumber
A numeric input with stepper buttons and locale-aware formatting. Supports currency and percent styles, min/max clamping, and step snapping via keyboard or wheel.
Playground
Experiment with different props in real-time.
Basic Usage
<script lang="ts">
import { InputNumber } from 'sv5ui';
let value = $state<number | null>(1);
</script>
<InputNumber bind:value />Min & Max
Values are clamped on commit and the steppers disable at the bounds.
<!-- Values are clamped to min/max on commit -->
<InputNumber value={5} min={0} max={10} />Step
Steps snap to multiples of step by default.
<!-- Step by 5, snapped to multiples of the step -->
<InputNumber value={10} step={5} min={0} />Currency
<InputNumber
value={1999.99}
formatOptions={{ style: 'currency', currency: 'USD' }}
/>Percent
<!-- step defaults to 0.01 for percent -->
<InputNumber value={0.25} formatOptions={{ style: 'percent' }} />Locale
Formatting and parsing follow the given locale.
<InputNumber
value={1234567.89}
locale="de-DE"
formatOptions={{ minimumFractionDigits: 2 }}
/>Vertical Steppers
<InputNumber value={3} orientation="vertical" min={0} max={10} />Variants
<InputNumber value={1} variant="outline" />
<InputNumber value={1} variant="soft" />
<InputNumber value={1} variant="subtle" />
<InputNumber value={1} variant="ghost" />Sizes
<InputNumber value={1} size="xs" />
<InputNumber value={1} size="sm" />
<InputNumber value={1} size="md" />
<InputNumber value={1} size="lg" />
<InputNumber value={1} size="xl" />Disabled & Readonly
<InputNumber value={5} disabled />
<InputNumber value={5} readonly />Form Field
The hidden input carries the raw numeric value for native submission.
<script lang="ts">
import { InputNumber, FormField } from 'sv5ui';
let quantity = $state<number | null>(1);
const error = $derived(
(quantity ?? 0) < 1 ? 'Quantity must be at least 1' : ''
);
</script>
<FormField label="Quantity" {error}>
<InputNumber bind:value={quantity} name="quantity" min={1} max={99} />
</FormField>UI Slots
Use the ui prop to override classes.
| Slot | Description |
|---|---|
root | The field wrapper |
base | The underlying input element |
increment | The increment button |
decrement | The decrement button |
incrementIcon | The increment button icon |
decrementIcon | The decrement button icon |
Props
| Prop | Type | Default |
|---|---|---|
value | number | null | null |
onValueChange | (value: number | null) => void | - |
min | number | - |
max | number | - |
step | number | 1 |
stepSnapping | boolean | true |
formatOptions | Intl.NumberFormatOptions | - |
locale | string | 'en' |
orientation | 'horizontal' | 'vertical' | 'horizontal' |
incrementIcon | string | 'lucide:plus' |
decrementIcon | string | 'lucide:minus' |
increment | ButtonProps | - |
decrement | ButtonProps | - |
disableWheelChange | boolean | false |
invertWheelChange | boolean | false |
variant | 'outline' | 'soft' | 'subtle' | 'ghost' | 'none' | 'outline' |
color | ColorType | 'primary' |
size | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | 'md' |
disabled | boolean | false |
readonly | boolean | false |
required | boolean | false |
name | string | - |
highlight | boolean | false |
ref | HTMLInputElement | null | null |
class | string | - |
ui | Record<Slot, Class> | - |