DocSpace-client/packages/components/code-input/index.js

111 lines
2.8 KiB
JavaScript
Raw Normal View History

2022-02-02 21:57:47 +00:00
import React, { useRef, useEffect } from "react";
import PropTypes from "prop-types";
import InputWrapper from "./styled-code-input";
const CodeInput = (props) => {
const { onSubmit, handleChange, isDisabled } = props;
2022-02-02 21:57:47 +00:00
const inputsRef = useRef([]);
const characters = 6;
const allowed = "^[A-Za-z0-9]*$";
2022-02-02 21:57:47 +00:00
useEffect(() => {
inputsRef.current[0].focus();
}, []);
const onEnter = () => {
const code = inputsRef.current.map((input) => input.value).join("");
if (code.length === characters) {
onSubmit && onSubmit(code);
}
};
const handleOnChange = (e) => {
if (e.target.value.match(allowed)) {
handleChange();
2022-02-02 21:57:47 +00:00
if (e.target.nextElementSibling !== null) {
2022-02-03 11:23:20 +00:00
if (e.target.nextElementSibling.nodeName === "HR") {
e.target.nextElementSibling.nextElementSibling.focus();
}
2022-02-02 21:57:47 +00:00
e.target.nextElementSibling.focus();
}
} else {
e.target.value = "";
}
onEnter();
2022-02-02 21:57:47 +00:00
};
const handleOnKeyDown = (e) => {
const { key } = e;
const target = e.target;
if (key === "Backspace") {
2022-02-03 13:10:03 +00:00
handleChange();
2022-02-02 21:57:47 +00:00
if (target.value === "" && target.previousElementSibling !== null) {
if (target.previousElementSibling !== null) {
2022-02-03 11:23:20 +00:00
if (e.target.previousElementSibling.nodeName === "HR") {
e.target.previousElementSibling.previousElementSibling.focus();
}
2022-02-02 21:57:47 +00:00
target.previousElementSibling.focus();
e.preventDefault();
}
} else {
target.value = "";
}
}
};
const handleOnFocus = (e) => {
e.target.select();
};
const handleOnPaste = (e) => {
const value = e.clipboardData.getData("Text");
if (value.match(allowed)) {
for (let i = 0; i < characters && i < value.length; i++) {
inputsRef.current[i].value = value.charAt(i);
if (inputsRef.current[i].nextElementSibling !== null) {
inputsRef.current[i].nextElementSibling.focus();
}
}
}
onEnter();
2022-02-02 21:57:47 +00:00
e.preventDefault();
};
const elements = [];
for (let i = 0; i < characters; i++) {
2022-02-07 04:57:49 +00:00
if (i === 3) elements.push(<hr key="InputCode-line" />);
2022-02-02 21:57:47 +00:00
elements.push(
2022-02-07 04:57:49 +00:00
<input
key={`InputCode-${i}`}
onChange={handleOnChange}
onKeyDown={handleOnKeyDown}
onFocus={handleOnFocus}
onPaste={handleOnPaste}
ref={(el) => (inputsRef.current[i] = el)}
maxLength={1}
disabled={isDisabled}
/>
2022-02-02 21:57:47 +00:00
);
}
return <InputWrapper {...props}>{elements}</InputWrapper>;
};
CodeInput.propTypes = {
onSubmit: PropTypes.func.isRequired,
handleChange: PropTypes.func,
2022-02-03 11:08:45 +00:00
isDisabled: PropTypes.bool,
2022-02-02 21:57:47 +00:00
className: PropTypes.string,
id: PropTypes.string,
style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
};
2022-02-03 11:08:45 +00:00
CodeInput.defaultProps = {
isDisabled: false,
};
2022-02-02 21:57:47 +00:00
export default CodeInput;