Skip to main content
Vuetify0 is now in beta!
Vuetify0 Logo
Theme
Mode
Palettes
Accessibility
Vuetify One
Sign in to Vuetify One

Access premium tools across the Vuetify ecosystem — Bin, Play, Studio, and more.

Not a subscriber? See what's included

NumberField

Numeric input with increment/decrement buttons, drag-to-scrub, and locale-aware formatting. Supports currency, percent, and unit display via Intl.NumberFormat.

Usage

NumberField renders a spinbutton input with optional increment, decrement, and scrub controls. Wire it up with v-model for two-way binding.

<script setup lang="ts">
  import { NumberField } from '@vuetify/v0'
  import { shallowRef } from 'vue'

  const quantity = shallowRef<number | null>(1)
</script>

<template>
  <div class="flex items-center justify-center">
    <NumberField.Root v-model="quantity" :max="99" :min="0">
      <NumberField.Decrement class="px-3 py-2 border border-divider rounded-l-lg hover:bg-surface-tint disabled:opacity-50">
        &minus;
      </NumberField.Decrement>

      <NumberField.Control class="w-20 text-center border-y border-divider py-2 outline-none bg-transparent" />

      <NumberField.Increment class="px-3 py-2 border border-divider rounded-r-lg hover:bg-surface-tint disabled:opacity-50">
        +
      </NumberField.Increment>
    </NumberField.Root>
  </div>
</template>

Anatomy

vue
<script setup lang="ts">
  import { NumberField } from '@vuetify/v0'
</script>

<template>
  <NumberField.Root>
    <NumberField.Scrub />

    <NumberField.Description />

    <NumberField.Decrement />

    <NumberField.Control />

    <NumberField.Increment />

    <NumberField.Error />

    <NumberField.HiddenInput />
  </NumberField.Root>
</template>

Architecture

Root composes createNumberField which delegates to createInput for field state and createNumeric for math operations. Each sub-component consumes the root context.

NumberField Architecture

Use controls to zoom and pan. Click outside or press Escape to close.

NumberField Architecture

Examples

Currency Formatting

Locale-aware currency display using Intl.NumberFormat. The format prop accepts any Intl.NumberFormatOptions, and the Scrub label allows drag-to-adjust the value.

Total: $48.30

Design Tool Scrub

Figma-style property inputs where the label acts as a scrub control. Drag horizontally on any label to adjust its value. Uses the Pointer Lock API for unbounded movement.

Recipes

Spin-on-Hold

Increment and Decrement buttons repeat automatically when held. Configure timing with spin-delay (initial pause, default 400ms) and spin-rate (repeat interval, default 60ms):

vue
<template>
  <NumberField.Root :spin-delay="300" :spin-rate="40">
    <NumberField.Decrement>-</NumberField.Decrement>
    <NumberField.Control />
    <NumberField.Increment>+</NumberField.Increment>
  </NumberField.Root>
</template>

Mouse Wheel

Enable value adjustment via scroll wheel when the input is focused:

vue
<template>
  <NumberField.Root v-model="value" wheel>
    <NumberField.Control />
  </NumberField.Root>
</template>

Data Attributes

Style interactive states without slot props:

AttributeValuesComponents
data-statevalid, invalid, pristineRoot, Control
data-dirtytrueRoot
data-focusedtrueRoot, Control
data-disabledtrueRoot, Control, Increment, Decrement, Scrub
data-readonlytrueRoot, Control, Scrub

Accessibility

NumberField.Control renders with role="spinbutton" and full ARIA attributes per the WAI-ARIA Spinbutton pattern↗︎.

ARIA Attributes

AttributeValueNotes
rolespinbuttonApplied to Control
aria-valuenowCurrent valueundefined when empty
aria-valueminMin valueOnly when finite
aria-valuemaxMax valueOnly when finite
aria-valuetextFormatted stringScreen readers announce “$42.00” not “42”
aria-invalidtrueWhen validation fails
aria-labelLabel textFrom Root’s label prop
aria-describedbyDescription IDWhen Description is mounted
aria-errormessageError IDWhen Error is mounted with messages
aria-requiredtrueWhen Root has required

Increment and Decrement buttons use tabindex="-1" to keep them out of the tab sequence — only the Input is focusable.

Keyboard Navigation

KeyAction
ArrowUpIncrement by one step
ArrowDownDecrement by one step
Shift+ArrowUpIncrement by 10 steps
Shift+ArrowDownDecrement by 10 steps
PageUpIncrement by leap (default step × 10)
PageDownDecrement by leap (default step × 10)
HomeSet to minimum
EndSet to maximum
EnterCommit the typed value
Was this page helpful?

Ctrl+/