Field Config
Configure presentation and behavior with typed field options.
The schema defines fields and validation. fieldConfig controls labels, placeholders, descriptions, input variants, choices, state, and layout. Match configuration keys to schema property names. Fields still render when no configuration is provided.
Usage
Use your form instance from useForm. See the initial setup.
const schema = z.object({ username: z.string(), email: z.email(), bio: z.string() });
<ErlForm
form={form}
schema={schema}
fieldConfig={{
username: {
label: "Username",
placeholder: "Enter username",
description: "Your public name.",
},
bio: { type: "textarea" },
}}
/>Input options
| Option | Type or behavior |
|---|---|
| label | ReactNode or synchronous scope callback |
| placeholder / description | String or synchronous callback |
| options | Array of string label/value objects or synchronous callback; enables select |
| type | text, password, textarea, number, checkbox, radio, email, url, date, time, datetime-local, file, range, color |
| min / max | Number or string; supported by number and native string controls |
| step | Number or "any" on supported number/string controls |
| accept / multiple | Declared in the type, but not forwarded by the built-in file renderer |
| component | Per-field input component; overrides the registry |
| className | Native control class where supported |
| wrapperClassName | Single-field wrapper class |
| labelClassName / descriptionClassName / errorClassName | Classes for the corresponding elements |
| showIf / clearOnHide | Visibility callback and value reset when hidden |
| disableIf / readOnlyIf / requiredIf | Boolean callbacks controlling input state |
| layout / section | Responsive grid and root grouping |
The type list is the TypeScript option surface, not a guarantee that every schema can become every native input. Schema inference selects the renderer first: number remains a number input, boolean a checkbox, and date/file fields use specialized renderers. Password, textarea, radio, color, and range work on the relevant string path.
Structured fields
Objects configure their children directly and accept an optional component. Arrays support direct object children, explicit item configuration, array controls, and inputType/options for checkbox groups. Tuples use numeric position keys. Containers do not automatically accept single-input options such as label or placeholder.
import type { FieldConfig } from "erlangform";
const config = {
profile: { firstName: { label: "First name" } },
contacts: {
array: { minItems: 1, maxItems: 5, reorderable: true },
item: { phone: { label: "Phone" } },
},
} satisfies FieldConfig<Values>;This configuration requires Values with profile.firstName and contacts as an array of objects containing phone. See Objects and Arrays for schemas and defaults. An explicit item replaces fallback child configuration on the parent. Legacy flat child keys remain a fallback; scoped configuration avoids collisions.
Use z.infer from the schema and satisfies FieldConfig for type checking. Validation rules still belong in the schema and useForm validators. See conditions, layout, sections, and custom components.