@fanatics-ui/react-credit-card-input
Version:
A React component for credit/debit card input - it was inspired from react-credit-card-input, authored by jxom <jake@medipass.io> (https://medipass.com.au)
1,043 lines (883 loc) • 33.9 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('react'), require('payment'), require('credit-card-type')) :
typeof define === 'function' && define.amd ? define(['react', 'payment', 'credit-card-type'], factory) :
(global.CreditCardInput = factory(global.React,global.payment,global.creditCardType));
}(this, (function (React,payment,creditCardType) { 'use strict';
var React__default = 'default' in React ? React['default'] : React;
payment = payment && payment.hasOwnProperty('default') ? payment['default'] : payment;
creditCardType = creditCardType && creditCardType.hasOwnProperty('default') ? creditCardType['default'] : creditCardType;
var classCallCheck = function (instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
};
var createClass = function () {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps);
return Constructor;
};
}();
var defineProperty = function (obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
};
var _extends = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
var inherits = function (subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
enumerable: false,
writable: true,
configurable: true
}
});
if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
};
var possibleConstructorReturn = function (self, call) {
if (!self) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return call && (typeof call === "object" || typeof call === "function") ? call : self;
};
var slicedToArray = function () {
function sliceIterator(arr, i) {
var _arr = [];
var _n = true;
var _d = false;
var _e = undefined;
try {
for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
_arr.push(_s.value);
if (i && _arr.length === i) break;
}
} catch (err) {
_d = true;
_e = err;
} finally {
try {
if (!_n && _i["return"]) _i["return"]();
} finally {
if (_d) throw _e;
}
}
return _arr;
}
return function (arr, i) {
if (Array.isArray(arr)) {
return arr;
} else if (Symbol.iterator in Object(arr)) {
return sliceIterator(arr, i);
} else {
throw new TypeError("Invalid attempt to destructure non-iterable instance");
}
};
}();
var toArray = function (arr) {
return Array.isArray(arr) ? arr : Array.from(arr);
};
var DEFAULT_CVC_LENGTH = 3;
var DEFAULT_CARD_NUMBER_MAX_LENGTH = 16;
var DEFAULT_CARD_FORMAT = /(\d{1,4})/g;
var CARD_TYPES = [{
type: 'amex',
format: /(\d{1,4})(\d{1,6})?(\d{1,5})?/,
startPattern: /^3[47]/,
maxCardNumberLength: 15,
cvcLength: 4
}, {
type: 'dankort',
format: DEFAULT_CARD_FORMAT,
startPattern: /^5019/,
maxCardNumberLength: 16,
cvcLength: DEFAULT_CVC_LENGTH
}, {
type: 'hipercard',
format: DEFAULT_CARD_FORMAT,
startPattern: /^(384100|384140|384160|606282|637095|637568|60(?!11))/,
maxCardNumberLength: 19,
cvcLength: DEFAULT_CVC_LENGTH
}, {
type: 'dinersclub',
format: DEFAULT_CARD_FORMAT,
startPattern: /^(36|38|30[0-5])/,
maxCardNumberLength: 14,
cvcLength: DEFAULT_CVC_LENGTH
}, {
type: 'discover',
format: DEFAULT_CARD_FORMAT,
startPattern: /^(6011|65|64[4-9]|622)/,
maxCardNumberLength: 16,
cvcLength: DEFAULT_CVC_LENGTH
}, {
type: 'jcb',
format: DEFAULT_CARD_FORMAT,
startPattern: /^35/,
maxCardNumberLength: 16,
cvcLength: DEFAULT_CVC_LENGTH
}, {
type: 'laser',
format: DEFAULT_CARD_FORMAT,
startPattern: /^(6706|6771|6709)/,
maxCardNumberLength: 19,
cvcLength: DEFAULT_CVC_LENGTH
}, {
type: 'maestro',
format: DEFAULT_CARD_FORMAT,
startPattern: /^(5018|5020|5038|6304|6703|6708|6759|676[1-3])/,
maxCardNumberLength: 19,
cvcLength: DEFAULT_CVC_LENGTH
}, {
type: 'mastercard',
format: DEFAULT_CARD_FORMAT,
startPattern: /^(5[1-5]|677189)|^(222[1-9]|2[3-6]\d{2}|27[0-1]\d|2720)/,
maxCardNumberLength: 16,
cvcLength: DEFAULT_CVC_LENGTH
}, {
type: 'unionpay',
format: DEFAULT_CARD_FORMAT,
startPattern: /^62/,
maxCardNumberLength: 19,
cvcLength: DEFAULT_CVC_LENGTH,
luhn: false
}, {
type: 'visaelectron',
format: DEFAULT_CARD_FORMAT,
startPattern: /^4(026|17500|405|508|844|91[37])/,
maxCardNumberLength: 16,
cvcLength: DEFAULT_CVC_LENGTH
}, {
type: 'elo',
format: DEFAULT_CARD_FORMAT,
startPattern: /^(4011(78|79)|43(1274|8935)|45(1416|7393|763(1|2))|50(4175|6699|67[0-7][0-9]|9000)|627780|63(6297|6368)|650(03([^4])|04([0-9])|05(0|1)|4(0[5-9]|3[0-9]|8[5-9]|9[0-9])|5([0-2][0-9]|3[0-8])|9([2-6][0-9]|7[0-8])|541|700|720|901)|651652|655000|655021)/,
maxCardNumberLength: 16,
cvcLength: DEFAULT_CVC_LENGTH
}, {
type: 'visa',
format: DEFAULT_CARD_FORMAT,
startPattern: /^4/,
maxCardNumberLength: 19,
cvcLength: DEFAULT_CVC_LENGTH
}];
var getCardTypeByValue = function getCardTypeByValue(value) {
return CARD_TYPES.filter(function (cardType) {
return cardType.startPattern.test(value);
})[0];
};
var getCardTypeByType = function getCardTypeByType(type) {
return CARD_TYPES.filter(function (cardType) {
return cardType.type === type;
})[0];
};
var hasCardNumberReachedMaxLength = function hasCardNumberReachedMaxLength(currentValue, currentValueLength) {
var cardType = getCardTypeByValue(currentValue);
var maxLength = cardType ? cardType.maxCardNumberLength : DEFAULT_CARD_NUMBER_MAX_LENGTH;
return currentValueLength >= Math.min(DEFAULT_CARD_NUMBER_MAX_LENGTH, maxLength);
};
var hasCVCReachedMaxLength = function hasCVCReachedMaxLength(type, currentValueLength) {
var cardType = getCardTypeByType(type);
if (!cardType) {
return currentValueLength >= DEFAULT_CVC_LENGTH;
}
return currentValueLength >= cardType.cvcLength;
};
var formatCvc = function formatCvc(cvc) {
return (cvc.match(/\d+/g) || []).join('');
};
var formatExpiry = function formatExpiry(event) {
var eventData = event.nativeEvent && event.nativeEvent.data;
var prevExpiry = event.target.value.split(' / ').join('/');
if (!prevExpiry) return null;
var expiry = prevExpiry;
if (/^[2-9]$/.test(expiry)) {
expiry = '0' + expiry;
}
if (prevExpiry.length === 2 && +prevExpiry > 12) {
var _prevExpiry = toArray(prevExpiry),
head = _prevExpiry[0],
tail = _prevExpiry.slice(1);
expiry = '0' + head + '/' + tail.join('');
}
if (/^1[/-]$/.test(expiry)) {
return '01 / ';
}
expiry = expiry.match(/(\d{1,2})/g) || [];
if (expiry.length === 1) {
if (!eventData && prevExpiry.includes('/')) {
return expiry[0];
}
if (/\d{2}/.test(expiry)) {
return expiry[0] + ' / ';
}
}
if (expiry.length > 2) {
var _ref = expiry.join('').match(/^(\d{2}).*(\d{2})$/) || [],
_ref2 = slicedToArray(_ref, 3),
month = _ref2[1],
year = _ref2[2];
return [month, year].join(' / ');
}
return expiry.join(' / ');
};
var isHighlighted = function isHighlighted() {
return window.getSelection().type === 'Range';
};
// https://websemantics.uk/tools/image-to-data-uri-converter/
// https://www.easy400.net/js2/regexp/ccnums.html
var images = {
placeholder: '/static/images/payments/cc-placeholder.svg',
visa: '/static/images/payments/visa_icon.svg',
mastercard: '/static/images/payments/mastercard_icon.svg',
amex: '/static/images/payments/american-express_icon.svg',
dinersclub: '/static/images/payments/discover_icon.svg',
discover: '/static/images/payments/discover_icon.svg'
};
var ERROR_TEXT__INVALID_EXPIRY_DATE = 'Expiry date is invalid';
var ERROR_TEXT__MONTH_OUT_OF_RANGE = 'Expiry month must be between 01 and 12';
var ERROR_TEXT__YEAR_OUT_OF_RANGE = 'Expiry year cannot be in the past';
var ERROR_TEXT__DATE_OUT_OF_RANGE = 'Expiry date cannot be in the past';
var EXPIRY_DATE_REGEX = /^(\d{2})\/(\d{4}|\d{2})$/;
var MONTH_REGEX = /(0[1-9]|1[0-2])/;
var isExpiryInvalid = (function (expiryDate) {
var customExpiryErrorTexts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var splitDate = expiryDate.split('/');
if (!EXPIRY_DATE_REGEX.test(expiryDate)) {
return customExpiryErrorTexts.invalidExpiryDate || ERROR_TEXT__INVALID_EXPIRY_DATE;
}
var expiryMonth = splitDate[0];
if (!MONTH_REGEX.test(expiryMonth)) {
return customExpiryErrorTexts.monthOutOfRange || ERROR_TEXT__MONTH_OUT_OF_RANGE;
}
var expiryYear = splitDate[1];
var date = new Date();
var currentYear = date.getFullYear();
var currentMonth = date.getMonth() + 1;
currentYear = parseInt(expiryYear.length === 4 ? currentYear : currentYear.toString().substr(-2), 10);
if (currentYear > parseInt(expiryYear, 10)) {
return customExpiryErrorTexts.yearOutOfRange || ERROR_TEXT__YEAR_OUT_OF_RANGE;
}
if (parseInt(expiryYear, 10) === currentYear && parseInt(expiryMonth, 10) < currentMonth) {
return customExpiryErrorTexts.dateOutOfRange || ERROR_TEXT__DATE_OUT_OF_RANGE;
}
return false;
});
// SassMeister | The Sass Playground!
// https://www.sassmeister.com/
//
// Four ways to style react components
// https://codeburst.io/4-four-ways-to-style-react-components-ac6f323da822
var styles = {
container: {
display: 'inline-block'
},
fieldWrapper: {
display: 'flex',
alignItems: 'center',
position: 'relative',
backgroundColor: 'white',
padding: '10px',
borderRadius: '3px',
overflow: 'hidden'
},
isInvalid: {
border: '1px solid #ff3860'
},
cardImage: {
height: '1.5em',
zIndex: 2,
width: '2em'
},
inputWrapper: {
alignItems: 'center',
marginLeft: '0.5em',
// position: 'relative',
display: 'flex',
transition: 'transform 0.5s',
transform: 'translateX(0)',
height: '1.1em',
overflow: 'hidden'
},
inputWrapperPsedoAfter: {
// https://stackoverflow.com/questions/43701748/react-pseudo-selector-inline-styling
// https://stackoverflow.com/questions/45730224/css-pseudo-code-libefore-in-react-inline-style
// https://blog.logrocket.com/the-best-react-inline-style-libraries-comparing-radium-aphrodite-emotion-849ef148c473
// https://medium.com/@pioul/modular-css-with-react-61638ae9ea3e
// https://stackoverflow.com/questions/28269669/css-pseudo-elements-in-react/28269950
visibility: 'hidden',
height: 0
},
creditCardInput: {
border: '0px',
minWidth: '100%',
fontSize: '1em',
outline: '0px'
},
dangerText: {
fontSize: '0.8rem',
margin: '5px 0 0 0',
color: '#ff3860'
}
};
var BACKSPACE_KEY_CODE = 8;
var CARD_TYPES$1 = {
mastercard: 'MASTERCARD',
visa: 'VISA',
amex: 'AMERICAN_EXPRESS',
dinersclub: 'DINERS_CLUB',
discover: 'DISCOVER'
};
var Cursor = function () {
function Cursor(event) {
classCallCheck(this, Cursor);
this.cursorStart = event.target.selectionStart;
this.cursorEnd = event.target.selectionEnd;
this.event = event;
}
createClass(Cursor, [{
key: 'isSpace',
value: function isSpace(value) {
return value.charAt(this.cursorStart - 1) === ' ';
}
}, {
key: 'setSelectionRange',
value: function setSelectionRange(value) {
var currentCursor = this.event.target.selectionStart;
if (currentCursor - this.cursorStart > 2) {
var isSpace = this.isSpace(value);
var eventData = this.event.nativeEvent && this.event.nativeEvent.data;
var cursorStart = isSpace && eventData ? this.cursorStart + 1 : this.cursorStart;
var cursorEnd = isSpace && eventData ? this.cursorEnd + 1 : this.cursorEnd;
this.event.target.setSelectionRange(cursorStart, cursorEnd);
}
}
}]);
return Cursor;
}();
var removeObjectKey = function removeObjectKey(obj, keyName) {
return Object.entries(obj).filter(function (_ref) {
var _ref2 = slicedToArray(_ref, 2),
key = _ref2[0],
value = _ref2[1];
return key !== keyName;
}).reduce(function (memo, _ref3) {
var _ref4 = slicedToArray(_ref3, 2),
key = _ref4[0],
value = _ref4[1];
return Object.assign(memo, defineProperty({}, key, value));
}, {});
};
var extractNumbers = function extractNumbers(str) {
return ((str || '').match(/\d+/g) || []).join('').substr(0, DEFAULT_CARD_NUMBER_MAX_LENGTH);
};
var inputRenderer = function inputRenderer(_ref5) {
var props = _ref5.props;
var style = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
return React__default.createElement('input', _extends({ style: Object.assign({}, styles.creditCardInput, style) }, props));
};
var CreditCardInput = function (_Component) {
inherits(CreditCardInput, _Component);
function CreditCardInput(props) {
classCallCheck(this, CreditCardInput);
var _this = possibleConstructorReturn(this, (CreditCardInput.__proto__ || Object.getPrototypeOf(CreditCardInput)).call(this, props));
_this.componentDidMount = function () {
_this.setState({ cardNumber: _this.cardNumberField.value }, function () {
var cardType = payment.fns.cardType(_this.state.cardNumber);
_this.setState({
cardImage: images[cardType] || images.placeholder
});
});
};
_this.isMonthDashKey = function () {
var _ref6 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
key = _ref6.key,
value = _ref6.target.value;
return !value.match(/[/-]/) && /^[/-]$/.test(key);
};
_this.checkIsNumeric = function (e) {
if (!/^\d*$/.test(e.key)) {
e.preventDefault();
}
};
_this.handleCardNumberBlur = function () {
var _ref7 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { onBlur: null },
onBlur = _ref7.onBlur;
return function (e) {
var customTextLabels = _this.props.customTextLabels;
if (!payment.fns.validateCardNumber(e.target.value)) {
_this.setFieldInvalid(customTextLabels.invalidCardNumber || 'Card number is invalid', 'cardNumber');
} else {
_this.setOtherFieldInvalidIfNeeded();
}
var cardNumberInputProps = _this.props.cardNumberInputProps;
cardNumberInputProps.onBlur && cardNumberInputProps.onBlur(e);
onBlur && onBlur(e);
};
};
_this.handleCardNumberFocus = function () {
var _ref8 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { onFocus: null },
onFocus = _ref8.onFocus;
return function (e) {
var cardNumberInputProps = _this.props.cardNumberInputProps;
_this.setFieldValid('cardNumber');
cardNumberInputProps.onFocus && cardNumberInputProps.onFocus(e);
onFocus && onFocus(e);
};
};
_this.handleCardNumberChange = function () {
var _ref9 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { onChange: null },
onChange = _ref9.onChange;
return function (e) {
var _this$props = _this.props,
customTextLabels = _this$props.customTextLabels,
cardNumberInputProps = _this$props.cardNumberInputProps;
var cursor = new Cursor(e);
var cardNumber = extractNumbers(e.target.value);
var cardNumberLength = cardNumber.split(' ').join('').length;
var cardType = payment.fns.cardType(cardNumber);
var cardTypeInfo = creditCardType.getTypeInfo(creditCardType.types[CARD_TYPES$1[cardType]]) || { code: { size: DEFAULT_CVC_LENGTH } };
var cardTypeLengths = cardTypeInfo.lengths || [DEFAULT_CARD_NUMBER_MAX_LENGTH];
if (_this.cvcField && _this.cvcField.value) {
var codeSize = cardTypeInfo.code.size;
_this.cvcField.value = _this.cvcField.value.substr(0, codeSize);
if (!payment.fns.validateCardCVC(_this.cvcField.value, cardType)) {
_this.setFieldInvalid(customTextLabels.invalidCvc || 'CVV is invalid', 'cardCVV');
}
}
_this.cardNumberField.value = payment.fns.formatCardNumber(cardNumber);
cursor.setSelectionRange(_this.cardNumberField.value);
_this.setState({
cardImage: images[cardType] || images.placeholder,
cardNumber: cardNumber
});
_this.setFieldValid('cardNumber');
if (cardTypeLengths) {
var lastCardTypeLength = Math.min(DEFAULT_CARD_NUMBER_MAX_LENGTH, cardTypeLengths[cardTypeLengths.length - 1]);
if (cardTypeLengths.includes(cardNumberLength) && payment.fns.validateCardNumber(cardNumber)) {
_this.cardExpiryField.focus();
} else if (cardNumberLength >= lastCardTypeLength) {
_this.setFieldInvalid(customTextLabels.invalidCardNumber || 'Card number is invalid', 'cardNumber');
}
}
cardNumberInputProps.onChange && cardNumberInputProps.onChange(e);
onChange && onChange(e);
};
};
_this.handleCardNumberKeyPress = function (e) {
var value = e.target.value;
_this.checkIsNumeric(e);
if (value && !isHighlighted()) {
var valueLength = value.split(' ').join('').length;
if (hasCardNumberReachedMaxLength(value, valueLength)) {
e.preventDefault();
}
}
};
_this.handleCardExpiryBlur = function () {
var _ref10 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { onBlur: null },
onBlur = _ref10.onBlur;
return function (e) {
var customTextLabels = _this.props.customTextLabels;
var cardExpiry = e.target.value.split(' / ').join('/');
var expiryError = isExpiryInvalid(cardExpiry, customTextLabels.expiryError);
if (expiryError) {
_this.setFieldInvalid(expiryError, 'cardExpiry');
} else {
_this.setOtherFieldInvalidIfNeeded();
}
var cardExpiryInputProps = _this.props.cardExpiryInputProps;
cardExpiryInputProps.onBlur && cardExpiryInputProps.onBlur(e);
onBlur && onBlur(e);
};
};
_this.handleCardExpiryFocus = function () {
var _ref11 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { onFocus: null },
onFocus = _ref11.onFocus;
return function (e) {
var cardExpiryInputProps = _this.props.cardExpiryInputProps;
_this.setFieldValid('cardExpiry');
cardExpiryInputProps.onFocus && cardExpiryInputProps.onFocus(e);
onFocus && onFocus(e);
};
};
_this.handleCardExpiryChange = function () {
var _ref12 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { onChange: null },
onChange = _ref12.onChange;
return function (e) {
var customTextLabels = _this.props.customTextLabels;
_this.cardExpiryField.value = formatExpiry(e);
_this.setFieldValid('cardExpiry');
var value = _this.cardExpiryField.value.split(' / ').join('/');
var expiryError = isExpiryInvalid(value, customTextLabels.expiryError);
if (value.length > 4) {
if (expiryError) {
_this.setFieldInvalid(expiryError, 'cardExpiry');
} else {
_this.cvcField.focus();
}
}
var cardExpiryInputProps = _this.props.cardExpiryInputProps;
cardExpiryInputProps.onChange && cardExpiryInputProps.onChange(e);
onChange && onChange(e);
};
};
_this.handleCardExpiryKeyPress = function (e) {
var value = e.target.value;
if (!_this.isMonthDashKey(e)) {
_this.checkIsNumeric(e);
}
if (value && !isHighlighted()) {
var valueLength = value.split(' / ').join('').length;
if (valueLength >= 4) {
e.preventDefault();
}
}
};
_this.handleCardCVCBlur = function () {
var _ref13 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { onBlur: null },
onBlur = _ref13.onBlur;
return function (e) {
var customTextLabels = _this.props.customTextLabels;
var cardType = payment.fns.cardType(_this.state.cardNumber);
if (!payment.fns.validateCardCVC(e.target.value, cardType)) {
_this.setFieldInvalid(customTextLabels.invalidCvc || 'CVV is invalid', 'cardCVV');
} else {
_this.setOtherFieldInvalidIfNeeded();
}
var cardCVVInputProps = _this.props.cardCVVInputProps;
cardCVVInputProps.onBlur && cardCVVInputProps.onBlur(e);
onBlur && onBlur(e);
};
};
_this.handleCardCVCFocus = function () {
var _ref14 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { onFocus: null },
onFocus = _ref14.onFocus;
return function (e) {
var cardCVVInputProps = _this.props.cardCVVInputProps;
_this.setFieldValid('cardCVV');
cardCVVInputProps.onFocus && cardCVVInputProps.onFocus(e);
onFocus && onFocus(e);
};
};
_this.handleCardCVCChange = function () {
var _ref15 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { onChange: null },
onChange = _ref15.onChange;
return function (e) {
var customTextLabels = _this.props.customTextLabels;
var value = formatCvc(e.target.value);
_this.cvcField.value = value;
var CVC = value;
var CVCLength = CVC.length;
var cardType = payment.fns.cardType(_this.state.cardNumber);
_this.setFieldValid('cardCVV');
if (CVCLength >= 4) {
if (!payment.fns.validateCardCVC(CVC, cardType)) {
_this.setFieldInvalid(customTextLabels.invalidCvc || 'CVV is invalid', 'cardCVV');
}
}
var cardCVVInputProps = _this.props.cardCVVInputProps;
cardCVVInputProps.onChange && cardCVVInputProps.onChange(e);
onChange && onChange(e);
};
};
_this.handleCardCVCKeyPress = function (e) {
var cardType = payment.fns.cardType(_this.state.cardNumber);
var value = e.target.value;
_this.checkIsNumeric(e);
if (value && !isHighlighted()) {
var valueLength = value.split(' / ').join('').length;
if (hasCVCReachedMaxLength(cardType, valueLength)) {
e.preventDefault();
}
}
};
_this.handleKeyDown = function (ref) {
return function (e) {
if (e.keyCode === BACKSPACE_KEY_CODE && !e.target.value) {
ref.focus();
}
};
};
_this.setOtherFieldInvalidIfNeeded = function () {
var errors = _this.state.errors;
var _ref16 = Object.entries(errors)[0] || [],
_ref17 = slicedToArray(_ref16, 2),
inputName = _ref17[0],
_ref17$ = _ref17[1],
errorText = _ref17$ === undefined ? null : _ref17$;
errorText && _this.setFieldInvalid(errorText, inputName);
};
_this.setFieldInvalid = function (errorText, inputName) {
var onError = _this.props.onError;
_this.setState({ errorText: errorText, isFormInvalid: true });
if (inputName) {
var _onError = _this.props[inputName + 'InputProps'].onError;
_this.setState({
errors: Object.assign(_extends({}, _this.state.errors, defineProperty({}, inputName, errorText)))
});
_onError && _onError(errorText);
}
if (onError) {
onError({ inputName: inputName, error: errorText });
}
};
_this.setFieldValid = function (inputName) {
_this.setState(function (state) {
var errors = removeObjectKey(state.errors, inputName);
return _extends({}, state, {
errors: errors,
errorText: null,
isFormInvalid: false
});
});
};
_this.render = function () {
var _this$state = _this.state,
cardImage = _this$state.cardImage,
errors = _this$state.errors;
var _this$props2 = _this.props,
cardImageClassName = _this$props2.cardImageClassName,
cardImageStyle = _this$props2.cardImageStyle,
cardCVVInputProps = _this$props2.cardCVVInputProps,
cardExpiryInputProps = _this$props2.cardExpiryInputProps,
cardNumberInputProps = _this$props2.cardNumberInputProps,
cardCVCInputRenderer = _this$props2.cardCVCInputRenderer,
cardExpiryInputRenderer = _this$props2.cardExpiryInputRenderer,
cardNumberInputRenderer = _this$props2.cardNumberInputRenderer,
containerClassName = _this$props2.containerClassName,
containerStyle = _this$props2.containerStyle,
dangerTextClassName = _this$props2.dangerTextClassName,
dangerTextStyle = _this$props2.dangerTextStyle,
errorText = _this$props2.errorText,
fieldClassName = _this$props2.fieldClassName,
fieldStyle = _this$props2.fieldStyle,
inputClassName = _this$props2.inputClassName,
inputStyle = _this$props2.inputStyle,
invalidStyle = _this$props2.invalidStyle,
customTextLabels = _this$props2.customTextLabels,
setFieldInvalid = _this$props2.setFieldInvalid;
return React__default.createElement(
'div',
{
className: containerClassName,
style: Object.assign({}, styles.container, containerStyle)
},
React__default.createElement(
'div',
{
className: fieldClassName,
style: Object.assign({}, styles.fieldWrapper, fieldStyle, (!!errors.cardNumber || setFieldInvalid) && invalidStyle)
},
React__default.createElement('img', {
alt: 'credit card flag',
className: cardImageClassName,
style: Object.assign({}, styles.cardImage, cardImageStyle),
src: cardImage
}),
React__default.createElement(
'label',
{
style: Object.assign({}, styles.inputWrapper, inputStyle),
className: 'card-number-wrapper',
'data-max': '9999 9999 9999 9999 9999'
},
cardNumberInputRenderer({
handleCardNumberChange: function handleCardNumberChange(onChange) {
return _this.handleCardNumberChange({ onChange: onChange });
},
handleCardNumberBlur: function handleCardNumberBlur(onBlur) {
return _this.handleCardNumberBlur({ onBlur: onBlur });
},
handleCardNumberFocus: function handleCardNumberFocus(onFocus) {
return _this.handleCardNumberFocus({ onFocus: onFocus });
},
props: _extends({
id: 'card-number',
ref: function ref(cardNumberField) {
_this.cardNumberField = cardNumberField;
},
autoComplete: 'cc-number',
className: 'credit-card-input ' + inputClassName,
placeholder: customTextLabels.cardNumberPlaceholder || 'Card Number',
type: 'tel'
}, cardNumberInputProps, {
onBlur: _this.handleCardNumberBlur(),
onFocus: _this.handleCardNumberFocus(),
onChange: _this.handleCardNumberChange(),
onKeyPress: _this.handleCardNumberKeyPress
})
}),
React__default.createElement(
'label',
{ style: styles.inputWrapperPsedoAfter },
'9999 9999 9999 9999 9999'
)
)
),
React__default.createElement(
'div',
{
className: fieldClassName,
style: Object.assign({ margin: '10px 0 0 0' }, styles.fieldWrapper, fieldStyle, (!!errors.cardExpiry || !!errors.cardCVV || setFieldInvalid) && invalidStyle)
},
React__default.createElement(
'label',
{
style: Object.assign({}, styles.inputWrapper, inputStyle),
className: 'card-expiry-wrapper',
'data-max': 'MM / YY 9'
},
cardExpiryInputRenderer({
handleCardExpiryChange: function handleCardExpiryChange(onChange) {
return _this.handleCardExpiryChange({ onChange: onChange });
},
handleCardExpiryBlur: function handleCardExpiryBlur(onBlur) {
return _this.handleCardExpiryBlur({ onBlur: onBlur });
},
handleCardExpiryFocus: function handleCardExpiryFocus(onFocus) {
return _this.handleCardExpiryFocus({ onFocus: onFocus });
},
props: _extends({
id: 'card-expiry',
ref: function ref(cardExpiryField) {
_this.cardExpiryField = cardExpiryField;
},
autoComplete: 'cc-exp',
className: 'credit-card-input ' + inputClassName,
placeholder: customTextLabels.expiryPlaceholder || 'MM/YY',
type: 'tel'
}, cardExpiryInputProps, {
onBlur: _this.handleCardExpiryBlur(),
onFocus: _this.handleCardExpiryFocus(),
onChange: _this.handleCardExpiryChange(),
onKeyDown: _this.handleKeyDown(_this.cardNumberField),
onKeyPress: _this.handleCardExpiryKeyPress
})
}),
React__default.createElement(
'label',
{ style: styles.inputWrapperPsedoAfter },
'MM / YY 9'
)
),
React__default.createElement(
'label',
{
style: Object.assign({}, styles.inputWrapper, inputStyle),
className: 'card-cvc-wrapper',
'data-max': '99999'
},
cardCVCInputRenderer({
handleCardCVCChange: function handleCardCVCChange(onChange) {
return _this.handleCardCVCChange({ onChange: onChange });
},
handleCardCVCBlur: function handleCardCVCBlur(onBlur) {
return _this.handleCardCVCBlur({ onBlur: onBlur });
},
handleCardCVCFocus: function handleCardCVCFocus(onFocus) {
return _this.handleCardCVCFocus({ onFocus: onFocus });
},
props: _extends({
id: 'cvc',
ref: function ref(cvcField) {
_this.cvcField = cvcField;
},
maxLength: '5',
autoComplete: 'off',
className: 'credit-card-input ' + inputClassName,
placeholder: customTextLabels.cvcPlaceholder || 'CVV',
type: 'tel'
}, cardCVVInputProps, {
onBlur: _this.handleCardCVCBlur(),
onFocus: _this.handleCardCVCFocus(),
onChange: _this.handleCardCVCChange(),
onKeyDown: _this.handleKeyDown(_this.cardExpiryField),
onKeyPress: _this.handleCardCVCKeyPress
})
}),
React__default.createElement(
'label',
{ style: styles.inputWrapperPsedoAfter },
'99999'
)
)
),
(!!errors.cardNumber || !!errors.cardExpiry || !!errors.cardCVV || errorText) && React__default.createElement(
'p',
{
className: dangerTextClassName,
style: Object.assign({}, styles.dangerText, dangerTextStyle)
},
errors.cardNumber || errors.cardExpiry || errors.cardCVV || errorText
)
);
};
_this.cardExpiryField = null;
_this.cardNumberField = null;
_this.cvcField = null;
_this.state = {
cardImage: images.placeholder,
cardNumberLength: 0,
cardNumber: null,
errorText: null,
errors: {}
};
return _this;
}
return CreditCardInput;
}(React.Component);
CreditCardInput.defaultProps = {
cardCVCInputRenderer: inputRenderer,
cardExpiryInputRenderer: inputRenderer,
cardNumberInputRenderer: inputRenderer,
cardExpiryInputProps: {},
cardNumberInputProps: {},
cardCVVInputProps: {},
cardImageClassName: '',
cardImageStyle: {},
containerClassName: '',
containerStyle: {},
dangerTextClassName: '',
dangerTextStyle: {},
fieldClassName: '',
fieldStyle: {},
inputComponent: 'input',
inputClassName: '',
inputStyle: {},
invalidStyle: {
border: '1px solid #ff3860'
},
customTextLabels: {}
};
return CreditCardInput;
})));