Field
The field component exposes the elements around form inputs, and an API to compose them.
Quick Start
- Installation
npm install @adaptavant/eds-core- Import
import { Field } from '@adaptavant/eds-core';
Label
Each field must be accompanied by a label. Effective form labelling helps users understand what information to enter into an input.
Using placeholder text in lieu of a label is sometimes employed as a space-saving method. However, this is not recommended because it hides context and presents accessibility issues.
Label visibility
The label must always be provided for assistive technology, but you may hide it from sighted users when the intent can be inferred from context.
Secondary label
Provide additional context, typically used to indicate that the field is optional.
Size
Customize the size of the field using size prop.
Use standard in applications where space is a premium.
Use large in customer-facing experiences, such as the booking page, where accessibility is a priority.
{/* standard */}
<Field label="First name" size="standard">
<TextInput />
</Field>
{/* large */}
<Field label="First name" size="large">
<TextInput />
</Field>
Description
Provides relevant information that assists the user in completing a field. Description text is always visible and appears underneath the label. Use sentence-style capitalisation, and in most cases, write the text as full sentences with punctuation.
<Field
label="Email"
description="We take your privacy seriously. We will never give your email to a third party."
>
<TextInput type="email" />
</Field>
Error messages
The errorMessage prop is used to provide users with more context as to why the field is invalid. This will be announced on focus.
The
errorMessageprop is ⚠️ deprecated and will be removed in a future release, please check the FieldMessage section to add error state.
<Field
label="Email"
secondaryLabel="(Optional)"
errorMessage="Enter an email address in the correct format, like name@example.com"
>
<TextInput type="email" />
</Field>
Status
Use the status prop to indicate whether a field is in an error or warning state.
<Stack className="gap-4">
<Field
label="Email"
secondaryLabel="(Optional)"
status="error"
>
<TextInput type="email" />
</Field>
<Field
label="Email"
secondaryLabel="(Optional)"
status="warning"
>
<TextInput type="email" />
</Field>
</Stack>
Field Message
Use the status and fieldMessage props to convey why the field is in an error or warning state. The message is announced on focus for screen readers.
<Stack className="gap-4">
<Field
label="Email"
secondaryLabel="(Optional)"
fieldMessage="Enter an email address in the correct format, like name@example.com"
status="error"
>
<TextInput type="email" />
</Field>
<Field
label="Email"
secondaryLabel="(Optional)"
fieldMessage="Enter an email address in the correct format, like name@example.com"
status="warning"
>
<TextInput type="email" />
</Field>
</Stack>
Counter
Use the counter prop to display a character count indicator beneath any input component (e.g., TextInput, Textarea). The counter accepts value, maxValue, and isAlwaysVisible parameters.
The counter shows the difference between the current value and maxValue, along with a circular progress indicator. When the value exceeds maxValue, it displays a negative number.
By default, the counter appears when input reaches 50% of maxValue. Use isAlwaysVisible: true to show it at all times.
const [textInputValue, setTextInputValue] = React.useState('');
const [textareaValue, setTextareaValue] = React.useState('');
const maxLength = 40;
return (
<Box className="flex flex-col gap-4 w-[300px]">
{/* Counter with TextInput - appears at 50% threshold */}
<Field label="Characters counter demo" counter={{ value: textInputValue.length, maxValue: maxLength }}
errorMessage={textInputValue.length> maxLength ? 'Max length exceeded' : undefined}
>
<TextInput placeholder="Enter 20 characters or more to view counter" defaultValue={textInputValue} onChange={(e)=>
setTextInputValue(e.target.value)}
/>
</Field>
{/* Counter with Textarea - always visible */}
<Field label="Characters counter demo" counter={{ value: textareaValue.length, maxValue: maxLength, isAlwaysVisible:
true }} errorMessage={textareaValue.length> maxLength ? 'Max length exceeded' : undefined}
>
<Textarea placeholder="Enter text" defaultValue={textareaValue} onChange={(e)=> setTextareaValue(e.target.value)}
/>
</Field>
</Box>
)
Disabled
Use the isDisabled prop to show that a Field isn't usable.
Required
Use the isRequired prop if user input is required on the field before form submission.
API Reference
Field
| Props | Type | Description | Default |
|---|---|---|---|
children | React.ReactNode | Input component like TextInput, Textarea. | |
description? | React.ReactNode | Provide additional information that will aid user input. | _ |
errorMessage? | React.ReactNode | Message to show when the field is invalid. | _ |
status? | error | warning | Use the status prop to indicate whether a field is in an error or warning state. | _ |
fieldMessage? | string | Use the status and fieldMessage props to convey why the field is in an error or warning state. The message is announced on focus for screen readers. | |
controlId? | string | Specifies the unique identifier for the form control within the component. This ID is used to associate the input, textarea, select, button etc with its label or other descriptive elements. | _ |
isDisabled? | boolean | Whether the field is disabled. | false |
isRequired? | boolean | Whether user input is required on the field before form submission. | false |
label | React.ReactNode | Label for the field. | _ |
labelVisibility? | 'hidden' | 'visible' | A label must always be provided for assistive technology, but you may hide it from sighted users when the intent can be inferred from context. | 'visible' |
secondaryLabel? | React.ReactNode | Additional context, typically used to indicate that the field is optional. | _ |
size? | 'standard' | 'large' | The size of the field. | 'standard' |
counter? | CounterObjProps | Counter object containing maxValue, value and isAlwaysVisible. | _ |
counter.maxValue? | number | Maximum value the counter can reach. | _ |
counter.value? | number | Current value of the counter. | _ |
counter.isAlwaysVisible? | boolean | Whether the counter is always visible. | false |
Style API
Our design system components include style props that allow you to easily customize different parts of each component to match your design needs.
Please refer to the Style API documentation for more insights.
Field parts
{/* Styling the Label and Description parts */}
<Field
label="Username"
description="Enter your username"
secondaryLabel="(Optional)"
className="p-4 border border-positive"
classNames={{
label: 'text-positive font-stronger',
description: 'text-positive-secondary',
secondaryLabel: 'text-link'
}}
>
<TextInput />
</Field>
{/* Styling the Error state parts */}
<Field
label="Email"
errorMessage="Invalid email format"
classNames={{
errorTrack: 'mt-3',
errorIcon: 'fill-caution',
errorMessage: 'text-caution'
}}
>
<TextInput />
</Field>
{/* Styling the counter */}
<Field
label="Message"
counter={{ value: 10, maxValue: 100, isAlwaysVisible: true }}
classNames={{
counter: 'text-caution-secondary'
}}
>
<Textarea />
</Field>
| Stylable Parts | Description |
|---|---|
root | The container that wraps the entire field component, including the label, input, description, and error states. |
label | The main label element that identifies the field's purpose. |
secondaryLabel | A supplementary label element that can be used to display additional information next to the main label. |
description | The helper text element below the input that provides additional guidance or context to the user. |
errorTrack | The container element that holds both the error icon and error message when validation fails. |
errorIcon | The visual indicator (icon) that appears when the field is in an error state. |
errorMessage | The text element that displays validation error messages or feedback when the field is invalid. |
counter | The text element that displays the character count and limit information (e.g., "10/100"). |