Form element wrapper
Provides a structured container for form elements, clarifying their purpose, offering context, and displaying feedback consistently.
#Examples
#Overview of form elements
Control | Usage | Examples | Best practice |
---|---|---|---|
Form Element Wrapper | Wraps individual input controls to provide consistent styling, labeling, and error handling. | A group of radio buttons with a label, help text, and an error message area. |
|
Input Field | Captures short, single-line text. | Name, email address, phone number, short answer |
|
Checkbox | Allows users to select multiple options from a list. | "Agree to terms and conditions," selecting rows to display in the table, bulk selection |
|
Radios | Allows users to select a single option from a list of mutually exclusive choices. | Choosing WCAG version, level of WCAG conformance, or display title/ URL |
|
Toggle Switch | Provides a binary choice (on/off, yes/no). | Enabling/disabling an AI feature, showing/hiding a section of content, or toggling an enhanced contrast in Chart. |
|
File Input | Allows users to upload one or more files. | Uploading a company logo to customise dashboard report |
|
Select | Allows users to choose a single option (or multiple in a multi-select variant) from a list. | Selecting a country, state, or category from a predefined list. |
|
Text area | Captures longer, multi-line text input. | Writing a comment, Chart’s annotation providing feedback, or filling out a long-form description. |
|
#Default
The default wrapper is ideal for text input fields.
Best Practices:
- Use specific and descriptive labels (e.g., "Mailing Address" instead of just "Address").
- Consider using placeholder text to provide examples or hints, but not as a replacement for labels.
const [value, setValue] = useState("");
const [value2, setValue2] = useState("");
return (
<>
<FormElementWrapper label="Label" name="name">
<InputField value={value} onChange={setValue} />
</FormElementWrapper>
<FormElementWrapper label="Label with tooltip" name="name" tooltip="Some further explanation">
<InputField value={value2} onChange={setValue2} />
</FormElementWrapper>
</>
);
#Group
If you need to use another component (e.g. a Button) together with a form control you must pass a child with the type of a functional component, spread the props on the form control component (e.g. Input Field) and add the isGroup
prop. This will ensure that the correct aria
attributes are being added in the right places.
const [value, setValue] = useState("");
return (
<FormElementWrapper label="Label" name="name" isGroup>
{(formControlProps) => (
<>
<InputField {...formControlProps} value={value} onChange={setValue} />
<Button onClick={() => console.log("clicked")}>Button</Button>
</>
)}
</FormElementWrapper>
);
#Single Select
Allows users to choose one option from a list.
Best Practices:
- Use a clear label to describe the options in the list.
- If there are only a few options, consider using Radios instead for improved visibility.
const items = [
{ title: "Apple", value: 1 },
{ title: "Banana", value: 2 },
{ title: "Pear", value: 3 },
];
const [selected, setSelected] = useState<number | undefined>();
return (
<FormElementWrapper label="Fruit" name="Fruit">
<Select
items={items}
value={selected}
onChange={setSelected}
noDefaultOption
placeholder="Some placeholder"
/>
</FormElementWrapper>
);
#Multi Select
Allows users to choose multiple options from a list.
Best Practices:
- Follow the same guidelines as single select.
- Clearly indicate how many options the user can select (e.g., "Select up to 3").
const items = [
{ value: 0, title: "Apple" },
{ value: 1, title: "Banana" },
{ value: 2, title: "Blueberry" },
{ value: 3, title: "Cherry" },
{ value: 4, title: "Grape" },
{ value: 5, title: "Guava" },
{ value: 6, title: "Lemon" },
{ value: 7, title: "Lime" },
{ value: 8, title: "Orange" },
{ value: 9, title: "Peach" },
{ value: 10, title: "Pear" },
];
const [selectedItems, setSelectedItems] = useState<number[]>([]);
return (
<FormElementWrapper label="Fruit" name="Fruit">
<Select
items={items}
value={selectedItems}
onChange={setSelectedItems}
noDefaultOption
bulkActions
placeholder="Some placeholder"
/>
</FormElementWrapper>
);
#Checkbox
Allows users to select multiple options from a set of checkboxes.
Best Practices:
- Use a group label to explain the relationship between the checkboxes.
- Ensure each checkbox has a clear and concise label.
const [selected, setSelected] = useState<string[]>([]);
return (
<FormElementWrapper label="Fruit" name="Fruit">
<CheckboxGroup onChange={setSelected} value={selected}>
<CheckboxGroup.Checkbox value="Apple">Apple</CheckboxGroup.Checkbox>
<CheckboxGroup.Checkbox value="Banana">Banana</CheckboxGroup.Checkbox>
<CheckboxGroup.Checkbox value="Pear">Pear</CheckboxGroup.Checkbox>
</CheckboxGroup>
</FormElementWrapper>
);
#Radio button
Allows users to select a single option from a set of mutually exclusive choices.
Best Practices:
- Use radio buttons for a limited number of options.
- Ensure each radio button has a clear and concise label.
- Group related radio buttons.
const [radioValue, setRadioValue] = useState("Apple");
return (
<FormElementWrapper label="Fruit" name="Fruit">
<Radios value={radioValue} onChange={setRadioValue}>
<Radios.Radio value="Apple">Apple</Radios.Radio>
<Radios.Radio value="Banana">Banana</Radios.Radio>
<Radios.Radio value="Pear">Pear</Radios.Radio>
</Radios>
</FormElementWrapper>
);
#Helptext
Provide additional context and immediate feedback to the user.
Best Practices:
- Use concise help text to guide users.
- Avoid excessive placeholder texts.
Below (default)
Helptext to understand the context of the form control better
Above
Helptext to understand the context of the form control better
const [value, setValue] = useState("");
const [value2, setValue2] = useState("");
return (
<>
<H2>Below (default)</H2>
<FormElementWrapper
label="Label"
name="name"
helptext="Helptext to understand the context of the form control better"
>
<InputField value={value} onChange={setValue} />
</FormElementWrapper>
<H2>Above</H2>
<FormElementWrapper
label="Label"
name="name"
helptext="Helptext to understand the context of the form control better"
helptextPosition="above"
>
<InputField value={value2} onChange={setValue2} />
</FormElementWrapper>
</>
);
#Invalid state
Provide additional context and immediate feedback to the user.
Best Practices:
- Validate input in real-time and provide clear error messages.
- Use visual cues (color, icons) to indicate the state of the input (e.g error).
Some error message to let the user know what's wrong
const [value, setValue] = useState("");
const [value2, setValue2] = useState("");
return (
<>
<FormElementWrapper label="Invalid state" name="name" invalid>
<InputField value={value2} onChange={setValue2} />
</FormElementWrapper>
<FormElementWrapper
label="Invalid state with error"
name="name"
error="Some error message to let the user know what's wrong"
invalid
>
<InputField value={value} onChange={setValue} />
</FormElementWrapper>
</>
);
#Helptext and invalid state
Provide additional context and immediate feedback to the user.
Best Practices:
- Use concise help text to guide users.
- Validate input in real-time and provide clear error messages.
- Use visual cues (color and icons) to indicate the state of the input (e.g error).
Some error message to let the user know what's wrong
Helptext to understand the context of the form control better
const [value, setValue] = useState("");
return (
<>
<FormElementWrapper
label="Helptext and invalid state"
name="name"
helptext="Helptext to understand the context of the form control better"
error="Some error message to let the user know what's wrong"
invalid
>
<InputField value={value} onChange={setValue} />
</FormElementWrapper>
</>
);
#Horizontal
Arrange labels horizontally next to their corresponding input fields.
Best Practices:
- Use for forms with limited space or shorter labels.
- Ensure labels and inputs are visually aligned.
const [value, setValue] = useState("");
const [value2, setValue2] = useState("");
return (
<>
<FormElementWrapper horizontal label="Label" name="name">
<InputField value={value} onChange={setValue} />
</FormElementWrapper>
<FormElementWrapper
horizontal
label="Label with tooltip"
tooltip="Some further explanation"
name="name"
>
<InputField value={value2} onChange={setValue2} />
</FormElementWrapper>
</>
);
#Input with slugs, helptext and invalid state
Provide additional context and immediate feedback to the user.
Best Practices:
- Use concise help text to guide users.
- Validate input in real-time and provide clear error messages.
- Use visual cues (color and icons) to indicate the state of the input (error).
Some error message to let the user know what's wrong
Helptext to understand the context of the form control better
const [value, setValue] = useState("");
return (
<>
<FormElementWrapper
label="Slugs, helptext and invalid state"
name="name"
helptext="Helptext to understand the context of the form control better"
error="Some error message to let the user know what's wrong"
invalid
>
<InputFieldWithSlug
aria-label="My accessible input component"
placeholder="Placeholder"
name="some input"
value={value}
onChange={setValue}
leftSlug="Count:"
rightSlug="items"
fullWidth
/>
</FormElementWrapper>
</>
);
#Tooltip variants
Provide additional information on hover or focus.
Best Practices:
- Use tooltips sparingly for additional information that doesn't fit in the label.
- Keep tooltip content brief and relevant.
const [value, setValue] = useState("");
return (
<>
<FormElementWrapper
label="Label with tooltip variant"
name="name"
tooltip={
<Tooltip variant={{ type: "icon-only" }} content="Some further explanation">
<Icon>
<IconPotentialIssue />
</Icon>
</Tooltip>
}
>
<InputField value={value} onChange={setValue} />
</FormElementWrapper>
</>
);
#Properties
Property | Description | Defined | Value |
---|---|---|---|
labelRequired | string Label for the form control | ||
childrenRequired | | element | function Form control | ||
nameRequired | string Value for the name attribute | ||
tooltipOptional | | string | element The content of the form control tooltip | ||
invalidOptional | boolean Invalid state of the form control | ||
errorOptional | element Error message to be displayed when form control is in an invalid state | ||
helptextOptional | element Helptext to understand the context of the form control better | ||
helptextPositionOptional | "above" | "below" Positions the helptext above or below the form control (defaults to "below") | ||
horizontalOptional | boolean When true label and form control are displayed horizontally next to each other | ||
isGroupOptional | boolean If another component (e.g. a button) is used together with a regular form control as a group | ||
classNameOptional | string Custom className that's applied to the outermost element (only intended for special cases) | ||
styleOptional | object Style object to apply custom inline styles (only intended for special cases) | ||
data-observe-keyOptional | string Unique string, used by external script e.g. for event tracking |
#Guidelines
#Best practices
#Do not use when
#Accessibility
Explore detailed guidelines for this component: Accessibility Specifications