Field
A label, a hint and an error, bound to one control.
import { Field } from "@dede-style/ui/field", then wrap a control in it: <Field label="Email address"><TextInput …/></Field>. It knows nothing about text inputs — a Select, a Textarea and a Checkbox all need the same four rows and the same wiring, and only the box in the middle changes.
We'll only use this to reply.
| Prop | Description | Default | Control |
|---|---|---|---|
| label | the control's visible label. Required. Mark an optional field in these words: Middle name (optional) | ||
| label | hide the label visually but keep it for screen readers, only where the purpose is obvious (a search box beside its button) | false | |
| hint | one line of instructions, shown above the control | ||
| error | an error message, shown below the control. Setting it marks the control invalid | ||
| id | the control's id. Generated if left empty |
Tokens
What a theme can move, where the props above are what an instance can move.
Field has none, and that is a decision rather than an omission. Every value it renders already resolves through a foundation token or a role, so a theme moves it by moving those. A component token earns its place only when a theme needs to change one component without changing the role beneath it.
These are public and overridable — there is no private custom property, because anything on :root is reachable by any stylesheet. What replaces privacy is a stability contract: primitives may move, roles are the guarantee, and these are the per-component escape from both.