diff --git a/README.md b/README.md
index f19bec9..8a3b2e5 100644
--- a/README.md
+++ b/README.md
@@ -220,6 +220,13 @@ input::placeholder {
false |
Disables all the input fields. |
+
+ paste-filter |
+ boolean |
+ false |
+ false |
+ When enabled, filters out invalid characters during paste operations instead of rejecting the entire paste. For "number" input type, only numeric characters are kept. For "letter-numeric" type, only alphanumeric characters are kept. |
+
## 🤺 Methods
diff --git a/src/components/vue3-otp-input.vue b/src/components/vue3-otp-input.vue
index 9d1e4d6..dd7bf71 100644
--- a/src/components/vue3-otp-input.vue
+++ b/src/components/vue3-otp-input.vue
@@ -28,6 +28,7 @@ type Props = {
placeholder?: string[];
isDisabled?: boolean;
shouldFocusOrder?: boolean;
+ pasteFilter?: boolean;
};
const props = withDefaults(defineProps(), {
@@ -40,6 +41,7 @@ const props = withDefaults(defineProps(), {
isDisabled: false,
placeholder: () => [],
conditionalClass: () => [],
+ pasteFilter: false,
});
const emit = defineEmits<{
@@ -112,20 +114,42 @@ const changeCodeAtFocus = (value: number | string) => {
// Handle pasted OTP
const handleOnPaste = (event: any) => {
event.preventDefault();
- const pastedData = event.clipboardData
+ let pastedData = event.clipboardData
.getData("text/plain")
- .slice(0, props.numInputs - activeInput.value)
.split("");
- if (props.inputType === "number" && !pastedData.join("").match(/^\d+$/)) {
- return "Invalid pasted data";
- }
- if (
- props.inputType === "letter-numeric" &&
- !pastedData.join("").match(/^\w+$/)
- ) {
- return "Invalid pasted data";
+ if (props.pasteFilter) {
+ // Filter characters based on input type when pasteFilter is enabled
+ if (props.inputType === "number") {
+ pastedData = pastedData.filter((char: string) => /^\d$/.test(char));
+ } else if (props.inputType === "letter-numeric") {
+ pastedData = pastedData.filter((char: string) => /^\w$/.test(char));
+ }
+
+ // If no valid characters remain after filtering, return early
+ if (pastedData.length === 0) {
+ return "No valid characters to paste";
+ }
+
+ // Apply length limit after filtering
+ pastedData = pastedData.slice(0, props.numInputs - activeInput.value);
+ } else {
+ // Apply length limit before validation for original behavior
+ pastedData = pastedData.slice(0, props.numInputs - activeInput.value);
+
+ // Original validation behavior when pasteFilter is disabled
+ if (props.inputType === "number" && !pastedData.join("").match(/^\d+$/)) {
+ return "Invalid pasted data";
+ }
+
+ if (
+ props.inputType === "letter-numeric" &&
+ !pastedData.join("").match(/^\w+$/)
+ ) {
+ return "Invalid pasted data";
+ }
}
+
// Paste data from focused input onwards
const currentCharsInOtp = otp.value.slice(0, activeInput.value);
const combinedWithPastedData = currentCharsInOtp.concat(pastedData);