Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs[DST-572]: Form field guidelines #4174

Open
wants to merge 27 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
76da5b6
Initiate form guideline
OsamaAbdellateef Sep 23, 2024
4834835
Adding marigold form section
OsamaAbdellateef Sep 23, 2024
7e15657
Adding updates
OsamaAbdellateef Sep 24, 2024
6900f06
Move validation message
OsamaAbdellateef Sep 25, 2024
13c37d3
Remove unwanted section
OsamaAbdellateef Oct 4, 2024
1d1c2d0
Adding related section
OsamaAbdellateef Oct 4, 2024
ca0b784
Adding related sections
OsamaAbdellateef Oct 7, 2024
62593cd
Change title from form fields guideline to form fields
OsamaAbdellateef Oct 7, 2024
72b0297
Merge branch 'main' into form-guideline
OsamaAbdellateef Oct 9, 2024
ca21485
resolve conflicts
OsamaAbdellateef Oct 9, 2024
4fa8999
Adding more info about when to use lable etc..
OsamaAbdellateef Oct 9, 2024
412bb1b
Adding more info about helptext
OsamaAbdellateef Oct 9, 2024
03f746e
Removing unwanted tiles
OsamaAbdellateef Oct 9, 2024
30be7ca
Edit headline
OsamaAbdellateef Oct 9, 2024
db6d196
Test
OsamaAbdellateef Oct 9, 2024
aea75ba
Adding changeset
OsamaAbdellateef Oct 9, 2024
a480f95
Addnig dos and donts for label
OsamaAbdellateef Oct 9, 2024
c86a371
Adding dont for help text
OsamaAbdellateef Oct 9, 2024
cb15b2f
change file name
OsamaAbdellateef Oct 9, 2024
c26db33
Resolvnig comments
OsamaAbdellateef Oct 9, 2024
4cf54ee
Adding guideline section
OsamaAbdellateef Oct 10, 2024
bd1b34a
test
OsamaAbdellateef Oct 10, 2024
0c868e1
Separate the state exmples
OsamaAbdellateef Oct 11, 2024
a1aad6c
Resolve comments
OsamaAbdellateef Oct 11, 2024
ed5e59a
Changing the path
OsamaAbdellateef Oct 14, 2024
434e109
Fixing the paths
OsamaAbdellateef Oct 14, 2024
0dee034
Editing changeset title
OsamaAbdellateef Oct 14, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/sweet-pumpkins-cover.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@marigold/components': patch
'@marigold/docs': patch
---

Adding a general form guideline in docs explaining different concepts such as when to use lable and help text
OsamaAbdellateef marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Stack, TextField } from '@marigold/components';

