UNPKG

@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
(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; })));