Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Form examples · Multi Field

Form with Field Groups for React

A form split into Personal Information and Address groups, with paired fields side by side in each.

Framework
UI library

Long forms overwhelm people when fields blur together. This one groups related fields into two FieldSets with a FieldLegend each: Personal Information for the names and Address for street, city and ZIP. Paired fields share a two-column grid, and each field is a Field with its FieldLabel, Input and FieldError, wired to React Hook Form by a Controller. Use it for checkout, registration or onboarding, where grouping makes a form easier to finish.

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 are the two groups separated?

Each group is a FieldSet with a FieldLegend (Personal Information, Address) and its own FieldGroup. The outer FieldGroup spaces the two sets and the button.

Which fields share a row?

First Name and Last Name, then City and ZIP Code, each pair in a div with grid grid-cols-2 gap-4. Street Address spans the full width.

What message does each field use?

First and last name need 2 characters ("First name must be at least 2 characters.", "Last name must be at least 2 characters."). Street and city are .min(2) with "Street address is required." and "City is required." ZIP shows "Please enter a valid ZIP code."

What ZIP does the regex accept?

zipCode matches ^\d{5}(-\d{4})?$: five digits, optionally a hyphen and four more, such as 10001 or 10001-1234. The pattern is a module-level constant.

What are the initial values?

defaultValues sets all five fields to empty strings. Each label's htmlFor matches its input's id, such as form-with-field-groups-zip-code.

When does Continue validate the groups?

Continue is a type="submit" button. mode is unset, so one schema checks both groups on submit, and onSubmit logs the five values once they all pass.