Field
Label, help text, the right control for the field's type, and the inline error, from one `name`.
Field renders one schema field completely: Label, Help, the control chosen by field.type, and FieldError. It is what Form uses for every field when you give it no children.
Preview
Usage
import { Form, Field, FieldControl, Submit } from 'kibbleforms';
<Form schema={schema} client={kibble}>
<Field name="name" /> {/* label + help + control + error */}
<Field name="seats" className="gap-1"> {/* children replace the control only */}
<FieldControl name="seats" />
</Field>
<Submit />
</Form>
Props
| Prop | Type | Default | Description |
|---|---|---|---|
name |
string |
required | The field key. Throws if the key is not in the form's schema. |
children |
ReactNode |
the control for field.type |
Replaces the control slot only; label, help and error still render. Put your own input here using useField(name).inputProps. |
className |
string |
flex flex-col gap-1.5 |
Merged onto the wrapper. |
…<div> attributes |
Spread on the wrapper. |
Rendered: <div data-kb="field" data-type="<field.type>"> containing [data-kb="label"], [data-kb="help"] (when the schema has help), the control, and [data-kb="error"] (when invalid).
FieldControl (name only) renders just the control. Which control a type gets:
| Field type | Control | data-kb |
|---|---|---|
short_text, email, phone, url, number |
Input | input |
long_text |
Textarea | textarea |
dropdown |
Select | select |
single_choice, multiple_choice |
Choice | choice |
yes_no |
YesNo | yesno |
rating |
Rating | rating |
date |
DatePicker | date |
consent |
Consent (the row is its own label, so no Label; Field adds Help and FieldError under it) |
consent |
hidden |
<input type="hidden" data-type="hidden"> with no wrapper, label or error (className does not apply) |
hidden |
Fields hidden by a showWhen condition render nothing at all (see Conditional logic).
Variants and states
The preview above has a required field and a number field: submit empty to see the error state, which sets aria-invalid on the control and renders FieldError below it. Typing clears the error for that field.
Customization
- Spacing between label, control and error is the wrapper's
gap-1.5; override withclassName="gap-1"(tailwind-merge drops the default). - Target a type with CSS:
[data-kb="field"][data-type="long_text"] { … }. - To change the structure (help below the control, label inside the control…), compose
Label,Help,FieldControlandFieldErroryourself, or build onuseFieldfromkibbleforms/headless.
Accessibility
Field wires the pieces: the label's htmlFor targets the control (aria-labelledby for radio groups), help and error ids go into the control's aria-describedby, required fields get aria-required="true" (not the native required, so Kibble's messages show instead of the browser's), and invalid fields get aria-invalid="true".
Related
Form, Label, Help, FieldError, Headless: useField, Schema: field types