UNPKG

@quantfive/react-verification-code-input

Version:

🎉A verification code input

385 lines (340 loc) • 12.6 kB
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