shadcn.io is not affiliated with official shadcn/ui
Centered Store Buttons CTA Block for Svelte
A centered card-in-card CTA for a mobile app with iOS and Android download links, and a text-me-the-app form in a ruled band that has a country-code select and turns into a confirmation.
Installation
Overview
A centered call to action for a mobile app, for Svelte with Ark UI, on a raised panel that follows your theme inside a tinted shell with a + mark on each corner. A headline and a short paragraph for Tally Trails, a made-up hiking app, lead to two download links: "Download for iOS" is a Shine Button and "Download for Android" an outline button. At the panel's foot, in a ruled band, a "text me the app" form has a country-code select, a phone field and a "Text me a link" button. Submitting checks the number, shows the button's spinner, then swaps the form for a confirmation that repeats the number and offers to send to another one. It's built from Guides, Shine Button, Button, Native Select, Field and Input, with Lucide icons and a CSS entrance that stays still under reduced motion. Made for app launch pages and download sections where visitors are on a desktop and need the link on their phone.
FAQ
How do I point the download links at the stores?
Each link is an ordinary anchor inside a button, href="#" for now: replace it with your App Store and Google Play URLs, or with one smart link that picks the store from the visitor's device. The labels say where each goes without carrying a store's logo. If you have permission to use the official badges, put them in place of the two buttons and keep the labels as the links' accessible names.
Each button's asChild receives its props: spread them onto your router's link.
Does the form really text a link?
No: the send is simulated in send. After the number passes the check, the button shows its spinner for LATENCY (0.8 seconds) and then the confirmation replaces the form. Replace the timer with a request to your SMS provider through your own server, sending dial and phone together, and set the state to "done" on success. If it fails, set it back to "idle" and put the message in error.
How is the phone number checked?
The form has noValidate, and send counts the digits in the field: between 7 and 12 are accepted, whatever spaces, dashes or brackets are around them. A wrong number shows its message under the field, marks the field invalid and sends focus back to it; typing clears the message. This is a length check, not a carrier check, so validate the number again on your server.
What do keyboard and screen reader users get?
The select is named "Country code" and the field "Phone number", the latter with a visually hidden label. The select is the browser's own, so it works with the keyboard and on phones with their native picker. After a successful send, the form is hidden and inert and focus moves to the "Link sent" heading, so the confirmation is read aloud. The number is kept left to right, so it reads in order in right-to-left pages.
Does the panel follow my theme?
Yes. The card is bg-card with a soft shadow and a ring, inside a tinted bg-muted/50 shell, so it is light on a light page and dark on a dark one, in any preset. The Shine Button is the only primary control; the Android link is the outline variant and the text button is the secondary variant.
How does it fit on a phone?
The two download links wrap onto two lines when they don't fit side by side. In the form the country select and the phone field stay on one row and the button goes full width below them; from the sm breakpoint all three share one row. On a phone the shell sits a little inside the page rails.