Field
Wraps a form control with its label, description and error, wires them together for assistive tech and tracks validity. Comes with Input, Textarea, Label and Fieldset.
We send invoices and sign-in links here.
Installation
Set up Camaleo once (Installation), then import what you need.
import { Field, FieldLabel, FieldDescription, FieldError } from "@camaleo/react";import { Input, Textarea, Label, Fieldset, FieldsetLegend } from "@camaleo/react";Anatomy
A Field is a grid of up to four parts. The label points at the control, and the description and error are read with it.
Examples
Every example is a real file you can copy. They all wear the skin, mode and brand from the bar above.
As it appears on your ID. We print it on invoices.
0 / 160 characters
Textarea with a counter
Type in it. A live count in FieldDescription is read with the field, so people hear the limit before they hit it.
Required
Type a letter, delete it and leave. valueMissing waits until the field was changed or the form submitted, so a fresh form never opens in red.
Error from the server
When the error comes from your API, set invalid and render FieldError match. The input gets aria-invalid and the message is linked to it.
Lowercase letters, numbers, dots and underscores.
Custom validation
Type a space or delete letters. validate returns the message, and an empty FieldError shows it while people type.
Only workspace owners can change it.
Disabled
disabled on the Field reaches the label and the control. Say why in the description, or nobody knows who can change it.
Grouped with a fieldset
Fieldset and FieldsetLegend name a group, so "Name" is announced as part of "Emergency contact".
Label outside a field
For a checkbox or switch, wrap it in Label: the whole line becomes clickable and names the control.
Input types
The right type and autoComplete bring up the matching phone keyboard and let the browser fill the value in.
In context
Fields come in forms. These are whole pieces of UI you can copy, in the skin you picked.
Public profile
Shown on your profile and next to your comments.
Guidelines
We send invoices and sign-in links here.
It stays put while people type, and the placeholder is free to show an example.
It disappears on the first keystroke, and its low contrast is hard to read.
The error names the rule, so people know what to type.
"Invalid input." tells people something is wrong, not what to change.
Props
Field takes the props of the Base UI field root. These are the ones you use most:
name.validate and the native constraints run.validate calls in onChange mode.FieldError takes match: true to always show it, a ValidityState key such as "valueMissing" to show it only for that error, or nothing to show it whenever the field is invalid. Fieldset takes disabled. Input and Textarea take the attributes of <input> and <textarea>; Label takes those of <label>.
Styling hooks
Restyle it without forking: target the attributes, or set the tokens on a parent, a skin or the field itself.
Attributes
Tokens it reads
Color
Shape & size
Type & motion
This component only
/* a tighter form, only in this dialog */
.quick-add [data-slot="field"] {
--cml-field-gap: 0.25rem;
}Accessibility
- FieldLabel is a real <label> linked to the control, so its text is the control's accessible name.
- FieldDescription and a visible FieldError are added to aria-describedby, so screen readers read them after the name.
- An invalid field sets aria-invalid on the control. Color is never the only signal: the error message is always text.
- FieldsetLegend names the group, and the legend is announced when focus enters it.