Form Fields
Comprehensive guide for working with form fields
Form fields are the input controls that collect data in a form, such as text fields, checkboxes, radio buttons, select fields, and text areas. Buttons are part of a form too, but they trigger actions rather than capture input. See the Forms pattern for guidance on submit and other actions.
Browse the full set of form components in the sidebar under Components → Form.
Anatomy
An accessible form field includes a clear label associated with its corresponding form control (<input>, <select>, ...). Additional guidance is provided by the help text, which can give extra context or instructions.
Marigold's form components let you set these through the label, description (which renders as the help text), and errorMessages props, alongside any control-specific props. The help text slot doubles as the error message slot when validation fails.
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, the purpose of the input is clear. In these cases, it is still important to provide an aria-label attribute to ensure that users with assistive technologies can understand the input's purpose, maintaining accessibility for all users.
Do
Do provide a clear, descriptive label for each form field
Don't
Placeholder
Placeholder text is a short hint displayed inside an input field before a user enters a value. To save space, placeholder text is often used instead of a label, as shown in the first example. This is problematic for the following reasons:
- Placeholder text disappears once a person starts filling in an input field, causing some to forget what the field was for
- Some might miss or skip fields with placeholder text, as it can look like the field has already been pre-filled.
- Placeholder text colour contrast is almost always inaccessible, as it’s very light by design. This means many will struggle to read the label.
Do
Provide a short description of what the user will be able to search for.
Don't
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.
Don't
Don’t use Help Text as a substitute for a label. It should complement the label, not replace it.
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." /> );};Width
The width of form fields can be adjusted based on the context and design requirements. Marigold's form components support a width prop that allows you to set the width of the field using keywords (fit, full, auto), scales (32, 64, 96), or fraction values (1/2, 2/3, etc.).
Scale values may be passed either as a number or as the equivalent string. Both width={32} and width="32" are valid and produce the same result. The same applies to spacing-scale props on layout components (space, spaceX, spaceY, pl, pr, pt, pb).
Numeric values map to the spacing scale, not pixels: width={64} resolves to calc(var(--spacing) * 64), roughly 16rem (256px), not 64px. The width prop sizes the field element directly, so no wrapper element is needed.
<TextField label="Name" width={64} />
<Select label="Country" width="1/2">
{/* options */}
</Select>When using fixed/keywords widths the label and description won't be included in the width calculation and won't adapt to the width of the field. The text will not shrink if the field is too small to fit the text.
For fraction values, the field will take up the specified fraction of the width of its parent container. This is particularly useful for creating responsive layouts where fields need to adjust based on the available space.
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 scenarios. Below are the common field states used in forms.
Disabled State
Disabled input fields are non-interactive and signal that they are temporarily unavailable. They are typically used when the input is irrelevant based on prior user choices or when a prerequisite action is required. To avoid confusion, it's important to provide clear context or messaging explaining why the field is disabled, ensuring users understand when and how the input will become available.
import { Stack, TextField } from '@marigold/components';export default () => { return ( <Stack space={2}> <TextField label="username" placeholder="enter user name" disabled /> </Stack> );};Required State
Required fields must be completed before form submission.
import { Select } from '@marigold/components';export default () => ( <Select label="Genre" placeholder="Select genre" 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>);Error State
Fields in an error state indicate that the entered value is invalid or incorrect. Error messages and visual feedback.
import { NumberField } from '@marigold/components';export default () => { return ( <NumberField label="Quantity" error errorMessage="Max number of available tickets is 3" value={4} /> );};ReadOnly State
Read-only fields display data that users can view but not modify. They are commonly used for displaying information that is fixed or derived from other inputs. It's important to provide context or a clear explanation for why a field is read-only, so users understand its purpose and why it cannot be changed.
ReadOnly State
import { Headline, Stack, Switch } from '@marigold/components';export default () => { return ( <Stack space={2}> <Headline level={'5'}>ReadOnly State</Headline> <Switch label="Settings Locked" readOnly /> </Stack> );};