Billing Card Brand Selection
A card brand selection grid for payment setup and checkout flows. Renders each supported network (Visa, Mastercard, Amex, Discover, Apple Pay, Google Pay) as a selectable card with an icon and label, built as real buttons in an accessible radio group so selection works with keyboard and screen readers. Individual options can be disabled, for example a network you don't support yet.
Docs
Installation
A real shadcn registry command, not a copy-paste stand-in: it fetches this block plus its dependencies and any missing npm packages, and installs them straight into your project.
npx shadcn add https://staaarter.com/r/billing-card-brand-selection.jsonPrefer not to use the CLI? Copy the source from the Code toggle above into src/components/blocks/billing/billing30.tsx instead.
Usage
The file also exports billing30Demo, the exact props behind the preview above. Spread it to get a working section in one line, then replace it with your own data.
import { Billing30, billing30Demo } from "@/components/blocks/billing/billing30"; export default function Page() { return <Billing30 {...billing30Demo} />; }
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| heading | string | none | Optional heading above the grid. |
| description | string | none | Optional supporting line under the heading. |
| brands | CardBrandItem[] | none | Payment options rendered as selectable cards. |
| defaultBrandId | string | brands[0].id | Which option is selected on first render. |
| className | string | none | Extra classes for the outer wrapper. |
Types
type CardBrandOption = | "visa" | "mastercard" | "amex" | "discover" | "apple-pay" | "google-pay" | "other"; interface CardBrandItem { id: string; brand: CardBrandOption; label: string; helperText?: string; disabled?: boolean; }
Behavior notes
- Selection is local state seeded from defaultBrandId (falling back to the first item), clicking any enabled card updates it and moves the selected ring and icon color to that card.
- Icons are looked up internally from a Record<CardBrandOption, LucideIcon>, never accepted as a prop, since passing a component reference from a server-rendered page into this client component would break at runtime.
- The icons are generic Lucide glyphs (a card icon for the four card networks, a phone icon for Apple Pay, a wallet icon for Google Pay), not official brand marks. Swap BRAND_ICONS for real brand SVGs before shipping to production if you need pixel-accurate logos.
- Cards with disabled: true render at reduced opacity, ignore clicks, and can't become the selected option even if they're listed as defaultBrandId.
- The grid is role=radiogroup with each card as role=radio and aria-checked, so arrow-key and screen reader behavior matches a native radio group despite being built from plain buttons.
Frequently asked questions
More Billing Blocks
View all →Billing Invoice List
Invoice history table with status badges, formatted amounts, and a per-row download link, built with shadcn/ui and Tailwind CSS.
Billing Failed Payment Alert
High-contrast failed-payment alert with a message, a retry button, and an optional update-payment-method button, built with shadcn/ui and Tailwind CSS.
Billing Credit Balance
Compact credit balance card with a large total, an optional purchased-versus-promotional breakdown, a low-balance notice, and a top-up button.
Billing Payment Methods
A saved payment method list for React and Next.js with brand icons, a default badge, near-expiry warnings, and remove/set-default actions per row.
Billing Add Card
A card entry form for React and Next.js with auto-formatted fields, internal brand detection, and per-field validation feedback built with shadcn/ui and Tailwind CSS.
Billing Coupon Code
An inline promo code input for React and Next.js with a simulated loading state, an applied summary showing the discount amount, and an invalid-code message.