Open EncryptedCurse opened 3 years ago
Would be awesome to have Ant Design compatibility.
@odragora I managed to come up with my own solution that may interest you. This is not a minimal working example and there's probably a better way to do it, but it works for my purpose. I used the card-validator
library and my own custom icons (though you could swap them for something like Font Awesome without too much trouble).
Do note that it's definitely not as full-featured as react-payment-inputs
, but it's capable of dynamically changing the card type icon as the number is typed and performing validation on it using the aforementioned library and the Form
component built into Ant Design.
import { useState } from "react";
import * as cardValidator from "card-validator";
import visaIcon from "./payment/visa.png";
import mastercardInputIcon from "./payment/mastercard.png";
import maestroIcon from "./payment/maestro.png";
import amexIcon from "./payment/amex.png";
const cardIcons = {
"visa": visaIcon,
"american-express": amexIcon,
"mastercard": mastercardInputIcon,
"maestro": maestroIcon,
};
const cardExpirationDropdown = (type, text) => (
<Tooltip title={text} placement="right" trigger={["hover"]}>
<Form.Item name={["card", "expiration", type]} initialValue={text} rules={[{ required: true }]}>
<Select>
{cardExpirationData[type].map((value) => (
<Select.Option key={value} value={value}>
{value}
</Select.Option>
))}
</Select>
</Form.Item>
</Tooltip>
);
export default function Example() {
const [cardNumberSuffix, setCardNumberSuffix] = useState(null);
...
const cardFormGroup = () => {
function validateCard(_, value) {
const { card, isPotentiallyValid, isValid } = cardValidator.number(value);
if (value) {
setCardNumberSuffix(
card && card in cardIcons ? (
<img src={cardIcons[card.type]} title={card.niceType} width="32" />
) : null
);
return (value.length >= 15 ? isValid : isPotentiallyValid)
? Promise.resolve()
: Promise.reject(new Error("Invalid"));
} else {
setCardNumberSuffix(null);
return Promise.reject(new Error("Required"));
}
}
const normalize = (value) => value.replace(/\D+/g, "");
return (
<>
<Form.Item label="Name" name={["card", "name"]}>
<Input />
</Form.Item>
<Form.Item
label="Number"
name={["card", "number"]}
rules={[{ validator: validateCard }]}
normalize={normalize}
>
<Input maxLength={16} suffix={<>{cardNumberSuffix}</>} />
</Form.Item>
<Form.Item
label="CVV"
name={["card", "cvv"]}
rules={[{ required: true }]}
normalize={normalize}
>
<Input maxLength={4} />
</Form.Item>
<Form.Item label="Expiration" required>
<Row gutter={6}>
<Col span={12}>{cardExpirationDropdown("month", "Month")}</Col>
<Col span={12}>{cardExpirationDropdown("year", "Year")}</Col>
</Row>
</Form.Item>
</>
);
};
...
}
Thank you very much @EncryptedCurse ! I think your code can save a lot of time for me.
How can I use this library with Ant Design?
Attempting a minimal working example as follows...
...produces this error: