The paste command works on Windows computer but not on MacOS. However, I notice right clicking to open the context menu and clicking on paste does work. This seems a bit strange.
Here's a link to the component hosted, https://otpinput.vercel.app/ and here's the link to the full code, https://github.com/contigen/otp-input/blob/main/src/input/index.tsx
I've attempted several approaches to handle the paste functionality. I tried handling the paste event directly on the form element using onPaste={handlePaste} with a handler that distributed the pasted numbers across input fields. When that didn't work, I moved to handling paste events on individual input elements using useEffect hooks with addEventListener('paste', handlePasteEvent), that still didn't work. I then tried a different approach using the input event instead of paste, detecting paste operations by checking if the input value length was greater than 1, which still didn't work.
Below are some important code snippet to directed related to this
function handlePaste(evt: ClipboardEvent<HTMLFormElement>) {
const $input = evt.target as HTMLInputElement;
const $inputsParent = $input.parentElement!;
const inputsLength = $inputsParent.childElementCount;
const clip = evt.clipboardData.getData(`text`);
for (let i = 0; i < inputsLength; i++) {
const data = clip[i];
if (isNaN(+data)) {
evt.preventDefault();
continue;
}
// eslint-disable-next-line no-extra-semi
($inputsParent.children[i] as HTMLInputElement).value = data;
($inputsParent.lastElementChild as HTMLInputElement).focus();
}
}
return (
<form
className="form-otp"
onSubmit={handleSubmit}
onChange={handleChange}
onKeyDown={handleKeyDown}
onKeyUp={handleKeyUp}
onPaste={handlePaste}
ref={formRef}
>
<div className="form-otp__box">
{INPUTS_LENGTH.map((_, idx, arr) => (
<input
key={crypto.randomUUID()}
type="text"
pattern="[0-9]"
maxLength={1}
name={`input${idx}`}
className="form-otp__input"
required
placeholder="・"
inputMode="numeric"
enterKeyHint={idx === arr.length - 1 ? `done` : `next`}
autoComplete="one-time-code"
/>
))}
</div>
</form>
);
I reviewed the code you linked on GitHub and determined that the form's onKeyDown handler function is causing the "Cmd + V" paste issue.
At the top of the handleKeyDown
function, you will want to extend your !evt.ctrlKey
check to check the "meta key" isn't being pressed either. This may look something like the following:
if ((!evt.ctrlKey && !evt.metaKey) && key.length === 1 && isNaN(+key)) evt.preventDefault()