@onefifteen-z/react-input-otp
Version:
A fully flexible one-time password input component for ReactJS.
299 lines (254 loc) • 9.64 kB
JavaScript
;
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
var React = require('react');
var React__default = _interopDefault(React);
var PropTypes = _interopDefault(require('prop-types'));
var KEY = {
backspace: 8,
left: 37,
right: 39
};
function styleInject(css, ref) {
if ( ref === void 0 ) ref = {};
var insertAt = ref.insertAt;
if (!css || typeof document === 'undefined') { return; }
var head = document.head || document.getElementsByTagName('head')[0];
var style = document.createElement('style');
style.type = 'text/css';
if (insertAt === 'top') {
if (head.firstChild) {
head.insertBefore(style, head.firstChild);
} else {
head.appendChild(style);
}
} else {
head.appendChild(style);
}
if (style.styleSheet) {
style.styleSheet.cssText = css;
} else {
style.appendChild(document.createTextNode(css));
}
}
var css = ".styles_otpWrapper__ZaQlv {\n display: flex;\n}\n\n.styles_otpInputWrapper__DkICY {\n height: 48px;\n max-width: 40px;\n min-width: 40px;\n margin-right: 8px;\n}\n\n.styles_otpInput__2umfM {\n width: 100%;\n height: inherit;\n\n border: 1px solid;\n border-radius: 10%;\n border-color: #cdcdcd;\n outline: none;\n\n font-size: 2rem;\n text-align: center;\n color: #4a4a4a;\n padding: 0 1px;\n}\n\n.styles_otpInput__2umfM:focus {\n border-color: #20c4f4;\n}\n\n.styles_otpInput__2umfM:disabled {\n background-color: #eee;\n cursor: not-allowed;\n}\n\n.styles_error__2Hacn > .styles_otpInput__2umfM, .styles_error__2Hacn > .styles_otpInput__2umfM:focus {\n border-color: #d0021b;\n}\n\n.styles_errorMessage__1sjan {\n margin: 8px 0 0 0;\n color: #d0021b;\n font-size: 0.8rem;\n}\n";
var styles = { "otpWrapper": "styles_otpWrapper__ZaQlv", "otpInputWrapper": "styles_otpInputWrapper__DkICY", "otpInput": "styles_otpInput__2umfM", "error": "styles_error__2Hacn", "errorMessage": "styles_errorMessage__1sjan" };
styleInject(css);
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 _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 objectWithoutProperties = function (obj, keys) {
var target = {};
for (var i in obj) {
if (keys.indexOf(i) >= 0) continue;
if (!Object.prototype.hasOwnProperty.call(obj, i)) continue;
target[i] = obj[i];
}
return target;
};
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 toConsumableArray = function (arr) {
if (Array.isArray(arr)) {
for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
return arr2;
} else {
return Array.from(arr);
}
};
var InputOTP = function (_Component) {
inherits(InputOTP, _Component);
function InputOTP(props) {
classCallCheck(this, InputOTP);
var _this = possibleConstructorReturn(this, (InputOTP.__proto__ || Object.getPrototypeOf(InputOTP)).call(this, props));
_this.doms = [];
return _this;
}
createClass(InputOTP, [{
key: 'componentDidMount',
value: function componentDidMount() {
var autoFocus = this.props.autoFocus;
if (autoFocus) this.doms[0].focus();
}
}, {
key: 'render',
value: function render() {
var _this2 = this;
var _props = this.props,
otpLength = _props.otpLength,
numberOnly = _props.numberOnly,
type = _props.type,
pattern = _props.pattern,
disabled = _props.disabled,
error = _props.error,
errorMessage = _props.errorMessage,
onChange = _props.onChange,
autoFocus = _props.autoFocus,
value = _props.value,
wrapperClass = _props.wrapperClass,
inputWrapperClass = _props.inputWrapperClass,
inputClass = _props.inputClass,
errorMessageClass = _props.errorMessageClass,
rest = objectWithoutProperties(_props, ['otpLength', 'numberOnly', 'type', 'pattern', 'disabled', 'error', 'errorMessage', 'onChange', 'autoFocus', 'value', 'wrapperClass', 'inputWrapperClass', 'inputClass', 'errorMessageClass']);
var inputFilter = pattern || (numberOnly ? /[^0-9]/gi : /[^0-9a-zA-Z]/gi);
var focusOn = function focusOn(i) {
if (_this2.doms[i]) _this2.doms[i].focus();
};
var handleChange = function handleChange(e, i) {
e.target.value = e.target.value.replace(inputFilter, '');
if (e.target.value.length > 1) e.target.value = e.target.value.slice(0, 1);
if (e.target.value !== '') focusOn(i + 1);
var otpCode = _this2.doms.map(function (d) {
return d.value;
}).join('');
onChange(otpCode);
};
var handleKeyDown = function handleKeyDown(e, i) {
if (e.keyCode === KEY.backspace && e.target.value === '') focusOn(i - 1);
if (e.keyCode === KEY.left) focusOn(i - 1);
if (e.keyCode === KEY.right) focusOn(i + 1);
};
var handlePaste = function handlePaste(e, i) {
var pastedString = e.clipboardData.getData('text/plain').replace(inputFilter, '').slice(0, otpLength - i);
var pastedData = pastedString.split('');
_this2.doms[otpLength - 1].focus();
for (var pos = i; pos < otpLength; pos += 1) {
_this2.doms[pos].value = pastedData.shift();
}
var otpCode = _this2.doms.map(function (d) {
return d.value;
}).join('');
onChange(otpCode);
};
var codeBoxItems = [].concat(toConsumableArray(Array(otpLength).keys())).map(function (i) {
return React__default.createElement(
'div',
{
className: inputWrapperClass + ' ' + (error ? styles.error : ''),
key: i
},
React__default.createElement('input', _extends({
type: type,
autoComplete: 'false',
autoCorrect: 'off',
autoCapitalize: 'off',
spellCheck: 'false',
className: inputClass,
ref: function ref(dom) {
_this2.doms[i] = dom;
},
onFocus: function onFocus(e) {
return e.target.select();
},
onChange: function onChange(e) {
return handleChange(e, i);
},
onKeyDown: function onKeyDown(e) {
return handleKeyDown(e, i);
},
onPaste: function onPaste(e) {
return handlePaste(e, i);
},
disabled: disabled,
defaultValue: value && value[i]
}, rest))
);
});
return React__default.createElement(
'div',
null,
React__default.createElement(
'div',
{ className: wrapperClass },
codeBoxItems
),
error && errorMessage && React__default.createElement(
'p',
{ className: errorMessageClass },
errorMessage
)
);
}
}]);
return InputOTP;
}(React.Component);
InputOTP.propTypes = {
value: PropTypes.string,
otpLength: PropTypes.number,
type: PropTypes.string,
numberOnly: PropTypes.bool,
autoFocus: PropTypes.bool,
pattern: PropTypes.instanceOf(RegExp),
error: PropTypes.bool,
errorMessage: PropTypes.string,
disabled: PropTypes.bool,
onChange: PropTypes.func,
wrapperClass: PropTypes.string,
inputWrapperClass: PropTypes.string,
inputClass: PropTypes.string,
errorMessageClass: PropTypes.string
};
InputOTP.defaultProps = {
value: '',
otpLength: 6,
type: 'tel',
numberOnly: false,
autoFocus: false,
pattern: null,
disabled: false,
error: false,
errorMessage: null,
onChange: function onChange() {},
wrapperClass: styles.otpWrapper,
inputWrapperClass: styles.otpInputWrapper,
inputClass: styles.otpInput,
errorMessageClass: styles.errorMessage
};
module.exports = InputOTP;
//# sourceMappingURL=index.js.map