Skip to content

Commit

Permalink
feat: add RegEx implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
SectionTN committed Mar 22, 2024
1 parent 791230d commit acba6f9
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 2 deletions.
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,20 +52,27 @@ You may need to import type `OTPTextViewHandle` to use the `ref` on the componen

```typescript jsx
import { OTPTextInput, type OTPTextViewHandle } from '@sectiontn/otp-input';
// Later in your component.
const OTPRef = useRef<OTPTextViewHandle || null>(null);
```
## ♻ Usage
Call the `OTPTextInput` component in your JSX code and pass the required props to customize the OTP input field.

```typescript jsx
import { Platform } from 'react-native';

// later in your component's render

<OTPTextInput
ref={OTPRef}
inputCount={4}
tintColor={"#FF6F61"}
offTintColor={"#BBBCBE"}
onTextChangeHandler={(pin: string) => {
console.log('Current OTP:', pin);
}}
editable={true}
autoFocus={true}
keyboardType={Platform.OS === 'ios' ? 'number-pad' : 'numeric'}
/>
```
Expand Down Expand Up @@ -118,4 +125,12 @@ See the [contributing guide](CONTRIBUTING.md) to learn how to contribute to the
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.

## ❤️ Support

<p>
<a href="https://www.buymeacoffee.com/sectiontn">
<img style="text-align: left;" src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" height="50" width="210" alt="sectiontn" />
</a>
</p>

Made with [create-react-native-library](https://github.com/callstack/react-native-builder-bob)
44 changes: 42 additions & 2 deletions src/OTPTextInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ interface OTPTextInputProps {
onFocus?: (index: number) => void;
onBlur?: (index: number) => void;
autoFocus?: boolean;
useNumbersRegex?: boolean;
useLettersRegex?: boolean;
useCustomRegex?: boolean;
customRegex?: RegExp;
}

export interface OTPTextInputHandle {
Expand Down Expand Up @@ -86,9 +90,42 @@ const OTPTextInput = forwardRef<OTPTextInputHandle, OTPTextInputProps>(
keyboardType = 'numeric',
editable = true,
autoFocus = true,
useNumbersRegex = true,
useCustomRegex = false,
customRegex = undefined,
},
ref
) => {
/**
*
*/
if (useNumbersRegex && useCustomRegex) {
throw new Error(
'You cannot set both useNumbersRegex and useCustomRegex to true!'
);
}

/**
* The regular expression used for matching strings based on certain conditions.
*
* @type {RegExp}
*
* @param {boolean} useNumbersRegex - Determines if only digits should be matched.
* @param {boolean} useCustomRegex - Determines if a custom regular expression should be used.
* @param {RegExp} customRegex - The custom regular expression provided by the user.
*
* @returns {RegExp} - The regular expression that matches strings based on the given conditions.
*/
const regex: RegExp = useMemo(() => {
if (useNumbersRegex) {
return new RegExp('\\d*'); // Only numbers allowed.
} else if (useCustomRegex && customRegex) {
return customRegex; // User supplied regex.
}

return new RegExp('.*'); // Default regex (rarely used?) maybe the user doesn't want to use any regex.
}, [useNumbersRegex, useCustomRegex, customRegex]);

const [focusedInput, setFocusedInput] = useState(0);
const [otpText, setOtpText] = useState<string[]>(
Array.from({ length: inputCount }, (_, i) => defaultValue[i] || '')
Expand Down Expand Up @@ -162,14 +199,17 @@ const OTPTextInput = forwardRef<OTPTextInputHandle, OTPTextInputProps>(
*/
const onTextChange = useCallback(
(text: string, position: number): void => {
if (!regex.test(text)) {
return; // Do not update the OTP value if the text does not match the regex
}
const newOtp = [...otpText];
newOtp[position] = text;
if (text.length === inputMaxLength && position !== inputCount - 1) {
if (text?.length === inputMaxLength && position !== inputCount - 1) {
setFocusedInput(position + 1);
}
updateOTP(newOtp);
},
[inputMaxLength, inputCount, otpText, updateOTP]
[regex, otpText, inputMaxLength, inputCount, updateOTP]
);

/**
Expand Down

0 comments on commit acba6f9

Please sign in to comment.