Card Fields

Card Fields are the masked inputs a payment form needs: a grouped card number that checks its own checksum, an expiry that pads an unambiguous month, and a security code.

Installation

Nothing to add. This component ships as source in your download, so it is already in your project.

Filesrc/vui/card-fields.tsx
Import from@viliha/vui-react/card-fields

The exported names are at the top of that file. The import path is an alias the download's tsconfig.json points at src/vui/, so you can move that folder and change one line rather than every file that imports from it.

Usage

card-fields-demo.tsx
import {
  CardNumberInput,
  ExpiryInput,
  SecurityCodeInput,
  CardNameInput,
} from "@viliha/vui-react/card-fields";

Exports

Everything this family exports. They are read from the source, so this list is what the package actually ships.

PropTypeDefault
CardNumberInputcomponent—
ExpiryInputcomponent—
SecurityCodeInputcomponent—
CardNameInputcomponent—

CardNumberInput props

Plus everything Omit<React.ComponentProps<typeof Input>, "value" | "onChange"> accepts, passed straight through to the underlying element.

PropTypeDefaultWhat it does
value?string—The digits, if the caller is holding them. Omit for an uncontrolled field.
onValueChange?(next: MaskedCardValue) => void—Told the masked value on every change: digits, completeness and validity together.
error?boolean—Shown as invalid, on top of whatever the mask found. A server declining a card is not something a mask can know, so a caller has to be able to say so. `invalid` from the mask and this are ORed.

ExpiryInput props

Plus everything Omit<React.ComponentProps<typeof Input>, "value" | "onChange"> accepts, passed straight through to the underlying element.

PropTypeDefaultWhat it does
value?string—The digits, if the caller is holding them. Omit for an uncontrolled field.
onValueChange?(next: MaskedCardValue) => void—Told the masked value on every change: digits, completeness and validity together.
error?boolean—Shown as invalid, on top of whatever the mask found. A server declining a card is not something a mask can know, so a caller has to be able to say so. `invalid` from the mask and this are ORed.

SecurityCodeInput props

Plus everything Omit<React.ComponentProps<typeof Input>, "value" | "onChange"> accepts, passed straight through to the underlying element.

PropTypeDefaultWhat it does
value?string—The digits, if the caller is holding them. Omit for an uncontrolled field.
onValueChange?(next: MaskedCardValue) => void—Told the masked value on every change: digits, completeness and validity together.
error?boolean—Shown as invalid, on top of whatever the mask found. A server declining a card is not something a mask can know, so a caller has to be able to say so. `invalid` from the mask and this are ORed.

CardNameInput props

Plus everything Omit<React.ComponentProps<typeof Input>, "value" | "onChange"> accepts, passed straight through to the underlying element.

PropTypeDefault
value?string—
onChange?React.ChangeEventHandler<HTMLInputElement>—

Customize

Every value this component draws comes from the theme: the colours, the radius, the control height and the type scale. Change a token and this moves with everything else, which is the difference between theming the product and overriding a component. See Theming for the token contract, and Swapping defaults for replacing the markup itself.