Number Field
NumberField is an unstyled spinbutton control. It combines a native number input with increment/decrement buttons, optional scrub area, wheel and keyboard stepping, min/max/step constraints, cancelable changes, commit events, and Field integration.
Use Number Field for exact numeric input, Slider for range input, and Meter for read-only values.
Anatomy
#scrub: Custom content for the optional drag scrub area.#decrement: Content inside the decrement button.#increment: Content inside the increment button.
The native type="number" input is generated by the component and owns keyboard, form, and role="spinbutton" behavior. Style it with ui.input.
Usage
Value: 3
Examples
Min, max, and step
Use min, max, and step for button, keyboard, wheel, and input normalization.
<script setup lang="ts">
import { ref } from "vue";
import { NumberField } from "akaza-ui";
const seats = ref<number | null>(3);
</script>
<template>
<NumberField v-model="seats" :min="1" :max="10" :step="1" />
</template>
Decimal values
Decimals work with step. By default, values snap to the nearest step.
<template>
<NumberField v-model="ratio" :min="0" :max="1" :step="0.05" />
</template>
Scrub area
Add scrub-label or #scrub to let pointer users drag horizontally to change the value.
<template>
<NumberField v-model="amount" scrub-label="Drag" :min="0" :max="100" />
</template>
Change vs commit
value-change fires before every accepted value update. value-commit fires after completed interactions such as blur, button click, wheel step, keyboard step, or scrub release.
<template>
<NumberField
v-model="quantity"
@value-change="(value) => draft = value"
@value-commit="(value) => save(value)"
/>
</template>
Field integration
NumberField inherits metadata from Field, including name, required, invalid state, and described-by ids. Native invalid state from required/min/max/step constraints is revealed after input, blur, or invalid submit; it is not shown on initial render.
<template>
<Field label="CPU cores" name="cpu" required>
<NumberField v-model="cpu" :min="1" :max="16" />
</Field>
</template>
Drafts, bounds, and reset
Typing a finite number emits value-change without immediately snapping or clamping it. This permits intermediate values such as 1 while entering 12 with min="10". On blur after an edit, the value snaps to the step grid and clamps to min/max before value-commit. A supplied out-of-range value is validated on blur; merely focusing and leaving it does not silently repair external state.
Increment/decrement remain available when empty. They start from min when present, otherwise zero, apply the requested step, then clamp. Canceled changes restore the accepted input value. Native form reset restores the mount-time value and clears interaction state; a canceled reset leaves both unchanged.
API Reference
Props
| Prop | Type | Default | Description |
|---|---|---|---|
id | string | field id | Input id. |
name | string | field name | Form field name. |
min | number | — | Minimum value. |
max | number | — | Maximum value. |
step | number | 1 | Increment/decrement step. |
placeholder | string | — | Native input placeholder. |
required | boolean | false | Required state. |
disabled | boolean | false | Disabled state. |
readonly | boolean | false | Read-only state. |
invalid | boolean | false | Sets invalid attrs. |
stepSnapping | boolean | true | Snap input/button values to the nearest step. |
disableWheelChange | boolean | false | Disables focused wheel stepping. |
invertWheelChange | boolean | false | Reverses wheel direction. |
focusOnChange | boolean | true | Focuses the input after button/scrub changes. |
scrubLabel | string | — | Renders a drag scrub area before the decrement button. |
scrubStep | number | step | Step used by scrub dragging. |
disableScrub | boolean | false | Disables scrub dragging. |
getValueLabel | (value) => string | undefined | — | Human-readable aria-valuetext. |
ariaLabel | string | — | Accessible label when no visible label exists. |
ariaDescribedby | string | field description/error | Accessible description ids. |
ui | NumberFieldUi | — | Classes for structural parts. |
Emits
| Event | Payload | Description |
|---|---|---|
value-change | (value, details) | Fired before model updates. details.cancel() prevents the update. |
value-commit | (value, details) | Fired on blur and after button, wheel, keyboard, or scrub interactions. |
Slots
| Slot | Props | Description |
|---|---|---|
scrub | value, isScrubbing | Custom scrub area content. |
decrement | value, decrement | Custom decrement button content. |
increment | value, increment | Custom increment button content. |
UI Options
| Key | Description |
|---|---|
root | Root wrapper. |
scrubArea | Optional drag scrub area. |
decrement | Decrement button. |
input | Native number input. |
increment | Increment button. |
Styling Hooks
| UI key | CSS class | Data attrs |
|---|---|---|
root | akaza-number-field | data-akaza-disabled, data-akaza-readonly, data-akaza-invalid, data-akaza-dirty, data-akaza-touched, data-akaza-filled, data-akaza-focused, data-akaza-scrubbing |
scrubArea | akaza-number-field-scrub-area | same state attrs |
decrement | akaza-number-field-decrement | same state attrs |
input | akaza-number-field-input | same state attrs plus native validity attrs |
increment | akaza-number-field-increment | same state attrs |
Plain class applies to the root wrapper. Use ui.input for the actual input.
Native data-akaza-invalid appears after interaction or invalid submit. Controlled invalid state from the invalid prop or parent Field appears immediately.
Keyboard
| Key | Behavior |
|---|---|
ArrowUp / ArrowDown | Increment/decrement by step. |
PageUp / PageDown | Increment/decrement by step * 10. |
Home | Set to min when provided. |
End | Set to max when provided. |
Mouse wheel changes the value only while the input is focused. Set disableWheelChange to opt out.