Skip to content

RHFField

React Hook Form adapter that wires useController through Cynosure's FormField scaffolding — label, error, aria-invalid, and message in one component.

  • stable
  • since v0.1.0
  • 1.28 kB
  • forms

Inherits the underlying control's a11y; surfaces validation errors via aria-describedby and aria-invalid.

Preview
Open
tsx

RHFField accepts the control from useForm() plus a name and label, and clones its single child to inject value, onChange, onBlur, and ref from useController.

import { useForm } from "react-hook-form";
import { RHFField, Input } from "@arshad-shah/cynosure-react/rhf";
function MyForm() {
const { control, handleSubmit } = useForm({ defaultValues: { email: "" } });
return (
<form onSubmit={handleSubmit(console.log)}>
<RHFField control={control} name="email" label="Email">
<Input type="email" />
</RHFField>
</form>
);
}

react-hook-form is declared as an optional peer dependency — consumers that never import RHFField don’t need it installed.

Pass rules (RHF’s RegisterOptions) to validate the field; the error message is announced via FormMessage.

Preview
Open
tsx

Supply description to render helper copy below the control.

Preview
Open
tsx

The required prop marks the Label and propagates to the inner control; disabled is forwarded as well.

Preview
Open
tsx
PropTypeDefaultDescription
control*
Control<TValues>
RHF control from `useForm()`.
name*
string
Field path in the RHF schema.
label*
ReactNode
Label content.
description
ReactNode
Optional helper copy.
children*
ReactElement<unknown, string | JSXElementConstructor<any>>
The input-like element that renders this field's control.
rules
RegisterOptions<TValues, TName>
RHF validation rules.
required
boolean
Mark the field as required on the Label + `aria-required`.
disabled
boolean
Mark the field as disabled.
  • The label prop renders inside FormLabel, wired by htmlFor to the cloned input child.
  • Validation errors are announced via FormMessage and linked through aria-describedby and aria-invalid on the input.
  • The single child must forward ref, value, and onChange — all native and Cynosure inputs do.
  • For non-input controls (Slider, RadioGroup, Select), wrap with the same pattern — RHFField injects value/onChange/onBlur/ref, which they all consume.
  • Group multiple RHFFields under a single useForm and submit via handleSubmit.
  • Pass rules={{ required: "…" }} to drive both required marking and inline messaging in one place.