From f5cea6d1a7950066ed3f2726af60d49efa47a3b6 Mon Sep 17 00:00:00 2001 From: Surykant das Date: Sun, 3 Nov 2024 01:55:59 +0530 Subject: [PATCH 1/2] fixed: Backspace,Added Copy-Paste, and Tab Functionality; disable button when OTP is filled --- src/App.jsx | 16 +++-- src/components/Buttons.jsx | 24 +++---- src/components/Otp.jsx | 125 +++++++++++++++++++++++-------------- 3 files changed, 97 insertions(+), 68 deletions(-) diff --git a/src/App.jsx b/src/App.jsx index 77ef13a..8d47b93 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,15 +1,13 @@ - -import './App.css' -import { Otp } from './components/Otp' +import "./App.css"; +import { Button } from "./components/Buttons"; +import Otp from "./components/Otp"; function App() { - return ( -
-



- +
+
- ) + ); } -export default App +export default App; diff --git a/src/components/Buttons.jsx b/src/components/Buttons.jsx index 9de3a9a..8044c42 100644 --- a/src/components/Buttons.jsx +++ b/src/components/Buttons.jsx @@ -1,12 +1,14 @@ +export const Button = ({ disabled, children, onClick, variant }) => { + // clsx, cx -export const Button = ({ - disabled, - children, - onClick, - variant -}) => { - // clsx, cx - return - {children} - -} \ No newline at end of file + return ( +
+ {children} +
+ ); +}; diff --git a/src/components/Otp.jsx b/src/components/Otp.jsx index 25b8b85..4c53725 100644 --- a/src/components/Otp.jsx +++ b/src/components/Otp.jsx @@ -1,52 +1,81 @@ +import React, { useRef, useState } from "react"; import { Button } from "./Buttons"; -import { useRef, useState } from "react"; -// 1, 2, 3, 6, 10 -export function Otp({ number }) { - const ref = useRef(Array(number).fill(0)); +const Otp = ({ number }) => { + const inputsRef = useRef([]); + const [disable, setDisable] = useState(false); + const [inputValue, setInputValue] = useState(Array(number).fill("")); + const handleChange = (e, index) => { + const { value } = e.target; - const [disabled, setDisabled] = useState(true); + if (!/^[0-9]$/.test(value) && value) { + return; + } + const newValue = [...inputValue]; + newValue[index] = value; + setInputValue(newValue); + if (value && index < number - 1) { + inputsRef.current[index + 1].focus(); + } + setDisable(newValue.every((val) => val !== "")); + }; + const handleBackspace = (e, index) => { + if (e.key === "Tab") { + e.preventDefault(); + return; + } + if (e.key === "Backspace" && index > 0 && !e.target.value) { + inputsRef.current[index - 1].focus(); + } + setDisable(inputValue.every((val) => val !== "")); + }; + const handleCopyPaste = (e, index) => { + e.preventDefault(); + const copiedOtp = e.clipboardData.getData("text"); + if (!/^[0-9]+$/.test(copiedOtp)) { + return; + } + const newValue = [...inputValue]; + let idx = 0; + for (let eachNumber of copiedOtp) { + const targetIndex = index + idx; + if (targetIndex < number) { + newValue[targetIndex] = eachNumber; + setInputValue(newValue); + idx++; + if (targetIndex < number - 1) { + inputsRef.current[targetIndex + 1].focus(); + setDisable(true); + } + } + } + setDisable(newValue.every((val) => val !== "")); + }; + return ( + <> +
+ {Array(number) + .fill(0) + .map((item, index) => ( + { + inputsRef.current[index] = each; + }} + type="text" + maxLength={1} + value={inputValue[index]} + className="w-[40px] h-[50px] rounded-md outline-none text-white text-center bg-slate-600 text-2xl focus:outline-none font-extrabold focus:ring-2 focus:ring-blue-500" + key={index} + onChange={(e) => handleChange(e, index)} + onKeyDown={(e) => handleBackspace(e, index)} + onPaste={(e) => handleCopyPaste(e, index)} + pattern="[0-9]*" + /> + ))} +
+ + + ); +}; - return
- - {Array(number).fill(1).map((x, index) => ref.current[index] = e} key={index} onDone={() => { - console.log(ref) - console.log(index) - if (index + 1 >= number) { - return - } - ref.current[index + 1].focus(); - }} goBack={() => { - if (index == 0) { - return - } - ref.current[index - 1].focus(); - }} />)} - -
- -
-} - -function SubOtpBox({ - reference, onDone, goBack -}) { - const [inputBoxVal, setInputBoxVal] = useState(""); - - return
- { - if (e.key == "Backspace") { - goBack() - } - }} onChange={(e) => { - const val = e.target.value - - if (val == "1" || val == "2" || val == "3" || val == "4" || val == "5" || val == "6" || val == "7" || val == "8" || val == "9") { - setInputBoxVal(val); - onDone() - } else { - - } - }} type="text" className="m-1 w-[40px] h-[50px] rounded-xl bg-blue-500 outline-none px-4 text-white"> -
-} \ No newline at end of file +export default Otp; From ff569445685701a0da8857f17fe3a6a5a597dee3 Mon Sep 17 00:00:00 2001 From: Surykant das Date: Sun, 3 Nov 2024 01:56:41 +0530 Subject: [PATCH 2/2] fixed: Backspace,Added Copy-Paste, and Tab Functionality; disable button when OTP is filled --- src/App.jsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/App.jsx b/src/App.jsx index 8d47b93..6228a3a 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,5 +1,4 @@ import "./App.css"; -import { Button } from "./components/Buttons"; import Otp from "./components/Otp"; function App() {