Field
Field wrapper that combines label, input, and feedback messages
into one cohesive unit. It receives a component (Input, Checkbox,
InputSelect, etc.) and injects value, onChange, variant, and reset
into it — it is the piece that marries an input to the Form (RHF + Zod)
and to the validation UI.
When to use
| ✅ Use when… | 🚫 Avoid when… |
|---|---|
|
|
Visual states
Common combinations of label + hint + state:
Label, optionalText and hints
loading
Stable hint slot
The hint line always reserves one line of micro text — empty, hidden or
filled. A Field that goes from idle to error on submit keeps the same
height, so the next input or the submit button does not jump. Do not pad
hintText with a blank space, and do not bump the parent Form gap to
compensate.
Hint with inline action
hintText accepts a ReactNode, not just a string. Use this for affixes
that previously had to be rendered outside the Field — an action ("use all"),
a limit Text, a help link:
<Field
component={Input}
label="Amount"
hintText={
<Flex flexDirection="row" wrap="wrap" justifyContent="between" width="100%">
<Text text="Daily limit: R$ 5.000" />
<Button variant="linked" size="extraSmall" text="use all" onClick={fillMax} />
</Flex>
}
/>hintSuccessText and hintErrorText also accept a ReactNode.
Field inside Form
Inside a Form, the Field must be declared as an object in fields:
<Form
handleSubmit={console.log}
fields={{
email: {
label: 'Email',
component: Input,
validation: z.email('Required'),
inputProps: { type: 'email', placeholder: 'you@company.com' },
},
}}
/>Messages returned by the field's validation are automatically turned into
hintErrorText.
Do not pass value/onChange directly to a Field inside a Form — the
Form (via React Hook Form) injects them automatically through inputProps.
Gotchas
- Do not set
errorandsuccessat the same time — usevariantinstead, which expresses the combined state. - Avoid duplicating the
labelasplaceholderwhen both are present —placeholdershould show an example value, not repeat the label.
Properties
Prop | Type | Default | Description |
|---|---|---|---|
component * | any | — | — |
error | boolean | — | — |
errors | any | — | — |
fieldProps | DefaultFlexInterface | — | — |
hideLabel | boolean | — | — |
hintErrorText | ReactNode | Something went wrong | Message displayed when `error`. Accepts `ReactNode` (a string when it comes from `Form` validation). |
hintSuccessText | ReactNode | Everything is alright | Message displayed when `success`. Accepts `ReactNode`. |
hintText | ReactNode | — | Neutral message below the input. Accepts `ReactNode` (not just `string`):
besides text, it can carry inline actions (e.g. a "use all" button) or a
supporting `Text` (e.g. a daily limit) — previously these affixes had to
be rendered as siblings outside the `Field`. Backward-compatible widening
(`string ⊂ ReactNode`). |
inputProps | any | — | — |
label | string | — | — |
name | string | — | — |
optionalText | string | — | — |
readOnly | boolean | — | — |
readOnlyText | string | apenas leitura | — |
setFieldValue | UseFormSetValue<any> | — | — |
success | boolean | — | — |
value | any | — | — |
variant | "default" | "success" | "error" | — | — |
In addition to the props above, every component accepts the layout props (spacing, color, flex/grid, sizing, border) — not repeated here.
See also
- Storybook story: Components / Field
- Full form:
Form