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

Flora ships several 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.

FileInput

FileInput is the equivalent to the HTML

<input type="file">
element.

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.

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.

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.

Slider

Slider is another variation which different UX tradeoffs. It is useful if only a certain range of values is accepted and the steps are linear. Instead of having to type a value, the customer will get immediate feedback on dragging.

CheckboxCard

CheckboxCard is another variation of the Checkbox with additional properties for options that are better described with multiple data points.

RadioCard

RadioCard is similar to CheckboxCard but for Radios respectively.
It is supposed to be used with RadioGroup as well.

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 Flora, 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:

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, an initial value must be passed.

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.

Submitting Forms

Action buttons with a

type
of
submit
will automatically submit the form if it is within the
form
DOM element.
If it is located outside of the DOM element, one can pass a unique
id
to the
form
element and reference the same one in a
form
prop passed to the button.

This is useful e.g. when using Modal and passing the button as an action.

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

Note: At Carla, if not explicitly stated, we always want to implement Validation on Submit.

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

Note: At Carla, if not explicitly stated, we always want to implement Validation on Submit.
Additionally, due to the immediate feedback, this type of validation can be really distracting, discouraging and sometimes even confusing to the customer. It should only be used with caution.

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
.

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.