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 it for exact numeric input. For approximate values over a range, use Slider. For read-only values, use Meter.
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>
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.