React Hook Form
A React Hook Form integration with RizzUI Form components and zod validations.
import React from "react";
import { z } from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { Controller, useForm } from "react-hook-form";
import {
  Text,
  Input,
  Title,
  Select,
  Button,
  NumberInput,
  AdvancedRadio,
  type SelectOption,
} from "rizzui";
import { BoltIcon, CubeIcon } from "@heroicons/react/20/solid";
const companyOptions = [
  {
    label: "Google Inc",
    value: "google",
  },
  {
    label: "RizzUI Inc",
    value: "rizzui",
  },
 ...
];
const schema = z.object({
  email: z.string().email({ message: "Invalid email address" }),
  name: z.string().min(1, { message: "Name is required" }),
  plan: z.string().min(1, { message: "Plan is required" }),
  amount: z.number().min(1, { message: "Amount is required" }),
  beneficiary: z.string().optional(),
  company: z.string().min(1, { message: "Company is required" }),
});
type SchemaType = z.infer<typeof schema>;
export default function RizzUIForm() {
  const {
    control,
    register,
    handleSubmit,
    formState: { errors },
  } = useForm<SchemaType>({
    defaultValues: {
      company: "",
    },
    resolver: zodResolver(schema),
  });
  const onSubmit = (data: SchemaType) => {
    console.log("Submitted data", data);
  };
  return (
    <div className="w-full max-w-2xl mb-10">
      <form
        noValidate
        onSubmit={handleSubmit(onSubmit)}
        className="grid grid-cols-1 gap-y-6 items-end"
      >
        <div>
          <Text className="font-semibold mb-4">Contact Information</Text>
          <div className="grid grid-cols-2 gap-x-6 items-end">
            <Input
              type="email"
              label="Email"
              placeholder="person@mail.com"
              {...register("email")}
              error={errors.email?.message}
            />
            <Input
              label="Name"
              placeholder="John Doe"
              {...register("name")}
              error={errors.name?.message}
            />
          </div>
        </div>
        <div>
          <Text className="font-semibold mb-2">Select Plan</Text>
          <div className="grid grid-cols-2 gap-6">
            <AdvancedRadio
              value="onetime"
              contentClassName="p-4"
              {...register("plan")}
            >
              <span className="bg-gray-100 p-3 rounded inline-block mb-3">
                <CubeIcon className="size-6 text-blue" />
              </span>
              <Title
                as="h4"
                className="text-base"
              >
                One-Time Payment
              </Title>
              <Text>Change users a one-time payment fee to access the content</Text>
            </AdvancedRadio>
            <AdvancedRadio
              defaultChecked
              value="membership"
              contentClassName="p-4"
              {...register("plan")}
            >
              <span className="bg-gray-100 p-3 rounded inline-block mb-3">
                <BoltIcon className="size-6 text-blue" />
              </span>
              <Title
                as="h4"
                className="text-base"
              >
                Membership
              </Title>
              <Text>Split the full bundle price over several monthly payments</Text>
            </AdvancedRadio>
          </div>
        </div>
        <div>
          <Text className="font-semibold mb-4">Amount Submission</Text>
          <div className="grid grid-cols-2 gap-6">
            <Controller
              control={control}
              name="amount"
              render={({ field: { value, onChange }, fieldState: { error } }) => (
                <NumberInput
                  formatType="numeric"
                  thousandSeparator=","
                  placeholder="$123456"
                  value={value}
                  onValueChange={(v) => onChange(v.floatValue ?? 0)}
                  customInput={Input as React.ComponentType<unknown>}
                  {...{
                    label: "Amount",
                    error: error?.message,
                  }}
                />
              )}
            />
            <Input
              label="Beneficiary"
              placeholder="John Doe"
              {...register("beneficiary")}
              error={errors.beneficiary?.message}
            />
          </div>
        </div>
        <Controller
          control={control}
          name="company"
          render={({ field: { value, onChange }, fieldState: { error } }) => (
            <Select
              value={value}
              label="Company Name"
              options={companyOptions}
              onChange={(v: SelectOption) => onChange(v.value)}
              error={error?.message}
              displayValue={(selected: string) =>
                companyOptions?.find((r) => r.value === selected)?.label ?? ""
              }
            />
          )}
        />
        <Button
          type="submit"
          className="w-full mt-2"
        >
          Submit
        </Button>
      </form>
    </div>
  );
}