React Flexible FormDocsExamplesGitHub
DocumentationOverviewGetting StartedTypeScriptAPIuseFormFielduseSubformuseFieldArrayuseConvertutilsExamplesSimple FormChakra UI FormForm with ArraySubformCustom useConvertForm State in ReduxForm with LoaderForm based on Material UIThrottled error validation

Form built using Chakra UI components

Below is the example how to integrate with Chakra UI.


There is a custom <ChakraFormInput /> component which accepts essential form props, onChange, onBlur, error and touched and renders Chakra's input, label and helper text under the input.


Alternative way is to use useConvert hook to adopt form props to component.

"use client";
import { yupResolver } from "react-flexible-form-resolvers";
import { OnSubmit, useForm, Field } from "react-flexible-form";
import { useCallback } from "react";
import * as Yup from "yup";
import ChakraFormInput from "./ChakraFormInput";
import { Button, HStack, VStack } from "@chakra-ui/react";

type Values = {
  country: string;
  state: string;
  city: string;
  zipCode: string;
  street1: string;
  street2?: string | undefined;
};

const resolver = yupResolver(
  Yup.object({
    country: Yup.string().required("Required"),
    state: Yup.string().required("Required"),
    city: Yup.string().required("Required"),
    zipCode: Yup.string().required("Required"),
    street1: Yup.string().required("Required"),
    street2: Yup.string(),
  }),
);

const ChakraAddressForm = () => {
  const onSubmit = useCallback<OnSubmit<Values>>(
    async ({ formControl: { values, setIsSubmitting } }) => {
      await new Promise((resolve) => setTimeout(resolve, 100));
      alert(`Form values: \n ${JSON.stringify(values)}`);
      setIsSubmitting(false);
    },
    [],
  );

  const formControl = useForm({
    initialValues: {
      country: "",
      state: "",
      city: "",
      zipCode: "",
      street1: "",
      street2: undefined,
    },
    onSubmit,
    resolver,
  });

  return (
    <VStack w="full" alignItems="flex-start">
      <HStack w="full">
        <VStack w="full">
          <Field
            rffFormControl={formControl}
            rffName="country"
            rffComponent={ChakraFormInput}
            label="Country"
          />
          <Field
            rffFormControl={formControl}
            rffName="state"
            rffComponent={ChakraFormInput}
            label="State"
          />
          <Field
            rffFormControl={formControl}
            rffName="city"
            rffComponent={ChakraFormInput}
            label="City"
          />
        </VStack>
        <VStack w="full">
          <Field
            rffFormControl={formControl}
            rffName="zipCode"
            rffComponent={ChakraFormInput}
            label="Zip Code"
          />
          <Field
            rffFormControl={formControl}
            rffName="street1"
            rffComponent={ChakraFormInput}
            label="Street Address 1"
          />
          <Field
            rffFormControl={formControl}
            rffName="street2"
            rffComponent={ChakraFormInput}
            label="Street Address 2"
          />
        </VStack>
      </HStack>
      <Button
        onClick={formControl.handleSubmit}
        isLoading={formControl.isSubmitting}
      >
        Submit
      </Button>
    </VStack>
  );
};

export default ChakraAddressForm;
"use client";
import {
  FormControl,
  FormHelperText,
  FormLabel,
  Input,
  InputProps,
} from "@chakra-ui/react";
import { FC } from "react";

type Props = {
  error: string | undefined;
  touched: boolean;
  label: string;
  value: string | number | undefined;
  onChange: (arg: { target: { value: string | number } }) => void;
  onBlur: () => void;
} & Omit<InputProps, "value" | "onChange" | "onBlur">;

const ChakraFormInput: FC<Props> = ({ touched, error, label, ...rest }) => {
  const isInvalid = !!(error && touched);
  return (
    <FormControl isInvalid={isInvalid}>
      <FormLabel>{label}</FormLabel>
      <Input {...rest} />
      {isInvalid ? (
        <FormHelperText color="red">{error}</FormHelperText>
      ) : (
        <FormHelperText whiteSpace="pre"> </FormHelperText>
      )}
    </FormControl>
  );
};

export default ChakraFormInput;