react-auth-code-input
Version:
One-time password (OTP) React input component, uncontrolled, zero dependencies, fully tested.
193 lines (166 loc) • 5.18 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 allowedCharactersValues = ['alpha', 'numeric', 'alphanumeric'];
var propsMap = {
alpha: {
type: 'text',
inputMode: 'text',
pattern: '[a-zA-Z]{1}'
},
alphanumeric: {
type: 'text',
inputMode: 'text',
pattern: '[a-zA-Z0-9]{1}'
},
numeric: {
type: 'tel',
inputMode: 'numeric',
pattern: '[0-9]{1}',
min: '0',
max: '9'
}
};
var AuthCode = React.forwardRef(function (_ref, ref) {
var _ref$allowedCharacter = _ref.allowedCharacters,
allowedCharacters = _ref$allowedCharacter === void 0 ? 'alphanumeric' : _ref$allowedCharacter,
ariaLabel = _ref.ariaLabel,
_ref$autoFocus = _ref.autoFocus,
autoFocus = _ref$autoFocus === void 0 ? true : _ref$autoFocus,
containerClassName = _ref.containerClassName,
disabled = _ref.disabled,
inputClassName = _ref.inputClassName,
_ref$isPassword = _ref.isPassword,
isPassword = _ref$isPassword === void 0 ? false : _ref$isPassword,
_ref$length = _ref.length,
length = _ref$length === void 0 ? 6 : _ref$length,
placeholder = _ref.placeholder,
onChange = _ref.onChange;
if (isNaN(length) || length < 1) {
throw new Error('Length should be a number and greater than 0');
}
if (!allowedCharactersValues.some(function (value) {
return value === allowedCharacters;
})) {
throw new Error('Invalid value for allowedCharacters. Use alpha, numeric, or alphanumeric');
}
var inputsRef = React.useRef([]);
var inputProps = propsMap[allowedCharacters];
React.useImperativeHandle(ref, function () {
return {
focus: function focus() {
if (inputsRef.current) {
inputsRef.current[0].focus();
}
},
clear: function clear() {
if (inputsRef.current) {
for (var i = 0; i < inputsRef.current.length; i++) {
inputsRef.current[i].value = '';
}
inputsRef.current[0].focus();
}
sendResult();
}
};
});
React.useEffect(function () {
if (autoFocus) {
inputsRef.current[0].focus();
}
}, []);
var sendResult = function sendResult() {
var res = inputsRef.current.map(function (input) {
return input.value;
}).join('');
onChange && onChange(res);
};
var handleOnChange = function handleOnChange(e) {
var _e$target = e.target,
value = _e$target.value,
nextElementSibling = _e$target.nextElementSibling;
if (value.length > 1) {
e.target.value = value.charAt(0);
if (nextElementSibling !== null) {
nextElementSibling.focus();
}
} else {
if (value.match(inputProps.pattern)) {
if (nextElementSibling !== null) {
nextElementSibling.focus();
}
} else {
e.target.value = '';
}
}
sendResult();
};
var handleOnKeyDown = function handleOnKeyDown(e) {
var key = e.key;
var target = e.target;
if (key === 'Backspace') {
if (target.value === '') {
if (target.previousElementSibling !== null) {
var t = target.previousElementSibling;
t.value = '';
t.focus();
e.preventDefault();
}
} else {
target.value = '';
}
sendResult();
}
};
var handleOnFocus = function handleOnFocus(e) {
e.target.select();
};
var handleOnPaste = function handleOnPaste(e) {
var pastedValue = e.clipboardData.getData('Text');
var currentInput = 0;
for (var i = 0; i < pastedValue.length; i++) {
var pastedCharacter = pastedValue.charAt(i);
var currentValue = inputsRef.current[currentInput].value;
if (pastedCharacter.match(inputProps.pattern)) {
if (!currentValue) {
inputsRef.current[currentInput].value = pastedCharacter;
if (inputsRef.current[currentInput].nextElementSibling !== null) {
inputsRef.current[currentInput].nextElementSibling.focus();
currentInput++;
}
}
}
}
sendResult();
e.preventDefault();
};
var inputs = [];
var _loop = function _loop(i) {
inputs.push(React__default.createElement("input", Object.assign({
key: i,
onChange: handleOnChange,
onKeyDown: handleOnKeyDown,
onFocus: handleOnFocus,
onPaste: handleOnPaste
}, inputProps, {
type: isPassword ? 'password' : inputProps.type,
ref: function ref(el) {
inputsRef.current[i] = el;
},
maxLength: 1,
className: inputClassName,
autoComplete: i === 0 ? 'one-time-code' : 'off',
"aria-label": ariaLabel ? ariaLabel + ". Character " + (i + 1) + "." : "Character " + (i + 1) + ".",
disabled: disabled,
placeholder: placeholder
})));
};
for (var i = 0; i < length; i++) {
_loop(i);
}
return React__default.createElement("div", {
className: containerClassName
}, inputs);
});
module.exports = AuthCode;
//# sourceMappingURL=index.js.map