Import
import { FormControl } from '@contentful/f36-components';
import { FormControl } from '@contentful/f36-forms';
- FormControl provides context to form elements:
isRequired
, isDisabled
, isInvalid
, isReadOnly
- Compound components of FormControl are:
Label
, HelpText
, ValidationMessage
, Counter
. These components provide additional visual context and hints for users. - For more information on how to use FormControl in Form, check the guide for Form.
Design guidelines
To uphold a consistent look and experience for your application, we recommend following the same design layout guidelines for all inputs:
Label
is a required element that all your inputs should have to pass the a11y requirements. It should be placed on top of the input, so it would be first in your HTML structure.- An input component should follow the label
HelpText
should appear under the input, when you need to display some additional information to the userValidationMessage
should be appearing directly under the input or under HelpText
if displayed, to clearly indicate that it is invalidTextInput
and Textarea
components can have an option of counting characters. In that case, we recommend aligning HelpText and Counter by using the Flex component and placed them right below the input. Have a look on the example over here
Examples
Basic
function FormControlExample() {
return (
<FormControl isRequired>
<FormControl.Label>Name</FormControl.Label>
<TextInput />
<FormControl.HelpText>Please enter your first name</FormControl.HelpText>
</FormControl>
);
}
function FormControlInvalidExample() {
return (
<FormControl isInvalid>
<FormControl.Label>Name</FormControl.Label>
<TextInput />
<FormControl.HelpText>Please enter your first name</FormControl.HelpText>
<FormControl.ValidationMessage>Error</FormControl.ValidationMessage>
</FormControl>
);
}
function FormControlSelectExample() {
return (
<FormControl>
<FormControl.Label>Name</FormControl.Label>
<Select defaultValue="optionTwo">
<Select.Option value="optionOne">Option 1</Select.Option>
<Select.Option value="optionTwo">Option 2</Select.Option>
</Select>
<FormControl.HelpText>Please select an option</FormControl.HelpText>
</FormControl>
);
}
function FormControlRadioGroupExample() {
return (
<FormControl as="fieldset">
<FormControl.Label as="legend">Radio group options</FormControl.Label>
<Radio.Group name="radio-options" defaultValue="option 1">
<Radio
value="option 1"
id="radio-option-1"
helpText="Help text for option 1"
>
Option 1
</Radio>
<Radio
value="option 2"
id="radio-option-2"
helpText="Help text for option 2"
>
Option 2
</Radio>
</Radio.Group>
<FormControl.HelpText>Please, select an option</FormControl.HelpText>
</FormControl>
);
}
function FormControlCheckboxGroupExample() {
return (
<FormControl as="fieldset" isRequired>
<FormControl.Label as="legend">Checkbox group options</FormControl.Label>
<Checkbox.Group name="checkbox-options">
<Checkbox
value="option 1"
id="checkbox-option-1"
helpText="Some help text"
>
Option 1
</Checkbox>
<Checkbox
value="option 2"
id="checkbox-option-2"
helpText="Another help text"
>
Option 2
</Checkbox>
</Checkbox.Group>
<FormControl.HelpText>
Please, select at least one option
</FormControl.HelpText>
</FormControl>
);
}
With character count
function FormControlCharacterCountExample() {
const limit = 20;
return (
<FormControl>
<FormControl.Label isRequired>Name</FormControl.Label>
<TextInput defaultValue="Initial value" maxLength={limit} />
<Grid columns="auto 80px">
<FormControl.HelpText>
Name should be no longer than {limit} characters
</FormControl.HelpText>
<FormControl.Counter />
</Grid>
</FormControl>
);
}
Label
HelpText
ValidationMessage
Density support
This component supports multiple densities thanks to the useDensity hook and automatically adjusts its styling for each density (when wrapped with the DensityProvider
).