INTEGRATIONS / REACT HOOK FORM
Use the form state you know.
BLD8 fields work with registration and Controller. The optional adapter adds labels, focus, touched state and service-error bindings.
REACT HOOK FORM / HTTP
A form that fits your setup.
Native and controlled fields, one form state.
Optional, and typed.
npm install react-hook-form
npx shadcn@latest add https://ui.bld8.dev/r/react-hook-form.jsonThe package adapter lives at @bld8/ui/react-hook-form. A registry install uses your local bld8/react-hook-form path. Core components stay independent of React Hook Form.
import { useForm } from "react-hook-form";
import { RHFField, RHFControl } from "@bld8/ui/react-hook-form";
const form = useForm({
defaultValues: {name: "", tags: [] as string[]}
});
<RHFField control={form.control} name="name" label="Name"
rules={{required: "Enter a name."}}>
{field => <Input {...field} />}
</RHFField>
<RHFControl control={form.control} name="tags">
{binding => <MultiSelect {...binding} label="Tags" options={options} />}
</RHFControl>RHFField wraps native controls in Field. RHFControl maps value/onValueChange, onBlur, inputRef and error to Select, MultiSelect and date fields. Use explicit empty defaults such as null, [] and "".
Native registration works too.
<Field label="Name" error={form.formState.errors.name?.message}>
<Input {...form.register("name", {required: "Enter a name."})} />
</Field>The working example sends a real request to the sample Outline API. Duplicate names become field errors; service failures keep the entered values for retry. Try Tab, blur validation and the failed-save action.
Download the integration starterAdapter props
RHFField
| Prop | Type | Default |
|---|---|---|
childrenRequired | (field: ControllerRenderProps<T, N>) => ReactNode | — |
labelRequired | string | — |
nameRequired | N | — |
control | Control<T, any, T> | undefined | — |
defaultValue | PathValueImpl<T, N> | undefined | — |
disabled | boolean | undefined | — |
exact | boolean | undefined | — |
hint | string | undefined | — |
required | boolean | undefined | — |
rules | Omit<RegisterOptions<T, N>, "disabled" | "valueAsNumber" | "valueAsDate" | "setValueAs"> | undefined | — |
shouldUnregister | boolean | undefined | — |
RHFControl
| Prop | Type | Default |
|---|---|---|
childrenRequired | (binding: RHFControlBinding<T, N>) => ReactNode | — |
nameRequired | N | — |
control | Control<T, any, T> | undefined | — |
defaultValue | PathValueImpl<T, N> | undefined | — |
disabled | boolean | undefined | — |
exact | boolean | undefined | — |
rules | Omit<RegisterOptions<T, N>, "disabled" | "valueAsNumber" | "valueAsDate" | "setValueAs"> | undefined | — |
shouldUnregister | boolean | undefined | — |
Tables come from the public TypeScript declarations. Related types are shown alongside their component. A dash means no default is declared at the public function boundary.