Components Forms
FormField
StableWires a label, help text and error message to any Stance form control.
FormField is the standard wrapper for a single form control. It renders the label, description and error and passes ids and ARIA state to the control through context, so every Stance input, select, checkbox, switch, slider and file upload is labelled and described correctly with no manual id plumbing.
Overview
As it should appear on signed documents.
import { FormField, Input } from '@bindshq/stance-react';
export function Basic() {
return (
<div style={{ width: '100%', maxWidth: 380 }}>
<FormField label="Full name" description="As it should appear on signed documents." required>
<Input autoComplete="name" />
</FormField>
</div>
);
}Light, dark and high contrast
Every Stance component is designed and tested in all three appearance modes.
As it should appear on signed documents.
As it should appear on signed documents.
As it should appear on signed documents.
Import
import { FormField } from '@bindshq/stance-react';Platforms
FormField has native counterparts. They share Stance tokens and intent, and use each platform’s own controls and conventions. The live previews on this page are the web implementation.
import { FormField } from '@bindshq/stance-react';Examples
Validation
An error marks the control aria-invalid and is announced via role="alert".
Enter an email address like name@company.com
import { FormField, Input } from '@bindshq/stance-react';
export function Validation() {
return (
<div style={{ width: '100%', maxWidth: 380 }}>
<FormField label="Signer email" error="Enter an email address like name@company.com" required>
<Input type="email" defaultValue="priya@" />
</FormField>
</div>
);
}Horizontal layout
Label beside the control on wide screens; stacks on phones.
Visible to your organisation.
import { FormField, Input } from '@bindshq/stance-react';
export function Horizontal() {
return (
<div style={{ display: 'grid', gap: 16, width: '100%', maxWidth: 640 }}>
<FormField
label="Display name"
orientation="horizontal"
description="Visible to your organisation."
>
<Input defaultValue="Acme Legal" />
</FormField>
<FormField label="Department" orientation="horizontal" optionalText="Optional">
<Input />
</FormField>
</div>
);
}Appended below every signature.
You must accept to continue
import { Checkbox, FormField, NativeSelect, Textarea } from '@bindshq/stance-react';
export function AnyControl() {
return (
<div style={{ display: 'grid', gap: 16, width: '100%', maxWidth: 380 }}>
<FormField label="Default template">
<NativeSelect
options={[
{ value: 'classic', label: 'Classic' },
{ value: 'minimal', label: 'Minimal' },
]}
/>
</FormField>
<FormField label="Disclaimer" description="Appended below every signature.">
<Textarea rows={3} />
</FormField>
<FormField label="Accept the data processing terms" error="You must accept to continue">
<Checkbox />
</FormField>
</div>
);
}API reference
FormField
| Prop | Type | Default | Description |
|---|---|---|---|
label | ReactNode | None | Visible label, associated with the control. |
description | ReactNode | None | Help text, linked via aria-describedby. |
error | ReactNode | None | Error message. Its presence marks the field invalid. |
required | boolean | false | Adds a required indicator and sets required on the control. |
optionalText | ReactNode | None | Marker for optional fields, e.g. "Optional". |
disabled | boolean | false | Disables the control. |
readOnly | boolean | false | Makes the control read-only. |
id | string | None | Explicit id for the control; generated otherwise. |
orientation | 'vertical' | 'horizontal' | 'vertical' | Label above or beside the control. |
hideLabel | boolean | false | Visually hides the label but keeps it accessible. |
useFormFieldControl
| Prop | Type | Default | Description |
|---|---|---|---|
(props) => props | hook | None | Merges field state into your own custom control’s props. |
Accessibility
- The label is a real <label for>, so clicking it focuses or toggles the control.
- Description and error are both referenced by aria-describedby, in that order.
- Errors render with role="alert" so they are announced when they appear.
- The required indicator is decorative; ", required" is announced through visually hidden text.
- Errors carry an icon as well as colour, so they are not communicated by colour alone.
Usage guidelines
Do
- Use one FormField per control.
- Write errors that say how to fix the problem.
Don’t
- Nest FormFields.
- Use FormField around a CheckboxGroup or RadioGroup. They render their own fieldset and legend.