shadcn.io is not affiliated with official shadcn/ui
Billing Address Checkout Block for Svelte
Shipping and billing side by side: a Same as shipping switch mirrors the shipping fields live, switching it off unlocks billing with the values copied in, a Differs badge marks changed fields and the postcode is checked per country.
Installation
Overview
Collect two addresses without asking for one twice, with this billing-address checkout for Svelte with Ark UI. A compact header from Isleworth Studio, an art-supply shop, sits over a hairline frame split into two cells: Shipping and Billing, with Shipping first on a phone. Shipping shows its values read-only until you press Edit shipping. Billing starts on a Switch "Same as shipping": its fields mirror the shipping ones as you type, read-only. Switching it off unlocks every billing field with the shipping values already copied in, so nothing is lost, and a "Differs" Badge marks each field that no longer matches. The country is a Native Select and the postcode is checked against that country's real shape. Save addresses is the only Shine Button: a press names every problem that applies, moves focus to the first and, when clean, waits a moment and says what happened. It's built from Switch, Badge, Field, Input, Native Select, Shine Button and Guides, with a CSS entrance only. For any checkout that takes a delivery address and a billing address.
FAQ
How does the mirror work?
While the switch is on, the billing fields show the shipping values directly instead of keeping their own copy, so a change to shipping (after pressing Edit shipping) appears in billing at once and there is nothing to get out of step. When you switch it off, the shipping values are copied into billing once and from then on billing keeps its own. Switching it back on shows shipping again and the copy you made is not used.
What does the Differs badge mean?
That the billing value, trimmed, no longer equals the shipping value for that field. It is a word, not a colour, and it keeps its space when hidden so the labels never move. The status line also counts the fields that differ ("Billing differs on 2 of 5") so the same information reaches someone who can't see the badges.
How is the postcode checked?
By a pattern for the chosen country: a UK postcode like TN24 8QA, a US ZIP like 97214 or 97214-1234, a German code of five digits. The check is only about shape; it does not know whether the place exists. For real validation use your address-lookup provider and keep this check as the first, instant line of defence. Changing the country re-checks the postcode with the new pattern.
How does autofill behave with two addresses?
The fields use the standard name, address, town and postcode tokens, so a browser may fill the first address it meets. Because both address blocks are on one page, a production form should add the shipping and billing section prefixes to the tokens (for example shipping postal-code) so a browser can fill each block from the right saved address.
What happens if I press Save with something wrong?
The button is never disabled. A press marks every field that applies (billing only when it is unlocked), says "Not saved" in the polite status line and moves focus to the first problem: shipping first, then billing. If the shipping fields are locked when one is wrong, they unlock first so you can fix them. Each field's problem has its own reserved line, so nothing below it moves.
What stays local in the demo, and how do I wire it up?
Everything. Both addresses live in the block's state, nothing is stored, looked up or verified, and Save only waits 600 ms and says so. To connect it, send both addresses to your server on Save (sending a single address and a "same" flag when the switch is on), validate there too, and show the server's message in the field's problem slot or the status line.