Forms

Creating rich forms is one of the key challenges in web development. Since there're plently of different ways and libraries to achieve the same thing, we provide a bunch of form components and utilities.
In this guide, you'll learn how to use our built-in form component and how different validation patterns are implemented.

Form Components

vcc-ui ships 6 pre-built form components which implement the corporate design.
They accept props to control the functionality (more on that later) as well as accessibility attributes.

For more details on each component, also check the Components section.

TextInput

TextInput is the default input field. It is used for string-based values such as firstname or city, but can also be turned into an email, date or password field by passing in the correct type prop.

TextArea

TextArea is similar to TextInput, but is used specifically for multi-line string-based values such as a description or a biography.

SelectInput

SelectInput is the equivalent to the HTML <select> element. It even takes plain <option> elements as children. It is used whenever only a limited set of values is eligible and the user has to choose a single one of them.

RadioGroup / Radio

RadioGroup is used to control a set of radio buttons. Radio itself is the equivalent to the HTML <input type="radio"> element. They should be used whenever only a limited set of values is eligible and the user has to choose a single one of them.
In comparison to the SelectInput, radio buttons should only be used if the number of available options is small or else it will get confusing. A good rule of thumb is a maximum of 5 radio buttons per radio group.
Radio should never be used by itself and only if there're at least 2 options available. Otherwise you most likely want to use a Checkbox instead.

Checkbox

Checkbox is the direct equivalent to the HTML <input type="checkbox"> element. It should be used whenever the value is boolean, thus consists only of 2 values true and false. In general, checkboxes are used if the value represents a yes/no pair, for example "I accept the terms of service" or "Send me a newsletter". For values that represent a on/off pair or any other specific value pair that's not boolean, consider using the Toggle component.

Toggle

Toggle is similar to Checkbox, but represents boolean values that have a different semantic meaning. As mentioned above, toggles are usually used if the value represents a on/off pair e.g. "Flight-mode".
Another option are specific value pairs that can be toggled e.g. "Gas" or "Electric" cars. In this scenario, both sides should be described by a label.

Controlling Form Components

Next to the components, we ship two React hooks to control those components in a simple and declarative way.
Those hooks are inspired by the react-form-hook API and are built especially for vcc-ui, integrating seamlessly with the existing components.

We use the concept of touching fields. A field only shows its validation state and error message if it's touched. We can configure whether we want to touch a field on change, blur or submit. Additionally, we can touch fields manually.

Check the Utilities section for a full overview of all options and return values.

useField

This hook uses useState under-the-hood and controls the state changes and validation for each field. The internal representation of a field contains the following keys:

  • value
  • isValid
  • isTouched
  • isDisabled
  • isRequired
  • isLoading
  • errorMessage

It takes initial field values as well as a validation map.
It returns an object containing all internal field properties listed above, 3 functions to update the field and a props object which we can spread onto any of the above built-in components.

Note: In order to correctly function with boolean values when working with Checkbox and Toggle, make sure to pass an initial value.

useForm

This hook takes a list of fields, where a field is the output of the useField hook.
It returns a submit and reset function to handle form submits. It automatically touches all fields on submit.

const { submit, reset } = useForm(firstname, newsletter);
const Form = () => (
<form
onSubmit={(e) => {
e.preventDefault();
submit((isValid, data) => {
if (isValid) {
// do something with data
alert(JSON.stringify(data));
// reset all fields to their initial state
reset();
}
});
}}
>
<FormContent />
</form>
);

Validation

Form validation is an important part of user-friendly forms and can happen at different stages depending on the use case.
To simplify the use of different validation pattern, the useField hook accepts a showValidationOn configuration option that aims to simplify that.

Validation on Submit

The most common validation pattern is to validate all fields once the user tries to submit a form.
Since it is the most common pattern, is it automatically done if we're using the useForm hook to submit our forms.
Upon submitting, every field is touched and thus reveals the validation state and error message.

Validation on Blur

Another common pattern is to validate a field once the user "leaves" the input field. For most components, that's when we lose focus.
To minimize distraction, the validation is hidden again if the user "re-enters" the input field. To achieve that, we can set showValidationOn to blur.

Validation on Change

The last common validation pattern is immediate feedback. As soon as the user changes the initial value, the validation state is revealed and possible error messages are shown. To achieve that, we can set showValidationOn to change.

It should only be used with caution, as the immediate feedback can be distracting and sometimes even confusing.

Async Validation

Another common task is asynchronous validation.
For example, a user enters his favored username. We can't validate that right away, but need to ask our backend if the username is still available.

We do not provide any predefined option or utility since this is often use-case specific and quite complex to generalize. But, we can use the provided hooks and field functions to achieve that nevertheless.

Recommended Reading:

Check out the forms example in the vcc-ui repository which includes all of those best practices.

2024 © Volvo Car Corporation