Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Form examples · Layouts

Grid Layout (2 Columns) Form for React

A contact details form with six fields in a two-column grid: first and last name, email and phone, city and ZIP code.

Framework
UI library

Related fields belong together: first and last name, email and phone, city and ZIP code. This form puts six Fields in a grid grid-cols-2 gap-4 inside its FieldGroup, so each pair shares a row and the form needs half the height. Each Field has its FieldLabel, Input and FieldError, a Controller wires it into React Hook Form, and one Zod schema validates all six on submit. Use it for registration, contact and address forms.

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 pairs arranged?

One div with grid grid-cols-2 gap-4 holds all six fields in order, so they fill three rows of two. The form is max-w-2xl, and Submit sits under the grid in a horizontal Field.

What does each field check, and where is the message?

firstName, lastName and city are z.string().min(2), email is z.email(), phone is z.string().min(10) and zipCode is z.string().regex(ZIP_CODE_PATTERN). None passes a custom message, so each FieldError shows Zod's default under its input.

Which ZIP values match?

ZIP_CODE_PATTERN is /^\d{5}(-\d{4})?$/: five digits, optionally followed by a hyphen and four more, such as 10001 or 10001-0000. The placeholder is 10001.

Which inputs set a type?

The six fields come from one fields array mapped to a Controller each, with a label, name, placeholder and type. Email is type="email", phone is type="tel" and the rest are text. Each input's id is the slug plus its name, such as form-grid-layout-2-columns-zipCode, and its FieldLabel points at it.

What are the initial values?

defaultValues sets city, email, firstName, lastName, phone and zipCode to empty strings.

When does the grid validate?

useForm doesn't set mode, so form.handleSubmit(onSubmit) checks every field on submit and logs the values once all six pass.