Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Form examples · Patterns

Checkout Form for React

A checkout form with a contact email, card details and a billing address with a country select, ending in a Complete Purchase button.

Framework
UI library

A payment page in three sections: Contact, Payment Method and Billing Address, each a FieldSet with its FieldLegend. Expiry and CVV, and city and ZIP code, sit side by side in two-column grids. Every field is a Field with its FieldLabel and FieldError, wired to React Hook Form by a Controller, and the Zod schema checks card number, expiry, CVV and ZIP code with patterns. Use it for checkout and billing forms, and send the card through your payment provider's own fields in production.

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

What card number does the schema accept?

Exactly 16 digits: cardNumber must match /^\d{16}$/, with the message "Card number must be 16 digits". The input also has maxLength={16}, and spaces fail the pattern.

What do expiry and CVV check?

Expiry must look like MM/YY, /^\d{2}\/\d{2}$/ with "Format: MM/YY"; it doesn't check the month or that the date is in the future. CVV must be 3 or 4 digits, with "CVV must be 3 or 4 digits" and maxLength={4}.

What do the address fields check?

Address is .min(5), city .min(2) and ZIP code a 5-digit or ZIP+4 pattern; name on card is .min(2) and email z.email(). These use Zod's default messages.

What happens if country is left on the placeholder?

country starts as "" and must pass .min(1, "Please select a country."), so Complete Purchase shows that message until United States, United Kingdom, Canada or Australia is picked.

How are the sections arranged?

A Payment Details heading, then three FieldSets with a FieldLegend and a FieldGroup each. The email has the FieldDescription "We'll send your receipt here." Expiry and CVV, and city and ZIP code, are in grid grid-cols-2 gap-4 rows.

What does Complete Purchase receive?

Complete Purchase is a full-width type="submit" button. form.handleSubmit(onSubmit) logs all nine values to the console once the schema passes. Never send raw card numbers to your own server; use your payment provider's SDK.