Behive Tech Registry

Form Field Managed

v0.1.2

`FormField` with its react-hook-form wiring already done — the control's value/onChange/onBlur/ref, the label association, and the error message.

pnpm add @behivetech/forms.form-field-managed

FormField with its react-hook-form wiring already done — the control's value/onChange/onBlur/ref, the label association, and the error message.

Use plain FormField when you are managing state yourself; use this when the field belongs to a react-hook-form form.

Usage

The error message comes from the field's own validation state — there is no error prop to pass, and no need to read formState.errors. label, hint, required and className pass through to FormField.

control is optional; the field resolves it from the surrounding Form / FormProvider context.

Typing in TypeScript

field.value is typed as the field name points at, so it spreads onto a control without a cast. Getting that narrowing depends on how the generics are supplied.

Passing control infers both type parameters and needs no annotation:

Taking control from context instead means naming the field type too:

Supplying only the first type argument — <FormFieldManaged<Values> name="email"> — does not narrow. TypeScript stops inferring the remaining parameters once any is given explicitly, so TName falls back to its default and field.value widens to a union of every field in the form. Prefer one of the two forms above.

Why a render prop

The one thing that genuinely differs between controls is the prop they report changes on. Native inputs take the field as-is:

Radix-backed controls (Select, Checkbox, Toggle) report through onValueChange / onCheckedChange, so the caller maps that one prop:

Making that visible is deliberate — it is the difference that matters, and it cannot be typed if hidden behind a clone.

Why not register

register() returns an uncontrolled native input contract ({name, onChange, onBlur, ref}). It works on TextField and Textarea, which render real <input> / <textarea> elements.

It does not work on Checkbox, Toggle or Select. Those are Radix-backed: the ref would land on the trigger <button>, whose value is always "", and Radix reports changes through onCheckedChange / onValueChange, never onChange. The field would silently submit its default value with no type or runtime error. FormFieldManaged uses useController, which works for all of them.

The render prop also receives the field's state as a second argument ((field, fieldState) => …) if you need invalid, isDirty or isTouched.

Compositions

Open all 1 →

Properties

FormFieldManaged props

PropTypeDefaultDescription
children*(field: ManagedField<TFieldValues, TName>, fieldState: ControllerFieldState) => ReactNode—Renders the control from the wired field
name*string—Field path in the form values; infers the field's value type
classNamestring—Additional class names to merge with the component root element
controlControl<TFieldValues>—Form control; falls back to the surrounding `useFormContext()` when omitted
hintReactNode—Supporting hint text; hidden while `error` is present
labelReactNode—Field label
requiredboolean—Shows a required marker next to the label
rulesRegisterOptions<TFieldValues, TName>—Validation rules passed through to react-hook-form

Also accepts the native attributes of its root element (className, aria-*, event handlers, …).

PartialArgsStillWiden props

No props of its own.