react-credit-card-primitives
Version:
React primitives for building credit card components
221 lines (186 loc) • 8.46 kB
JavaScript
;
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 _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; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(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; }
function _inherits(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 React = require('react');
var PropTypes = require('prop-types');
var creditcards = require('creditcards');
var _require = require('./util'),
callAll = _require.callAll,
INPUT_TYPE = _require.INPUT_TYPE;
var MM_YY = /^\D*(\d{1,2})(\D+)?(\d{1,4})?/;
var NAME = 'cc-exp';
var AUTOCOMPLETE = 'exp-date';
var SEPARATOR = ' / ';
var pad = function pad(n) {
return n < 10 ? '0' + n : String(n);
};
var ExpirationPrimitive = function (_React$Component) {
_inherits(ExpirationPrimitive, _React$Component);
function ExpirationPrimitive(props) {
_classCallCheck(this, ExpirationPrimitive);
var _this = _possibleConstructorReturn(this, (ExpirationPrimitive.__proto__ || Object.getPrototypeOf(ExpirationPrimitive)).call(this, props));
_initialiseProps.call(_this);
_this.state = {
month: _this.props.defaultMonth,
year: _this.props.defaultYear
};
if (_this.state.month || _this.state.year) {
_this.state.rawValue = _this.formatExpiration(_this.state);
}
return _this;
}
_createClass(ExpirationPrimitive, [{
key: 'isControlled',
value: function isControlled() {
return this.props.month !== undefined && this.props.year !== undefined;
}
}, {
key: 'getExpiration',
value: function getExpiration() {
var expiration = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var key = this.isControlled() ? 'props' : 'state';
return {
month: expiration.month !== undefined ? expiration.month : this[key].month,
year: expiration.year !== undefined ? expiration.year : this[key].year
};
}
}, {
key: 'isValid',
value: function isValid(expiration) {
return !this.getError(expiration);
}
}, {
key: 'getError',
value: function getError(expiration) {
var _getExpiration = this.getExpiration(expiration),
month = _getExpiration.month,
year = _getExpiration.year;
var monthValid = this.props.creditcards.expiration.month.isValid(month);
var yearValid = this.props.creditcards.expiration.year.isValid(year);
if (!monthValid && !yearValid) return ExpirationPrimitive.ERROR_MONTH_YEAR;
if (!monthValid) return ExpirationPrimitive.ERROR_MONTH;
if (!yearValid) return ExpirationPrimitive.ERROR_YEAR;
if (this.props.creditcards.expiration.isPast(month, year)) return ExpirationPrimitive.ERROR_PAST_DATE;
}
}, {
key: 'getStateAndHelpers',
value: function getStateAndHelpers() {
var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
return _extends({}, this.getExpiration(props), {
rawValue: this.state.rawValue,
error: this.getError(props),
valid: this.isValid(props),
setRawValue: this.setRawValue,
getInputProps: this.getInputProps
});
}
}, {
key: 'render',
value: function render() {
return this.props.render(this.getStateAndHelpers());
}
}, {
key: 'parseInput',
value: function parseInput(raw) {
var parts = raw.match(MM_YY);
if (!parts) return { month: undefined, year: undefined };
var rawMonth = parts[1];
var rawYear = parts[3];
return {
month: this.props.creditcards.expiration.month.parse(rawMonth),
year: !rawYear || rawYear.length % 2 ? undefined : this.props.creditcards.expiration.year.parse(rawYear, rawYear.length < 4)
};
}
}, {
key: 'formatExpiration',
value: function formatExpiration() {
var expiration = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
if (!expiration.month || !expiration.year) return;
return [pad(expiration.month), expiration.year >= 2000 && expiration.year <= 2100 ? String(expiration.year).substring(2) : expiration.year].join(SEPARATOR);
}
}, {
key: 'formatRawValue',
value: function formatRawValue(raw) {
if (!raw) return '';
var parts = raw.match(MM_YY);
if (!parts) return '';
var month = parts[1] || '';
var separator = parts[2] || '';
var year = parts[3] || '';
if (year.length > 0) {
separator = SEPARATOR;
} else if (separator === ' /') {
month = month.substring(0, 1);
separator = '';
} else if (month.length === 2 || separator) {
separator = SEPARATOR;
} else if (month.length === 1 && month !== '0' && month !== '1') {
month = '0' + month;
separator = ' / ';
}
return [month, separator, year].join('');
}
}]);
return ExpirationPrimitive;
}(React.Component);
ExpirationPrimitive.propTypes = {
month: PropTypes.number,
year: PropTypes.number,
defaultMonth: PropTypes.number,
defaultYear: PropTypes.number,
onChange: PropTypes.func,
render: PropTypes.func.isRequired,
creditcards: PropTypes.object.isRequired
};
ExpirationPrimitive.defaultProps = {
onChange: function onChange() {},
creditcards: creditcards
};
ExpirationPrimitive.ERROR_MONTH_YEAR = 'err_monthyear';
ExpirationPrimitive.ERROR_MONTH = 'err_month';
ExpirationPrimitive.ERROR_YEAR = 'err_year';
ExpirationPrimitive.ERROR_PAST_DATE = 'err_pastdate';
var _initialiseProps = function _initialiseProps() {
var _this2 = this;
this.handleChange = function (ev) {
_this2.setRawValue(ev.target.value);
};
this.setRawValue = function (rawValue) {
if (_this2.isControlled()) {
_this2.setState({ rawValue: rawValue }, function () {
_this2.props.onChange(_this2.getStateAndHelpers(_this2.parseInput(_this2.state.rawValue)));
});
} else {
_this2.setState(_extends({
rawValue: rawValue
}, _this2.parseInput(rawValue)), function () {
_this2.props.onChange(_this2.getStateAndHelpers());
});
}
};
this.getInputProps = function () {
var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var value = _this2.getExpiration(props);
return _extends({
'aria-invalid': value.month || value.year ? String(!_this2.isValid(props.value)) : undefined,
name: NAME,
autoComplete: AUTOCOMPLETE,
type: INPUT_TYPE,
placeholder: 'MM' + SEPARATOR + 'YY',
maxLength: 2 + SEPARATOR.length + 4
}, props, {
onChange: callAll(props.onChange, _this2.handleChange),
value: _this2.formatExpiration(_this2.getExpiration(props)) || _this2.formatRawValue(_this2.state.rawValue)
});
};
this.getLabelProps = function () {
var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
return _extends({}, props, {
htmlFor: NAME
});
};
};
module.exports = exports.default = ExpirationPrimitive;