Forms
All form styles are provided using the Design System CSS in @volvo-cars/css. These work with any framework, or no framework at all.
Native form elements like <input type="text"> will be given some default styles:
<input type="text" />For public facing apps, the only Design System compliant design is labels floating inside the input, which requires some more markup, and for some input types also requires some client-side JavaScript.
<div class="input-floating-label"> <input type="text" id="name" placeholder="" /> <label for="name">Name</label></div>React apps should use the @volvo-cars/react-forms package, which provides components with:
- Support for floating labels with all input types
- Accessible markup for hints and error messages
- Developer experience enhancements with detailed TypeScript types and documentation
- Improved user experience with appropriate autofill and mobile keyboard modes
The components exported by @volvo-cars/react-forms are high-level abstractions, encapsulating best practices but with little flexibility in markup or styling. If you need more control, you can use the CSS classes directly and create your own components, in HTML, React or another framework.
Getting started
Section titled “Getting started”- Add
@volvo-cars/cssto your application - Install the React forms package:
Terminal window yarn add @volvo-cars/react-forms
Recommended reading
Section titled “Recommended reading”Autocomplete and spellcheck
Section titled “Autocomplete and spellcheck”Set a suitable autocomplete value on inputs as this helps users fill out forms significantly faster and ensures that the appropriate values are used for browser autofill.
Set spellcheck=false on inputs for which the user is expected to enter a specific value, such as a reference number or model name. This prevents the browser from suggesting incorrect values.
Validation
Section titled “Validation”Client side validation should only be used to enhance the user experience. All forms must also be validated on the server.
When a user first fills out a form, it should be validated either:
- On submit — showing the form with all error messages at once
- On blur — showing error messages for each field when the user focuses another element by clicking or pressing tab
After the first round of validation, the form should be validated on change for each field.
Premature error messages are often perceived as a disturbance which can lead to more errors, increased completion times and even abandonment. Consider each case: will it be more helpful to show the user the error message immediately, or should we wait until they have finished filling out the form and let them fix all errors at once?
Form inputs should rarely be initially validated on change, as this can be distracting and lead to a poor user experience with error messages appearing and disappearing. Notable exceptions are real-time feedback such as password strength meters or a character length limit.
See the example app for how to use the @volvo-cars/react-forms components together with React Server Actions and zod to validate forms.
Hints and error messages
Section titled “Hints and error messages”Form messages are small text elements displayed below an input to provide additional context or communicate errors. They come in two variants:
- Hint — a short, secondary-colored message that adds context or guidance, such as expected format or constraints. Rendered as a
<p>with themicroandtext-secondarystyles. - Error message — a red message with an icon, shown when validation fails. Rendered as a
<p>withmicroandtext-feedback-redstyles, prefixed with an exclamation mark icon.
Hints and error messages can be shown together — the hint remains visible alongside the error to help the user resolve the issue.
Character limits
Section titled “Character limits”- Label: max 40 characters
- Form message (hint or error): max 150 characters
React usage
Section titled “React usage”In @volvo-cars/react-forms, hints and errors are built into every form component via the hint and errorMessage props. These automatically generate the correct accessible markup, linking messages to their input via aria-describedby and aria-errormessage.
<TextInput label="Email" hint="We'll never share your email." errorMessage="Please enter a valid email address."/>The ErrorMessage and Hint components are also exported individually for advanced use cases where you build custom form controls:
import { ErrorMessage, Hint } from '@volvo-cars/react-forms';Accessibility
Section titled “Accessibility”- Error messages are linked to their input via both
aria-errormessageandaria-describedbyfor broad screen reader support. - Hint text is linked via
aria-describedbyso it is announced when the input receives focus. - Error messages are hidden when the input is disabled to avoid confusion.
- VoiceOver in Safari has known issues announcing
role="alert"on error messages — the design system avoids this pattern intentionally.