Skip to content

Number Field

Alpha
A number field allows a user to enter a number and increment or decrement the value using stepper buttons.
vue
<script setup lang="ts">
import { NumberFieldDecrement, NumberFieldIncrement, NumberFieldInput, NumberFieldRoot } from 'radix-vue'
import { Icon } from '@iconify/vue'
</script>

<template>
  <NumberFieldRoot
    id="age"
    class="text-sm text-white"
    :min="0"
    :default-value="18"
  >
    <label for="age">Age</label>
    <div class="mt-1 flex items-center border bg-blackA7 border-blackA9 rounded-md">
      <NumberFieldDecrement class="p-2 disabled:opacity-20">
        <Icon icon="radix-icons:minus" />
      </NumberFieldDecrement>
      <NumberFieldInput class="bg-transparent w-20 tabular-nums focus:outline-0 p-1" />
      <NumberFieldIncrement class="p-2 disabled:opacity-20">
        <Icon icon="radix-icons:plus" />
      </NumberFieldIncrement>
    </div>
  </NumberFieldRoot>
</template>

Features

  • Full keyboard navigation.
  • Can be controlled or uncontrolled.
  • Support button hold and wheel event.
  • Support numbering systems in different locale.
  • Customizable formatting.

Installation

Install the number package.

sh
$ npm add @internationalized/number

Install the component from your command line.

sh
$ npm add radix-vue

Anatomy

Import all parts and piece them together.

vue
<script setup>
import { NumberFieldDecrement, NumberFieldIncrement, NumberFieldInput, NumberFieldRoot } from 'radix-vue'
</script>

<template>
  <NumberFieldRoot>
    <NumberFieldDecrement />
    <NumberFieldInput />
    <NumberFieldIncrement />
  </NumberFieldRoot>
</template>

API Reference

Root

Contains all the parts of a number field. An input will also render when used within a form to ensure events propagate correctly.

PropDefaultType
as
'div'
AsTag | Component

The element or component this component should render as. Can be overwrite by asChild

asChild
boolean

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read our Composition guide for more details.

defaultValue
number
disabled
boolean

When true, prevents the user from interacting with the Number Field.

formatOptions
NumberFormatOptions

Formatting options for the value displayed in the number field. This also affects what characters are allowed to be typed by the user.

id
string

Id of the element

locale
'en-US'
string

The locale to use for formatting dates

max
number

The largest value allowed for the input.

min
number

The smallest value allowed for the input.

modelValue
number
name
string

The name of the number field. Submitted with its owning form as part of a name/value pair.

required
boolean

When true, indicates that the user must set the value before the owning form can be submitted.

step
1
number

The amount that the input value changes with each increment or decrement "tick".

EmitPayload
update:modelValue
[val: number]

Event handler called when the value changes.

Slots (default)Payload
modelValue
number
textValue
string
Data AttributeValue
[data-disabled]Present when disabled

Input

Input

The input component that renders the text value based on value and format options.

PropDefaultType
as
'input'
AsTag | Component

The element or component this component should render as. Can be overwrite by asChild

asChild
boolean

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read our Composition guide for more details.

Data AttributeValue
[data-disabled]Present when disabled

Increment

The button that increases the value.

PropDefaultType
as
'button'
AsTag | Component

The element or component this component should render as. Can be overwrite by asChild

asChild
boolean

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read our Composition guide for more details.

disabled
boolean
Data AttributeValue
[data-pressed]Present when pressed
[data-disabled]Present when disabled

Decrement

The button that decreases the value.

PropDefaultType
as
'button'
AsTag | Component

The element or component this component should render as. Can be overwrite by asChild

asChild
boolean

Change the default rendered element for the one passed as a child, merging their props and behavior.

Read our Composition guide for more details.

disabled
boolean
Data AttributeValue
[data-pressed]Present when pressed
[data-disabled]Present when disabled

Example

Decimal

All options supported by Intl.NumberFormat are supported, including configuration of minimum and maximum fraction digits, sign display, grouping separators, etc.

vue
<template>
  <NumberFieldRoot
    :default-value="5"
    :format-options="{
      signDisplay: 'exceptZero',
      minimumFractionDigits: 1,
    }"
  >

  </NumberFieldRoot>
</template>

Percentage

You can set formatOptions.style to percent to treat the value as a percentage. You need to set the step to 0.01 manually to allow an appropriate step size in this mode.

vue
<template>
  <NumberFieldRoot
    :default-value="0.05"
    :step="0.01"
    :format-options="{
      style: 'percent',
    }"
  >

  </NumberFieldRoot>
</template>

Currency

You can set formatOptions.style to currency to treat the value as a currency value. The currency option must also be passed to set the currency code (e.g., USD).

If you need to allow the user to change the currency, you should include a separate dropdown next to the number field. The number field itself will not determine the currency from the user input.

vue
<template>
  <NumberFieldRoot
    :default-value="5"
    :format-options="{
      style: 'currency',
      currency: 'EUR',
      currencyDisplay: 'code',
      currencySign: 'accounting',
    }"
  >

  </NumberFieldRoot>
</template>

Accessibility

Adheres to the Spinbutton WAI-ARIA design pattern.

Keyboard Interactions

KeyDescription
Arrow Up
Increase the value
Arrow Down
Decrease the value
Page Up
Increase the value by scale of 10
Page Down
Decrease the value by scale of 10
Home
Set value to minimum (if min is provided)
End
Set value to maximum (if max is provided)