Field
Connects a form input to its label, description and validation message using context.
import { Field, FieldDescription, FieldLabel, FieldMessage, HelpIndicator, useFieldContext, useMaybeFieldContext, useRemainingCharactersGuidance, useTextareaRemainingCharactersGuidance } from '@balance-web/field';Field
Using context, the field component connects the label, description, and message to the input element.
label
labelVisible
There may be occasions where the label is apparent through context to sighted
users, so you wish to omit it from the view. We still need a label attached to
the input for assistive technology, in these cases you can provide the
labelVisible property.
requiredOrOptional
Shows "(required)" or "(optional)" after the label, in the label colour and in
regular weight. When the property is not set, the label shows no suffix. Do not
also put "(required)" or "(optional)" in the label text.
In a form, mark the required fields or the optional fields, never both. Mark the kind that has fewer fields. See the guidelines.
When most fields are optional, mark the required fields:
When most fields are required, mark the optional fields:
description
Link inside description text
You can pass a ReactElement as description. This should only be used when you need to put a link or some other interactive element in the description.
You don't need to concern yourself styling the text, it will be handled by the component. Just render your normal text inside a Fragment and use a TextLink component to render the link.
helpText
Help text is hidden by default, and revealed in a tooltip invoked by an icon beside the label.
invalidMessage
reserveMessageSpace
Reserve the vertical space that will be taken by an invalid message. You would use this to stop subsequent elements from being pushed down when an invalid message is displayed.
guidance
Field guidance is an extra information about the field. For example, it can be used to show remaining characters of the input field with maxLength property.
layout
Decides if the label and input should be laid out horizontally or vertically.
When horizontal, the component will try to fill all horizontal space via flex: 1.
Default value is vertical
Building a custom input
Field doesn't require its child to be a Balance input — any input passed as
children can read the field's id, aria-describedby and invalid state
via useFieldContext (or useMaybeFieldContext, which returns null instead
of throwing outside a Field) to wire itself up automatically. Every input in
this design system (TextInput, Textarea, Combobox, DatePicker, Radio,
…) uses this to auto-connect to its enclosing Field without the consumer
having to pass id/aria-describedby by hand — reach for it directly when
building a new input component of your own.
FieldLabel is the standalone label component Field renders internally —
reach for it directly only if you're composing a field-like layout without
using Field itself.
useTextareaRemainingCharactersGuidance
Like useRemainingCharactersGuidance above, but the guidance text is only
visible while the textarea is focused (or once the limit is exceeded), and
reserves its layout space the rest of the time so focusing the textarea
doesn't shift surrounding content. Spread the returned textareaProps onto
the Textarea to track its focus state.
Testing
The field component generates testids automatically based on their field id. You can override this by providing a data attribute with a custom testid field.
Public Composition
Within the <Field>, the component sets a data-testid attribute on the root element and other public composable components will derive their own testids from it.
For more information on how to use the
dataattribute, see
This ends up generating the following testids:
my-field-1- Main wrapper elementmy-field-input-1- Text input fieldmy-field-label-1- Label elementmy-field-description-1- Description elementmy-field-message-1- Message elementmy-field-help-indicator-1- Help text tooltip element
Each component also provides a data-balance-component attribute. These are :
data-balance-component="field"- Main wrapper elementdata-balance-component="field-input"- Text input fielddata-balance-component="field-label"- Label elementdata-balance-component="field-description"- Description elementdata-balance-component="field-message"- Message elementdata-balance-component="field-help-indicator"- Help text tooltip element
Private Composition
If you choose to provide your own instance of <FieldDescription>, <FieldMessage> or <HelpIndicator> inside your <Field> as children, then these will you will need to provide the testid to these yourself.
Without providing a data attribute, the component will not generate testids for these elements.
When you provide your own instances of these components, you can still use the data attribute to generate testids for them. This is useful for testing purposes.