Import
import { useForm } from 'react-hook-form';import {Form,FormControl,Radio,Checkbox,Select,Textarea,TextInput,} from '@contentful/f36-forms';
Examples
Example of integration with register()
function RegisterIntegrationExample() { const { register, handleSubmit, formState: { errors }, } = useForm(); // Create your submit function that will be passed to react-hook-form’s handleSubmit const onSubmit = (data) => { console.log(data); }; /* Pass react-hook-form’s handleSubmit to the onSubmit prop of the Form component */ return ( <Form onSubmit={handleSubmit(onSubmit)}> {/* To set the FormControl invalid state, check if there is an error related to this input */} <FormControl isInvalid={Boolean(errors.name)}> <FormControl.Label isRequired>Name</FormControl.Label> {/* Use the register function from react-hook-form on TextInput */} <TextInput {...register('name', { required: true })} /> {/* Show a ValidationMessage if the input has any errors */} {errors.name && ( <FormControl.ValidationMessage> This field is required </FormControl.ValidationMessage> )} </FormControl> <FormControl isInvalid={Boolean(errors.description)}> <FormControl.Label>Description</FormControl.Label> {/* Registering a Textarea is similar to TextInput */} <Textarea {...register('description', { maxLength: 20 })} /> {errors.description && ( <FormControl.ValidationMessage> Your description must have a maximum of 20 characters </FormControl.ValidationMessage> )} </FormControl> <FormControl> <FormControl.Label>City</FormControl.Label> {/* When using a Select, it’s only necessary to register the Select component */} <Select defaultValue="Mumbai" {...register('city')}> <Select.Option value="Cape Town">Cape Town</Select.Option> <Select.Option value="Mumbai">Mumbai</Select.Option> <Select.Option value="Rio de Janeiro">Rio de Janeiro</Select.Option> </Select> </FormControl> <FormControl as="fieldset"> <FormControl.Label as="legend">Martial status</FormControl.Label> {/* When using Radio.Group, it’s necessary to register each Radio with the same "name". This is necessary because of how react-hook-form works. */} <Radio.Group defaultValue="single"> <Radio value="married" {...register('martial-status')}> Married </Radio> <Radio value="single" {...register('martial-status')}> Single </Radio> </Radio.Group> </FormControl> <FormControl isInvalid={Boolean(errors.checkbox)}> <Checkbox {...register('checkbox', { required: true })}> I confirm everything that said above is true </Checkbox> {errors.checkbox && ( <FormControl.ValidationMessage> You must confirm that everything is true </FormControl.ValidationMessage> )} </FormControl> <Button variant="primary" type="submit"> Submit </Button> </Form> ); }
Example of integration with useController
First, it's necessary to create a controlled component which will use the useController hook and pass its props to the Forma 36 component. Then you use this controlled component in your form:
function UseControllerIntegrationExample() { const ControlledTextInput = (props) => { const { field: { ref, ...inputProps }, } = useController(props); return <TextInput {...inputProps} ref={ref} />; }; const { // instead of register, this time we use the control object returned by useForm() control, handleSubmit, formState: { errors }, } = useForm(); const onSubmit = (data) => { console.log(data); }; return ( <Form onSubmit={handleSubmit(onSubmit)}> <FormControl isInvalid={Boolean(errors.textInput)}> <FormControl.Label isRequired>Name</FormControl.Label> {/* Then we pass control to the controlled component as a prop */} <ControlledTextInput control={control} name="textInput" rules={{ required: true }} /** * We need to pass an empty string as default value * otherwise react will trigger the uncontrolled inputs warning * * more information in https://react-hook-form.com/api/usecontroller */ defaultValue="" /> {errors.textInput && ( <FormControl.ValidationMessage> This field is required </FormControl.ValidationMessage> )} </FormControl> <Button variant="primary" type="submit"> Submit </Button> </Form> ); }