Number fields are a common field in many forms. They include built-in validation to reject non-numerical input. Additionally, the browser may provide stepper arrows to let the user increase and decrease the value with a configurable step amount.
The Number field is usually used for number values rather than numeric values. For example while a credit card number is numeric, you should not use a number field for it. Instead you should use it for values that are meant to be consumed as a number like units, prices and percentages.
The native HTML number input and most other implementations do not offer a good experience. Here are a couple of common issues:
Lack of proper internationalization: Mainly, the lack of support for other numeral systems like the Arabic numerals (٠١٢٣٤٥٦٧٨٩) are a pain to work with. Users often have to switch keyboard languages/layout to enter numbers and even then it is not perfect. Keyboards don’t always have all the necessary characters for decimals and thousands separators. This means the number input is not accessible for the global audience.
No formatting support: this includes grouping , and displaying units and currencies and other simple masking features.
Formwerk tries to address all these issues and more by utilizing the Intl.NumberFormat API. It provides a solid foundation for building number fields that are accessible and easy to use for users all over the world.
Features
Supports using the input element as a base with type="text" (don’t worry, we add the inputmode automatically for accessability and mobile keyboards).
Labeling, descriptions, error message displays are automatically linked to input and label elements with aria-* attributes.
Formatting and parsing numbers with the Intl.NumberFormat API depending on the site locale or the user’s preferred language.
Support for multiple numeral systems (Latin, Arabic, and Chinese).
Support for Intl.NumberFormat units and currencies.
Validation support with native HTML constraint validation or Standard Schema validation.
Rejects non-numerical input characters and any incoming key presses that would make the number invalid.
Support for v-model binding.
Supported Keyboard features:
Key
Description
↑Arrow Up
increment the value by the step amount.
↓Arrow Down
decrement the value by the step amount.
⇞Page Up
increment the value by larger multiple of the step amount.
⇟Page Down
decrement the value by larger multiple of the step amount.
Home
set the value to the min value if provided, otherwise has no effect.
End
set the value to the max value if provided, otherwise has no effect.
Wheel up
increment the value by the step amount.
Wheel down
decrement the value by the step amount.
Anatomy
Label
Label
47
Increment button
Decrement button
Input
Help text
Description or Error Message
Building a Number Field Component
You can start by importing the useNumberField composable and using it in your number field component.
The useNumberField composable returns binding objects for the elements shown in the anatomy, you will use v-bind to bind them to the corresponding DOM elements.
Notice that we imported the NumberFieldProps in the previous example. This is recommended to use as your component prop types. Not only you get type safety for your component out of it but also it handles the reactivity aspects of the props so you don’t have to. You are free to extend it with your own props or omit the ones you don’t need.
Validation
HTML Constraints
You can use the following native HTML validation properties to validate the number field:
Name
Type
Description
max
number
The maximum value for the number field.
min
number
The minimum value for the number field.
required
boolean
Whether the number field is required.
step
number
The step amount for the number field.
Here is an example of how to use the max and min properties to limit the number field value between 0 and 100.
Assuming you have a NumberField component like the one shown above, you can use it like this:
Standard Schema
useNumberField also supports Standard Schema validation through the schema prop. This includes multiple providers like Zod, Valibot, Arktype, and more.
Mixed Validation
While it is unlikely that you need both HTML constraints and Standard Schemas to validate a number field, Formwerk supports mixed validation, which means you can use both HTML constraints and Standard Schemas to validate the field and define step amount and min/max values and they work seamlessly together.
Note that HTML constraints are validated first, so any errors from the HTML constraints will be displayed first. Then once all HTML constraints are satisfied, the Standard Schema is validated.
Usage
Disabled
Use disabled to mark fields as non-interactive, disabled fields are not validated and are not submitted.
If you need to prevent the user from interacting with the field while still allowing it to submit, consider using readonly instead.
Readonly
Readonly fields are validated and submitted, but they do not accept user input. The field is still focusable and the value is copyable. For more info, check the MDN.
Formatting and Units
You can use the formatOptions prop to format the number field value. It accepts all options that are supported by the Intl.NumberFormat API.
i18n
Aside from formatting you can also use any numeral system supported by the Intl.NumberFormat API. Like Arabic, and Chinese.
The number field also accepts a locale prop to change the locale of the number field. Usually you should not want to pass it manually but for demonstration purposes it is shown below.
Actually, here are 3 fields each with a different numeral system bound to the same value, and you get the parsed value with either of them.
RTL
The number field doesn’t really need much for RTL support, however the dir prop can be used to set the direction of the field for convenience.
Examples
These are some examples of number fields built with Formwerk.