From 7b7c1f94abfd93a9e00ae35e7575eac7c770fd70 Mon Sep 17 00:00:00 2001 From: sai6855 Date: Thu, 11 Jan 2024 18:19:55 +0530 Subject: [PATCH 01/32] add demo --- docs/data/base/components/input/OTPInput.js | 163 ++++++++++++++++ docs/data/base/components/input/OTPInput.tsx | 175 ++++++++++++++++++ .../components/input/OTPInput.tsx.preview | 16 ++ docs/data/base/components/input/input.md | 6 + 4 files changed, 360 insertions(+) create mode 100644 docs/data/base/components/input/OTPInput.js create mode 100644 docs/data/base/components/input/OTPInput.tsx create mode 100644 docs/data/base/components/input/OTPInput.tsx.preview diff --git a/docs/data/base/components/input/OTPInput.js b/docs/data/base/components/input/OTPInput.js new file mode 100644 index 00000000000000..09664f6ac56e6b --- /dev/null +++ b/docs/data/base/components/input/OTPInput.js @@ -0,0 +1,163 @@ +import * as React from 'react'; +import { Input as BaseInput } from '@mui/base/Input'; +import { Box, styled } from '@mui/system'; + +const CustomNumberInput = React.forwardRef(function CustomNumberInput(props, ref) { + return ( + + ); +}); + +export default function OTPInput() { + const inputCount = 6; + const inputRefs = React.useRef(new Array(6).fill(null)); + const [otp, setOtp] = React.useState(new Array(inputCount).fill('')); + + const otpAsString = otp.join(''); + console.log(otpAsString); + + const focusInput = (targetIndex) => { + const targetInput = inputRefs.current[targetIndex]; + targetInput.focus(); + }; + + const selectInput = (targetIndex) => { + const targetInput = inputRefs.current[targetIndex]; + targetInput.select(); + }; + + const handleKeyDown = (event, currentIndex) => { + switch (event.key) { + case 'ArrowLeft': + if (currentIndex > 0) { + focusInput(currentIndex - 1); + selectInput(currentIndex - 1); + } + break; + case 'ArrowRight': + if (currentIndex < inputCount - 1) { + focusInput(currentIndex + 1); + selectInput(currentIndex + 1); + } + break; + case 'Backspace': + event.preventDefault(); + if (currentIndex > 0) { + focusInput(currentIndex - 1); + selectInput(currentIndex - 1); + } + + setOtp((prev) => { + const otpArray = [...prev]; + otpArray.splice(currentIndex, 1); + otpArray.push(''); + return otpArray; + }); + + break; + default: + break; + } + }; + + const handleChange = (event, currentIndex) => { + const value = event.target.value; + setOtp((prev) => { + const otpArray = [...prev]; + const lastValue = value[value.length - 1]; + otpArray[currentIndex] = lastValue; + return otpArray; + }); + if (value !== '') { + if (currentIndex < inputCount - 1) { + focusInput(currentIndex + 1); + } + } + }; + + const handleClick = (event, currentIndex) => { + selectInput(currentIndex); + }; + + return ( + + {new Array(inputCount).fill(null).map((_, index) => ( + { + inputRefs.current[index] = ele; + }, + onKeyDown: (event) => handleKeyDown(event, index), + onChange: (event) => handleChange(event, index), + onClick: (event) => handleClick(event, index), + value: otp[index], + }, + }} + /> + ))} + + ); +} + +const blue = { + 100: '#DAECFF', + 200: '#80BFFF', + 400: '#3399FF', + 500: '#007FFF', + 600: '#0072E5', + 700: '#0059B2', +}; + +const grey = { + 50: '#F3F6F9', + 100: '#E5EAF2', + 200: '#DAE2ED', + 300: '#C7D0DD', + 400: '#B0B8C4', + 500: '#9DA8B7', + 600: '#6B7A90', + 700: '#434D5B', + 800: '#303740', + 900: '#1C2025', +}; + +const InputElement = styled('input')( + ({ theme }) => ` + width: 15px; + font-family: 'IBM Plex Sans', sans-serif; + font-size: 0.875rem; + font-weight: 400; + line-height: 1.5; + padding: 8px 12px; + border-radius: 8px; + text-align: center; + color: ${theme.palette.mode === 'dark' ? grey[300] : grey[900]}; + background: ${theme.palette.mode === 'dark' ? grey[900] : '#fff'}; + border: 1px solid ${theme.palette.mode === 'dark' ? grey[700] : grey[200]}; + box-shadow: 0px 2px 4px ${ + theme.palette.mode === 'dark' ? 'rgba(0,0,0, 0.5)' : 'rgba(0,0,0, 0.05)' + }; + + &:hover { + border-color: ${blue[400]}; + } + + &:focus { + border-color: ${blue[400]}; + box-shadow: 0 0 0 3px ${theme.palette.mode === 'dark' ? blue[600] : blue[200]}; + } + + // firefox + &:focus-visible { + outline: 0; + } +`, +); diff --git a/docs/data/base/components/input/OTPInput.tsx b/docs/data/base/components/input/OTPInput.tsx new file mode 100644 index 00000000000000..a594aaffa1e72e --- /dev/null +++ b/docs/data/base/components/input/OTPInput.tsx @@ -0,0 +1,175 @@ +import * as React from 'react'; +import { Input as BaseInput, InputProps } from '@mui/base/Input'; +import { Box, styled } from '@mui/system'; + +const CustomNumberInput = React.forwardRef(function CustomNumberInput( + props: InputProps, + ref: React.ForwardedRef, +) { + return ( + + ); +}); + +export default function OTPInput() { + const inputCount = 6; + const inputRefs = React.useRef(new Array(6).fill(null)); + const [otp, setOtp] = React.useState(new Array(inputCount).fill('')); + + const otpAsString = otp.join(''); + console.log(otpAsString); + + const focusInput = (targetIndex: number) => { + const targetInput = inputRefs.current[targetIndex]; + targetInput.focus(); + }; + + const selectInput = (targetIndex: number) => { + const targetInput = inputRefs.current[targetIndex]; + targetInput.select(); + }; + + const handleKeyDown = ( + event: React.KeyboardEvent, + currentIndex: number, + ) => { + switch (event.key) { + case 'ArrowLeft': + if (currentIndex > 0) { + focusInput(currentIndex - 1); + selectInput(currentIndex - 1); + } + break; + case 'ArrowRight': + if (currentIndex < inputCount - 1) { + focusInput(currentIndex + 1); + selectInput(currentIndex + 1); + } + break; + case 'Backspace': + event.preventDefault(); + if (currentIndex > 0) { + focusInput(currentIndex - 1); + selectInput(currentIndex - 1); + } + + setOtp((prev) => { + const otpArray = [...prev]; + otpArray.splice(currentIndex, 1); + otpArray.push(''); + return otpArray; + }); + + break; + default: + break; + } + }; + + const handleChange = ( + event: React.ChangeEvent, + currentIndex: number, + ) => { + const value = event.target.value; + setOtp((prev) => { + const otpArray = [...prev]; + const lastValue = value[value.length - 1]; + otpArray[currentIndex] = lastValue; + return otpArray; + }); + if (value !== '') { + if (currentIndex < inputCount - 1) { + focusInput(currentIndex + 1); + } + } + }; + + const handleClick = ( + event: React.MouseEvent, + currentIndex: number, + ) => { + selectInput(currentIndex); + }; + + return ( + + {new Array(inputCount).fill(null).map((_, index) => ( + { + inputRefs.current[index] = ele!; + }, + onKeyDown: (event) => handleKeyDown(event, index), + onChange: (event) => handleChange(event, index), + onClick: (event) => handleClick(event, index), + value: otp[index], + }, + }} + /> + ))} + + ); +} + +const blue = { + 100: '#DAECFF', + 200: '#80BFFF', + 400: '#3399FF', + 500: '#007FFF', + 600: '#0072E5', + 700: '#0059B2', +}; + +const grey = { + 50: '#F3F6F9', + 100: '#E5EAF2', + 200: '#DAE2ED', + 300: '#C7D0DD', + 400: '#B0B8C4', + 500: '#9DA8B7', + 600: '#6B7A90', + 700: '#434D5B', + 800: '#303740', + 900: '#1C2025', +}; + +const InputElement = styled('input')( + ({ theme }) => ` + width: 15px; + font-family: 'IBM Plex Sans', sans-serif; + font-size: 0.875rem; + font-weight: 400; + line-height: 1.5; + padding: 8px 12px; + border-radius: 8px; + text-align: center; + color: ${theme.palette.mode === 'dark' ? grey[300] : grey[900]}; + background: ${theme.palette.mode === 'dark' ? grey[900] : '#fff'}; + border: 1px solid ${theme.palette.mode === 'dark' ? grey[700] : grey[200]}; + box-shadow: 0px 2px 4px ${ + theme.palette.mode === 'dark' ? 'rgba(0,0,0, 0.5)' : 'rgba(0,0,0, 0.05)' + }; + + &:hover { + border-color: ${blue[400]}; + } + + &:focus { + border-color: ${blue[400]}; + box-shadow: 0 0 0 3px ${theme.palette.mode === 'dark' ? blue[600] : blue[200]}; + } + + // firefox + &:focus-visible { + outline: 0; + } +`, +); diff --git a/docs/data/base/components/input/OTPInput.tsx.preview b/docs/data/base/components/input/OTPInput.tsx.preview new file mode 100644 index 00000000000000..d852c4364e5878 --- /dev/null +++ b/docs/data/base/components/input/OTPInput.tsx.preview @@ -0,0 +1,16 @@ +{new Array(inputCount).fill(null).map((_, index) => ( + { + inputRefs.current[index] = ele!; + }, + onKeyDown: (event) => handleKeyDown(event, index), + onChange: (event) => handleChange(event, index), + onClick: (event) => handleClick(event, index), + value: otp[index], + }, + }} + /> +))} \ No newline at end of file diff --git a/docs/data/base/components/input/input.md b/docs/data/base/components/input/input.md index 7a150f2fa67ebc..b2a33e1938fd82 100644 --- a/docs/data/base/components/input/input.md +++ b/docs/data/base/components/input/input.md @@ -134,3 +134,9 @@ To set minimum and maximum sizes, add the `minRows` and `maxRows` props. The following demo shows how to insert a Textarea Autosize component into an Input so that its height grows with the length of the content: {{"demo": "InputMultilineAutosize.js"}} + +## Common examples + +### OTP Input + +{{"demo": "OTPInput.js"}} From 919930a649468b44cec99e17e1ecb651b57d5800 Mon Sep 17 00:00:00 2001 From: sai6855 Date: Thu, 11 Jan 2024 19:56:49 +0530 Subject: [PATCH 02/32] Update width of OTPInput component --- docs/data/base/components/input/OTPInput.js | 2 +- docs/data/base/components/input/OTPInput.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/data/base/components/input/OTPInput.js b/docs/data/base/components/input/OTPInput.js index 09664f6ac56e6b..f95b5aaef31121 100644 --- a/docs/data/base/components/input/OTPInput.js +++ b/docs/data/base/components/input/OTPInput.js @@ -131,7 +131,7 @@ const grey = { const InputElement = styled('input')( ({ theme }) => ` - width: 15px; + width: 40px; font-family: 'IBM Plex Sans', sans-serif; font-size: 0.875rem; font-weight: 400; diff --git a/docs/data/base/components/input/OTPInput.tsx b/docs/data/base/components/input/OTPInput.tsx index a594aaffa1e72e..a07ef76002a3f3 100644 --- a/docs/data/base/components/input/OTPInput.tsx +++ b/docs/data/base/components/input/OTPInput.tsx @@ -143,7 +143,7 @@ const grey = { const InputElement = styled('input')( ({ theme }) => ` - width: 15px; + width: 40px; font-family: 'IBM Plex Sans', sans-serif; font-size: 0.875rem; font-weight: 400; From 6176f7c0d03cf76f15cb7f2128e477c1ca19395e Mon Sep 17 00:00:00 2001 From: sai6855 Date: Thu, 11 Jan 2024 19:58:29 +0530 Subject: [PATCH 03/32] Refactor OTPInput component to remove CustomNumberInput --- docs/data/base/components/input/OTPInput.js | 15 ++----------- docs/data/base/components/input/OTPInput.tsx | 22 +++++--------------- 2 files changed, 7 insertions(+), 30 deletions(-) diff --git a/docs/data/base/components/input/OTPInput.js b/docs/data/base/components/input/OTPInput.js index f95b5aaef31121..ba09ce850f927e 100644 --- a/docs/data/base/components/input/OTPInput.js +++ b/docs/data/base/components/input/OTPInput.js @@ -2,18 +2,6 @@ import * as React from 'react'; import { Input as BaseInput } from '@mui/base/Input'; import { Box, styled } from '@mui/system'; -const CustomNumberInput = React.forwardRef(function CustomNumberInput(props, ref) { - return ( - - ); -}); - export default function OTPInput() { const inputCount = 6; const inputRefs = React.useRef(new Array(6).fill(null)); @@ -88,8 +76,9 @@ export default function OTPInput() { return ( {new Array(inputCount).fill(null).map((_, index) => ( - { diff --git a/docs/data/base/components/input/OTPInput.tsx b/docs/data/base/components/input/OTPInput.tsx index a07ef76002a3f3..cdf64e62488ad9 100644 --- a/docs/data/base/components/input/OTPInput.tsx +++ b/docs/data/base/components/input/OTPInput.tsx @@ -1,22 +1,7 @@ import * as React from 'react'; -import { Input as BaseInput, InputProps } from '@mui/base/Input'; +import { Input as BaseInput } from '@mui/base/Input'; import { Box, styled } from '@mui/system'; -const CustomNumberInput = React.forwardRef(function CustomNumberInput( - props: InputProps, - ref: React.ForwardedRef, -) { - return ( - - ); -}); - export default function OTPInput() { const inputCount = 6; const inputRefs = React.useRef(new Array(6).fill(null)); @@ -100,7 +85,10 @@ export default function OTPInput() { return ( {new Array(inputCount).fill(null).map((_, index) => ( - Date: Fri, 12 Jan 2024 16:22:34 +0530 Subject: [PATCH 04/32] Fix arrow key navigation in OTPInput component --- docs/data/base/components/input/OTPInput.js | 14 +++++++++++++- docs/data/base/components/input/OTPInput.tsx | 2 ++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/docs/data/base/components/input/OTPInput.js b/docs/data/base/components/input/OTPInput.js index ba09ce850f927e..edf53cdd5777bb 100644 --- a/docs/data/base/components/input/OTPInput.js +++ b/docs/data/base/components/input/OTPInput.js @@ -24,12 +24,14 @@ export default function OTPInput() { switch (event.key) { case 'ArrowLeft': if (currentIndex > 0) { + event.preventDefault(); focusInput(currentIndex - 1); selectInput(currentIndex - 1); } break; case 'ArrowRight': if (currentIndex < inputCount - 1) { + event.preventDefault(); focusInput(currentIndex + 1); selectInput(currentIndex + 1); } @@ -59,7 +61,17 @@ export default function OTPInput() { setOtp((prev) => { const otpArray = [...prev]; const lastValue = value[value.length - 1]; - otpArray[currentIndex] = lastValue; + let indexToEnter = 0; + + while (indexToEnter <= currentIndex) { + if (prev[indexToEnter]) { + indexToEnter+=1; + } else { + break; + } + } + + otpArray[indexToEnter] = lastValue; return otpArray; }); if (value !== '') { diff --git a/docs/data/base/components/input/OTPInput.tsx b/docs/data/base/components/input/OTPInput.tsx index cdf64e62488ad9..8e8175e37b9195 100644 --- a/docs/data/base/components/input/OTPInput.tsx +++ b/docs/data/base/components/input/OTPInput.tsx @@ -27,12 +27,14 @@ export default function OTPInput() { switch (event.key) { case 'ArrowLeft': if (currentIndex > 0) { + event.preventDefault(); focusInput(currentIndex - 1); selectInput(currentIndex - 1); } break; case 'ArrowRight': if (currentIndex < inputCount - 1) { + event.preventDefault(); focusInput(currentIndex + 1); selectInput(currentIndex + 1); } From af79960b36a4a2554cb0a7321361c46953a8a531 Mon Sep 17 00:00:00 2001 From: sai6855 Date: Fri, 12 Jan 2024 16:36:55 +0530 Subject: [PATCH 05/32] Refactor OTPInput component to accept separator and inputCount as props --- docs/data/base/components/input/OTPInput.tsx | 66 +++++++++++++------- 1 file changed, 42 insertions(+), 24 deletions(-) diff --git a/docs/data/base/components/input/OTPInput.tsx b/docs/data/base/components/input/OTPInput.tsx index 8e8175e37b9195..3c02064f8b53ef 100644 --- a/docs/data/base/components/input/OTPInput.tsx +++ b/docs/data/base/components/input/OTPInput.tsx @@ -2,14 +2,16 @@ import * as React from 'react'; import { Input as BaseInput } from '@mui/base/Input'; import { Box, styled } from '@mui/system'; -export default function OTPInput() { - const inputCount = 6; +function OTP({ + seperator, + inputCount, +}: { + seperator: React.ReactNode; + inputCount: number; +}) { const inputRefs = React.useRef(new Array(6).fill(null)); const [otp, setOtp] = React.useState(new Array(inputCount).fill('')); - const otpAsString = otp.join(''); - console.log(otpAsString); - const focusInput = (targetIndex: number) => { const targetInput = inputRefs.current[targetIndex]; targetInput.focus(); @@ -64,10 +66,19 @@ export default function OTPInput() { currentIndex: number, ) => { const value = event.target.value; + let indexToEnter = 0; + + while (indexToEnter <= currentIndex) { + if (otp[indexToEnter] && indexToEnter < currentIndex) { + indexToEnter += 1; + } else { + break; + } + } setOtp((prev) => { const otpArray = [...prev]; const lastValue = value[value.length - 1]; - otpArray[currentIndex] = lastValue; + otpArray[indexToEnter] = lastValue; return otpArray; }); if (value !== '') { @@ -85,30 +96,37 @@ export default function OTPInput() { }; return ( - + {new Array(inputCount).fill(null).map((_, index) => ( - { - inputRefs.current[index] = ele!; + + { + inputRefs.current[index] = ele!; + }, + onKeyDown: (event) => handleKeyDown(event, index), + onChange: (event) => handleChange(event, index), + onClick: (event) => handleClick(event, index), + value: otp[index], }, - onKeyDown: (event) => handleKeyDown(event, index), - onChange: (event) => handleChange(event, index), - onClick: (event) => handleClick(event, index), - value: otp[index], - }, - }} - /> + }} + /> + {index === inputCount - 1 ? null : seperator} + ))} ); } +export default function OTPInput() { + return -} inputCount={6} />; +} + const blue = { 100: '#DAECFF', 200: '#80BFFF', @@ -143,7 +161,7 @@ const InputElement = styled('input')( text-align: center; color: ${theme.palette.mode === 'dark' ? grey[300] : grey[900]}; background: ${theme.palette.mode === 'dark' ? grey[900] : '#fff'}; - border: 1px solid ${theme.palette.mode === 'dark' ? grey[700] : grey[200]}; + border: 1px solid ${theme.palette.mode === 'dark' ? grey[700] : grey[400]}; box-shadow: 0px 2px 4px ${ theme.palette.mode === 'dark' ? 'rgba(0,0,0, 0.5)' : 'rgba(0,0,0, 0.05)' }; From 20cb6ca04a8a634cd1cea44baef29b576a1848ee Mon Sep 17 00:00:00 2001 From: sai6855 Date: Fri, 12 Jan 2024 16:43:42 +0530 Subject: [PATCH 06/32] Refactor OTPInput component styling --- docs/data/base/components/input/OTPInput.tsx | 57 ++++++++++---------- 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/docs/data/base/components/input/OTPInput.tsx b/docs/data/base/components/input/OTPInput.tsx index 3c02064f8b53ef..f3d9b8a674f9f4 100644 --- a/docs/data/base/components/input/OTPInput.tsx +++ b/docs/data/base/components/input/OTPInput.tsx @@ -95,36 +95,35 @@ function OTP({ selectInput(currentIndex); }; - return ( - - {new Array(inputCount).fill(null).map((_, index) => ( - - { - inputRefs.current[index] = ele!; - }, - onKeyDown: (event) => handleKeyDown(event, index), - onChange: (event) => handleChange(event, index), - onClick: (event) => handleClick(event, index), - value: otp[index], - }, - }} - /> - {index === inputCount - 1 ? null : seperator} - - ))} - - ); + return new Array(inputCount).fill(null).map((_, index) => ( + + { + inputRefs.current[index] = ele!; + }, + onKeyDown: (event) => handleKeyDown(event, index), + onChange: (event) => handleChange(event, index), + onClick: (event) => handleClick(event, index), + value: otp[index], + }, + }} + /> + {index === inputCount - 1 ? null : seperator} + + )); } export default function OTPInput() { - return -} inputCount={6} />; + return ( + + -} inputCount={6} /> + + ); } const blue = { @@ -156,12 +155,12 @@ const InputElement = styled('input')( font-size: 0.875rem; font-weight: 400; line-height: 1.5; - padding: 8px 12px; + padding: 8px 0px; border-radius: 8px; text-align: center; color: ${theme.palette.mode === 'dark' ? grey[300] : grey[900]}; background: ${theme.palette.mode === 'dark' ? grey[900] : '#fff'}; - border: 1px solid ${theme.palette.mode === 'dark' ? grey[700] : grey[400]}; + border: 1px solid ${theme.palette.mode === 'dark' ? grey[700] : grey[500]}; box-shadow: 0px 2px 4px ${ theme.palette.mode === 'dark' ? 'rgba(0,0,0, 0.5)' : 'rgba(0,0,0, 0.05)' }; From 095dbd16997b8aae19ea68018b74d315ef4c772c Mon Sep 17 00:00:00 2001 From: sai6855 Date: Fri, 12 Jan 2024 16:47:38 +0530 Subject: [PATCH 07/32] Add OTP Input demo to Input component --- docs/data/base/components/input/input.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/data/base/components/input/input.md b/docs/data/base/components/input/input.md index b2a33e1938fd82..e9679e705e46de 100644 --- a/docs/data/base/components/input/input.md +++ b/docs/data/base/components/input/input.md @@ -139,4 +139,6 @@ The following demo shows how to insert a Textarea Autosize component into an Inp ### OTP Input +The following demo shows how to build a one-time password component using `Input`. + {{"demo": "OTPInput.js"}} From 539657dfd010255e52d1c8502320f7dd1db6911a Mon Sep 17 00:00:00 2001 From: sai6855 Date: Fri, 12 Jan 2024 16:48:27 +0530 Subject: [PATCH 08/32] Refactor OTPInput component to use a reusable OTP component --- docs/data/base/components/input/OTPInput.js | 73 ++++++++++--------- .../components/input/OTPInput.tsx.preview | 17 +---- 2 files changed, 39 insertions(+), 51 deletions(-) diff --git a/docs/data/base/components/input/OTPInput.js b/docs/data/base/components/input/OTPInput.js index edf53cdd5777bb..722d4bf59ca96e 100644 --- a/docs/data/base/components/input/OTPInput.js +++ b/docs/data/base/components/input/OTPInput.js @@ -2,14 +2,10 @@ import * as React from 'react'; import { Input as BaseInput } from '@mui/base/Input'; import { Box, styled } from '@mui/system'; -export default function OTPInput() { - const inputCount = 6; +function OTP({ seperator, inputCount }) { const inputRefs = React.useRef(new Array(6).fill(null)); const [otp, setOtp] = React.useState(new Array(inputCount).fill('')); - const otpAsString = otp.join(''); - console.log(otpAsString); - const focusInput = (targetIndex) => { const targetInput = inputRefs.current[targetIndex]; targetInput.focus(); @@ -58,19 +54,18 @@ export default function OTPInput() { const handleChange = (event, currentIndex) => { const value = event.target.value; + let indexToEnter = 0; + + while (indexToEnter <= currentIndex) { + if (otp[indexToEnter] && indexToEnter < currentIndex) { + indexToEnter += 1; + } else { + break; + } + } setOtp((prev) => { const otpArray = [...prev]; const lastValue = value[value.length - 1]; - let indexToEnter = 0; - - while (indexToEnter <= currentIndex) { - if (prev[indexToEnter]) { - indexToEnter+=1; - } else { - break; - } - } - otpArray[indexToEnter] = lastValue; return otpArray; }); @@ -85,25 +80,33 @@ export default function OTPInput() { selectInput(currentIndex); }; - return ( - - {new Array(inputCount).fill(null).map((_, index) => ( - { - inputRefs.current[index] = ele; - }, - onKeyDown: (event) => handleKeyDown(event, index), - onChange: (event) => handleChange(event, index), - onClick: (event) => handleClick(event, index), - value: otp[index], + return new Array(inputCount).fill(null).map((_, index) => ( + + { + inputRefs.current[index] = ele; }, - }} - /> - ))} + onKeyDown: (event) => handleKeyDown(event, index), + onChange: (event) => handleChange(event, index), + onClick: (event) => handleClick(event, index), + value: otp[index], + }, + }} + /> + {index === inputCount - 1 ? null : seperator} + + )); +} + +export default function OTPInput() { + return ( + + -} inputCount={6} /> ); } @@ -137,12 +140,12 @@ const InputElement = styled('input')( font-size: 0.875rem; font-weight: 400; line-height: 1.5; - padding: 8px 12px; + padding: 8px 0px; border-radius: 8px; text-align: center; color: ${theme.palette.mode === 'dark' ? grey[300] : grey[900]}; background: ${theme.palette.mode === 'dark' ? grey[900] : '#fff'}; - border: 1px solid ${theme.palette.mode === 'dark' ? grey[700] : grey[200]}; + border: 1px solid ${theme.palette.mode === 'dark' ? grey[700] : grey[500]}; box-shadow: 0px 2px 4px ${ theme.palette.mode === 'dark' ? 'rgba(0,0,0, 0.5)' : 'rgba(0,0,0, 0.05)' }; diff --git a/docs/data/base/components/input/OTPInput.tsx.preview b/docs/data/base/components/input/OTPInput.tsx.preview index d852c4364e5878..7333f14df1166c 100644 --- a/docs/data/base/components/input/OTPInput.tsx.preview +++ b/docs/data/base/components/input/OTPInput.tsx.preview @@ -1,16 +1 @@ -{new Array(inputCount).fill(null).map((_, index) => ( - { - inputRefs.current[index] = ele!; - }, - onKeyDown: (event) => handleKeyDown(event, index), - onChange: (event) => handleChange(event, index), - onClick: (event) => handleClick(event, index), - value: otp[index], - }, - }} - /> -))} \ No newline at end of file +-} inputCount={6} /> \ No newline at end of file From ab1a664fdf42ed275090f5f2def59356597a1443 Mon Sep 17 00:00:00 2001 From: sai6855 Date: Fri, 12 Jan 2024 16:53:28 +0530 Subject: [PATCH 09/32] Update OTPInput.js and OTPInput.tsx to add aria-label attribute --- docs/data/base/components/input/OTPInput.js | 1 + docs/data/base/components/input/OTPInput.tsx | 1 + 2 files changed, 2 insertions(+) diff --git a/docs/data/base/components/input/OTPInput.js b/docs/data/base/components/input/OTPInput.js index 722d4bf59ca96e..a3b8551a04041e 100644 --- a/docs/data/base/components/input/OTPInput.js +++ b/docs/data/base/components/input/OTPInput.js @@ -86,6 +86,7 @@ function OTP({ seperator, inputCount }) { slots={{ input: InputElement, }} + aria-label="OTP input field" slotProps={{ input: { ref: (ele) => { diff --git a/docs/data/base/components/input/OTPInput.tsx b/docs/data/base/components/input/OTPInput.tsx index f3d9b8a674f9f4..db3f52105a8ccc 100644 --- a/docs/data/base/components/input/OTPInput.tsx +++ b/docs/data/base/components/input/OTPInput.tsx @@ -101,6 +101,7 @@ function OTP({ slots={{ input: InputElement, }} + aria-label='OTP input field' slotProps={{ input: { ref: (ele) => { From 7d759fb0e3c7b57e1f20eb9c022ac1dd8ae5829a Mon Sep 17 00:00:00 2001 From: sai6855 Date: Fri, 12 Jan 2024 16:57:24 +0530 Subject: [PATCH 10/32] prettier --- docs/data/base/components/input/OTPInput.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/data/base/components/input/OTPInput.tsx b/docs/data/base/components/input/OTPInput.tsx index db3f52105a8ccc..6fd9d9e29d5121 100644 --- a/docs/data/base/components/input/OTPInput.tsx +++ b/docs/data/base/components/input/OTPInput.tsx @@ -101,7 +101,7 @@ function OTP({ slots={{ input: InputElement, }} - aria-label='OTP input field' + aria-label="OTP input field" slotProps={{ input: { ref: (ele) => { From b91d99ea388c60a08456e12ccbe8e390ff7f7c3c Mon Sep 17 00:00:00 2001 From: zanivan Date: Fri, 12 Jan 2024 10:06:08 -0300 Subject: [PATCH 11/32] Tiny visual tweak --- docs/data/base/components/input/OTPInput.js | 2 +- docs/data/base/components/input/OTPInput.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/data/base/components/input/OTPInput.js b/docs/data/base/components/input/OTPInput.js index a3b8551a04041e..30ff15da09aa8a 100644 --- a/docs/data/base/components/input/OTPInput.js +++ b/docs/data/base/components/input/OTPInput.js @@ -146,7 +146,7 @@ const InputElement = styled('input')( text-align: center; color: ${theme.palette.mode === 'dark' ? grey[300] : grey[900]}; background: ${theme.palette.mode === 'dark' ? grey[900] : '#fff'}; - border: 1px solid ${theme.palette.mode === 'dark' ? grey[700] : grey[500]}; + border: 1px solid ${theme.palette.mode === 'dark' ? grey[700] : grey[200]}; box-shadow: 0px 2px 4px ${ theme.palette.mode === 'dark' ? 'rgba(0,0,0, 0.5)' : 'rgba(0,0,0, 0.05)' }; diff --git a/docs/data/base/components/input/OTPInput.tsx b/docs/data/base/components/input/OTPInput.tsx index 6fd9d9e29d5121..7f1a0654843cf1 100644 --- a/docs/data/base/components/input/OTPInput.tsx +++ b/docs/data/base/components/input/OTPInput.tsx @@ -161,7 +161,7 @@ const InputElement = styled('input')( text-align: center; color: ${theme.palette.mode === 'dark' ? grey[300] : grey[900]}; background: ${theme.palette.mode === 'dark' ? grey[900] : '#fff'}; - border: 1px solid ${theme.palette.mode === 'dark' ? grey[700] : grey[500]}; + border: 1px solid ${theme.palette.mode === 'dark' ? grey[700] : grey[200]}; box-shadow: 0px 2px 4px ${ theme.palette.mode === 'dark' ? 'rgba(0,0,0, 0.5)' : 'rgba(0,0,0, 0.05)' }; From 6c2a8a588430cdea0aefbf2d3f6bf23826e9abd4 Mon Sep 17 00:00:00 2001 From: zanivan Date: Fri, 12 Jan 2024 10:08:55 -0300 Subject: [PATCH 12/32] More tweaks --- docs/data/base/components/input/OTPInput.js | 4 ++-- docs/data/base/components/input/OTPInput.tsx | 4 ++-- docs/data/base/components/input/OTPInput.tsx.preview | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/data/base/components/input/OTPInput.js b/docs/data/base/components/input/OTPInput.js index 30ff15da09aa8a..8a1d3df0edd0da 100644 --- a/docs/data/base/components/input/OTPInput.js +++ b/docs/data/base/components/input/OTPInput.js @@ -106,8 +106,8 @@ function OTP({ seperator, inputCount }) { export default function OTPInput() { return ( - - -} inputCount={6} /> + + -} inputCount={5} /> ); } diff --git a/docs/data/base/components/input/OTPInput.tsx b/docs/data/base/components/input/OTPInput.tsx index 7f1a0654843cf1..4ef796d720ff11 100644 --- a/docs/data/base/components/input/OTPInput.tsx +++ b/docs/data/base/components/input/OTPInput.tsx @@ -121,8 +121,8 @@ function OTP({ export default function OTPInput() { return ( - - -} inputCount={6} /> + + -} inputCount={5} /> ); } diff --git a/docs/data/base/components/input/OTPInput.tsx.preview b/docs/data/base/components/input/OTPInput.tsx.preview index 7333f14df1166c..86469576616e58 100644 --- a/docs/data/base/components/input/OTPInput.tsx.preview +++ b/docs/data/base/components/input/OTPInput.tsx.preview @@ -1 +1 @@ --} inputCount={6} /> \ No newline at end of file +-} inputCount={5} /> \ No newline at end of file From da2757e09c01fb9a0aa7aaa574f244633bb182b4 Mon Sep 17 00:00:00 2001 From: sai chand <60743144+sai6855@users.noreply.github.com> Date: Fri, 12 Jan 2024 21:35:30 +0530 Subject: [PATCH 13/32] Update OTPInput.tsx --- docs/data/base/components/input/OTPInput.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/data/base/components/input/OTPInput.tsx b/docs/data/base/components/input/OTPInput.tsx index 4ef796d720ff11..ab9064d0d8e2e3 100644 --- a/docs/data/base/components/input/OTPInput.tsx +++ b/docs/data/base/components/input/OTPInput.tsx @@ -9,7 +9,7 @@ function OTP({ seperator: React.ReactNode; inputCount: number; }) { - const inputRefs = React.useRef(new Array(6).fill(null)); + const inputRefs = React.useRef(new Array(inputCount).fill(null)); const [otp, setOtp] = React.useState(new Array(inputCount).fill('')); const focusInput = (targetIndex: number) => { From 581f41b470a806698da84bc7526834a33bc0fe27 Mon Sep 17 00:00:00 2001 From: sai chand <60743144+sai6855@users.noreply.github.com> Date: Fri, 12 Jan 2024 21:36:06 +0530 Subject: [PATCH 14/32] Update OTPInput.js --- docs/data/base/components/input/OTPInput.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/data/base/components/input/OTPInput.js b/docs/data/base/components/input/OTPInput.js index 8a1d3df0edd0da..6a32e645b271ef 100644 --- a/docs/data/base/components/input/OTPInput.js +++ b/docs/data/base/components/input/OTPInput.js @@ -3,7 +3,7 @@ import { Input as BaseInput } from '@mui/base/Input'; import { Box, styled } from '@mui/system'; function OTP({ seperator, inputCount }) { - const inputRefs = React.useRef(new Array(6).fill(null)); + const inputRefs = React.useRef(new Array(inputCount).fill(null)); const [otp, setOtp] = React.useState(new Array(inputCount).fill('')); const focusInput = (targetIndex) => { From 82fb39fe0388e5f96a710485c883ac3d63347ad6 Mon Sep 17 00:00:00 2001 From: sai6855 Date: Fri, 12 Jan 2024 21:41:19 +0530 Subject: [PATCH 15/32] prettier --- docs/data/base/components/input/OTPInput.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/data/base/components/input/OTPInput.tsx b/docs/data/base/components/input/OTPInput.tsx index ab9064d0d8e2e3..7dca78a0473677 100644 --- a/docs/data/base/components/input/OTPInput.tsx +++ b/docs/data/base/components/input/OTPInput.tsx @@ -9,7 +9,9 @@ function OTP({ seperator: React.ReactNode; inputCount: number; }) { - const inputRefs = React.useRef(new Array(inputCount).fill(null)); + const inputRefs = React.useRef( + new Array(inputCount).fill(null), + ); const [otp, setOtp] = React.useState(new Array(inputCount).fill('')); const focusInput = (targetIndex: number) => { From 51965ca667aca027f7224ca39997f01b0b47ea56 Mon Sep 17 00:00:00 2001 From: sai6855 Date: Tue, 16 Jan 2024 21:49:41 +0530 Subject: [PATCH 16/32] move otp state to parent --- docs/data/base/components/input/OTPInput.js | 12 +++++++++--- docs/data/base/components/input/OTPInput.tsx | 14 ++++++++++++-- .../base/components/input/OTPInput.tsx.preview | 7 ++++++- 3 files changed, 27 insertions(+), 6 deletions(-) diff --git a/docs/data/base/components/input/OTPInput.js b/docs/data/base/components/input/OTPInput.js index 6a32e645b271ef..0b5993bdbdfa72 100644 --- a/docs/data/base/components/input/OTPInput.js +++ b/docs/data/base/components/input/OTPInput.js @@ -2,9 +2,8 @@ import * as React from 'react'; import { Input as BaseInput } from '@mui/base/Input'; import { Box, styled } from '@mui/system'; -function OTP({ seperator, inputCount }) { +function OTP({ seperator, inputCount, otp, setOtp }) { const inputRefs = React.useRef(new Array(inputCount).fill(null)); - const [otp, setOtp] = React.useState(new Array(inputCount).fill('')); const focusInput = (targetIndex) => { const targetInput = inputRefs.current[targetIndex]; @@ -105,9 +104,16 @@ function OTP({ seperator, inputCount }) { } export default function OTPInput() { + const inputCount = 5; + const [otp, setOtp] = React.useState(new Array(inputCount).fill('')); return ( - -} inputCount={5} /> + -} + otp={otp} + setOtp={setOtp} + inputCount={inputCount} + /> ); } diff --git a/docs/data/base/components/input/OTPInput.tsx b/docs/data/base/components/input/OTPInput.tsx index 7dca78a0473677..319909f0eb43c1 100644 --- a/docs/data/base/components/input/OTPInput.tsx +++ b/docs/data/base/components/input/OTPInput.tsx @@ -5,14 +5,17 @@ import { Box, styled } from '@mui/system'; function OTP({ seperator, inputCount, + otp, + setOtp, }: { seperator: React.ReactNode; inputCount: number; + otp: string[]; + setOtp: React.Dispatch>; }) { const inputRefs = React.useRef( new Array(inputCount).fill(null), ); - const [otp, setOtp] = React.useState(new Array(inputCount).fill('')); const focusInput = (targetIndex: number) => { const targetInput = inputRefs.current[targetIndex]; @@ -122,9 +125,16 @@ function OTP({ } export default function OTPInput() { + const inputCount = 5; + const [otp, setOtp] = React.useState(new Array(inputCount).fill('')); return ( - -} inputCount={5} /> + -} + otp={otp} + setOtp={setOtp} + inputCount={inputCount} + /> ); } diff --git a/docs/data/base/components/input/OTPInput.tsx.preview b/docs/data/base/components/input/OTPInput.tsx.preview index 86469576616e58..0fb11b55415368 100644 --- a/docs/data/base/components/input/OTPInput.tsx.preview +++ b/docs/data/base/components/input/OTPInput.tsx.preview @@ -1 +1,6 @@ --} inputCount={5} /> \ No newline at end of file +-} + otp={otp} + setOtp={setOtp} + inputCount={inputCount} +/> \ No newline at end of file From d67da7cc71757cc7298da17c3414a89516a45eda Mon Sep 17 00:00:00 2001 From: sai6855 Date: Tue, 16 Jan 2024 21:52:56 +0530 Subject: [PATCH 17/32] Update aria-label for OTP input field --- docs/data/base/components/input/OTPInput.js | 2 +- docs/data/base/components/input/OTPInput.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/data/base/components/input/OTPInput.js b/docs/data/base/components/input/OTPInput.js index 0b5993bdbdfa72..100f7d0961c180 100644 --- a/docs/data/base/components/input/OTPInput.js +++ b/docs/data/base/components/input/OTPInput.js @@ -85,7 +85,7 @@ function OTP({ seperator, inputCount, otp, setOtp }) { slots={{ input: InputElement, }} - aria-label="OTP input field" + aria-label={`Digit ${index + 1} of OTP`} slotProps={{ input: { ref: (ele) => { diff --git a/docs/data/base/components/input/OTPInput.tsx b/docs/data/base/components/input/OTPInput.tsx index 319909f0eb43c1..c91916b635131f 100644 --- a/docs/data/base/components/input/OTPInput.tsx +++ b/docs/data/base/components/input/OTPInput.tsx @@ -106,7 +106,7 @@ function OTP({ slots={{ input: InputElement, }} - aria-label="OTP input field" + aria-label={`Digit ${index + 1} of OTP`} slotProps={{ input: { ref: (ele) => { From 23ee497173f8b9d26a1f0a9fc22ee646fcd1f67e Mon Sep 17 00:00:00 2001 From: sai6855 Date: Tue, 16 Jan 2024 21:55:42 +0530 Subject: [PATCH 18/32] fix selction --- docs/data/base/components/input/OTPInput.js | 4 ++-- docs/data/base/components/input/OTPInput.tsx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/data/base/components/input/OTPInput.js b/docs/data/base/components/input/OTPInput.js index 100f7d0961c180..2ab23f4bfcb974 100644 --- a/docs/data/base/components/input/OTPInput.js +++ b/docs/data/base/components/input/OTPInput.js @@ -18,15 +18,15 @@ function OTP({ seperator, inputCount, otp, setOtp }) { const handleKeyDown = (event, currentIndex) => { switch (event.key) { case 'ArrowLeft': + event.preventDefault(); if (currentIndex > 0) { - event.preventDefault(); focusInput(currentIndex - 1); selectInput(currentIndex - 1); } break; case 'ArrowRight': + event.preventDefault(); if (currentIndex < inputCount - 1) { - event.preventDefault(); focusInput(currentIndex + 1); selectInput(currentIndex + 1); } diff --git a/docs/data/base/components/input/OTPInput.tsx b/docs/data/base/components/input/OTPInput.tsx index c91916b635131f..d059db1b9b86f6 100644 --- a/docs/data/base/components/input/OTPInput.tsx +++ b/docs/data/base/components/input/OTPInput.tsx @@ -33,15 +33,15 @@ function OTP({ ) => { switch (event.key) { case 'ArrowLeft': + event.preventDefault(); if (currentIndex > 0) { - event.preventDefault(); focusInput(currentIndex - 1); selectInput(currentIndex - 1); } break; case 'ArrowRight': + event.preventDefault(); if (currentIndex < inputCount - 1) { - event.preventDefault(); focusInput(currentIndex + 1); selectInput(currentIndex + 1); } From b8b382f567c8ca7388601a22e7b71e9d503293dd Mon Sep 17 00:00:00 2001 From: sai6855 Date: Tue, 16 Jan 2024 22:26:46 +0530 Subject: [PATCH 19/32] fill inputs on paste --- docs/data/base/components/input/OTPInput.js | 30 ++++++++++++++++++ docs/data/base/components/input/OTPInput.tsx | 33 ++++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/docs/data/base/components/input/OTPInput.js b/docs/data/base/components/input/OTPInput.js index 2ab23f4bfcb974..b0b19bf5a55302 100644 --- a/docs/data/base/components/input/OTPInput.js +++ b/docs/data/base/components/input/OTPInput.js @@ -79,6 +79,35 @@ function OTP({ seperator, inputCount, otp, setOtp }) { selectInput(currentIndex); }; + const handlePaste = (event, currentIndex) => { + event.preventDefault(); + const clipboardData = event.clipboardData; + + // Check if there is text data in the clipboard + if (clipboardData.types.includes('text/plain')) { + let pastedText = clipboardData.getData('text/plain'); + pastedText = pastedText.substring(0, inputCount); + let indexToEnter = 0; + + while (indexToEnter <= currentIndex) { + if (otp[indexToEnter] && indexToEnter < currentIndex) { + indexToEnter += 1; + } else { + break; + } + } + + const otpArray = [...otp]; + + for (let i = indexToEnter; i < inputCount; i += 1) { + const lastValue = pastedText[i - indexToEnter] ?? ''; + otpArray[i] = lastValue; + } + + setOtp(otpArray); + } + }; + return new Array(inputCount).fill(null).map((_, index) => ( handleKeyDown(event, index), onChange: (event) => handleChange(event, index), onClick: (event) => handleClick(event, index), + onPaste: (event) => handlePaste(event, index), value: otp[index], }, }} diff --git a/docs/data/base/components/input/OTPInput.tsx b/docs/data/base/components/input/OTPInput.tsx index d059db1b9b86f6..ebab2254556f33 100644 --- a/docs/data/base/components/input/OTPInput.tsx +++ b/docs/data/base/components/input/OTPInput.tsx @@ -100,6 +100,38 @@ function OTP({ selectInput(currentIndex); }; + const handlePaste = ( + event: React.ClipboardEvent, + currentIndex: number, + ) => { + event.preventDefault(); + const clipboardData = event.clipboardData; + + // Check if there is text data in the clipboard + if (clipboardData.types.includes('text/plain')) { + let pastedText = clipboardData.getData('text/plain'); + pastedText = pastedText.substring(0, inputCount); + let indexToEnter = 0; + + while (indexToEnter <= currentIndex) { + if (otp[indexToEnter] && indexToEnter < currentIndex) { + indexToEnter += 1; + } else { + break; + } + } + + const otpArray = [...otp]; + + for (let i = indexToEnter; i < inputCount; i += 1) { + const lastValue = pastedText[i - indexToEnter] ?? ''; + otpArray[i] = lastValue; + } + + setOtp(otpArray); + } + }; + return new Array(inputCount).fill(null).map((_, index) => ( handleKeyDown(event, index), onChange: (event) => handleChange(event, index), onClick: (event) => handleClick(event, index), + onPaste: (event) => handlePaste(event, index), value: otp[index], }, }} From bb2f3a83364c06f2e173196191ea45354b381bef Mon Sep 17 00:00:00 2001 From: sai6855 Date: Wed, 17 Jan 2024 14:17:35 +0530 Subject: [PATCH 20/32] handle arrow up, down --- docs/data/base/components/input/OTPInput.js | 4 ++++ docs/data/base/components/input/OTPInput.tsx | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/docs/data/base/components/input/OTPInput.js b/docs/data/base/components/input/OTPInput.js index b0b19bf5a55302..2612945d447e6a 100644 --- a/docs/data/base/components/input/OTPInput.js +++ b/docs/data/base/components/input/OTPInput.js @@ -17,6 +17,10 @@ function OTP({ seperator, inputCount, otp, setOtp }) { const handleKeyDown = (event, currentIndex) => { switch (event.key) { + case 'ArrowUp': + case 'ArrowDown': + event.preventDefault(); + break; case 'ArrowLeft': event.preventDefault(); if (currentIndex > 0) { diff --git a/docs/data/base/components/input/OTPInput.tsx b/docs/data/base/components/input/OTPInput.tsx index ebab2254556f33..a4f13bdd4c2eb2 100644 --- a/docs/data/base/components/input/OTPInput.tsx +++ b/docs/data/base/components/input/OTPInput.tsx @@ -32,6 +32,10 @@ function OTP({ currentIndex: number, ) => { switch (event.key) { + case 'ArrowUp': + case 'ArrowDown': + event.preventDefault(); + break; case 'ArrowLeft': event.preventDefault(); if (currentIndex > 0) { From 6f58502fc33593ed8558dbca3898ea432eb4d308 Mon Sep 17 00:00:00 2001 From: sai6855 Date: Wed, 17 Jan 2024 14:18:05 +0530 Subject: [PATCH 21/32] Add support for Delete key in OTPInput component --- docs/data/base/components/input/OTPInput.js | 1 + docs/data/base/components/input/OTPInput.tsx | 1 + 2 files changed, 2 insertions(+) diff --git a/docs/data/base/components/input/OTPInput.js b/docs/data/base/components/input/OTPInput.js index 2612945d447e6a..d062bc014a9867 100644 --- a/docs/data/base/components/input/OTPInput.js +++ b/docs/data/base/components/input/OTPInput.js @@ -36,6 +36,7 @@ function OTP({ seperator, inputCount, otp, setOtp }) { } break; case 'Backspace': + case 'Delete': event.preventDefault(); if (currentIndex > 0) { focusInput(currentIndex - 1); diff --git a/docs/data/base/components/input/OTPInput.tsx b/docs/data/base/components/input/OTPInput.tsx index a4f13bdd4c2eb2..d77a7b494caf28 100644 --- a/docs/data/base/components/input/OTPInput.tsx +++ b/docs/data/base/components/input/OTPInput.tsx @@ -51,6 +51,7 @@ function OTP({ } break; case 'Backspace': + case 'Delete': event.preventDefault(); if (currentIndex > 0) { focusInput(currentIndex - 1); From 7c6a2326f6972bf6cac5b06b9dd7d65a9a5b605b Mon Sep 17 00:00:00 2001 From: sai6855 Date: Wed, 17 Jan 2024 14:23:42 +0530 Subject: [PATCH 22/32] change prop name to value and onChange --- docs/data/base/components/input/OTPInput.js | 26 +++++++-------- docs/data/base/components/input/OTPInput.tsx | 32 +++++++++---------- .../components/input/OTPInput.tsx.preview | 4 +-- 3 files changed, 31 insertions(+), 31 deletions(-) diff --git a/docs/data/base/components/input/OTPInput.js b/docs/data/base/components/input/OTPInput.js index d062bc014a9867..717baf197db7b6 100644 --- a/docs/data/base/components/input/OTPInput.js +++ b/docs/data/base/components/input/OTPInput.js @@ -2,7 +2,7 @@ import * as React from 'react'; import { Input as BaseInput } from '@mui/base/Input'; import { Box, styled } from '@mui/system'; -function OTP({ seperator, inputCount, otp, setOtp }) { +function OTP({ seperator, inputCount, value, onChange }) { const inputRefs = React.useRef(new Array(inputCount).fill(null)); const focusInput = (targetIndex) => { @@ -43,7 +43,7 @@ function OTP({ seperator, inputCount, otp, setOtp }) { selectInput(currentIndex - 1); } - setOtp((prev) => { + onChange((prev) => { const otpArray = [...prev]; otpArray.splice(currentIndex, 1); otpArray.push(''); @@ -57,23 +57,23 @@ function OTP({ seperator, inputCount, otp, setOtp }) { }; const handleChange = (event, currentIndex) => { - const value = event.target.value; + const currentValue = event.target.value; let indexToEnter = 0; while (indexToEnter <= currentIndex) { - if (otp[indexToEnter] && indexToEnter < currentIndex) { + if (value[indexToEnter] && indexToEnter < currentIndex) { indexToEnter += 1; } else { break; } } - setOtp((prev) => { + onChange((prev) => { const otpArray = [...prev]; - const lastValue = value[value.length - 1]; + const lastValue = currentValue[currentValue.length - 1]; otpArray[indexToEnter] = lastValue; return otpArray; }); - if (value !== '') { + if (currentValue !== '') { if (currentIndex < inputCount - 1) { focusInput(currentIndex + 1); } @@ -95,21 +95,21 @@ function OTP({ seperator, inputCount, otp, setOtp }) { let indexToEnter = 0; while (indexToEnter <= currentIndex) { - if (otp[indexToEnter] && indexToEnter < currentIndex) { + if (value[indexToEnter] && indexToEnter < currentIndex) { indexToEnter += 1; } else { break; } } - const otpArray = [...otp]; + const otpArray = [...value]; for (let i = indexToEnter; i < inputCount; i += 1) { const lastValue = pastedText[i - indexToEnter] ?? ''; otpArray[i] = lastValue; } - setOtp(otpArray); + onChange(otpArray); } }; @@ -129,7 +129,7 @@ function OTP({ seperator, inputCount, otp, setOtp }) { onChange: (event) => handleChange(event, index), onClick: (event) => handleClick(event, index), onPaste: (event) => handlePaste(event, index), - value: otp[index], + value: value[index], }, }} /> @@ -145,8 +145,8 @@ export default function OTPInput() { -} - otp={otp} - setOtp={setOtp} + value={otp} + onChange={setOtp} inputCount={inputCount} /> diff --git a/docs/data/base/components/input/OTPInput.tsx b/docs/data/base/components/input/OTPInput.tsx index d77a7b494caf28..812f1e1cd7468a 100644 --- a/docs/data/base/components/input/OTPInput.tsx +++ b/docs/data/base/components/input/OTPInput.tsx @@ -5,13 +5,13 @@ import { Box, styled } from '@mui/system'; function OTP({ seperator, inputCount, - otp, - setOtp, + value, + onChange, }: { seperator: React.ReactNode; inputCount: number; - otp: string[]; - setOtp: React.Dispatch>; + value: string[]; + onChange: React.Dispatch>; }) { const inputRefs = React.useRef( new Array(inputCount).fill(null), @@ -58,7 +58,7 @@ function OTP({ selectInput(currentIndex - 1); } - setOtp((prev) => { + onChange((prev) => { const otpArray = [...prev]; otpArray.splice(currentIndex, 1); otpArray.push(''); @@ -75,23 +75,23 @@ function OTP({ event: React.ChangeEvent, currentIndex: number, ) => { - const value = event.target.value; + const currentValue = event.target.value; let indexToEnter = 0; while (indexToEnter <= currentIndex) { - if (otp[indexToEnter] && indexToEnter < currentIndex) { + if (value[indexToEnter] && indexToEnter < currentIndex) { indexToEnter += 1; } else { break; } } - setOtp((prev) => { + onChange((prev) => { const otpArray = [...prev]; - const lastValue = value[value.length - 1]; + const lastValue = currentValue[currentValue.length - 1]; otpArray[indexToEnter] = lastValue; return otpArray; }); - if (value !== '') { + if (currentValue !== '') { if (currentIndex < inputCount - 1) { focusInput(currentIndex + 1); } @@ -119,21 +119,21 @@ function OTP({ let indexToEnter = 0; while (indexToEnter <= currentIndex) { - if (otp[indexToEnter] && indexToEnter < currentIndex) { + if (value[indexToEnter] && indexToEnter < currentIndex) { indexToEnter += 1; } else { break; } } - const otpArray = [...otp]; + const otpArray = [...value]; for (let i = indexToEnter; i < inputCount; i += 1) { const lastValue = pastedText[i - indexToEnter] ?? ''; otpArray[i] = lastValue; } - setOtp(otpArray); + onChange(otpArray); } }; @@ -153,7 +153,7 @@ function OTP({ onChange: (event) => handleChange(event, index), onClick: (event) => handleClick(event, index), onPaste: (event) => handlePaste(event, index), - value: otp[index], + value: value[index], }, }} /> @@ -169,8 +169,8 @@ export default function OTPInput() { -} - otp={otp} - setOtp={setOtp} + value={otp} + onChange={setOtp} inputCount={inputCount} /> diff --git a/docs/data/base/components/input/OTPInput.tsx.preview b/docs/data/base/components/input/OTPInput.tsx.preview index 0fb11b55415368..957b34510e63f4 100644 --- a/docs/data/base/components/input/OTPInput.tsx.preview +++ b/docs/data/base/components/input/OTPInput.tsx.preview @@ -1,6 +1,6 @@ -} - otp={otp} - setOtp={setOtp} + value={otp} + onChange={setOtp} inputCount={inputCount} /> \ No newline at end of file From 50c9913b08e6f874e8ad6e9cddc25f5379bad2e5 Mon Sep 17 00:00:00 2001 From: sai6855 Date: Wed, 17 Jan 2024 14:30:34 +0530 Subject: [PATCH 23/32] display entered value --- docs/data/base/components/input/OTPInput.js | 67 ++++++++++++------- docs/data/base/components/input/OTPInput.tsx | 59 +++++++++------- .../components/input/OTPInput.tsx.preview | 3 +- 3 files changed, 80 insertions(+), 49 deletions(-) diff --git a/docs/data/base/components/input/OTPInput.js b/docs/data/base/components/input/OTPInput.js index 717baf197db7b6..762a9ec38f471c 100644 --- a/docs/data/base/components/input/OTPInput.js +++ b/docs/data/base/components/input/OTPInput.js @@ -1,4 +1,5 @@ import * as React from 'react'; +import PropTypes from 'prop-types'; import { Input as BaseInput } from '@mui/base/Input'; import { Box, styled } from '@mui/system'; @@ -113,42 +114,60 @@ function OTP({ seperator, inputCount, value, onChange }) { } }; - return new Array(inputCount).fill(null).map((_, index) => ( - - { - inputRefs.current[index] = ele; - }, - onKeyDown: (event) => handleKeyDown(event, index), - onChange: (event) => handleChange(event, index), - onClick: (event) => handleClick(event, index), - onPaste: (event) => handlePaste(event, index), - value: value[index], - }, - }} - /> - {index === inputCount - 1 ? null : seperator} - - )); + return ( + + {new Array(inputCount).fill(null).map((_, index) => ( + + { + inputRefs.current[index] = ele; + }, + onKeyDown: (event) => handleKeyDown(event, index), + onChange: (event) => handleChange(event, index), + onClick: (event) => handleClick(event, index), + onPaste: (event) => handlePaste(event, index), + value: value[index], + }, + }} + /> + {index === inputCount - 1 ? null : seperator} + + ))} + + ); } +OTP.propTypes = { + inputCount: PropTypes.number.isRequired, + onChange: PropTypes.func.isRequired, + seperator: PropTypes.node, + value: PropTypes.arrayOf(PropTypes.string).isRequired, +}; + export default function OTPInput() { const inputCount = 5; const [otp, setOtp] = React.useState(new Array(inputCount).fill('')); return ( - + -} value={otp} onChange={setOtp} inputCount={inputCount} /> + Entered value: {otp.join('')} ); } diff --git a/docs/data/base/components/input/OTPInput.tsx b/docs/data/base/components/input/OTPInput.tsx index 812f1e1cd7468a..3d00f0a6e501d0 100644 --- a/docs/data/base/components/input/OTPInput.tsx +++ b/docs/data/base/components/input/OTPInput.tsx @@ -137,42 +137,53 @@ function OTP({ } }; - return new Array(inputCount).fill(null).map((_, index) => ( - - { - inputRefs.current[index] = ele!; - }, - onKeyDown: (event) => handleKeyDown(event, index), - onChange: (event) => handleChange(event, index), - onClick: (event) => handleClick(event, index), - onPaste: (event) => handlePaste(event, index), - value: value[index], - }, - }} - /> - {index === inputCount - 1 ? null : seperator} - - )); + return ( + + {new Array(inputCount).fill(null).map((_, index) => ( + + { + inputRefs.current[index] = ele!; + }, + onKeyDown: (event) => handleKeyDown(event, index), + onChange: (event) => handleChange(event, index), + onClick: (event) => handleClick(event, index), + onPaste: (event) => handlePaste(event, index), + value: value[index], + }, + }} + /> + {index === inputCount - 1 ? null : seperator} + + ))} + + ); } export default function OTPInput() { const inputCount = 5; const [otp, setOtp] = React.useState(new Array(inputCount).fill('')); return ( - + -} value={otp} onChange={setOtp} inputCount={inputCount} /> + Entered value: {otp.join('')} ); } diff --git a/docs/data/base/components/input/OTPInput.tsx.preview b/docs/data/base/components/input/OTPInput.tsx.preview index 957b34510e63f4..3a553e4f01a7cf 100644 --- a/docs/data/base/components/input/OTPInput.tsx.preview +++ b/docs/data/base/components/input/OTPInput.tsx.preview @@ -3,4 +3,5 @@ value={otp} onChange={setOtp} inputCount={inputCount} -/> \ No newline at end of file +/> +Entered value: {otp.join('')} \ No newline at end of file From e2c30fef32a5eee84e0cac43d1ac87cbaca31b9b Mon Sep 17 00:00:00 2001 From: sai6855 Date: Wed, 17 Jan 2024 14:32:16 +0530 Subject: [PATCH 24/32] fix delete key usage --- docs/data/base/components/input/OTPInput.js | 12 +++++++++++- docs/data/base/components/input/OTPInput.tsx | 12 +++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/docs/data/base/components/input/OTPInput.js b/docs/data/base/components/input/OTPInput.js index 762a9ec38f471c..df24c3ab636156 100644 --- a/docs/data/base/components/input/OTPInput.js +++ b/docs/data/base/components/input/OTPInput.js @@ -36,9 +36,19 @@ function OTP({ seperator, inputCount, value, onChange }) { selectInput(currentIndex + 1); } break; - case 'Backspace': case 'Delete': event.preventDefault(); + + onChange((prev) => { + const otpArray = [...prev]; + otpArray.splice(currentIndex, 1); + otpArray.push(''); + return otpArray; + }); + + break; + case 'Backspace': + event.preventDefault(); if (currentIndex > 0) { focusInput(currentIndex - 1); selectInput(currentIndex - 1); diff --git a/docs/data/base/components/input/OTPInput.tsx b/docs/data/base/components/input/OTPInput.tsx index 3d00f0a6e501d0..6222d9b5a5294f 100644 --- a/docs/data/base/components/input/OTPInput.tsx +++ b/docs/data/base/components/input/OTPInput.tsx @@ -50,9 +50,19 @@ function OTP({ selectInput(currentIndex + 1); } break; - case 'Backspace': case 'Delete': event.preventDefault(); + + onChange((prev) => { + const otpArray = [...prev]; + otpArray.splice(currentIndex, 1); + otpArray.push(''); + return otpArray; + }); + + break; + case 'Backspace': + event.preventDefault(); if (currentIndex > 0) { focusInput(currentIndex - 1); selectInput(currentIndex - 1); From 12f808a5a87cdb6119a6e9cc3877b4b926663def Mon Sep 17 00:00:00 2001 From: sai6855 Date: Wed, 17 Jan 2024 16:30:20 +0530 Subject: [PATCH 25/32] change inputCount to otp.length --- docs/data/base/components/input/OTPInput.js | 2 +- docs/data/base/components/input/OTPInput.tsx | 2 +- docs/data/base/components/input/OTPInput.tsx.preview | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/data/base/components/input/OTPInput.js b/docs/data/base/components/input/OTPInput.js index df24c3ab636156..f0d5427d869769 100644 --- a/docs/data/base/components/input/OTPInput.js +++ b/docs/data/base/components/input/OTPInput.js @@ -175,7 +175,7 @@ export default function OTPInput() { seperator={-} value={otp} onChange={setOtp} - inputCount={inputCount} + inputCount={otp.length} /> Entered value: {otp.join('')} diff --git a/docs/data/base/components/input/OTPInput.tsx b/docs/data/base/components/input/OTPInput.tsx index 6222d9b5a5294f..e30bcbc08a0fcd 100644 --- a/docs/data/base/components/input/OTPInput.tsx +++ b/docs/data/base/components/input/OTPInput.tsx @@ -191,7 +191,7 @@ export default function OTPInput() { seperator={-} value={otp} onChange={setOtp} - inputCount={inputCount} + inputCount={otp.length} /> Entered value: {otp.join('')} diff --git a/docs/data/base/components/input/OTPInput.tsx.preview b/docs/data/base/components/input/OTPInput.tsx.preview index 3a553e4f01a7cf..6755def68ebd39 100644 --- a/docs/data/base/components/input/OTPInput.tsx.preview +++ b/docs/data/base/components/input/OTPInput.tsx.preview @@ -2,6 +2,6 @@ seperator={-} value={otp} onChange={setOtp} - inputCount={inputCount} + inputCount={otp.length} /> Entered value: {otp.join('')} \ No newline at end of file From 817bc3f368586dad68e2b91c72cbf8d76fb95c6c Mon Sep 17 00:00:00 2001 From: sai6855 Date: Wed, 17 Jan 2024 16:31:22 +0530 Subject: [PATCH 26/32] separator type --- docs/data/base/components/input/OTPInput.js | 8 ++++---- docs/data/base/components/input/OTPInput.tsx | 8 ++++---- docs/data/base/components/input/OTPInput.tsx.preview | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/data/base/components/input/OTPInput.js b/docs/data/base/components/input/OTPInput.js index f0d5427d869769..2807444122c67f 100644 --- a/docs/data/base/components/input/OTPInput.js +++ b/docs/data/base/components/input/OTPInput.js @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import { Input as BaseInput } from '@mui/base/Input'; import { Box, styled } from '@mui/system'; -function OTP({ seperator, inputCount, value, onChange }) { +function OTP({ separator, inputCount, value, onChange }) { const inputRefs = React.useRef(new Array(inputCount).fill(null)); const focusInput = (targetIndex) => { @@ -146,7 +146,7 @@ function OTP({ seperator, inputCount, value, onChange }) { }, }} /> - {index === inputCount - 1 ? null : seperator} + {index === inputCount - 1 ? null : separator} ))} @@ -156,7 +156,7 @@ function OTP({ seperator, inputCount, value, onChange }) { OTP.propTypes = { inputCount: PropTypes.number.isRequired, onChange: PropTypes.func.isRequired, - seperator: PropTypes.node, + separator: PropTypes.node, value: PropTypes.arrayOf(PropTypes.string).isRequired, }; @@ -172,7 +172,7 @@ export default function OTPInput() { }} > -} + separator={-} value={otp} onChange={setOtp} inputCount={otp.length} diff --git a/docs/data/base/components/input/OTPInput.tsx b/docs/data/base/components/input/OTPInput.tsx index e30bcbc08a0fcd..7e40350a18bdc0 100644 --- a/docs/data/base/components/input/OTPInput.tsx +++ b/docs/data/base/components/input/OTPInput.tsx @@ -3,12 +3,12 @@ import { Input as BaseInput } from '@mui/base/Input'; import { Box, styled } from '@mui/system'; function OTP({ - seperator, + separator, inputCount, value, onChange, }: { - seperator: React.ReactNode; + separator: React.ReactNode; inputCount: number; value: string[]; onChange: React.Dispatch>; @@ -169,7 +169,7 @@ function OTP({ }, }} /> - {index === inputCount - 1 ? null : seperator} + {index === inputCount - 1 ? null : separator} ))} @@ -188,7 +188,7 @@ export default function OTPInput() { }} > -} + separator={-} value={otp} onChange={setOtp} inputCount={otp.length} diff --git a/docs/data/base/components/input/OTPInput.tsx.preview b/docs/data/base/components/input/OTPInput.tsx.preview index 6755def68ebd39..a2e425a3b09b98 100644 --- a/docs/data/base/components/input/OTPInput.tsx.preview +++ b/docs/data/base/components/input/OTPInput.tsx.preview @@ -1,5 +1,5 @@ -} + separator={-} value={otp} onChange={setOtp} inputCount={otp.length} From 45cd082fc127bda79fc2a072992003e9124acf6d Mon Sep 17 00:00:00 2001 From: sai6855 Date: Wed, 17 Jan 2024 16:43:15 +0530 Subject: [PATCH 27/32] change otp type to string from array --- docs/data/base/components/input/OTPInput.js | 30 ++++++-------- docs/data/base/components/input/OTPInput.tsx | 40 ++++++++----------- .../components/input/OTPInput.tsx.preview | 9 +---- 3 files changed, 31 insertions(+), 48 deletions(-) diff --git a/docs/data/base/components/input/OTPInput.js b/docs/data/base/components/input/OTPInput.js index 2807444122c67f..538eabbec0ab34 100644 --- a/docs/data/base/components/input/OTPInput.js +++ b/docs/data/base/components/input/OTPInput.js @@ -40,10 +40,10 @@ function OTP({ separator, inputCount, value, onChange }) { event.preventDefault(); onChange((prev) => { - const otpArray = [...prev]; + const otpArray = prev.split(''); otpArray.splice(currentIndex, 1); otpArray.push(''); - return otpArray; + return otpArray.join(''); }); break; @@ -55,10 +55,10 @@ function OTP({ separator, inputCount, value, onChange }) { } onChange((prev) => { - const otpArray = [...prev]; + const otpArray = prev.split(''); otpArray.splice(currentIndex, 1); otpArray.push(''); - return otpArray; + return otpArray.join(''); }); break; @@ -79,10 +79,10 @@ function OTP({ separator, inputCount, value, onChange }) { } } onChange((prev) => { - const otpArray = [...prev]; + const otpArray = prev.split(''); const lastValue = currentValue[currentValue.length - 1]; otpArray[indexToEnter] = lastValue; - return otpArray; + return otpArray.join(''); }); if (currentValue !== '') { if (currentIndex < inputCount - 1) { @@ -113,14 +113,14 @@ function OTP({ separator, inputCount, value, onChange }) { } } - const otpArray = [...value]; + const otpArray = value.split(''); for (let i = indexToEnter; i < inputCount; i += 1) { const lastValue = pastedText[i - indexToEnter] ?? ''; otpArray[i] = lastValue; } - onChange(otpArray); + onChange(otpArray.join('')); } }; @@ -157,12 +157,11 @@ OTP.propTypes = { inputCount: PropTypes.number.isRequired, onChange: PropTypes.func.isRequired, separator: PropTypes.node, - value: PropTypes.arrayOf(PropTypes.string).isRequired, + value: PropTypes.string.isRequired, }; export default function OTPInput() { - const inputCount = 5; - const [otp, setOtp] = React.useState(new Array(inputCount).fill('')); + const [otp, setOtp] = React.useState(''); return ( - -} - value={otp} - onChange={setOtp} - inputCount={otp.length} - /> - Entered value: {otp.join('')} + -} value={otp} onChange={setOtp} inputCount={5} /> + Entered value: {otp} ); } diff --git a/docs/data/base/components/input/OTPInput.tsx b/docs/data/base/components/input/OTPInput.tsx index 7e40350a18bdc0..1ec203c0056ee0 100644 --- a/docs/data/base/components/input/OTPInput.tsx +++ b/docs/data/base/components/input/OTPInput.tsx @@ -10,8 +10,8 @@ function OTP({ }: { separator: React.ReactNode; inputCount: number; - value: string[]; - onChange: React.Dispatch>; + value: string; + onChange: React.Dispatch>; }) { const inputRefs = React.useRef( new Array(inputCount).fill(null), @@ -54,10 +54,10 @@ function OTP({ event.preventDefault(); onChange((prev) => { - const otpArray = [...prev]; + const otpArray = prev.split(''); otpArray.splice(currentIndex, 1); - otpArray.push(''); - return otpArray; + otpArray.push(' '); + return otpArray.join(''); }); break; @@ -69,10 +69,10 @@ function OTP({ } onChange((prev) => { - const otpArray = [...prev]; + const otpArray = prev.split(''); otpArray.splice(currentIndex, 1); - otpArray.push(''); - return otpArray; + otpArray.push(' '); + return otpArray.join(''); }); break; @@ -96,10 +96,10 @@ function OTP({ } } onChange((prev) => { - const otpArray = [...prev]; + const otpArray = prev.split(''); const lastValue = currentValue[currentValue.length - 1]; otpArray[indexToEnter] = lastValue; - return otpArray; + return otpArray.join(''); }); if (currentValue !== '') { if (currentIndex < inputCount - 1) { @@ -125,7 +125,7 @@ function OTP({ // Check if there is text data in the clipboard if (clipboardData.types.includes('text/plain')) { let pastedText = clipboardData.getData('text/plain'); - pastedText = pastedText.substring(0, inputCount); + pastedText = pastedText.substring(0, inputCount).trim(); let indexToEnter = 0; while (indexToEnter <= currentIndex) { @@ -136,14 +136,14 @@ function OTP({ } } - const otpArray = [...value]; + const otpArray = value.split(''); for (let i = indexToEnter; i < inputCount; i += 1) { - const lastValue = pastedText[i - indexToEnter] ?? ''; + const lastValue = pastedText[i - indexToEnter] ?? ' '; otpArray[i] = lastValue; } - onChange(otpArray); + onChange(otpArray.join('')); } }; @@ -177,8 +177,7 @@ function OTP({ } export default function OTPInput() { - const inputCount = 5; - const [otp, setOtp] = React.useState(new Array(inputCount).fill('')); + const [otp, setOtp] = React.useState(''); return ( - -} - value={otp} - onChange={setOtp} - inputCount={otp.length} - /> - Entered value: {otp.join('')} + -} value={otp} onChange={setOtp} inputCount={5} /> + Entered value: {otp} ); } diff --git a/docs/data/base/components/input/OTPInput.tsx.preview b/docs/data/base/components/input/OTPInput.tsx.preview index a2e425a3b09b98..b38359fd3aca3e 100644 --- a/docs/data/base/components/input/OTPInput.tsx.preview +++ b/docs/data/base/components/input/OTPInput.tsx.preview @@ -1,7 +1,2 @@ --} - value={otp} - onChange={setOtp} - inputCount={otp.length} -/> -Entered value: {otp.join('')} \ No newline at end of file +-} value={otp} onChange={setOtp} inputCount={5} /> +Entered value: {otp} \ No newline at end of file From c4c61d330a461db11e06f4e09acc72cf130e1fba Mon Sep 17 00:00:00 2001 From: sai6855 Date: Wed, 17 Jan 2024 16:45:08 +0530 Subject: [PATCH 28/32] handle space button --- docs/data/base/components/input/OTPInput.js | 10 ++++++---- docs/data/base/components/input/OTPInput.tsx | 2 ++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/docs/data/base/components/input/OTPInput.js b/docs/data/base/components/input/OTPInput.js index 538eabbec0ab34..31eb007c9c08d2 100644 --- a/docs/data/base/components/input/OTPInput.js +++ b/docs/data/base/components/input/OTPInput.js @@ -20,6 +20,7 @@ function OTP({ separator, inputCount, value, onChange }) { switch (event.key) { case 'ArrowUp': case 'ArrowDown': + case ' ': event.preventDefault(); break; case 'ArrowLeft': @@ -42,7 +43,7 @@ function OTP({ separator, inputCount, value, onChange }) { onChange((prev) => { const otpArray = prev.split(''); otpArray.splice(currentIndex, 1); - otpArray.push(''); + otpArray.push(' '); return otpArray.join(''); }); @@ -57,11 +58,12 @@ function OTP({ separator, inputCount, value, onChange }) { onChange((prev) => { const otpArray = prev.split(''); otpArray.splice(currentIndex, 1); - otpArray.push(''); + otpArray.push(' '); return otpArray.join(''); }); break; + default: break; } @@ -102,7 +104,7 @@ function OTP({ separator, inputCount, value, onChange }) { // Check if there is text data in the clipboard if (clipboardData.types.includes('text/plain')) { let pastedText = clipboardData.getData('text/plain'); - pastedText = pastedText.substring(0, inputCount); + pastedText = pastedText.substring(0, inputCount).trim(); let indexToEnter = 0; while (indexToEnter <= currentIndex) { @@ -116,7 +118,7 @@ function OTP({ separator, inputCount, value, onChange }) { const otpArray = value.split(''); for (let i = indexToEnter; i < inputCount; i += 1) { - const lastValue = pastedText[i - indexToEnter] ?? ''; + const lastValue = pastedText[i - indexToEnter] ?? ' '; otpArray[i] = lastValue; } diff --git a/docs/data/base/components/input/OTPInput.tsx b/docs/data/base/components/input/OTPInput.tsx index 1ec203c0056ee0..7f1a453805a6b0 100644 --- a/docs/data/base/components/input/OTPInput.tsx +++ b/docs/data/base/components/input/OTPInput.tsx @@ -34,6 +34,7 @@ function OTP({ switch (event.key) { case 'ArrowUp': case 'ArrowDown': + case ' ': event.preventDefault(); break; case 'ArrowLeft': @@ -76,6 +77,7 @@ function OTP({ }); break; + default: break; } From d1676f6038c937f6e6f9a7b264b5733a20e86249 Mon Sep 17 00:00:00 2001 From: sai6855 Date: Wed, 17 Jan 2024 17:12:57 +0530 Subject: [PATCH 29/32] fix bugs --- docs/data/base/components/input/OTPInput.js | 26 +++++++++----------- docs/data/base/components/input/OTPInput.tsx | 26 +++++++++----------- 2 files changed, 24 insertions(+), 28 deletions(-) diff --git a/docs/data/base/components/input/OTPInput.js b/docs/data/base/components/input/OTPInput.js index 31eb007c9c08d2..99d7fe44ccc737 100644 --- a/docs/data/base/components/input/OTPInput.js +++ b/docs/data/base/components/input/OTPInput.js @@ -39,12 +39,10 @@ function OTP({ separator, inputCount, value, onChange }) { break; case 'Delete': event.preventDefault(); - - onChange((prev) => { - const otpArray = prev.split(''); - otpArray.splice(currentIndex, 1); - otpArray.push(' '); - return otpArray.join(''); + onChange((prevOtp) => { + let otp = prevOtp; + otp = otp.slice(0, currentIndex) + otp.slice(currentIndex + 1); + return otp; }); break; @@ -55,11 +53,10 @@ function OTP({ separator, inputCount, value, onChange }) { selectInput(currentIndex - 1); } - onChange((prev) => { - const otpArray = prev.split(''); - otpArray.splice(currentIndex, 1); - otpArray.push(' '); - return otpArray.join(''); + onChange((prevOtp) => { + let otp = prevOtp; + otp = otp.slice(0, currentIndex) + otp.slice(currentIndex + 1); + return otp; }); break; @@ -74,7 +71,7 @@ function OTP({ separator, inputCount, value, onChange }) { let indexToEnter = 0; while (indexToEnter <= currentIndex) { - if (value[indexToEnter] && indexToEnter < currentIndex) { + if (inputRefs.current[indexToEnter].value && indexToEnter < currentIndex) { indexToEnter += 1; } else { break; @@ -108,7 +105,7 @@ function OTP({ separator, inputCount, value, onChange }) { let indexToEnter = 0; while (indexToEnter <= currentIndex) { - if (value[indexToEnter] && indexToEnter < currentIndex) { + if (inputRefs.current[indexToEnter].value && indexToEnter < currentIndex) { indexToEnter += 1; } else { break; @@ -144,7 +141,7 @@ function OTP({ separator, inputCount, value, onChange }) { onChange: (event) => handleChange(event, index), onClick: (event) => handleClick(event, index), onPaste: (event) => handlePaste(event, index), - value: value[index], + value: value[index] ?? '', }, }} /> @@ -164,6 +161,7 @@ OTP.propTypes = { export default function OTPInput() { const [otp, setOtp] = React.useState(''); + return ( { - const otpArray = prev.split(''); - otpArray.splice(currentIndex, 1); - otpArray.push(' '); - return otpArray.join(''); + onChange((prevOtp) => { + let otp = prevOtp; + otp = otp.slice(0, currentIndex) + otp.slice(currentIndex + 1); + return otp; }); break; @@ -69,11 +67,10 @@ function OTP({ selectInput(currentIndex - 1); } - onChange((prev) => { - const otpArray = prev.split(''); - otpArray.splice(currentIndex, 1); - otpArray.push(' '); - return otpArray.join(''); + onChange((prevOtp) => { + let otp = prevOtp; + otp = otp.slice(0, currentIndex) + otp.slice(currentIndex + 1); + return otp; }); break; @@ -91,7 +88,7 @@ function OTP({ let indexToEnter = 0; while (indexToEnter <= currentIndex) { - if (value[indexToEnter] && indexToEnter < currentIndex) { + if (inputRefs.current[indexToEnter].value && indexToEnter < currentIndex) { indexToEnter += 1; } else { break; @@ -131,7 +128,7 @@ function OTP({ let indexToEnter = 0; while (indexToEnter <= currentIndex) { - if (value[indexToEnter] && indexToEnter < currentIndex) { + if (inputRefs.current[indexToEnter].value && indexToEnter < currentIndex) { indexToEnter += 1; } else { break; @@ -167,7 +164,7 @@ function OTP({ onChange: (event) => handleChange(event, index), onClick: (event) => handleClick(event, index), onPaste: (event) => handlePaste(event, index), - value: value[index], + value: value[index] ?? '', }, }} /> @@ -180,6 +177,7 @@ function OTP({ export default function OTPInput() { const [otp, setOtp] = React.useState(''); + return ( Date: Wed, 17 Jan 2024 17:30:46 +0530 Subject: [PATCH 30/32] refactor --- docs/data/base/components/input/OTPInput.js | 9 ++++----- docs/data/base/components/input/OTPInput.tsx | 9 ++++----- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/docs/data/base/components/input/OTPInput.js b/docs/data/base/components/input/OTPInput.js index 99d7fe44ccc737..6d532ee3e578b3 100644 --- a/docs/data/base/components/input/OTPInput.js +++ b/docs/data/base/components/input/OTPInput.js @@ -40,8 +40,8 @@ function OTP({ separator, inputCount, value, onChange }) { case 'Delete': event.preventDefault(); onChange((prevOtp) => { - let otp = prevOtp; - otp = otp.slice(0, currentIndex) + otp.slice(currentIndex + 1); + const otp = + prevOtp.slice(0, currentIndex) + prevOtp.slice(currentIndex + 1); return otp; }); @@ -54,11 +54,10 @@ function OTP({ separator, inputCount, value, onChange }) { } onChange((prevOtp) => { - let otp = prevOtp; - otp = otp.slice(0, currentIndex) + otp.slice(currentIndex + 1); + const otp = + prevOtp.slice(0, currentIndex) + prevOtp.slice(currentIndex + 1); return otp; }); - break; default: diff --git a/docs/data/base/components/input/OTPInput.tsx b/docs/data/base/components/input/OTPInput.tsx index 02bed95bbcce47..803c68c3543704 100644 --- a/docs/data/base/components/input/OTPInput.tsx +++ b/docs/data/base/components/input/OTPInput.tsx @@ -54,8 +54,8 @@ function OTP({ case 'Delete': event.preventDefault(); onChange((prevOtp) => { - let otp = prevOtp; - otp = otp.slice(0, currentIndex) + otp.slice(currentIndex + 1); + const otp = + prevOtp.slice(0, currentIndex) + prevOtp.slice(currentIndex + 1); return otp; }); @@ -68,11 +68,10 @@ function OTP({ } onChange((prevOtp) => { - let otp = prevOtp; - otp = otp.slice(0, currentIndex) + otp.slice(currentIndex + 1); + const otp = + prevOtp.slice(0, currentIndex) + prevOtp.slice(currentIndex + 1); return otp; }); - break; default: From 7dee93b997e710c0d33aa4c32045997055f7288f Mon Sep 17 00:00:00 2001 From: sai6855 Date: Thu, 18 Jan 2024 11:16:09 +0530 Subject: [PATCH 31/32] change inputCount to length --- docs/data/base/components/input/OTPInput.js | 20 +++++++++---------- docs/data/base/components/input/OTPInput.tsx | 20 +++++++++---------- .../components/input/OTPInput.tsx.preview | 2 +- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/docs/data/base/components/input/OTPInput.js b/docs/data/base/components/input/OTPInput.js index 6d532ee3e578b3..4b3e5512147af8 100644 --- a/docs/data/base/components/input/OTPInput.js +++ b/docs/data/base/components/input/OTPInput.js @@ -3,8 +3,8 @@ import PropTypes from 'prop-types'; import { Input as BaseInput } from '@mui/base/Input'; import { Box, styled } from '@mui/system'; -function OTP({ separator, inputCount, value, onChange }) { - const inputRefs = React.useRef(new Array(inputCount).fill(null)); +function OTP({ separator, length, value, onChange }) { + const inputRefs = React.useRef(new Array(length).fill(null)); const focusInput = (targetIndex) => { const targetInput = inputRefs.current[targetIndex]; @@ -32,7 +32,7 @@ function OTP({ separator, inputCount, value, onChange }) { break; case 'ArrowRight': event.preventDefault(); - if (currentIndex < inputCount - 1) { + if (currentIndex < length - 1) { focusInput(currentIndex + 1); selectInput(currentIndex + 1); } @@ -83,7 +83,7 @@ function OTP({ separator, inputCount, value, onChange }) { return otpArray.join(''); }); if (currentValue !== '') { - if (currentIndex < inputCount - 1) { + if (currentIndex < length - 1) { focusInput(currentIndex + 1); } } @@ -100,7 +100,7 @@ function OTP({ separator, inputCount, value, onChange }) { // Check if there is text data in the clipboard if (clipboardData.types.includes('text/plain')) { let pastedText = clipboardData.getData('text/plain'); - pastedText = pastedText.substring(0, inputCount).trim(); + pastedText = pastedText.substring(0, length).trim(); let indexToEnter = 0; while (indexToEnter <= currentIndex) { @@ -113,7 +113,7 @@ function OTP({ separator, inputCount, value, onChange }) { const otpArray = value.split(''); - for (let i = indexToEnter; i < inputCount; i += 1) { + for (let i = indexToEnter; i < length; i += 1) { const lastValue = pastedText[i - indexToEnter] ?? ' '; otpArray[i] = lastValue; } @@ -124,7 +124,7 @@ function OTP({ separator, inputCount, value, onChange }) { return ( - {new Array(inputCount).fill(null).map((_, index) => ( + {new Array(length).fill(null).map((_, index) => ( - {index === inputCount - 1 ? null : separator} + {index === length - 1 ? null : separator} ))} @@ -152,7 +152,7 @@ function OTP({ separator, inputCount, value, onChange }) { } OTP.propTypes = { - inputCount: PropTypes.number.isRequired, + length: PropTypes.number.isRequired, onChange: PropTypes.func.isRequired, separator: PropTypes.node, value: PropTypes.string.isRequired, @@ -169,7 +169,7 @@ export default function OTPInput() { gap: 2, }} > - -} value={otp} onChange={setOtp} inputCount={5} /> + -} value={otp} onChange={setOtp} length={5} /> Entered value: {otp} ); diff --git a/docs/data/base/components/input/OTPInput.tsx b/docs/data/base/components/input/OTPInput.tsx index 803c68c3543704..4c03d745076162 100644 --- a/docs/data/base/components/input/OTPInput.tsx +++ b/docs/data/base/components/input/OTPInput.tsx @@ -4,17 +4,17 @@ import { Box, styled } from '@mui/system'; function OTP({ separator, - inputCount, + length, value, onChange, }: { separator: React.ReactNode; - inputCount: number; + length: number; value: string; onChange: React.Dispatch>; }) { const inputRefs = React.useRef( - new Array(inputCount).fill(null), + new Array(length).fill(null), ); const focusInput = (targetIndex: number) => { @@ -46,7 +46,7 @@ function OTP({ break; case 'ArrowRight': event.preventDefault(); - if (currentIndex < inputCount - 1) { + if (currentIndex < length - 1) { focusInput(currentIndex + 1); selectInput(currentIndex + 1); } @@ -100,7 +100,7 @@ function OTP({ return otpArray.join(''); }); if (currentValue !== '') { - if (currentIndex < inputCount - 1) { + if (currentIndex < length - 1) { focusInput(currentIndex + 1); } } @@ -123,7 +123,7 @@ function OTP({ // Check if there is text data in the clipboard if (clipboardData.types.includes('text/plain')) { let pastedText = clipboardData.getData('text/plain'); - pastedText = pastedText.substring(0, inputCount).trim(); + pastedText = pastedText.substring(0, length).trim(); let indexToEnter = 0; while (indexToEnter <= currentIndex) { @@ -136,7 +136,7 @@ function OTP({ const otpArray = value.split(''); - for (let i = indexToEnter; i < inputCount; i += 1) { + for (let i = indexToEnter; i < length; i += 1) { const lastValue = pastedText[i - indexToEnter] ?? ' '; otpArray[i] = lastValue; } @@ -147,7 +147,7 @@ function OTP({ return ( - {new Array(inputCount).fill(null).map((_, index) => ( + {new Array(length).fill(null).map((_, index) => ( - {index === inputCount - 1 ? null : separator} + {index === length - 1 ? null : separator} ))} @@ -185,7 +185,7 @@ export default function OTPInput() { gap: 2, }} > - -} value={otp} onChange={setOtp} inputCount={5} /> + -} value={otp} onChange={setOtp} length={5} /> Entered value: {otp} ); diff --git a/docs/data/base/components/input/OTPInput.tsx.preview b/docs/data/base/components/input/OTPInput.tsx.preview index b38359fd3aca3e..9e5f02b24737cc 100644 --- a/docs/data/base/components/input/OTPInput.tsx.preview +++ b/docs/data/base/components/input/OTPInput.tsx.preview @@ -1,2 +1,2 @@ --} value={otp} onChange={setOtp} inputCount={5} /> +-} value={otp} onChange={setOtp} length={5} /> Entered value: {otp} \ No newline at end of file From 0da0fb5b03fba61fa46fd7f064efd52de0710d30 Mon Sep 17 00:00:00 2001 From: sai6855 Date: Thu, 18 Jan 2024 11:20:21 +0530 Subject: [PATCH 32/32] pnpm prettier --- docs/data/base/components/input/OTPInput.tsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/data/base/components/input/OTPInput.tsx b/docs/data/base/components/input/OTPInput.tsx index 4c03d745076162..16342a4935cf6d 100644 --- a/docs/data/base/components/input/OTPInput.tsx +++ b/docs/data/base/components/input/OTPInput.tsx @@ -13,9 +13,7 @@ function OTP({ value: string; onChange: React.Dispatch>; }) { - const inputRefs = React.useRef( - new Array(length).fill(null), - ); + const inputRefs = React.useRef(new Array(length).fill(null)); const focusInput = (targetIndex: number) => { const targetInput = inputRefs.current[targetIndex];