Import
import { FormControl } from '@contentful/f36-components';// orimport { FormControl } from '@contentful/f36-forms';
How to use FormControl
- 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 underHelpText
if displayed, to clearly indicate that it is invalidTextInput
andTextarea
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
With invalid input
Select component with FormControl
Radio Group component with FormControl
Checkbox Group component with FormControl
With character count
Props (API reference)
Open in StorybookFormControl
Name | Type | Default |
---|---|---|
children required | ReactNode | |
as | HTML Tag or React Component (e.g. div, span, etc) | |
className | string CSS class to be appended to the root element | |
id | string | |
inputValue | string value from text input and textarea to used for counting characters | |
isDisabled | false true If `true` set the form control to the disabled state. | |
isInvalid | false true If `true` set the form control to the invalid state. | |
isReadOnly | false true If `true` set the form control to the read only state. | |
isRequired | false true If `true` set the form control to be required. | |
margin | "none" "spacing2Xs" "spacingXs" "spacingS" "spacingM" "spacingL" "spacingXl" "spacing2Xl" "spacing3Xl" "spacing4Xl" sets margin to one of the corresponding spacing tokens | |
marginBottom | "none" "spacing2Xs" "spacingXs" "spacingS" "spacingM" "spacingL" "spacingXl" "spacing2Xl" "spacing3Xl" "spacing4Xl" sets margin-bottom to one of the corresponding spacing tokens | |
marginLeft | "none" "spacing2Xs" "spacingXs" "spacingS" "spacingM" "spacingL" "spacingXl" "spacing2Xl" "spacing3Xl" "spacing4Xl" sets margin-left to one of the corresponding spacing tokens | |
marginRight | "none" "spacing2Xs" "spacingXs" "spacingS" "spacingM" "spacingL" "spacingXl" "spacing2Xl" "spacing3Xl" "spacing4Xl" sets margin-right to one of the corresponding spacing tokens | |
marginTop | "none" "spacing2Xs" "spacingXs" "spacingS" "spacingM" "spacingL" "spacingXl" "spacing2Xl" "spacing3Xl" "spacing4Xl" sets margin-top to one of the corresponding spacing tokens | |
maxLength | number Max length of characters used for the text input and textarea | |
setInputValue | Dispatch<SetStateAction<string>> Set input value function | |
setMaxLength | Dispatch<SetStateAction<number>> Set max length function | |
testId | string A [data-test-id] attribute used for testing purposes |
Label
Name | Type | Default |
---|---|---|
children required | ReactNode Label value to show | |
as | HTML Tag or React Component (e.g. div, span, etc) Defines how the element will be rendered | label |
className | string CSS class to be appended to the root element | |
isRequired | false true Whether or not the associated input element is required | false |
margin | "none" "spacing2Xs" "spacingXs" "spacingS" "spacingM" "spacingL" "spacingXl" "spacing2Xl" "spacing3Xl" "spacing4Xl" sets margin to one of the corresponding spacing tokens | |
marginBottom | "none" "spacing2Xs" "spacingXs" "spacingS" "spacingM" "spacingL" "spacingXl" "spacing2Xl" "spacing3Xl" "spacing4Xl" sets margin-bottom to one of the corresponding spacing tokens | |
marginLeft | "none" "spacing2Xs" "spacingXs" "spacingS" "spacingM" "spacingL" "spacingXl" "spacing2Xl" "spacing3Xl" "spacing4Xl" sets margin-left to one of the corresponding spacing tokens | |
marginRight | "none" "spacing2Xs" "spacingXs" "spacingS" "spacingM" "spacingL" "spacingXl" "spacing2Xl" "spacing3Xl" "spacing4Xl" sets margin-right to one of the corresponding spacing tokens | |
marginTop | "none" "spacing2Xs" "spacingXs" "spacingS" "spacingM" "spacingL" "spacingXl" "spacing2Xl" "spacing3Xl" "spacing4Xl" sets margin-top to one of the corresponding spacing tokens | |
requiredText | string Custom text to show in parentheses that gets rendered if the associated input is required | "required" |
testId | string A [data-test-id] attribute used for testing purposes |
HelpText
Name | Type | Default |
---|---|---|
children required | ReactNode | |
className | string CSS class to be appended to the root element | |
css | string number false true ComponentSelector Keyframes SerializedStyles ArrayInterpolation<undefined> ObjectInterpolation<undefined> (theme: any) => Interpolation<undefined> | |
margin | "none" "spacing2Xs" "spacingXs" "spacingS" "spacingM" "spacingL" "spacingXl" "spacing2Xl" "spacing3Xl" "spacing4Xl" sets margin to one of the corresponding spacing tokens | |
marginBottom | "none" "spacing2Xs" "spacingXs" "spacingS" "spacingM" "spacingL" "spacingXl" "spacing2Xl" "spacing3Xl" "spacing4Xl" sets margin-bottom to one of the corresponding spacing tokens | |
marginLeft | "none" "spacing2Xs" "spacingXs" "spacingS" "spacingM" "spacingL" "spacingXl" "spacing2Xl" "spacing3Xl" "spacing4Xl" sets margin-left to one of the corresponding spacing tokens | |
marginRight | "none" "spacing2Xs" "spacingXs" "spacingS" "spacingM" "spacingL" "spacingXl" "spacing2Xl" "spacing3Xl" "spacing4Xl" sets margin-right to one of the corresponding spacing tokens | |
marginTop | "none" "spacing2Xs" "spacingXs" "spacingS" "spacingM" "spacingL" "spacingXl" "spacing2Xl" "spacing3Xl" "spacing4Xl" sets margin-top to one of the corresponding spacing tokens | |
testId | string A [data-test-id] attribute used for testing purposes | cf-ui-help-text |
ValidationMessage
Name | Type | Default |
---|---|---|
children required | ReactNode | |
className | string CSS class to be appended to the root element | |
css | string number false true ComponentSelector Keyframes SerializedStyles ArrayInterpolation<undefined> ObjectInterpolation<undefined> (theme: any) => Interpolation<undefined> | |
margin | "none" "spacing2Xs" "spacingXs" "spacingS" "spacingM" "spacingL" "spacingXl" "spacing2Xl" "spacing3Xl" "spacing4Xl" sets margin to one of the corresponding spacing tokens | |
marginBottom | "none" "spacing2Xs" "spacingXs" "spacingS" "spacingM" "spacingL" "spacingXl" "spacing2Xl" "spacing3Xl" "spacing4Xl" sets margin-bottom to one of the corresponding spacing tokens | |
marginLeft | "none" "spacing2Xs" "spacingXs" "spacingS" "spacingM" "spacingL" "spacingXl" "spacing2Xl" "spacing3Xl" "spacing4Xl" sets margin-left to one of the corresponding spacing tokens | |
marginRight | "none" "spacing2Xs" "spacingXs" "spacingS" "spacingM" "spacingL" "spacingXl" "spacing2Xl" "spacing3Xl" "spacing4Xl" sets margin-right to one of the corresponding spacing tokens | |
marginTop | "none" "spacing2Xs" "spacingXs" "spacingS" "spacingM" "spacingL" "spacingXl" "spacing2Xl" "spacing3Xl" "spacing4Xl" sets margin-top to one of the corresponding spacing tokens | |
testId | string A [data-test-id] attribute used for testing purposes | cf-ui-validation-message |
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
).