export default () => {
return (
<Stack space={2}>
<TextField label="username" placeholder="enter user name" disabled />
</Stack>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { NumberField } from '@marigold/components';

export default () => {
return (
<NumberField
label="Quantity"
error
errorMessage="Max number of available tickets is 3"
value={4}
/>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { TextField } from '@marigold/components';

export default () => {
return (
<TextField
label="Promo Code"
description="You can find the code on the back of your ticket."
errorMessage="The promo code was already used."
/>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Headline, Stack, Switch } from '@marigold/components';

export default () => {
return (
<Stack space={2}>
<Headline level={'5'}>ReadOnly State</Headline>
<Switch readOnly>Settings Locked</Switch>
</Stack>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Select } from '@marigold/components';

export default () => (
<Select
label="Genre"
placeholder="Select genre"
description="Select the genre you want."
width="fit"
required
>
<Select.Option id="pop">Pop</Select.Option>
<Select.Option id="hiphop">Hip Hop</Select.Option>
<Select.Option id="rock">Rock</Select.Option>
<Select.Option id="schlager">Schlager</Select.Option>
<Select.Option id="jazz">Jazz</Select.Option>
<Select.Option id="dance">Dance</Select.Option>
</Select>
);
205 changes: 205 additions & 0 deletions docs/content/foundations/form-fields/form-fields.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
---
title: Form Fields
caption: Comprehensive guide for working with form fields
badge: new
---

Form components are individual elements that make up a form, such as text fields, checkboxes, radio buttons, select fields, text areas and buttons. They allow user input, selection and actions.

Marigold has a set of form components that you can use to build your form.

- [Autocomplete](/components/form/autocomplete)
- [Button](/components/form/button)
- [Calendar](/components/form/calendar)
- [Checkbox](/components/form/checkbox)
- [ComboBox](/components/form/combobox)
- [DateField](/components/form/datefield)
- [DatePicker](/components/form/datepicker)
- [FieldGroup](/components/form/fieldgroup)
- [NumberField](/components/form/number-field)
- [Radio](/components/form/radio)
- [SearchField](/components/form/search-field)
- [Select](/components/form/select)
- [Slider](/components/form/slider)
- [Switch](/components/form/switch)
- [TextArea](/components/form/text-area)
- [TextField](/components/form/text-field)

## Anatomy

An accessible form field includes a clear label associated with its corresponding form control (`<input>`, `<select>`, ...). Additional guidance is provided by a help text, which can give additional context or instructions or display a descriptive messages.

<Image
src="/field.png"
alt="Anatomy of a field"
width={300}
height={150}
className="mx-auto block"
/>

Marigold's form components allow to set these properties like shown below. All form components allow to set a `label`, `description` and `errorMessages` besides some additional control-specific props.

## Usage

Form fields are essential for collecting user input, making selections, or triggering actions. They should be designed for clarity and accessibility to ensure a smooth user experience. Proper use of labels, help texts, and error messages ensures users understand each field's purpose and can interact with it correctly. Accessible form fields also improve usability for people using assistive technologies.

### Label

Labels are essential for accessibility and clarity, ensuring that each form field is clearly defined. In most cases, a label should be provided for each form control to describe the expected input. They are used when fields require specific instructions (e.g., name, email, or password should have a clear label).

However, labels might not be necessary when the purpose of the input is obvious from context. For example, in search bars because the purpose of the input is obvious.

<GuidelineTiles>
<Do>
<Do.Description>
Do provide a clear, descriptive label for each form field
</Do.Description>
</Do>
<Dont>
<Dont.Description>
Don’t make labels overly long or complex.
</Dont.Description>
</Dont>
</GuidelineTiles>

### Help Text

Help Text should be used to provide additional clarification or instructions when the label alone isn't enough to explain the input (e.g., complex or uncommon fields). It’s helpful for explaining specific formats or validation rules. However, it shouldn't be used when the input is straightforward and the label is clear, as it can clutter the form and overwhelm the user with unnecessary details.

<Dont>
<Dont.Description>
Don’t use Help Text as a substitute for a label. It should complement the
label, not replace it.
</Dont.Description>
</Dont>
<ComponentDemo file="./form-fields-helper-text.demo.tsx" />

### Field States

Form components often exist in various states to indicate how they should behave or be interacted with. These states provide important context for users and ensure proper handling of inputs in different senarios. Below are the common field states used in forms.

#### Disabled State

Fields in a disabled state are non-interactive and prevent user input. They visually indicate that a field is temporarily unavailable.

<ComponentDemo file="./form-fields-disabled-state.demo.tsx" />

#### Required State

Required fields must be completed before form submission.

<ComponentDemo file="./form-fields-required-state.demo.tsx" />

#### Error State

Fields in an error state indicate that the entered value is invalid or incorrect. Error messages and visual feedback.

<ComponentDemo file="./form-fields-error-state.demo.tsx" />

#### ReadOnly State

Read-only fields display data that cannot be modified by the user. They are typically used for information that users can view but not change.

<ComponentDemo file="./form-fields-readonly-state.demo.tsx" />

### Validation

HTML forms enable the collection and submission of user input on web pages. Form elements also support validation of those inputs through attributes like `required` and input types such as `email` or `number` to provide users with feedback.

Marigold's components seamlessly integrate with HTML forms, providing a developer-friendly solution for effective input data validation. It supports native attributes such as `required` and validation based on input types. Furthermore, Marigold's form elements enable the incorporation of custom validation functions, enhancing the browser's validation capabilities.

#### Built-in / Native Form Validation

The most straightforward way to validate user input is to use the built-in [constraint validation](https://developer.mozilla.org/en-US/docs/Web/HTML/Constraint_validation). Marigold's form components work seamlessly with this API, allowing you to set constraints for each field. The browser will check these constraints on blur (user leaves the field) or when the form is submitted.

Marigold's form components utilize the same API as native HTML forms. Yet, the browser won't display error messages; instead, they will be styled to seamlessly blend with the overall design.

Here is an email subscription form. If you submit it without entering an email address or if the entered email address is invalid, an error will be displayed:

<ComponentDemo file="./validation-base.demo.tsx" />{' '}

#### Custom Message

While browser-provided error messages are helpful, they might not be very descriptive. In such instances, you have the flexibility to override them by using a function with the `errorMessages` prop of the field. This allows you to display custom error messages tailored to better describe the occured error.

The example below customizes the default error messages for an unfilled required field. It's important to note that you only need to override the messages you want to; any unmodified aspects will fallback to the browser-provided messages.

<ComponentDemo file="./validation-custom-message.demo.tsx" />{' '}

#### Custom Validation

When the native validation options are insufficient or not ideal, it's also possible to entirely override them and implement a custom validation method by using the `validate` prop of a field. Ensure that the prop is assigned a function that returns one or more error messages. If there are multiple error messages, they should be provided as a string array.

The below example demonstrates a more sophisticated method for validating email addresses. The validation will always display the custom error messages. There is no separate message if the field is left empty.

<ComponentDemo file="./validation-custom-validation.demo.tsx" />{' '}

#### Real-time Validation

By default, validation errors are shown to the user after the value is confirmed, for example, when they click away (on blur) or upon submitting the form. This prevents the user from being confused by irrelevant errors while they are still in the process of entering a value.

In specific situations though, choosing real-time validation proves beneficial, for example when enforcing certain password requirements. To enable real-time validation, [control the field](https://react.dev/learn/sharing-state-between-components#controlled-and-uncontrolled-components) and configure the `error` and `errorMessages` props accordingly.

Here's an example where real-time validation is employed to check password requirements, immediately informing the user when a criteria is met.

<ComponentDemo file="./validation-realtime.demo.tsx" />{' '}

#### Handling Server Errors

Server-side validation is essential alongside client-side validation to ensure robust and secure applications. While client-side validation offers immediate feedback and a smoother user experience, server-side validation is crucial for maintaining data integrity and security.

Marigold supports displaying server validation errors via the `validationErrors` prop on the `<Form>` component. The errors should be an object, where each field's `name`is mapped to a string or array of strings representing error messages. The errors are immediately shown to the user upon setting the `validationErrors` and are cleared when the user modifies the field's value.

The subscription example now involves sending and receiving the provided email to and from the server. While most email subscriptions will be successful, attempting to use `support@reservix.de` serves as a negative example, triggering an error response from the server.

<ComponentDemo file="./validation-server-error.demo.tsx" />{' '}

#### Third party libraries

#### Zod

Zod is a TypeScript-first schema declaration and validation library. The term "schema" to broadly refer to any data type, from a simple string to a complex nested object.

It's designed to be as developer-friendly as possible. The goal is to eliminate duplicative type declarations. With Zod, you declare a validator once and Zod will automatically infer the static TypeScript type. It's easy to compose simpler types into complex data structures.

In the following example you can see how a form with all its fields can be submitted. The submitted data will be displayed in an alert message.

For validating the form we are using [`zod`](https://zod.dev/). It is a library for building schemas, which can be used to validate inputs. It is especially useful when you have more complex validation rules.

<ComponentDemo file="./validation-zod.demo.tsx" />{' '}

#### react-hook-form

React Hook Form is a library for managing form state and validation in React applications using hooks. It allows you to create forms with minimal boilerplate and provides a simple and efficient way to handle form validation, submission, and error handling.

With React Hook Form, you can easily manage form state without the need for controlled components, making your code cleaner and more concise. It also offers performance benefits by reducing unnecessary re-renders.

For some examples have a look at [Building Forms](/patterns/building-forms#handling-complex-forms-and-form-state) section.

## Related

<TeaserList
items={[
{
title: 'Building Forms',
href: '../../patterns/building-forms',
caption: 'Learn how to build forms.',
icon: (
<svg
xmlns="http://www.w3.org/2000/svg"
width={24}
height={24}
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth={2}
strokeLinecap="round"
strokeLinejoin="round"
>
<path d="M12 3H5a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2v-7" />
<path d="M18.375 2.625a2.121 2.121 0 113 3L12 15l-4 1 1-4z" />
</svg>
),
},
]}
/>
77 changes: 0 additions & 77 deletions docs/content/foundations/validation/validation.mdx

This file was deleted.

Loading
Loading