The single place `react-hook-form` is imported directly in this repo. Everything else should import form state/control from here instead of `react-hook-form` — that keeps the underlying library swappable from one spot later.
The single place react-hook-form is imported directly in this repo. Everything else should import form state/control from here instead of react-hook-form — that keeps the underlying library swappable from one spot later.
Re-exports: FormProvider (thin wrapper around RHF's own FormProvider), Form (convenience <form> wired to handleSubmit, with FormProvider already applied), useForm, useFormContext, useController, useFormState, useWatch, Controller, plus the common RHF types (UseFormReturn, FieldValues, SubmitHandler, Control, FieldErrors, ...).
Usage
The common case — a form with a real submit action — use Form:
1import { Form, useForm } from "@behivetech/forms.form-provider";2import { FormField } from "@behivetech/forms.form-field";3import { TextField } from "@behivetech/atoms.text-field";4import { Button } from "@behivetech/atoms.button";56function MyForm() {7 const methods = useForm({ defaultValues: { email: "" } });8 const { register } = methods;910 return (11 <Form methods={methods} onSubmit={(values) => console.log(values)}>12 <FormField label="Email" htmlFor="email">13 <TextField id="email" {...register("email")} />14 </FormField>15 <Button type="submit">Save</Button>16 </Form>17 );18}
If you need the raw <form> element for something Form doesn't cover, use FormProvider + handleSubmit directly:
1import { FormProvider, useForm } from "@behivetech/forms.form-provider";2import { TextField } from "@behivetech/atoms.text-field";3import { Button } from "@behivetech/atoms.button";45function Example() {6 const methods = useForm({ defaultValues: { name: "" } });7 const onSubmit = (values) => alert(JSON.stringify(values));8 return (9 <FormProvider methods={methods}>10 <form onSubmit={methods.handleSubmit(onSubmit)}>11 <TextField {...methods.register("name")} placeholder="Name" />12 <Button type="submit">Save</Button>13 </form>14 </FormProvider>15 );16}
Not every input needs this. TextField, Checkbox, etc. all work standalone with plain useState for simple one-off cases, and UI with no real submit moment — live/instant field-by-field editing, for example — should just use the bare atoms + FormField for layout, not Form/useForm. Reach for this package when you actually need multi-field form state, validation, or a real submit action.
Examples
Open all 2 →1interface DemoValues {2 email: string;3}45const BasicFormProvider = () => {6 const methods = useForm<DemoValues>({ defaultValues: { email: "" } });7 const { register, handleSubmit } = methods;89 return (10 <FormProvider methods={methods}>11 <form onSubmit={handleSubmit((values) => console.log(values))}>12 <FormField label="Email" htmlFor="email">13 <TextField id="email" {...register("email")} />14 </FormField>15 </form>16 </FormProvider>17 );18};1920render(<BasicFormProvider />);
1interface DemoValues {2 email: string;3}45const BasicForm = () => {6 const methods = useForm<DemoValues>({ defaultValues: { email: "" } });7 const { register } = methods;89 return (10 <Form methods={methods} onSubmit={(values) => console.log(values)}>11 <FormField label="Email" htmlFor="email-form">12 <TextField id="email-form" {...register("email")} />13 </FormField>14 <Button type="submit" variant="primary" size="sm">15 Save16 </Button>17 </Form>18 );19};2021render(<BasicForm />);
Properties
Form props
| Prop | Type | Default | Description |
|---|---|---|---|
children* | ReactNode | — | Form content, typically FormField-wrapped controls |
methods* | UseFormReturn<TFieldValues> | — | The return value of `useForm()` |
onSubmit* | SubmitHandler<TFieldValues> | — | Called with the validated values when the form is submitted |
Also accepts the native attributes of its root element (className, aria-*, event handlers, …).
FormProvider props
| Prop | Type | Default | Description |
|---|---|---|---|
children* | ReactNode | — | Descendants that will consume the form context via `useFormContext()` |
methods* | UseFormReturn<TFieldValues> | — | The return value of `useForm()` (re-exported from this package) |