Skip to main content
You are viewing Pre-Alpha documentation.
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.


Renders elementIntermediateApr 6, 2026

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

API Reference

The following API details are for all variations of the NumberField component.

NumberField.Root

Props

id

any

Unique identifier (auto-generated if not provided)

Default: useId()

label

string | undefined

Optional display label

name

string | undefined

Form field name

form

string | undefined

Associate with form by ID

required

boolean | undefined

Whether this field is required

disabled

MaybeRefOrGetter<boolean> | undefined

Disables this field

Default: false

readonly

MaybeRefOrGetter<boolean> | undefined

Makes this field readonly

min

number | undefined

Minimum value

max

number | undefined

Maximum value

step

number | undefined

Step increment (default: 1)

leap

number | undefined

Leap increment for PageUp/PageDown

wrap

boolean | undefined

Wrap around at boundaries

locale

string | undefined

BCP 47 locale tag (default: 'en-US')

format

Intl.NumberFormatOptions | undefined

Intl.NumberFormat options

clamp

boolean | undefined

Whether commit() clamps to min/max (default: true)

rules

any[] | undefined

Validation rules

Default: []

validateOn

any

When to trigger validation

Default: "blur"

error

boolean | undefined

Manual error state override — forces invalid

Default: false

errorMessages

any

Manual error messages — merged with rule-based errors

spinDelay

number | undefined

Delay in ms before spin-on-hold starts (default: 400)

Default: 400

spinRate

number | undefined

Interval in ms for repeated spin (default: 60)

Default: 60

wheel

boolean | undefined

Whether mouse wheel adjusts value (default: false)

Default: false

namespace

string | undefined

Namespace for context provision

Default: "v0:number-field:root"

modelValue

number | null | undefined

Default: null

Events

update:model-value

[value: number | null]

Slots

default

NumberFieldRootSlotProps

NumberField.Control

Props

namespace

string | undefined

Namespace for connecting to parent NumberField.Root

Default: "v0:number-field:root"

Slots

default

NumberFieldControlSlotProps

NumberField.Decrement

Props

namespace

string | undefined

Namespace for connecting to parent NumberField.Root

Default: "v0:number-field:root"

Slots

default

NumberFieldDecrementSlotProps

NumberField.Description

Props

id

string | undefined

Unique identifier (auto-generated if not provided)

Default: useId()

namespace

string | undefined

Namespace for connecting to parent NumberField.Root

Default: "v0:number-field:root"

Slots

default

NumberFieldDescriptionSlotProps

NumberField.Error

Props

id

string | undefined

Unique identifier (auto-generated if not provided)

Default: useId()

namespace

string | undefined

Namespace for connecting to parent NumberField.Root

Default: "v0:number-field:root"

Slots

default

NumberFieldErrorSlotProps

NumberField.Increment

Props

namespace

string | undefined

Namespace for connecting to parent NumberField.Root

Default: "v0:number-field:root"

Slots

default

NumberFieldIncrementSlotProps

NumberField.Scrub

Props

namespace

string | undefined

Namespace for connecting to parent NumberField.Root

Default: "v0:number-field:root"

sensitivity

number | undefined

Pixels of movement per step (default: 1)

Default: 1

Slots

default

NumberFieldScrubSlotProps
Was this page helpful?

© 2016-1970 Vuetify, LLC
Ctrl+/