Build · New
Card Details
Card number, expiry and security code as one group, formatted as you type and filled by browsers and wallets.
Preview
Mirrored is the same English content laid out right to left: it separates a mirroring bug from a translation one.
Installation
SoonInstalling from the registry opens at launch. Until then the command below is what it will be.
npx shadcn@latest add @ritla/card-detailsDependencies it brings: @base-ui/react
Usage
import { CardDetails } from "@/components/ui/card-details";<CardDetails label="Card details" onValueChange={(card, { brand, complete }) => setCard(card)} />Examples
Errors and disabled
errorPart marks the part in error (number, expiry or cvc), with the message under the group.
API reference
CardDetails
| Prop | Type | Default | Description |
|---|---|---|---|
label | ReactNode | Figma's Label. | |
value / defaultValue | { number, expiry, cvc } | The values (number without spaces, expiry MM/YY). | |
onValueChange | (card, { brand, complete }) => void | On every change: the network (visa, mastercard…) and whether all three are complete, Luhn-checked. | |
error / errorPart | ReactNode / "number" | "expiry" | "cvc" | Figma's State = Error and Field. Without errorPart all three are marked. | |
partLabels | { number?, expiry?, cvc? } | Screen reader names of the parts. Default: in the page language. | |
names | { number?, expiry?, cvc? } | cc-number, cc-exp, cc-csc | Form field names. |
required / helperText / disabled | … | As on Input Field. |
cardBrand / isValidCardNumber
| Prop | Type | Default | Description |
|---|---|---|---|
cardBrand(number) | CardBrand | The network from the first digits. mada cards are co-branded Visa or Mastercard and read as those. | |
isValidCardNumber(number) | boolean | Luhn check and length. |
Accessibility
Keyboard
Keys are written for left-to-right. In right-to-left the arrow keys swap: the one pointing toward the reading direction moves forward.
| Key | Action |
|---|---|
| Tab | Number, then expiry, then security code. |
ARIA
- The group is
role="group"named by the label; each part has its own name (“Card number”, “Expiry date (MM/YY)”, “Security code (CVC)”) in the page language. autocompletecc-number, cc-exp and cc-csc for browser and wallet fill, andinputmode="numeric".- The part in error has
aria-invalid; the message is linked to every part.
Arabic and RTL notes
Mirrors
- The label and helper text sit at the inline start (the right).
Does not mirror
- The group is left to right, as the card is printed: number on top, expiry left and security code right, in Arabic too.
- Numerals
- Typed Arabic-Indic and Persian digits are stored as 0-9 and show in Western digits, as on the card.
- Arabic typography
label-16, like every field.