From 6de0a173cae6d840c0f5b75b4725e15032d7e166 Mon Sep 17 00:00:00 2001 From: Aironas Kulvelis Date: Sat, 31 May 2025 00:07:18 +0300 Subject: [PATCH] expose blur ref --- README.MD | 1 + src/OtpInput/OtpInput.tsx | 4 ++-- src/OtpInput/OtpInput.types.ts | 1 + src/OtpInput/__tests__/useOtpInput.test.ts | 11 +++++++++++ src/OtpInput/useOtpInput.ts | 6 +++++- src/index.d.ts | 5 +++++ 6 files changed, 25 insertions(+), 3 deletions(-) diff --git a/README.MD b/README.MD index 9436829..743e5f8 100644 --- a/README.MD +++ b/README.MD @@ -144,6 +144,7 @@ The `react-native-otp-entry` component exposes these functions with `ref`: | ---------- | ------------------------ | ---------------------------------- | | `clear` | () => void; | Clears the value of the OTP input. | | `focus` | () => void; | Focus of the OTP input. | +| `blur` | () => void; | Blurs the OTP input. | | `setValue` | (value: string) => void; | Sets the value of the OTP input. | ## License diff --git a/src/OtpInput/OtpInput.tsx b/src/OtpInput/OtpInput.tsx index 55c14b6..f1efc5d 100644 --- a/src/OtpInput/OtpInput.tsx +++ b/src/OtpInput/OtpInput.tsx @@ -9,7 +9,7 @@ import { useOtpInput } from "./useOtpInput"; export const OtpInput = forwardRef((props, ref) => { const { models: { text, inputRef, focusedInputIndex, isFocused, placeholder }, - actions: { clear, handlePress, handleTextChange, focus, handleFocus, handleBlur }, + actions: { clear, handlePress, handleTextChange, focus, handleFocus, handleBlur, blur }, forms: { setTextWithRef }, } = useOtpInput(props); const { @@ -37,7 +37,7 @@ export const OtpInput = forwardRef((props, ref) => { placeholderTextStyle, } = theme; - useImperativeHandle(ref, () => ({ clear, focus, setValue: setTextWithRef })); + useImperativeHandle(ref, () => ({ clear, focus, setValue: setTextWithRef, blur })); const generatePinCodeContainerStyle = (isFocusedContainer: boolean, char: string) => { const stylesArray = [styles.codeContainer, pinCodeContainerStyle]; diff --git a/src/OtpInput/OtpInput.types.ts b/src/OtpInput/OtpInput.types.ts index 85da6e0..6c50a3b 100644 --- a/src/OtpInput/OtpInput.types.ts +++ b/src/OtpInput/OtpInput.types.ts @@ -24,6 +24,7 @@ export interface OtpInputRef { clear: () => void; focus: () => void; setValue: (value: string) => void; + blur: () => void; } export interface Theme { diff --git a/src/OtpInput/__tests__/useOtpInput.test.ts b/src/OtpInput/__tests__/useOtpInput.test.ts index 20b23bb..6e5010f 100644 --- a/src/OtpInput/__tests__/useOtpInput.test.ts +++ b/src/OtpInput/__tests__/useOtpInput.test.ts @@ -48,6 +48,17 @@ describe("useOtpInput", () => { }); }); + test("blur() should blur input", () => { + jest.spyOn(React, "useRef").mockReturnValueOnce({ current: { blur: jest.fn() } } as any); + + const { result } = renderUseOtInput(); + result.current.actions.blur(); + + act(() => { + expect(result.current.models.inputRef.current?.blur).toHaveBeenCalled(); + }); + }); + test("setTextWithRef() should only call setText the first 'numberOfDigits' characters", () => { jest.spyOn(React, "useState").mockImplementation(() => ["", jest.fn()]); const { result } = renderUseOtInput(); diff --git a/src/OtpInput/useOtpInput.ts b/src/OtpInput/useOtpInput.ts index 3d6456f..d8545b7 100644 --- a/src/OtpInput/useOtpInput.ts +++ b/src/OtpInput/useOtpInput.ts @@ -61,6 +61,10 @@ export const useOtpInput = ({ inputRef.current?.focus(); }; + const blur = () => { + inputRef.current?.blur(); + }; + const handleFocus = () => { setIsFocused(true); onFocus?.(); @@ -73,7 +77,7 @@ export const useOtpInput = ({ return { models: { text, inputRef, focusedInputIndex, isFocused, placeholder }, - actions: { handlePress, handleTextChange, clear, focus, handleFocus, handleBlur }, + actions: { handlePress, handleTextChange, clear, focus, blur, handleFocus, handleBlur }, forms: { setText, setTextWithRef }, }; }; diff --git a/src/index.d.ts b/src/index.d.ts index 3c93345..f10a17a 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -107,6 +107,11 @@ declare module "OTPInput" { * @param value - The value to be set. */ setValue: (value: string) => void; + + /** + * Blur the OTP input. + */ + blur: () => void; } export interface Theme {