From 27d9f73e667aac7a82ea4d06e8da9f6350301fc0 Mon Sep 17 00:00:00 2001 From: anday013 Date: Sun, 7 Apr 2024 11:21:06 +0200 Subject: [PATCH 1/5] docs: add diagram explaining theme props --- README.MD | 3 ++- otp.drawio.svg | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 otp.drawio.svg diff --git a/README.MD b/README.MD index cfddc13..c55faa0 100644 --- a/README.MD +++ b/README.MD @@ -93,7 +93,6 @@ The `react-native-otp-entry` component accepts the following props: | Theme | Type | Description | | ------------------------------- | --------- | ---------------------------------------------------------------------------------- | | `containerStyle` | ViewStyle | Custom styles for the root `View`. | -| `inputsContainerStyle` | ViewStyle | Custom styles for the container that holds the input fields. | | `pinCodeContainerStyle` | ViewStyle | Custom styles for the container that wraps each individual digit in the OTP entry. | | `pinCodeTextStyle` | TextStyle | Custom styles for the text within each individual digit in the OTP entry. | | `focusStickStyle` | ViewStyle | Custom styles for the focus stick, which indicates the focused input field. | @@ -103,6 +102,8 @@ The `react-native-otp-entry` component accepts the following props: Note: The `ViewStyle` and `TextStyle` types are imported from `react-native` and represent the style objects used in React Native for views and text, respectively. +![Theme](otp.drawio.svg) + ## Ref The `react-native-otp-entry` component exposes these functions with `ref`: diff --git a/otp.drawio.svg b/otp.drawio.svg new file mode 100644 index 0000000..a3132db --- /dev/null +++ b/otp.drawio.svg @@ -0,0 +1,4 @@ + + + +
2
2
3
3
1
1
containerStyle
containerS...
pinCodeContainerStyle
pinCodeCon...
filledPinCodeContainerStyle
filledPinC...
pinCodeTextStyle
pinCodeTex...
focusStickStyle
focusStick...
focusedPinCodeContainerStyle
focuse...
Text is not SVG - cannot display
\ No newline at end of file From 52a29f554eecf7c3140d4ac81d1e8818467faa23 Mon Sep 17 00:00:00 2001 From: Anday <48630069+anday013@users.noreply.github.com> Date: Sun, 7 Apr 2024 12:37:15 +0200 Subject: [PATCH 2/5] chore: decrease lib install size (#49) * chore: remove /dist from git * chore: keep only /dist in npm * chore: build for publish only necessary files * chore: set prepublishOnly --- .gitignore | 3 +- dist/jest.config.d.ts | 3 - dist/jest.config.js | 21 --- dist/jest.setupFilesAfterEnv.d.ts | 1 - dist/jest.setupFilesAfterEnv.js | 3 - dist/src/OtpInput/OtpInput.d.ts | 3 - dist/src/OtpInput/OtpInput.js | 46 ----- dist/src/OtpInput/OtpInput.styles.d.ts | 35 ---- dist/src/OtpInput/OtpInput.styles.js | 35 ---- dist/src/OtpInput/OtpInput.types.d.ts | 29 --- dist/src/OtpInput/OtpInput.types.js | 2 - dist/src/OtpInput/VerticalStick.d.ts | 9 - dist/src/OtpInput/VerticalStick.js | 28 --- .../src/OtpInput/__tests__/OtpInput.test.d.ts | 1 - dist/src/OtpInput/__tests__/OtpInput.test.js | 171 ------------------ .../__tests__/VerticalStick.test.d.ts | 1 - .../OtpInput/__tests__/VerticalStick.test.js | 16 -- .../OtpInput/__tests__/useOtpInput.test.d.ts | 1 - .../OtpInput/__tests__/useOtpInput.test.js | 126 ------------- dist/src/OtpInput/index.d.ts | 2 - dist/src/OtpInput/index.js | 18 -- dist/src/OtpInput/useOtpInput.d.ts | 23 --- dist/src/OtpInput/useOtpInput.js | 49 ----- dist/src/index.d.ts | 1 - dist/src/index.js | 5 - package.json | 12 +- tsconfig.prod.json | 4 + 27 files changed, 15 insertions(+), 633 deletions(-) delete mode 100644 dist/jest.config.d.ts delete mode 100644 dist/jest.config.js delete mode 100644 dist/jest.setupFilesAfterEnv.d.ts delete mode 100644 dist/jest.setupFilesAfterEnv.js delete mode 100644 dist/src/OtpInput/OtpInput.d.ts delete mode 100644 dist/src/OtpInput/OtpInput.js delete mode 100644 dist/src/OtpInput/OtpInput.styles.d.ts delete mode 100644 dist/src/OtpInput/OtpInput.styles.js delete mode 100644 dist/src/OtpInput/OtpInput.types.d.ts delete mode 100644 dist/src/OtpInput/OtpInput.types.js delete mode 100644 dist/src/OtpInput/VerticalStick.d.ts delete mode 100644 dist/src/OtpInput/VerticalStick.js delete mode 100644 dist/src/OtpInput/__tests__/OtpInput.test.d.ts delete mode 100644 dist/src/OtpInput/__tests__/OtpInput.test.js delete mode 100644 dist/src/OtpInput/__tests__/VerticalStick.test.d.ts delete mode 100644 dist/src/OtpInput/__tests__/VerticalStick.test.js delete mode 100644 dist/src/OtpInput/__tests__/useOtpInput.test.d.ts delete mode 100644 dist/src/OtpInput/__tests__/useOtpInput.test.js delete mode 100644 dist/src/OtpInput/index.d.ts delete mode 100644 dist/src/OtpInput/index.js delete mode 100644 dist/src/OtpInput/useOtpInput.d.ts delete mode 100644 dist/src/OtpInput/useOtpInput.js delete mode 100644 dist/src/index.d.ts delete mode 100644 dist/src/index.js create mode 100644 tsconfig.prod.json diff --git a/.gitignore b/.gitignore index f2a529e..9038659 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ node_modules .DS_Store -coverage \ No newline at end of file +coverage +dist \ No newline at end of file diff --git a/dist/jest.config.d.ts b/dist/jest.config.d.ts deleted file mode 100644 index 0c491e5..0000000 --- a/dist/jest.config.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -import type { Config } from "@jest/types"; -declare const config: Config.InitialOptions; -export default config; diff --git a/dist/jest.config.js b/dist/jest.config.js deleted file mode 100644 index 9c8d4b4..0000000 --- a/dist/jest.config.js +++ /dev/null @@ -1,21 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -const Presets = require("ts-jest/presets"); -const config = { - ...Presets.defaults, - preset: "react-native", - transform: { - "^.+\\.jsx$": "babel-jest", - "^.+\\.tsx?$": [ - "ts-jest", - { - tsconfig: "tsconfig.jest.json", - }, - ], - }, - moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"], - modulePathIgnorePatterns: ["./dist/"], - coverageReporters: ["json-summary", "html"], - setupFilesAfterEnv: ["./jest.setupFilesAfterEnv.ts"], -}; -exports.default = config; diff --git a/dist/jest.setupFilesAfterEnv.d.ts b/dist/jest.setupFilesAfterEnv.d.ts deleted file mode 100644 index 534d1ed..0000000 --- a/dist/jest.setupFilesAfterEnv.d.ts +++ /dev/null @@ -1 +0,0 @@ -import "@testing-library/jest-native/extend-expect"; diff --git a/dist/jest.setupFilesAfterEnv.js b/dist/jest.setupFilesAfterEnv.js deleted file mode 100644 index 4c53a92..0000000 --- a/dist/jest.setupFilesAfterEnv.js +++ /dev/null @@ -1,3 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -require("@testing-library/jest-native/extend-expect"); diff --git a/dist/src/OtpInput/OtpInput.d.ts b/dist/src/OtpInput/OtpInput.d.ts deleted file mode 100644 index c065295..0000000 --- a/dist/src/OtpInput/OtpInput.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -/// -import { OtpInputProps, OtpInputRef } from "./OtpInput.types"; -export declare const OtpInput: import("react").ForwardRefExoticComponent>; diff --git a/dist/src/OtpInput/OtpInput.js b/dist/src/OtpInput/OtpInput.js deleted file mode 100644 index c1c5e20..0000000 --- a/dist/src/OtpInput/OtpInput.js +++ /dev/null @@ -1,46 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.OtpInput = void 0; -const react_1 = require("react"); -const react_native_1 = require("react-native"); -const OtpInput_styles_1 = require("./OtpInput.styles"); -const VerticalStick_1 = require("./VerticalStick"); -const useOtpInput_1 = require("./useOtpInput"); -exports.OtpInput = (0, react_1.forwardRef)((props, ref) => { - const { models: { text, inputRef, focusedInputIndex, hasCursor }, actions: { clear, handlePress, handleTextChange, focus, handleFocus, handleBlur }, forms: { setTextWithRef }, } = (0, useOtpInput_1.useOtpInput)(props); - const { disabled, numberOfDigits = 6, autoFocus = true, hideStick, focusColor = "#A4D0A4", focusStickBlinkingDuration, secureTextEntry = false, theme = {}, textInputProps, } = props; - const { containerStyle, inputsContainerStyle, pinCodeContainerStyle, pinCodeTextStyle, focusStickStyle, focusedPinCodeContainerStyle, filledPinCodeContainerStyle, disabledPinCodeContainerStyle, } = theme; - (0, react_1.useImperativeHandle)(ref, () => ({ clear, focus, setValue: setTextWithRef })); - const generatePinCodeContainerStyle = (isFocusedInput, char) => { - const stylesArray = [OtpInput_styles_1.styles.codeContainer, pinCodeContainerStyle]; - if (focusColor && isFocusedInput) { - stylesArray.push({ borderColor: focusColor }); - } - if (focusedPinCodeContainerStyle && isFocusedInput) { - stylesArray.push(focusedPinCodeContainerStyle); - } - if (filledPinCodeContainerStyle && Boolean(char)) { - stylesArray.push(filledPinCodeContainerStyle); - } - if (disabledPinCodeContainerStyle && disabled) { - stylesArray.push(disabledPinCodeContainerStyle); - } - return stylesArray; - }; - return ( - - {Array(numberOfDigits) - .fill(0) - .map((_, index) => { - const char = text[index]; - const isFocusedInput = index === focusedInputIndex && !disabled && Boolean(hasCursor); - return ( - {isFocusedInput && !hideStick ? () : ( - {char && secureTextEntry ? "•" : char} - )} - ); - })} - - - ); -}); diff --git a/dist/src/OtpInput/OtpInput.styles.d.ts b/dist/src/OtpInput/OtpInput.styles.d.ts deleted file mode 100644 index ba365c1..0000000 --- a/dist/src/OtpInput/OtpInput.styles.d.ts +++ /dev/null @@ -1,35 +0,0 @@ -export declare const styles: { - container: { - flexDirection: "row"; - }; - inputsContainer: { - flexDirection: "row"; - flex: number; - justifyContent: "space-between"; - }; - codeContainer: { - borderWidth: number; - borderRadius: number; - borderColor: string; - height: number; - width: number; - justifyContent: "center"; - alignItems: "center"; - }; - codeText: { - fontSize: number; - }; - hiddenInput: { - opacity: number; - position: "absolute"; - left: 0; - right: 0; - top: 0; - bottom: 0; - }; - stick: { - width: number; - height: number; - backgroundColor: string; - }; -}; diff --git a/dist/src/OtpInput/OtpInput.styles.js b/dist/src/OtpInput/OtpInput.styles.js deleted file mode 100644 index 25c6cf8..0000000 --- a/dist/src/OtpInput/OtpInput.styles.js +++ /dev/null @@ -1,35 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.styles = void 0; -const react_native_1 = require("react-native"); -exports.styles = react_native_1.StyleSheet.create({ - container: { - flexDirection: "row", - }, - inputsContainer: { - flexDirection: "row", - flex: 1, - justifyContent: "space-between", - }, - codeContainer: { - borderWidth: 1, - borderRadius: 12, - borderColor: "#DFDFDE", - height: 60, - width: 44, - justifyContent: "center", - alignItems: "center", - }, - codeText: { - fontSize: 28, - }, - hiddenInput: { - ...react_native_1.StyleSheet.absoluteFillObject, - opacity: 0.01, - }, - stick: { - width: 2, - height: 30, - backgroundColor: "green", - }, -}); diff --git a/dist/src/OtpInput/OtpInput.types.d.ts b/dist/src/OtpInput/OtpInput.types.d.ts deleted file mode 100644 index de8d21b..0000000 --- a/dist/src/OtpInput/OtpInput.types.d.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { ColorValue, TextInputProps, TextStyle, ViewStyle } from "react-native"; -export interface OtpInputProps { - numberOfDigits?: number; - autoFocus?: boolean; - focusColor?: ColorValue; - onTextChange?: (text: string) => void; - onFilled?: (text: string) => void; - hideStick?: boolean; - focusStickBlinkingDuration?: number; - secureTextEntry?: boolean; - theme?: Theme; - disabled?: boolean; - textInputProps?: TextInputProps; -} -export interface OtpInputRef { - clear: () => void; - focus: () => void; - setValue: (value: string) => void; -} -export interface Theme { - containerStyle?: ViewStyle; - inputsContainerStyle?: ViewStyle; - pinCodeContainerStyle?: ViewStyle; - filledPinCodeContainerStyle?: ViewStyle; - pinCodeTextStyle?: TextStyle; - focusStickStyle?: ViewStyle; - focusedPinCodeContainerStyle?: ViewStyle; - disabledPinCodeContainerStyle?: ViewStyle; -} diff --git a/dist/src/OtpInput/OtpInput.types.js b/dist/src/OtpInput/OtpInput.types.js deleted file mode 100644 index c8ad2e5..0000000 --- a/dist/src/OtpInput/OtpInput.types.js +++ /dev/null @@ -1,2 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/dist/src/OtpInput/VerticalStick.d.ts b/dist/src/OtpInput/VerticalStick.d.ts deleted file mode 100644 index 0546512..0000000 --- a/dist/src/OtpInput/VerticalStick.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -/// -import { ColorValue, ViewStyle } from "react-native"; -interface VerticalStickProps { - focusColor?: ColorValue; - style?: ViewStyle; - focusStickBlinkingDuration?: number; -} -export declare const VerticalStick: React.FC; -export {}; diff --git a/dist/src/OtpInput/VerticalStick.js b/dist/src/OtpInput/VerticalStick.js deleted file mode 100644 index 961edbf..0000000 --- a/dist/src/OtpInput/VerticalStick.js +++ /dev/null @@ -1,28 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.VerticalStick = void 0; -const react_1 = require("react"); -const react_native_1 = require("react-native"); -const OtpInput_styles_1 = require("./OtpInput.styles"); -exports.VerticalStick = (0, react_1.memo)(({ focusColor, style, focusStickBlinkingDuration = 350 }) => { - const opacityAnim = (0, react_1.useRef)(new react_native_1.Animated.Value(1)).current; - (0, react_1.useEffect)(() => { - react_native_1.Animated.loop(react_native_1.Animated.sequence([ - react_native_1.Animated.timing(opacityAnim, { - toValue: 0, - useNativeDriver: true, - duration: focusStickBlinkingDuration, - }), - react_native_1.Animated.timing(opacityAnim, { - toValue: 1, - useNativeDriver: true, - duration: focusStickBlinkingDuration, - }), - ]), { - iterations: -1, - }).start(); - }, []); - return ( - - ); -}); diff --git a/dist/src/OtpInput/__tests__/OtpInput.test.d.ts b/dist/src/OtpInput/__tests__/OtpInput.test.d.ts deleted file mode 100644 index cb0ff5c..0000000 --- a/dist/src/OtpInput/__tests__/OtpInput.test.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/dist/src/OtpInput/__tests__/OtpInput.test.js b/dist/src/OtpInput/__tests__/OtpInput.test.js deleted file mode 100644 index 0f489df..0000000 --- a/dist/src/OtpInput/__tests__/OtpInput.test.js +++ /dev/null @@ -1,171 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -const react_native_1 = require("@testing-library/react-native"); -const React = require("react"); -const react_native_2 = require("react-native"); -const OtpInput_1 = require("../OtpInput"); -const renderOtpInput = (props) => (0, react_native_1.render)(); -describe("OtpInput", () => { - describe("UI", () => { - test("should render correctly", () => { - const tree = renderOtpInput().toJSON(); - expect(tree).toMatchSnapshot(); - }); - test("should render stick if hideStick is false", () => { - renderOtpInput({ hideStick: false }); - const stick = react_native_1.screen.getByTestId("otp-input-stick"); - expect(stick).toBeTruthy(); - }); - test('should not render stick if "hideStick" is true', () => { - renderOtpInput({ hideStick: true }); - const stick = react_native_1.screen.queryByTestId("otp-input-stick"); - expect(stick).toBeFalsy(); - }); - test('should not show values if "secureTextEntry" is true', () => { - renderOtpInput({ secureTextEntry: true }); - const input = react_native_1.screen.getByTestId("otp-input-hidden"); - react_native_1.fireEvent.changeText(input, "123456"); - const inputs = react_native_1.screen.getAllByTestId("otp-input"); - inputs.forEach((input) => { - expect(input).toHaveTextContent("•"); - }); - }); - test("should have 6 inputs by default", () => { - renderOtpInput(); - const inputs = react_native_1.screen.getAllByTestId("otp-input"); - expect(inputs).toHaveLength(6); - }); - test("should autoFocused by default", () => { - renderOtpInput(); - const input = react_native_1.screen.getByTestId("otp-input-hidden"); - expect(input.props.autoFocus).toBe(true); - }); - test('should not focus if "autoFocus" is false', () => { - renderOtpInput({ autoFocus: false }); - const input = react_native_1.screen.getByTestId("otp-input-hidden"); - expect(input.props.autoFocus).toBe(false); - }); - test("should not focus if disabled is true", () => { - renderOtpInput({ - disabled: true, - focusColor: "#444", - }); - const inputs = react_native_1.screen.getAllByTestId("otp-input"); - expect(inputs[0]).not.toHaveStyle({ borderColor: "#444" }); - }); - test("it should not allow input if disabled is true", () => { - renderOtpInput({ disabled: true }); - const input = react_native_1.screen.getByTestId("otp-input-hidden"); - react_native_1.fireEvent.changeText(input, "123456"); - const inputs = react_native_1.screen.getAllByTestId("otp-input"); - expect(inputs[0]).not.toHaveTextContent("1"); - inputs.forEach((i) => expect(i).toBeDisabled()); - const hiddenInput = react_native_1.screen.getByTestId("otp-input-hidden"); - expect(hiddenInput).toBeDisabled(); - }); - test("focusColor should not be overridden by theme", () => { - renderOtpInput({ - focusColor: "#000", - theme: { pinCodeContainerStyle: { borderColor: "#fff" } }, - }); - const inputs = react_native_1.screen.getAllByTestId("otp-input"); - expect(inputs[0]).toHaveStyle({ borderColor: "#000" }); - }); - test("focusedPinCodeContainerStyle should not be overridden by theme", () => { - renderOtpInput({ - focusColor: "#000", - theme: { focusedPinCodeContainerStyle: { borderColor: "#fff", backgroundColor: "green" } }, - }); - const inputs = react_native_1.screen.getAllByTestId("otp-input"); - expect(inputs[0]).toHaveStyle({ borderColor: "#fff", backgroundColor: "green" }); - }); - // Test if the number of rendered inputs is equal to the number of digits - test.each([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])("should render the correct number of inputs: %i", (numberOfDigits) => { - renderOtpInput({ numberOfDigits: numberOfDigits }); - const inputs = react_native_1.screen.getAllByTestId("otp-input"); - expect(inputs).toHaveLength(numberOfDigits); - }); - test("filledPinCodeContainerStyle should allow for new style when digit is present", () => { - renderOtpInput({ - theme: { filledPinCodeContainerStyle: { borderBottomColor: "red" } }, - }); - const input = react_native_1.screen.getByTestId("otp-input-hidden"); - react_native_1.fireEvent.changeText(input, "12"); - const inputs = react_native_1.screen.getAllByTestId("otp-input"); - expect(inputs[0]).toHaveStyle({ borderBottomColor: "red" }); - expect(inputs[1]).toHaveStyle({ borderBottomColor: "red" }); - expect(inputs[2]).not.toHaveStyle({ borderBottomColor: "red" }); - }); - test("disabledPinCodeContainerStyle should allow for new style when input is disabled", () => { - renderOtpInput({ - disabled: true, - theme: { disabledPinCodeContainerStyle: { borderBottomColor: "red" } }, - }); - const inputs = react_native_1.screen.getAllByTestId("otp-input"); - expect(inputs[0]).toHaveStyle({ borderBottomColor: "red" }); - }); - test('autoComplete should be set "sms-otp" on Android', () => { - react_native_2.Platform.OS = "android"; - renderOtpInput(); - const input = react_native_1.screen.getByTestId("otp-input-hidden"); - expect(input.props.autoComplete).toBe("sms-otp"); - }); - test('autoComplete should be set "one-time-code" on iOS', () => { - react_native_2.Platform.OS = "ios"; - renderOtpInput(); - const input = react_native_1.screen.getByTestId("otp-input-hidden"); - expect(input.props.autoComplete).toBe("one-time-code"); - }); - }); - describe("Logic", () => { - test("should split text on screen from the text written in the hidden input", () => { - const otp = "123456"; - renderOtpInput(); - const input = react_native_1.screen.getByTestId("otp-input-hidden"); - react_native_1.fireEvent.changeText(input, otp); - (0, react_native_1.act)(() => { - expect(react_native_1.screen.getByText("1")).toBeTruthy(); - expect(react_native_1.screen.getByText("2")).toBeTruthy(); - expect(react_native_1.screen.getByText("3")).toBeTruthy(); - expect(react_native_1.screen.getByText("4")).toBeTruthy(); - expect(react_native_1.screen.getByText("5")).toBeTruthy(); - expect(react_native_1.screen.getByText("6")).toBeTruthy(); - expect(react_native_1.screen.queryByText(otp)).not.toBeTruthy(); - }); - }); - test("ref clear() should clear input", () => { - const ref = React.createRef(); - (0, react_native_1.render)(); - const otp = "1"; - const input = react_native_1.screen.getByTestId("otp-input-hidden"); - react_native_1.fireEvent.changeText(input, otp); - (0, react_native_1.act)(() => { - ref.current?.clear(); - }); - expect(react_native_1.screen.queryByText("1")).toBeFalsy(); - }); - test("ref setValue() should set input value", () => { - const ref = React.createRef(); - (0, react_native_1.render)(); - const otp = "1"; - (0, react_native_1.act)(() => { - ref.current?.setValue(otp); - }); - expect(react_native_1.screen.getByText("1")).toBeTruthy(); - }); - test('ref setValue() should set only the first "numberOfDigits" characters', () => { - const ref = React.createRef(); - (0, react_native_1.render)(); - const otp = "123456"; - (0, react_native_1.act)(() => { - ref.current?.setValue(otp); - }); - expect(react_native_1.screen.getByText("1")).toBeTruthy(); - expect(react_native_1.screen.getByText("2")).toBeTruthy(); - expect(react_native_1.screen.getByText("3")).toBeTruthy(); - expect(react_native_1.screen.getByText("4")).toBeTruthy(); - expect(react_native_1.screen.queryByText("5")).toBeFalsy(); - expect(react_native_1.screen.queryByText("6")).toBeFalsy(); - }); - }); -}); diff --git a/dist/src/OtpInput/__tests__/VerticalStick.test.d.ts b/dist/src/OtpInput/__tests__/VerticalStick.test.d.ts deleted file mode 100644 index cb0ff5c..0000000 --- a/dist/src/OtpInput/__tests__/VerticalStick.test.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/dist/src/OtpInput/__tests__/VerticalStick.test.js b/dist/src/OtpInput/__tests__/VerticalStick.test.js deleted file mode 100644 index 9d0b158..0000000 --- a/dist/src/OtpInput/__tests__/VerticalStick.test.js +++ /dev/null @@ -1,16 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -const react_native_1 = require("@testing-library/react-native"); -const VerticalStick_1 = require("../VerticalStick"); -describe("VerticalStick", () => { - test("should set focusColor when passed", () => { - (0, react_native_1.render)(); - const stick = react_native_1.screen.getByTestId("otp-input-stick"); - expect(stick).toHaveStyle({ backgroundColor: "red" }); - }); - test("should set focusColor to 'green' if not passed", () => { - (0, react_native_1.render)(); - const stick = react_native_1.screen.getByTestId("otp-input-stick"); - expect(stick).toHaveStyle({ backgroundColor: "green" }); - }); -}); diff --git a/dist/src/OtpInput/__tests__/useOtpInput.test.d.ts b/dist/src/OtpInput/__tests__/useOtpInput.test.d.ts deleted file mode 100644 index cb0ff5c..0000000 --- a/dist/src/OtpInput/__tests__/useOtpInput.test.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {}; diff --git a/dist/src/OtpInput/__tests__/useOtpInput.test.js b/dist/src/OtpInput/__tests__/useOtpInput.test.js deleted file mode 100644 index 08af6af..0000000 --- a/dist/src/OtpInput/__tests__/useOtpInput.test.js +++ /dev/null @@ -1,126 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -const react_native_1 = require("@testing-library/react-native"); -const React = require("react"); -const react_native_2 = require("react-native"); -const useOtpInput_1 = require("../useOtpInput"); -const renderUseOtInput = (props) => (0, react_native_1.renderHook)(() => (0, useOtpInput_1.useOtpInput)({ numberOfDigits: 6, ...props })); -describe("useOtpInput", () => { - afterEach(() => { - jest.clearAllMocks(); - }); - test("should return models as defined", () => { - const { result: { current: { models: { text, focusedInputIndex, inputRef }, }, }, } = renderUseOtInput(); - expect(text).toBe(""); - expect(focusedInputIndex).toBe(0); - expect(inputRef.current).toBeNull(); - }); - test("clear() should clear text", () => { - jest.spyOn(React, "useState").mockImplementation(() => ["", jest.fn()]); - const { result } = renderUseOtInput(); - result.current.actions.clear(); - (0, react_native_1.act)(() => { - expect(result.current.forms.setText).toHaveBeenCalledWith(""); - }); - }); - test("focus() should focus on input", () => { - jest.spyOn(React, "useRef").mockReturnValue({ current: { focus: jest.fn() } }); - const { result } = renderUseOtInput(); - result.current.actions.focus(); - (0, react_native_1.act)(() => { - expect(result.current.models.inputRef.current?.focus).toHaveBeenCalled(); - }); - }); - test("setTextWithRef() should only call setText the first 'numberOfDigits' characters", () => { - jest.spyOn(React, "useState").mockImplementation(() => ["", jest.fn()]); - const { result } = renderUseOtInput(); - result.current.forms.setTextWithRef("123456789"); - (0, react_native_1.act)(() => { - expect(result.current.forms.setText).toHaveBeenCalledWith("123456"); - }); - }); - test("handlePress() should dismiss Keyboard if it's visible", () => { - jest.spyOn(react_native_2.Keyboard, "dismiss"); - jest.spyOn(react_native_2.Keyboard, "isVisible").mockReturnValue(false); - const { result } = renderUseOtInput(); - result.current.actions.handlePress(); - (0, react_native_1.act)(() => { - expect(react_native_2.Keyboard.dismiss).toHaveBeenCalled(); - }); - }); - test("handlePress() should NOT dismiss Keyboard if it's NOT visible", () => { - jest.spyOn(react_native_2.Keyboard, "dismiss"); - jest.spyOn(react_native_2.Keyboard, "isVisible").mockReturnValue(true); - const { result } = renderUseOtInput(); - result.current.actions.handlePress(); - (0, react_native_1.act)(() => { - expect(react_native_2.Keyboard.dismiss).not.toHaveBeenCalled(); - }); - }); - test("handlePress() should focus on input", () => { - jest.spyOn(React, "useRef").mockReturnValue({ current: { focus: jest.fn() } }); - const { result } = renderUseOtInput(); - result.current.actions.handlePress(); - (0, react_native_1.act)(() => { - expect(result.current.models.inputRef.current?.focus).toHaveBeenCalled(); - }); - }); - test("handleTextChange() should call setText() and onTextChange() with value", () => { - const value = "123456"; - const mockOnTextChange = jest.fn(); - jest.spyOn(React, "useState").mockImplementation(() => ["", jest.fn()]); - const { result } = renderUseOtInput({ onTextChange: mockOnTextChange }); - result.current.actions.handleTextChange(value); - (0, react_native_1.act)(() => { - expect(result.current.forms.setText).toHaveBeenCalledWith(value); - expect(mockOnTextChange).toHaveBeenCalledWith(value); - }); - }); - test("handleTextChange() should not proceed if the input is disabled", () => { - const value = "123456"; - const mockOnTextChange = jest.fn(); - jest.spyOn(React, "useState").mockImplementation(() => ["", jest.fn()]); - const { result } = renderUseOtInput({ onTextChange: mockOnTextChange, disabled: true }); - result.current.actions.handleTextChange(value); - (0, react_native_1.act)(() => { - expect(result.current.forms.setText).not.toHaveBeenCalled(); - expect(mockOnTextChange).not.toHaveBeenCalled(); - }); - }); - test("onFilled() should be called when the input filled", () => { - const value = "123456"; - const mockOnFilled = jest.fn(); - const { result } = renderUseOtInput({ onFilled: mockOnFilled }); - result.current.actions.handleTextChange(value); - (0, react_native_1.act)(() => { - expect(mockOnFilled).toHaveBeenCalledWith(value); - }); - }); - test("onFilled() should NOT be called when the input is NOT filled", () => { - const value = "12345"; - const mockOnFilled = jest.fn(); - const { result } = renderUseOtInput({ onFilled: mockOnFilled }); - result.current.actions.handleTextChange(value); - (0, react_native_1.act)(() => { - expect(mockOnFilled).not.toHaveBeenCalled(); - }); - }); - test("handleFocus() should set hasCurrentFocus to true", () => { - const mockSetState = jest.fn(); - jest.spyOn(React, "useState").mockImplementation(() => [false, mockSetState]); - const { result } = renderUseOtInput(); - result.current.actions.handleFocus(); - (0, react_native_1.act)(() => { - expect(mockSetState).toHaveBeenCalledWith(true); - }); - }); - test("handleBlur() should set hasCurrentFocus to false", () => { - const mockSetState = jest.fn(); - jest.spyOn(React, "useState").mockImplementation(() => [true, mockSetState]); - const { result } = renderUseOtInput(); - result.current.actions.handleBlur(); - (0, react_native_1.act)(() => { - expect(mockSetState).toHaveBeenCalledWith(false); - }); - }); -}); diff --git a/dist/src/OtpInput/index.d.ts b/dist/src/OtpInput/index.d.ts deleted file mode 100644 index 6b8d58e..0000000 --- a/dist/src/OtpInput/index.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./OtpInput"; -export * from "./OtpInput.types"; diff --git a/dist/src/OtpInput/index.js b/dist/src/OtpInput/index.js deleted file mode 100644 index a02e4f4..0000000 --- a/dist/src/OtpInput/index.js +++ /dev/null @@ -1,18 +0,0 @@ -"use strict"; -var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - var desc = Object.getOwnPropertyDescriptor(m, k); - if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { - desc = { enumerable: true, get: function() { return m[k]; } }; - } - Object.defineProperty(o, k2, desc); -}) : (function(o, m, k, k2) { - if (k2 === undefined) k2 = k; - o[k2] = m[k]; -})); -var __exportStar = (this && this.__exportStar) || function(m, exports) { - for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); -}; -Object.defineProperty(exports, "__esModule", { value: true }); -__exportStar(require("./OtpInput"), exports); -__exportStar(require("./OtpInput.types"), exports); diff --git a/dist/src/OtpInput/useOtpInput.d.ts b/dist/src/OtpInput/useOtpInput.d.ts deleted file mode 100644 index f076a0c..0000000 --- a/dist/src/OtpInput/useOtpInput.d.ts +++ /dev/null @@ -1,23 +0,0 @@ -/// -import { TextInput } from "react-native"; -import { OtpInputProps } from "./OtpInput.types"; -export declare const useOtpInput: ({ onTextChange, onFilled, numberOfDigits, disabled, autoFocus, }: OtpInputProps) => { - models: { - text: string; - inputRef: import("react").RefObject; - focusedInputIndex: number; - hasCursor: boolean; - }; - actions: { - handlePress: () => void; - handleTextChange: (value: string) => void; - clear: () => void; - focus: () => void; - handleFocus: () => void; - handleBlur: () => void; - }; - forms: { - setText: import("react").Dispatch>; - setTextWithRef: (value: string) => void; - }; -}; diff --git a/dist/src/OtpInput/useOtpInput.js b/dist/src/OtpInput/useOtpInput.js deleted file mode 100644 index 616255c..0000000 --- a/dist/src/OtpInput/useOtpInput.js +++ /dev/null @@ -1,49 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.useOtpInput = void 0; -const react_1 = require("react"); -const react_native_1 = require("react-native"); -const useOtpInput = ({ onTextChange, onFilled, numberOfDigits = 6, disabled, autoFocus = true, }) => { - const [text, setText] = (0, react_1.useState)(""); - const [hasCursor, setHasCursor] = (0, react_1.useState)(autoFocus); - const inputRef = (0, react_1.useRef)(null); - const focusedInputIndex = text.length; - const handlePress = () => { - // To fix bug when keyboard is not popping up after being dismissed - if (!react_native_1.Keyboard.isVisible()) { - react_native_1.Keyboard.dismiss(); - } - inputRef.current?.focus(); - }; - const handleTextChange = (value) => { - if (disabled) - return; - setText(value); - onTextChange?.(value); - if (value.length === numberOfDigits) { - onFilled?.(value); - } - }; - const setTextWithRef = (value) => { - const normalizedValue = value.length > numberOfDigits ? value.slice(0, numberOfDigits) : value; - handleTextChange(normalizedValue); - }; - const clear = () => { - setText(""); - }; - const focus = () => { - inputRef.current?.focus(); - }; - const handleFocus = () => { - setHasCursor(true); - }; - const handleBlur = () => { - setHasCursor(false); - }; - return { - models: { text, inputRef, focusedInputIndex, hasCursor }, - actions: { handlePress, handleTextChange, clear, focus, handleFocus, handleBlur }, - forms: { setText, setTextWithRef }, - }; -}; -exports.useOtpInput = useOtpInput; diff --git a/dist/src/index.d.ts b/dist/src/index.d.ts deleted file mode 100644 index d15c6f7..0000000 --- a/dist/src/index.d.ts +++ /dev/null @@ -1 +0,0 @@ -export { OtpInput, OtpInputProps, Theme, OtpInputRef } from "./OtpInput"; diff --git a/dist/src/index.js b/dist/src/index.js deleted file mode 100644 index 3d04da4..0000000 --- a/dist/src/index.js +++ /dev/null @@ -1,5 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.OtpInput = void 0; -var OtpInput_1 = require("./OtpInput"); -Object.defineProperty(exports, "OtpInput", { enumerable: true, get: function () { return OtpInput_1.OtpInput; } }); diff --git a/package.json b/package.json index b5217ca..7831100 100644 --- a/package.json +++ b/package.json @@ -2,14 +2,20 @@ "name": "react-native-otp-entry", "version": "1.6.0", "description": "A fully modifiable OTP Input Component for React Native", - "main": "dist/src/index.js", - "types": "dist/src/index.d.ts", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "files": [ + "dist", + "!dist/src/**/__tests__" + ], "repository": "git@github.com:anday2000/react-native-otp-entry.git", "scripts": { "test": "jest .", "test:watch": "jest --watch", "test:coverage": "jest --collectCoverage --coverageDirectory=\"./coverage\"", - "build": "tsc" + "build:dev": "tsc", + "build:prod": "tsc -p tsconfig.prod.json", + "prepublishOnly": "npm run build:prod" }, "keywords": [ "react-native", diff --git a/tsconfig.prod.json b/tsconfig.prod.json new file mode 100644 index 0000000..d6126a7 --- /dev/null +++ b/tsconfig.prod.json @@ -0,0 +1,4 @@ +{ + "extends": "./tsconfig", + "exclude": ["**/__tests__", "jest.config.ts", "jest.setupFilesAfterEnv.ts"] +} From c0ca2607054c3629cb8459524b9d23940b6c80fd Mon Sep 17 00:00:00 2001 From: anday013 Date: Sun, 7 Apr 2024 12:44:00 +0200 Subject: [PATCH 3/5] build: release version 1.6.1 --- package-lock.json | 4 ++-- package.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 43768ab..31f23be 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "react-native-otp-entry", - "version": "1.6.0", + "version": "1.6.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "react-native-otp-entry", - "version": "1.6.0", + "version": "1.6.1", "license": "MIT", "devDependencies": { "@testing-library/jest-native": "^5.4.3", diff --git a/package.json b/package.json index 7831100..fc3f9cf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-otp-entry", - "version": "1.6.0", + "version": "1.6.1", "description": "A fully modifiable OTP Input Component for React Native", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -15,7 +15,7 @@ "test:coverage": "jest --collectCoverage --coverageDirectory=\"./coverage\"", "build:dev": "tsc", "build:prod": "tsc -p tsconfig.prod.json", - "prepublishOnly": "npm run build:prod" + "prepublishOnly": "npm install && npm run build:prod" }, "keywords": [ "react-native", From f496714e23d0f3e471bc75ed11e9dc490661a6eb Mon Sep 17 00:00:00 2001 From: Anday <48630069+anday013@users.noreply.github.com> Date: Sun, 7 Apr 2024 12:50:45 +0200 Subject: [PATCH 4/5] docs: add install-size badge --- README.MD | 1 + 1 file changed, 1 insertion(+) diff --git a/README.MD b/README.MD index c55faa0..5edfe69 100644 --- a/README.MD +++ b/README.MD @@ -2,6 +2,7 @@ [![npm version](https://badge.fury.io/js/react-native-otp-entry.svg?&kill_cache=1)](https://badge.fury.io/js/react-native-otp-entry) [![npm](https://img.shields.io/npm/dm/react-native-otp-entry.svg?&kill_cache=1)]() +[![install size](https://packagephobia.com/badge?p=react-native-otp-entry)](https://packagephobia.com/result?p=react-native-otp-entry) [![cov](https://anday013.github.io/react-native-otp-entry/badges/coverage.svg?&kill_cache=1)](https://github.com/anday013/react-native-otp-entry/actions) [![License](https://img.shields.io/badge/license-MIT-blue.svg?&kill_cache=1)](https://github.com/your-username/react-native-otp-entry/blob/main/LICENSE) From 90a8d7568a63092d046e4909c53888e64a96e200 Mon Sep 17 00:00:00 2001 From: anday013 Date: Sat, 20 Apr 2024 00:24:32 +0200 Subject: [PATCH 5/5] docs: remove deprecated prop --- README.MD | 6 ++++-- src/OtpInput/OtpInput.types.ts | 3 +++ src/index.d.ts | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/README.MD b/README.MD index 5edfe69..9f76fa0 100644 --- a/README.MD +++ b/README.MD @@ -63,9 +63,11 @@ yarn add react-native-otp-entry focusStickBlinkingDuration={500} onTextChange={(text) => console.log(text)} onFilled={(text) => console.log(`OTP is ${text}`)} + textInputProps={{ + accessibilityLabel: "One-Time Password", + }} theme={{ containerStyle: styles.container, - inputsContainerStyle: styles.inputsContainer, pinCodeContainerStyle: styles.pinCodeContainer, pinCodeTextStyle: styles.pinCodeText, focusStickStyle: styles.focusStick, @@ -81,6 +83,7 @@ The `react-native-otp-entry` component accepts the following props: | Prop | Type | Description | | ---------------------------- | ---------------------- | -------------------------------------------------------------------------------------------------------------- | | `numberOfDigits` | number | The number of digits to be displayed in the OTP entry. | +| `textInputProps` | TextInputProps | Extra props passed to underlying hidden TextInput (see: https://reactnative.dev/docs/textinput) | | `autoFocus` | boolean | Default: true. Set autofocus. | | `focusColor` | ColorValue | The color of the input field border and stick when it is focused. | | `onTextChange` | (text: string) => void | A callback function is invoked when the OTP text changes. It receives the updated text as an argument. | @@ -89,7 +92,6 @@ The `react-native-otp-entry` component accepts the following props: | `theme` | Theme | Custom styles for each element. | | `focusStickBlinkingDuration` | number | The duration (in milliseconds) for the focus stick to blink. | | `disabled` | boolean | Default: false. Disable the input | -| `textInputProps` | TextInputProps | Extra props passed to underlying hidden TextInput (see: https://reactnative.dev/docs/textinput) | | Theme | Type | Description | | ------------------------------- | --------- | ---------------------------------------------------------------------------------- | diff --git a/src/OtpInput/OtpInput.types.ts b/src/OtpInput/OtpInput.types.ts index bcfda24..f1ecd96 100644 --- a/src/OtpInput/OtpInput.types.ts +++ b/src/OtpInput/OtpInput.types.ts @@ -22,6 +22,9 @@ export interface OtpInputRef { export interface Theme { containerStyle?: ViewStyle; + /** + * @deprecated Use `containerStyle` instead + */ inputsContainerStyle?: ViewStyle; pinCodeContainerStyle?: ViewStyle; filledPinCodeContainerStyle?: ViewStyle; diff --git a/src/index.d.ts b/src/index.d.ts index 31053b3..b732dfa 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -59,7 +59,7 @@ declare module "OTPInput" { containerStyle?: ViewStyle; /** - * Custom styles for the container that holds the input fields. + * @deprecated Use `containerStyle` instead */ inputsContainerStyle?: ViewStyle;