Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Form examples · Advanced

Form with Mixed Controls for React

A support request form that mixes a text input, radio buttons, a select, a textarea and a checkbox under one schema.

Framework
UI library

Real forms mix control types: a support request needs a title, a type, a priority, a description and an opt-in. This form puts an Input, a RadioGroup, a Select, a Textarea and a Checkbox under one Zod schema. A Controller wires each control into React Hook Form, and each sits in a Field with its FieldLabel and FieldError, so every type validates and reports errors the same way. Use it for support tickets, feedback forms and issue trackers.

Preview

Preview width

Installation

Sign in to get your install command
Free with an account. It carries your token, so the CLI installs everything in one go.

FAQ

How does React Hook Form connect these controls?

useForm takes zodResolver(formSchema) and defaultValues for name, priority, description and subscribe. Each control is rendered by a Controller with control and name, which hands it field (value and change handler) and fieldState (the error).

How does a field show its error?

The Field gets invalid={fieldState.invalid}, and FieldError gets fieldState.error?.message, which is empty while the field is valid. Title and Description use Zod's default messages for .min(2) and .min(10).

How is the type radio group wired?

type is z.enum(["bug", "feature", "question"]) with the error "Please select a type.", and it starts unset, so no option is selected. The group sits in a FieldSet with the FieldLegend Type. RadioGroup takes value={field.value ?? null} and passes the next value to field.onChange. Each RadioGroupItem has an id that its FieldLabel targets with htmlFor.

How does the priority select work?

priority starts as "" and must pass .min(1, "Please select a priority."), so the trigger shows "Select priority" until one of Low, Medium, High or Urgent is picked. Select takes items, value={field.value || null}, and onValueChange stores the next value or "".

How is the subscribe checkbox set up?

A horizontal Field with the Checkbox, then FieldContent with the label Subscribe to updates and its description. subscribe is z.boolean() starting at false, so either value submits. It's controlled with checked and onCheckedChange.

What does Submit send?

Submit is a type="submit" button in a horizontal Field at the end of the FieldGroup. form.handleSubmit(onSubmit) runs the schema and, once title, type, priority and description pass, logs the five values to the console.