Text fields are used to allow users to input plain text into a form.
Text fields are implemented with the input element for a single line of text or the textarea element for multiple lines of text.
Features
Uses input or textarea elements as a base.
Labels, descriptions, and error message displays are automatically linked to input and label elements with aria-* attributes.
Validation support with native HTML constraint validation or Standard Schema validation.
Support for v-model binding.
Anatomy
Label
Label
Value
Input
Help text
Description or Error Message
Building a Text Field Component
You can start by importing the useTextField composable and using it in your text field component.
The useTextField 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 TextFieldProps in the previous example. This is recommended to use as your component prop types.
Not only do you get type safety for your component out of it, but it also 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.
Building a Text Area Component
Instead of using an input[type="text"] element, you can switch to using a textarea element as a base element instead.
Validation
HTML Constraints
You can use the following properties to validate the text field with native HTML constraint validation:
Name
Type
Description
maxLength
number
The maximum length of characters.
minLength
number
The minimum length of characters.
required
boolean
Whether the text field is required.
pattern
string | RegExp
A regular expression for validation. Not supported for textarea fields.
In addition to the above properties, if you are using the input element, you can use the built-in validation for the type attribute.
Type
Description
email
Validates the value as an email.
url
Validates the value as a URL.
Here is an example of how to use the maxLength and minLength properties to limit the text length between 3 and 18 characters.
Assuming you have a TextField component like the one shown above, you can use it like this:
Standard Schema
useTextField also supports Standard Schema validation through the schema prop. This includes multiple providers like Zod, Valibot, Arktype, and more.
Mixed Validation
All text fields created with Formwerk support mixed validation, which means you can use both HTML constraints and Standard Schema validation to validate the field, 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.
This makes schemas lighter; however, we recommend sticking to one or the other per form for maintainability.
If you need to disable the native validation, you can do so by setting the disableHtmlValidation prop to true.
You can also disable it globally for all fields. For more information, check out the Validation guide.
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.
RTL
The text field doesn’t require much for RTL support; however, the dir prop can be used to set the direction of the field for convenience.
Styling
Formwerk does not come with any markup or styling, which is often the part that makes a design system unique. That means you can use any styling solution you want, whether it’s TailwindCSS or plain CSS, as you have already seen.
Note that we make use of the :user-invalid pseudo-classes to style the field and control when to show the error messages without any JavaScript. Formwerk leans into native APIs and browser features to provide a more seamless experience for the user. In fact, even if you use Standard Schemas to validate the field, the pseudo-classes will still work.
For more information on styling and recommendations, check the Styling guide.
API
Props
These are the properties that can be passed to the useTextField composable.
Name
Type
Description
description
Description text that provides additional context about the field.
disabled
Whether the field is disabled.
disableHtmlValidation
Whether to disable HTML5 validation.
label
The label of the text field.
maxLength
Maximum length of text input allowed.
minLength
Minimum length of text input required.
modelValue
The v-model value of the text field.
name
The name attribute of the input element.
pattern
Pattern for input validation using regex.
placeholder
Placeholder text shown when input is empty.
readonly
Whether the field is readonly.
required
Whether the field is required.
schema
Schema for field validation.
type
The type of input field (text, password, email, etc).
value
The value attribute of the input element.
Returns
These are the properties in the object returned by the useTextField composable.