Checkout
A four-step checkout with an order summary, address validation, delivery options, card fields, a review step and a confirmation.
A one-page checkout that keeps the order summary in view while people move through shipping address, delivery, payment and review. Fill it in, break it on purpose and press Continue: every step checks its own fields before letting you move on. The card field is a demo; nothing is sent anywhere.
Components
Behavior
- Validation per step. Continue checks only the fields of the current step. The errors appear after the first failed attempt and then update as you type, so fixing a field clears its message without another click.
- Postal code by country. The format hint and the check follow the country you pick:
01310-100for Brazil,94103for the United States,1100-148for Portugal,M5V 2T6for Canada. - Card fields format as you type. The number is grouped in fours and checked with the Luhn checksum, the expiry gets its slash and must not have passed, and the security code takes 3 or 4 digits.
autocompletetokens (cc-number,cc-exp,cc-csc) let browsers and password managers fill them. - Delivery changes the total. The radio cards are a real
RadioGroup: the summary and the Pay button update with the shipping price. - Promo code.
CAMALEO10takes 10% off the items; any other code shows an error under the field. - Review and edit. The review step lists what you entered, with an Edit button that jumps back to that step. Pay shows a loading state, then the confirmation replaces the form.
Accessibility
- After a failed Continue, focus moves to the
ErrorSummaryat the top of the step; each link in it moves focus to its field. - When the step changes, focus moves to the step heading, which reads "Step 2 of 4: Delivery". The
Steppermarks the current step witharia-current="step", and finished steps say "done" to screen readers. - Every field has a visible label, and hints and errors are linked to it, so they are read when the field gets focus.
- The confirmation heading takes focus when it replaces the form, so keyboard and screen reader users don't lose their place.
Use the code
The Code tab shows the whole screen as one file. It needs @camaleo/react and lucide-react, and nothing else: the validation is a plain function you can swap for your schema library. Replace the fixed cart and prices with your data, and send the payment fields to your provider's own components (Stripe Elements, Adyen, Pagar.me) instead of your server: card numbers should never touch it.