Docs

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 with className="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, FieldControl and FieldError yourself, or build on useField from kibbleforms/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".

Form, Label, Help, FieldError, Headless: useField, Schema: field types