shadcn.io is not affiliated with official shadcn/ui
Accordion Steps Checkout Block for Solid
A baking supplies checkout in three sections that open one at a time and fold into what you entered, where any folded value can be edited in place with Enter to keep it and Escape to cancel, each change checked again.
Installation
Overview
Let people fix a value without reopening a whole step, with this accordion checkout for Solid with Ark UI. A header from Nutmeg Row, a baking supplies shop, sits over a hairline frame with a plus mark on each corner. Under the order lines, three sections, Contact, Shipping and Payment, open one at a time; a later section stays locked and says why ("Finish Contact first") until the one before is done. The foot's single Shine Button checks the open section and folds it into a list of what was entered. Each value in a folded section is a button: press it and it becomes an Input in the same place, Enter keeps it after checking it again, Escape or Cancel puts the old value back, and focus returns to the value. Payment is the one section whose summary is never kept: after paying it says only "Visa ending 4242". The foot keeps the total in whole cents. For checkouts with a few short sections and customers who spot a typo late.
FAQ
How does editing a folded value work?
Press the value (its accessible name ends in "change") and an input replaces it in the same row, with Keep and Cancel beside it. Enter keeps the value if it passes the same check the section's field uses; if not, the reason appears under the input and the value stays open for editing. Escape or Cancel restores the old text. The row holds its height, so the section does not jump, and the status line says what was kept or left as it was.
Why are later sections not disabled controls?
A disabled control cannot be focused, so it could not say why it is locked. The header of a locked section is a button marked aria-disabled and described by a sentence that names what to finish first; pressing it does nothing. The open section's header is also aria-disabled and aria-expanded, the pattern for a single-open list that cannot be collapsed. Done sections can be reopened from their header.
What does the button check?
Only the open section. Contact needs a valid email and a phone number of 10 to 16 digits; Shipping needs a name, a street and a five-digit ZIP; Payment needs a card whose number passes the Luhn sum, whose expiry is not before October 2026 and whose CVC has the right length. A press with problems shows each under its field, says so in the status line and moves focus to the first. The button is never disabled.
Can I use this to take real card payments?
No, and the code says so. It checks a card in the tab's memory (brand by the first digits, the Luhn sum, the expiry against a fixed month) so you can see the pattern. A real page never lets card digits reach its own code: it uses the fields your payment provider hosts, an iframe of theirs, with this layout, labels and error wording around them and the real autocomplete tokens (cc-number, cc-exp, cc-csc, cc-name) that those fields set themselves. Autocomplete is off in the demo so a browser never offers a real saved card to it. Test card 4242 4242 4242 4242 passes with any future expiry (checked against October 2026); a number that fails the Luhn sum, a past expiry or a CVC of the wrong length says so under the field.
What stays local, and how do I connect it for real?
Everything: values live in this block's state and Pay waits 700 ms before saying what would happen. To connect it, load saved values into the sections, validate on the server with the same rules, and send the order with your provider's payment token. Keep the card out of the summary rows: show only what your provider returns (brand and last four).