Dots

Card Details

Card number, expiry, security code and cardholder in copyable tiles, with a button that shows the security code.

Card number4242 4242 4242 4242
Expires08/29
CVVHidden
CardholderAlex Morgan
import { CardDetails } from "@/components/ui/card-details"

export function CardDetailsDemo() {

The CardDetails component shows the details people need to pay online: the full number, the expiry date, the security code and the cardholder. Each one is a CopyField tile, and the security code stays hidden until its own button shows it. Show it only after the user has unlocked the details, for example with a passcode or biometrics, usually in a sheet under the card.

Installation

pnpm dlx shadcn@latest add @dots/card-details

Usage

import { CardDetails } from "@/components/ui/card-details"
<CardDetails
  number="4242 4242 4242 4242"
  expiry="08/29"
  cvv="123"
  cardholder="Alex Morgan"
/>

Features

  • Every value copies with one press
  • The number shows in groups of four and copies as digits only
  • The security code is masked until its button shows it; copying always writes the real code
  • Expiry and security code share a row
  • An optional cardholder tile for cards with a printed name
  • A nested surface for use inside a card or sheet
  • Every label can be changed, for example to translate it

Nested

Set surface="nested" when the details sit inside a card or a sheet, so the tiles stand out from that surface instead of the page.

Card ending in 5100
Card number5100 1234 5678 5100
Expires11/28
CVVHidden
import { BankCard } from "@/components/ui/bank-card"
import { Card, CardContent } from "@/components/ui/card"
import { CardDetails } from "@/components/ui/card-details"

Labels

Pass labels to change any field or button label. Labels you leave out keep their defaults.

<CardDetails
  number="4242424242424242"
  expiry="08/29"
  cvv="123"
  labels={{
    expiry: "Valid thru",
    cvv: "CVC",
    showCvv: "Show CVC",
    hideCvv: "Hide CVC",
  }}
/>

Security code

The code is hidden from the start. Set defaultCvvVisible to show it from the start, for example right after the user unlocked the details on purpose to read it.

Accessibility

Each tile is a CopyField, so its copy button is named after its label, such as "Copy card number", and the result is announced through a polite live region.

  • While hidden, the security code is replaced for screen readers by "Hidden", so it is never read aloud.
  • The show and hide button is a React Aria Button named "Show CVV" or "Hide CVV". Change both through labels.
  • The number is read in groups of four, as shown.

API Reference

CardDetails

Accepts all <div> props except children.

PropTypeDefaultDescription
numberstring-Required. Full card number. Shown in groups of four, copied as digits only.
expirystring-Required. Expiry date as printed, e.g. "08/29".
cvvstring-Required. Security code. Hidden until shown with its button.
cardholderstring-Name as printed on the card. Leave it out for cards without one.
defaultCvvVisiblebooleanfalseShow the security code from the start.
surface"default" | "nested""default""nested" inside a card or sheet.
labelsPartial<CardDetailsLabels>-Field and button labels. See below.
classNamestring-Additional classes to apply to the root.

CardDetailsLabels

KeyDefault
number"Card number"
expiry"Expires"
cvv"CVV"
cardholder"Cardholder"
showCvv"Show CVV"
hideCvv"Hide CVV"