The FormField component enhances form inputs with an accessible label and optionally displays additional help text.
Examples #
Import Syntax #
import { FormField } from 'mineral-ui/Form';Basic Usage #
FormField accepts any input, either to the input prop or
children, accessibly connecting the label to it.
<DemoLayout> {/* Use the "input" prop for a streamlined approach. */} <FormField input={TextInput} label="Name" /> {/* Or use "children", if you prefer. */} <FormField label="Description"> <TextArea /> </FormField> </DemoLayout>
Required #
Marking a FormField as required will display the requiredText
and pass along the required prop to the child input. requiredText takes
precedence over secondaryText.
<DemoLayout> <FormField input={TextInput} label="Name" required /> <FormField input={TextInput} label="Nombre" required requiredText="Necesario" /> </DemoLayout>
Secondary Text #
Use the secondaryText prop to provide brief additional
details to the label text. Note that if requiredText is provided, it
displays instead of secondaryText.
<FormField
input={TextInput}
label="Name"
secondaryText="Optional" />Caption #
Use a caption to display not-so-brief additional information,
such as help text or, along with a variant, a
validation message.
<FormField
input={TextInput}
label="Name"
caption="This is help text" />Variants #
FormField is available in a few variants, mostly for use with validation. Be sure to use the appropriate variant for your intent.
<DemoLayout> <FormField input={TextInput} label="Success" caption="This is help text" variant="success" /> <FormField input={TextInput} label="Warning" caption="This is help text" variant="warning" /> <FormField input={TextInput} label="Danger" caption="This is help text" variant="danger" /> </DemoLayout>
Visually Hidden Label #
If the purpose of a FormField is obvious from context and adding
a label would negatively affect the design, as in the example below, you can use
hideLabel to visually hide the label while retaining accessibility.
<DemoLayout> <FormField input={TextInput} label="Address" placeholder="1234 Main St" /> <FormField input={TextInput} label="Address Line 2" placeholder="Apt 101" hideLabel /> </DemoLayout>
Validation #
This example demonstrates simple required field validation. An empty input will fail validation while a non-empty input will pass.
() => { class MyForm extends Component { constructor(props) { super(props); this.state = { caption: undefined, valid: false, validated: false, value: '', variant: undefined }; this.handleTextInputChange = this.handleTextInputChange.bind(this); this.validate = this.validate.bind(this); } handleTextInputChange(event) { this.setState({ value: event.target.value }); } validate(event) { if (this.state.value) { this.setState({ caption: 'Success, the value is valid.', valid: true, validated: true, variant: 'success' }); } else { this.setState({ caption: 'Oops, the value is invalid.', valid: false, validated: true, variant: 'danger' }); } this.input.focus(); } render() { const { caption, valid, validated, variant, value } = this.state; const formFieldProps = { input: TextInput, inputRef: ref => { this.input = ref; }, invalid: validated ? !valid : undefined, label: 'Example', onChange: this.handleTextInputChange, caption, required: true, value, variant }; return ( <DemoLayout> <FormField {...formFieldProps} /> <Button onClick={this.validate}>Validate</Button> </DemoLayout> ); } } return <MyForm />; }
Bidirectionality #
FormFields support right-to-left (RTL) languages.
<div dir="rtl"> <ThemeProvider theme={{ direction: 'rtl' }}> <FormField input={TextInput} iconStart={<IconBackspace />} label="نموذج" defaultValue="مرحبا بالعالم" required requiredText="مطلوب" /> </ThemeProvider> </div>
API & Theme #
FormField Props #
The FormField component takes the following React props.
| Name | Type | Default | Description |
|---|---|---|---|
| caption | string | React$Element<*> | Caption associated with the input element; commonly used to provide help text | |
| children | React$Node | Form input element | |
| hideLabel | boolean | Visually hide label, but keep available for assistive technologies | |
| id | string | Id of the FormField | |
| input | React$ComponentType<*> | Form input class; alternative to | |
| label | string | React$Element<*> | required | Label associated with the input element |
| required | boolean | Marks associated input as required | |
| requiredText | string | React$Element<*> | 'Required' | Text used to indicate a required field |
| rootProps | Object | Props to be applied directly to the root element, rather than the input | |
| secondaryText | string | React$Element<*> | Secondary text associated with the input element; takes precedence over | |
| variant | 'danger' | 'success' | 'warning' | Available variants |
FormField Theme Variables #
These variables can be used as hooks to override this component's
style at either a
local
or global
level. The theme referenced below is whatever theme is available
from props to the instance of this component.
| Variable | Value |
|---|---|
| FormFieldCaption_color | theme.color_mouse |
| FormFieldCaption_fontSize | theme.fontSize_mouse |
| FormFieldCaption_marginTop | theme.space_stack_xxs |
| FormFieldCaption_marginTop_isGroup | theme.space_stack_sm |
| FormFieldLabel_color | theme.h6_color |
| FormFieldLabel_fontSize | theme.h6_fontSize |
| FormFieldLabel_fontWeight | theme.fontWeight_semiBold |
| FormFieldLabel_marginBottom | theme.space_stack_sm |
| FormFieldSecondaryText_fontSize | theme.fontSize_mouse |
| FormFieldSecondaryText_color | theme.color_mouse |
| FormFieldSecondaryText_color_required | theme.color_required |
| FormFieldSecondaryText_fontWeight | theme.fontWeight_regular |
Usage #
When/How to Use #
Wrap each input in your app with a FormField for appropriate accessibility and styling.
Labels should be short (1-3 words) and indicate the type of input requested. Labels are not meant to explain the intent of the form as a whole.
Placeholder text is not a replacement for labels.
Do not use an asterisk in labels for required fields; use the required prop
instead.
Error text should be short and concise, telling the user how to fix the problem.
Best Practices #
Wrap inputs in a FormField and provide a brief, descriptive label.
Use the appropriate variant to match your intent.
Don't use a variant that differs from intent, as this will cause confusion.
Provide useful secondaryText, when necessary.
Don't put too much secondaryText.
Provide a brief, helpful caption, when necessary.
Don't put too much text in a caption.
Passwords must contain at least 4 of the following:
- 8 or more characters
- less than 25 characters
- a letter
- a number
- a special character; not allowed: /\(),.
Use the hideLabel prop to hide the label in an
accessible manner when the design requires it.