Skip to content

NumberField ​

A number field is a text field that knows it holds a number. It parses what is typed against the reader's locale, clamps to the range, and formats the result when the field loses focus — so 1,024 and 1.024 both mean what the reader meant by them.

ts
import { NumberField, NumberFieldGroup, NumberFieldInput } from "ropav";
variant
size
template
<NumberField class="w-48" :default-value="1024" name="width">
  <Label>Width</Label>
  <NumberFieldGroup>
    <NumberFieldDecrementButton />
    <NumberFieldInput />
    <NumberFieldIncrementButton />
  </NumberFieldGroup>
</NumberField>

Steppers and formatting ​

format-options is passed straight to Intl.NumberFormat, so a percentage, a currency or a unit is a matter of describing it rather than of formatting it yourself.

number-field-basic.vue
vue
<script setup lang="ts">
import {
  Label,
  NumberField,
  NumberFieldDecrementButton,
  NumberFieldGroup,
  NumberFieldIncrementButton,
  NumberFieldInput,
} from "ropav";
</script>

<template>
  <div class="stack">
    <NumberField class="field" :default-value="1024" :min-value="0" name="width">
      <Label>Width</Label>
      <NumberFieldGroup>
        <NumberFieldDecrementButton />
        <NumberFieldInput />
        <NumberFieldIncrementButton />
      </NumberFieldGroup>
    </NumberField>

    <NumberField
      class="field"
      :default-value="0.15"
      :format-options="{ style: 'percent' }"
      name="rate"
      :step="0.01"
    >
      <Label>Rate</Label>
      <NumberFieldGroup>
        <NumberFieldDecrementButton />
        <NumberFieldInput />
        <NumberFieldIncrementButton />
      </NumberFieldGroup>
    </NumberField>
  </div>
</template>

<style scoped>
.stack {
  display: flex;
  flex-direction: column;
  gap: calc(var(--rp-spacing) * 4);
}

.field {
  width: calc(var(--rp-spacing) * 48);
}
</style>

step decides what the steppers and the arrow keys move by, and it is also what the value is snapped to.

Locale ​

The field reads its locale from the nearest I18nProvider, falling back to the browser's. Pin it with locale when the number has to be read the same way everywhere — a code, an identifier, anything that is a number by type but not by meaning.

Accessibility ​

  • The steppers are real buttons with their own labels, so they are reachable and announced.
  • Arrow keys step the value while the input is focused; Page Up and Page Down take larger steps.
  • is-wheel-disabled stops the scroll wheel changing the value, which is worth setting for a field inside a scrolling panel.

API ​

NumberField

PropTypeDefaultDescription
ariaDescribedbystring—
ariaLabelstring—Accessible name, for a field with no visible label.
ariaLabelledbystring—
autoFocusboolean—Whether the field takes focus on mount.
commitBehavior"snap" | "validate""snap"What happens to the value once the user is done editing. "snap" pulls it into range and onto a step; "validate" leaves it and lets validation object.
decrementAriaLabelstring—Overrides the name the decrement button announces.
defaultValuenumber—The number the field starts with, and goes back to when the form is reset.
formstring—id of the form to submit with, for a field rendered outside it.
formatOptionsIntl.NumberFormatOptions—How the number is written, and by extension which characters may be typed.
fullWidthboolean—Whether the field stretches to fill its container.
idstring—Lands on the control, which is the field as far as assistive technology is concerned.
incrementAriaLabelstring—Overrides the name the increment button announces.
isDisabledboolean—Whether the field is disabled — no interaction, no submission.
isInvalidboolean—Whether the value fails validation. Setting it either way takes the field over: false claims the field is valid and shadows validate, the browser and the server alike.
isReadOnlyboolean—Whether the number can be read but not changed.
isRequiredboolean—Whether the field has to be filled in for the form to submit.
isWheelDisabledboolean—Whether the wheel over a focused field is ignored.
localestring—Locale the number is written and read in. Defaults to the runtime's own.
maxValuenumber—
minValuenumber—
namestring—Name submitted with the form.
size"xs" | "sm" | "md" | "lg""md"How tall the field stands, matching a button of the same size.
stepnumber1, or 0.01 for a percentageHow far one step moves the value.
validateValidationFunction<number>—Checks the number and returns a message when it is not acceptable.
validationBehavior"aria" | "native""native"How the field reports validation. Inherited from the surrounding form when unset.
valuenumber | null—The number in the field. Makes it controlled. null means no number at all.
variant"primary" | "secondary""primary"Visual variant.

The default slot receives:

Slot propType
isDisabledboolean
isInvalidboolean
isReadOnlyboolean
isRequiredboolean
numberValuenumber
validationDetailsValidationDetails
validationErrorsstring[]
EventPayload
changenumber
focusChangeboolean
update:valuenumber

NumberFieldDecrementButton

Slots: default.

NumberFieldGroup

The default slot receives:

Slot propType
isDisabledboolean
isFocusWithinboolean
isHoveredboolean
isInvalidboolean

NumberFieldIncrementButton

Slots: default.

NumberFieldInput

PropTypeDefaultDescription
placeholderstring—