Passer au contenu principal

PaymentMethodForm

Implemented

Add-payment-method form with client-side validation for card number, MM/YY expiry, CVC, and name on card.

Categoryorganisms
Sourcecomponents/organisms/PaymentMethodForm/PaymentMethodForm.tsx
AI HintonSubmit fires with { cardNumber, expiry, cvc, name } only after validation passes; optional onCancel adds a secondary Cancel button.

Add-payment-method form with client-side validation for card number, MM/YY expiry, CVC, and name on card — onSubmit fires only after validation passes; optional onCancel adds a secondary Cancel button.

PaymentMethodForm

Organism — Account & payments family

Self-contained "Add payment method" form: four fields (name, card number with inputMode numeric, MM/YY expiry, 3–4 digit CVC) validated on submit — per-field role="alert" messages wired via aria-invalid + aria-describedby, values preserved across failed submits. onSubmit receives { cardNumber, expiry, cvc, name } only after validation passes; onCancel adds a secondary Cancel button. UI-only: tokenization and persistence belong to the consumer.

Press “Add card” with empty fields to see the validation errors; fill the four fields validly and the payload reaches onSubmit.

Nothing submitted yet.

This component supports light and dark mode.

Usage

PaymentMethodForm owns its field state and validation — hand it onSubmit (the validation gate) and, in modal contexts, onCancel so the flow can back out. Treat the payload as shape-validated, not payment-validated: run your own Luhn check / provider tokenization inside the handler.

import { PaymentMethodForm } from '@epasslive/design-system'

<PaymentMethodForm
  onSubmit={(data) => tokenizeCard(data)}
  onCancel={() => closeModal()}
/>

Validation rules

Built-in, English copy: name non-empty after trim; card number ≥ 13 digits after stripping spaces; expiry matching MM/YY; CVC ≥ 3 characters (maxLength 4). A failed submit renders the error set without clearing entered values, and every message is announced through a role="alert" paragraph linked by aria-describedby. Field and error ids derive from React.useId(), so multiple instances never clash.

Accessibility

Every field pairs a <label htmlFor> with its input (WCAG 1.3.1 / 4.1.2); failed fields set aria-invalid and describe their role="alert" message (WCAG 3.3.1 / 3.3.3) without a focus jump. The numeric fields summon the numeric keypad on touch devices, and the form is named ("Add payment method") via aria-label.

Props

Prop
Type
Default
Description
onSubmit*
(data: { cardNumber: string; expiry: string; cvc: string; name: string }) => void
—

Called on valid submission — validation must pass first.

onCancel
() => void
—

Adds a secondary Cancel button (variant secondary, size sm) left of the submit action.

className
string
—

Extra classes on the <form> (fields are already spaced with space-y-4).

Props

Preview

PaymentMethodForm

Prop
Type
Required
Default
Description
onSubmit
(data: { cardNumber: string; expiry: string; cvc: string; name: string }) => void
Required
—

Called on valid form submission — client-side validation must pass first.

onCancel
() => void
Optional
—

Optional secondary Cancel button click handler.

className
string
Optional
—

Extra classes on the <form> (fields already spaced with space-y-4).

locale
"en" | "fr"
Optional
"en"

Localizes all built-in copy (labels, placeholders, error messages, button text). Default 'en' keeps back-compat with the pre-cascade English-only build.

Quick use:<PaymentMethodForm />
Design System v4.1.0 | ePassLive