@quantfive/react-verification-code-input
Version:
🎉A verification code input
385 lines (340 loc) • 12.6 kB
JavaScript
import React, { Component } from 'react';
import PropTypes from 'prop-types';
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 = "/* add css styles here (optional) */\n\n.styles_react-code-input-container__tpiKG {\n position: relative;\n}\n\n.styles_react-code-input__CRulA > input {\n border: solid 1px #a8adb7;\n border-right: none;\n font-family: 'Lato';\n font-size: 20px;\n color: #525461;\n text-align: center;\n box-sizing: border-box;\n border-radius: 0;\n -webkit-appearance: initial;\n}\n\n.styles_react-code-input__CRulA > input:last-child {\n border-right: solid 1px #a8adb7;\n border-top-right-radius: 6px;\n border-bottom-right-radius: 6px;\n}\n\n.styles_react-code-input__CRulA > input:first-child {\n border-top-left-radius: 6px;\n border-bottom-left-radius: 6px;\n}\n\n.styles_react-code-input__CRulA > input:focus {\n outline: none;\n border: 1px solid #006fff;\n caret-color: #006fff;\n}\n\n.styles_react-code-input__CRulA > input:focus + input {\n border-left: none;\n}\n\n.styles_loading__Z65VQ {\n position: absolute;\n left: 0;\n right: 0;\n bottom: 0;\n text-align: center;\n}\n\n.styles_blur__19vMK {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background-color: #fff;\n opacity: 0.5;\n filter: blur(0.5px);\n transition: opacity 0.3s;\n}\n\n.styles_title__1cca0 {\n margin: 0;\n height: 20px;\n padding-bottom: 10px;\n}\n\n.styles_spin__6y_8G {\n display: inline-block;\n animation: styles_loadingCircle__293ky 1s infinite linear;\n}\n\n@keyframes styles_loadingCircle__293ky {\n 100% {\n transform: rotate(360deg);\n }\n}\n";
var styles = { "react-code-input-container": "styles_react-code-input-container__tpiKG", "react-code-input": "styles_react-code-input__CRulA", "loading": "styles_loading__Z65VQ", "blur": "styles_blur__19vMK", "title": "styles_title__1cca0", "spin": "styles_spin__6y_8G", "loadingCircle": "styles_loadingCircle__293ky" };
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 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 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 KEY_CODE = {
backspace: 8,
left: 37,
up: 38,
right: 39,
down: 40
};
var ReactCodeInput = function (_Component) {
inherits(ReactCodeInput, _Component);
function ReactCodeInput(props) {
classCallCheck(this, ReactCodeInput);
var _this = possibleConstructorReturn(this, (ReactCodeInput.__proto__ || Object.getPrototypeOf(ReactCodeInput)).call(this, props));
_initialiseProps.call(_this);
var fields = props.fields,
values = props.values;
var vals = void 0;
var autoFocusIndex = 0;
if (values && values.length) {
vals = [];
for (var i = 0; i < fields; i++) {
vals.push(values[i] || '');
}
autoFocusIndex = values.length >= fields ? 0 : values.length;
} else {
vals = Array(fields).fill('');
}
_this.state = { values: vals, autoFocusIndex: autoFocusIndex };
_this.iRefs = [];
for (var _i = 0; _i < fields; _i++) {
_this.iRefs.push(React.createRef());
}
_this.id = +new Date();
// this.handleKeys = Array(fields).fill(false);
return _this;
}
/**
* Clear all field value & focus first field
*/
// onKeyUp = e => {
// const index = parseInt(e.target.dataset.id);
// if (this.handleKeys[index]) {
// this.handleKeys[index] = false;
// const next = this.iRefs[index + 1];
// if (next) {
// next.current.focus();
// }
// }
// };
createClass(ReactCodeInput, [{
key: 'render',
value: function render() {
var _this2 = this;
var _state = this.state,
values = _state.values,
autoFocusIndex = _state.autoFocusIndex;
var _props = this.props,
loading = _props.loading,
title = _props.title,
fieldHeight = _props.fieldHeight,
fieldWidth = _props.fieldWidth,
fields = _props.fields,
autoFocus = _props.autoFocus,
className = _props.className,
type = _props.type;
var INPUT_STYLE = {
width: fieldWidth,
height: fieldHeight
};
var ROOT_STYLE = {
width: fields * fieldWidth
};
var LOADING_STYLE = {
lineHeight: fieldHeight + 'px'
};
return React.createElement(
'div',
{
className: styles['react-code-input-container'] + ' ' + className,
style: ROOT_STYLE
},
title && React.createElement(
'p',
{ className: styles['title'] },
title
),
React.createElement(
'div',
{ className: styles['react-code-input'] },
values.map(function (value, index) {
return React.createElement('input', {
type: type === 'number' ? 'tel' : type,
pattern: type === 'number' ? '[0-9]*' : null,
autoFocus: autoFocus && index === autoFocusIndex,
style: INPUT_STYLE,
key: _this2.id + '-' + index,
'data-id': index,
value: value,
ref: _this2.iRefs[index],
onChange: _this2.onChange,
onKeyDown: _this2.onKeyDown
// onKeyUp={this.onKeyUp}
, onFocus: _this2.onFocus,
autocomplete: _this2.props.autocomplete,
disabled: _this2.props.disabled,
required: _this2.props.required
});
})
),
loading && React.createElement(
'div',
{ className: styles['loading'], style: LOADING_STYLE },
React.createElement('div', { className: styles['blur'] }),
React.createElement(
'svg',
{
className: styles['spin'],
viewBox: '0 0 1024 1024',
'data-icon': 'loading',
width: '1em',
height: '1em',
fill: 'currentColor',
'aria-hidden': 'true'
},
React.createElement('path', {
fill: '#006fff',
d: 'M988 548c-19.9 0-36-16.1-36-36 0-59.4-11.6-117-34.6-171.3a440.45 440.45 0 0 0-94.3-139.9 437.71 437.71 0 0 0-139.9-94.3C629 83.6 571.4 72 512 72c-19.9 0-36-16.1-36-36s16.1-36 36-36c69.1 0 136.2 13.5 199.3 40.3C772.3 66 827 103 874 150c47 47 83.9 101.8 109.7 162.7 26.7 63.1 40.2 130.2 40.2 199.3.1 19.9-16 36-35.9 36z'
})
)
)
);
}
}]);
return ReactCodeInput;
}(Component);
ReactCodeInput.propTypes = {
type: PropTypes.oneOf(['text', 'number']),
onChange: PropTypes.func,
onComplete: PropTypes.func,
fields: PropTypes.number,
loading: PropTypes.bool,
title: PropTypes.string,
fieldWidth: PropTypes.number,
fieldHeight: PropTypes.number,
autoFocus: PropTypes.bool,
className: PropTypes.string,
values: PropTypes.arrayOf(PropTypes.string),
disabled: PropTypes.bool,
required: PropTypes.bool
};
ReactCodeInput.defaultProps = {
type: 'number',
fields: 6,
fieldWidth: 58,
fieldHeight: 54,
autoFocus: true,
disabled: false,
required: false
};
var _initialiseProps = function _initialiseProps() {
var _this3 = this;
this.__clearvalues__ = function () {
var fields = _this3.props.fields;
_this3.setState({ values: Array(fields).fill('') });
_this3.iRefs[0].current.focus();
};
this.triggerChange = function () {
var values = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _this3.state.values;
var _props2 = _this3.props,
onChange = _props2.onChange,
onComplete = _props2.onComplete,
fields = _props2.fields;
var val = values.join('');
onChange && onChange(val);
if (onComplete && val.length >= fields) {
onComplete(val);
}
};
this.onChange = function (e) {
var index = parseInt(e.target.dataset.id);
if (_this3.props.type === 'number') {
e.target.value = e.target.value.replace(/[^\d]/gi, '');
}
// this.handleKeys[index] = false;
if (e.target.value === '' || _this3.props.type === 'number' && !e.target.validity.valid) {
return;
}
var fields = _this3.props.fields;
var next = void 0;
var value = e.target.value;
var values = _this3.state.values;
values = Object.assign([], values);
if (value.length > 1) {
var nextIndex = value.length + index - 1;
if (nextIndex >= fields) {
nextIndex = fields - 1;
}
next = _this3.iRefs[nextIndex];
var split = value.split('');
split.forEach(function (item, i) {
var cursor = index + i;
if (cursor < fields) {
values[cursor] = item;
}
});
_this3.setState({ values: values });
} else {
next = _this3.iRefs[index + 1];
values[index] = value;
_this3.setState({ values: values });
}
if (next) {
next.current.focus();
next.current.select();
}
_this3.triggerChange(values);
};
this.onKeyDown = function (e) {
var index = parseInt(e.target.dataset.id);
var prevIndex = index - 1;
var nextIndex = index + 1;
var prev = _this3.iRefs[prevIndex];
var next = _this3.iRefs[nextIndex];
switch (e.keyCode) {
case KEY_CODE.backspace:
e.preventDefault();
var vals = [].concat(toConsumableArray(_this3.state.values));
if (_this3.state.values[index]) {
vals[index] = '';
_this3.setState({ values: vals });
_this3.triggerChange(vals);
} else if (prev) {
vals[prevIndex] = '';
prev.current.focus();
_this3.setState({ values: vals });
_this3.triggerChange(vals);
}
break;
case KEY_CODE.left:
e.preventDefault();
if (prev) {
prev.current.focus();
}
break;
case KEY_CODE.right:
e.preventDefault();
if (next) {
next.current.focus();
}
break;
case KEY_CODE.up:
case KEY_CODE.down:
e.preventDefault();
break;
default:
// this.handleKeys[index] = true;
break;
}
};
this.onFocus = function (e) {
e.target.select(e);
};
};
export default ReactCodeInput;
//# sourceMappingURL=index.es.js.map