Basic credit card form
import { html, atom, renderApp } from 'mates';
import { CreditCardInput, formatCardNumber, formatExpiry } from 'mates-ui';
const App = () => {
const cardNum = atom("");
const expiry = atom("");
const cvc = atom("");
const ccName = atom("");
const cvcVisible = atom(false);
const network = atom("unknown");
return () => html`
<x-col gap="var(--md-space-4)" style="max-width:28rem;width:100%;">
${CreditCardInput({
cardNumber: cardNum(),
expiryDate: expiry(),
cvc: cvc(),
cardholderName: ccName(),
cvcVisible: cvcVisible(),
onCardNumberChange: (value, net) => { cardNum.set(formatCardNumber(value, net)); network.set(net); },
onExpiryChange: (value) => expiry.set(formatExpiry(value)),
onCvcChange: (value) => cvc.set(value),
onNameChange: (value) => ccName.set(value),
onCvcToggle: () => cvcVisible.set(!cvcVisible()),
})}
</x-col>
`;
};
renderApp(App, document.getElementById('app'));
Card network detection
import { html, renderApp } from 'mates';
import { detectNetwork, formatCardNumber, Text } from 'mates-ui';
const SAMPLES = [
{ label: "Visa", raw: "4242424242424242" },
{ label: "Mastercard", raw: "5425233430109903" },
{ label: "Amex", raw: "378282246310005" },
{ label: "Discover", raw: "6011111111111117" },
];
const App = () => () => html`
<div style="display:grid;grid-template-columns:1fr 1fr;gap:var(--md-space-4);max-width:36rem;width:100%;">
${SAMPLES.map(({ label, raw }) => {
const net = detectNetwork(raw);
const formatted = formatCardNumber(raw, net);
return html`
<div style="padding:var(--md-space-4);border:1px solid var(--md-color-border);border-radius:var(--md-radius-md);">
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:var(--md-space-2);">
${Text(label, { type: "label-md" })}
${Text(net, { type: "label-sm", color: "muted" })}
</div>
<code style="font-size:var(--md-text-sm);font-family:monospace;">${formatted}</code>
</div>
`;
})}
</div>
`;
renderApp(App, document.getElementById('app'));
Without cardholder name
import { html, atom, renderApp } from 'mates';
import { CreditCardInput, formatCardNumber, formatExpiry } from 'mates-ui';
const App = () => {
const cardNum = atom("");
const expiry = atom("");
const cvc = atom("");
const cvcVisible = atom(false);
return () => html`
<div style="max-width:28rem;width:100%;">
${CreditCardInput({
cardNumber: cardNum(),
expiryDate: expiry(),
cvc: cvc(),
showName: false,
cvcVisible: cvcVisible(),
onCardNumberChange: (value, net) => cardNum.set(formatCardNumber(value, net)),
onExpiryChange: (value) => expiry.set(formatExpiry(value)),
onCvcChange: (value) => cvc.set(value),
onCvcToggle: () => cvcVisible.set(!cvcVisible()),
})}
</div>
`;
};
renderApp(App, document.getElementById('app'));
Disabled state
import { html, renderApp } from 'mates';
import { CreditCardInput } from 'mates-ui';
const App = () => () => html`
<div style="max-width:28rem;width:100%;">
${CreditCardInput({
cardNumber: "4242 4242 4242 4242",
expiryDate: "12/29",
cvc: "123",
cardholderName: "Jane Doe",
disabled: true,
})}
</div>
`;
renderApp(App, document.getElementById('app'));
Validation errors
import { html, atom, renderApp } from 'mates';
import { CreditCardInput, formatCardNumber, formatExpiry } from 'mates-ui';
const App = () => {
const cardNum = atom("4111 1111 111");
const expiry = atom("01/20");
const cvc = atom("1");
const name = atom("");
const cvcVisible = atom(false);
return () => html`
<div style="max-width:28rem;width:100%;">
${CreditCardInput({
cardNumber: cardNum(),
expiryDate: expiry(),
cvc: cvc(),
cardholderName: name(),
showErrors: true,
cvcVisible: cvcVisible(),
onCardNumberChange: (value, net) => cardNum.set(formatCardNumber(value, net)),
onExpiryChange: (value) => expiry.set(formatExpiry(value)),
onCvcChange: (value) => cvc.set(value),
onNameChange: (value) => name.set(value),
onCvcToggle: () => cvcVisible.set(!cvcVisible()),
})}
</div>
`;
};
renderApp(App, document.getElementById('app'));