Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
101 commits
Select commit Hold shift + click to select a range
1bc5140
Fixing RTL issue.
AZIMAT Dec 2, 2019
f409f75
Fix Active
AZIMAT Dec 10, 2019
787ba25
Add an boolean property to clear the OTP Input fields
Dec 13, 2019
d3e3bdc
Added keyboard type prop
DibakarHalder Dec 27, 2019
7ac4a2e
Merge pull request #35 from DibakarHalder/keyboard-type-prop
fpena Dec 28, 2019
e8c7817
Update README with keyboard type.
fpena Dec 28, 2019
ed8802b
Merge pull request #27 from AZIMAT/master
fpena Dec 28, 2019
d14f79e
Merge branch 'master' into master
hasithaWalpola Dec 30, 2019
7cc7b68
1.1.3
fpena Dec 30, 2019
6f1c754
Code formatting clean up
fpena Dec 30, 2019
91ff307
Bring back keyboard type
fpena Dec 30, 2019
627a7d6
Remove new line
fpena Dec 30, 2019
6a24d6f
Add space to if
fpena Dec 30, 2019
ed0a1d4
Bring back componentWillReceiveProps
fpena Dec 30, 2019
fb0a0b7
Remove spacing
fpena Dec 30, 2019
0025335
Remove extra spacing
fpena Dec 30, 2019
afbee61
Merge pull request #32 from hasithaWalpola/master
fpena Dec 30, 2019
cd1d475
1.1.4
fpena Dec 31, 2019
f7faf59
Add clearInput prop to README
fpena Dec 31, 2019
dd0c76c
fixes clearAllFields setState issue
Jan 17, 2020
abb321e
Merge pull request #39 from imtiaz191919/clear-all-fields-fix
ansonyao Jan 20, 2020
e2216d0
codeInputHighlightStyle apply for all fields issue fix
Jan 31, 2020
59056b1
Merge remote-tracking branch 'upstream/master'
Jan 31, 2020
2be475f
Added support for placeholders
DaniAkash Feb 4, 2020
3b0288d
Updated README for the placeholders
DaniAkash Feb 4, 2020
c8214ae
Merge pull request #41 from hasithaWalpola/master
fpena Feb 7, 2020
4ffadd1
1.1.5
fpena Feb 7, 2020
595e071
Merge branch 'test-placeholder' of https://github.com/DaniAkash/react…
BeckyWu220 Feb 13, 2020
2490c1f
By default disable placeholder. If placeholderCharacter prop exist, u…
BeckyWu220 Feb 14, 2020
dd05034
Merge pull request #45 from Twotalltotems/DaniAkash-test-placeholder
BeckyWu220 Feb 14, 2020
5f352e8
resolve merge conflict.
BeckyWu220 Feb 14, 2020
fb058ef
Added back the line of calling notifyCodeChanged() method and check o…
BeckyWu220 Feb 14, 2020
98895b8
Add .circleci/config.yml
BeckyWu220 Feb 14, 2020
bded478
Config Jest and Enzyme to setup unit test.
BeckyWu220 Feb 14, 2020
34c1e4b
Added additional dev dependency, jsdom, to enable the test use enzyme…
BeckyWu220 Feb 14, 2020
8cce48a
Added contributing guideline.
BeckyWu220 Feb 14, 2020
44635bc
1.2.0
fpena Feb 15, 2020
c99466a
Add Github Actions to run the unit test.
BeckyWu220 Feb 15, 2020
07e7a27
Merge pull request #47 from Twotalltotems/improvement/unit-test-setup
fpena Feb 15, 2020
65848e7
Update README
fpena Feb 15, 2020
1a31977
Add index.d.ts Typescript type, tsconfig
Feb 18, 2020
76a082a
Remove Prettier file
Feb 19, 2020
78c8ede
Complete Highlighted Slot Logic and Slot Content Change Logic Tests
Feb 19, 2020
eda158a
Update index.d.ts file, Keep the definition of InputProps
Feb 20, 2020
3a76b6b
Remove unit test from this branch.
BeckyWu220 Feb 22, 2020
1553a8e
Reverse the indent and semicolon caused by eslint.
BeckyWu220 Feb 22, 2020
7c2c36a
Moved typescript declaration file to root folder and deleted unnecess…
BeckyWu220 Feb 22, 2020
c7bf416
Refine props description.
BeckyWu220 Feb 22, 2020
9b9e3a7
Merge pull request #48 from Twotalltotems/typescript
fpena Feb 22, 2020
99599ac
1.2.1
fpena Feb 22, 2020
15969e4
Update README with todos and basic usage
fpena Feb 22, 2020
06ad645
Added `style` prop declaration to typescript definition file and upda…
BeckyWu220 Feb 27, 2020
0a1f7d3
Merge pull request #51 from Twotalltotems/hotfix/add-style-prop-to-ty…
BeckyWu220 Feb 27, 2020
ecd7abf
Fix issue #30: More than pinCount code can be entered bug
Mar 11, 2020
caa3dcf
add selectionColor as a customizeable prop.
domoniquecarter35 Mar 12, 2020
e8534b4
Bump acorn from 5.7.3 to 5.7.4 in /example
dependabot[bot] Mar 14, 2020
7601d5a
Make sure code extracted from clipboard only contains digits
JoelBesada Mar 16, 2020
fcaf590
Call onCodeFilled after etracting code from clipboard
JoelBesada Mar 16, 2020
f93e847
Merge pull request #54 from Twotalltotems/hotfix/issue-#30-more-than-…
BeckyWu220 Mar 16, 2020
26196f6
Merge pull request #58 from JoelBesada/fix-issue-12
BeckyWu220 Mar 16, 2020
e6d2e89
Merge pull request #57 from Twotalltotems/dependabot/npm_and_yarn/exa…
BeckyWu220 Mar 16, 2020
e882b5b
Add `selectionColor` props into typescript definition file, and add `…
BeckyWu220 Mar 16, 2020
bf835cf
Merge pull request #55 from TotalWineLabs/master
BeckyWu220 Mar 16, 2020
bf10b0b
Merge pull request #59 from Twotalltotems/features/customize-text-inp…
BeckyWu220 Mar 16, 2020
1721ed1
Cherry pick Eric's unit tests to separate branch.
BeckyWu220 Feb 22, 2020
ea1386d
1.2.2
BeckyWu220 Mar 22, 2020
26be1c6
Clean up.
BeckyWu220 Mar 27, 2020
afd6742
Merge pull request #63 from tttstudios/improvement/basic-unit-tests
BeckyWu220 Mar 27, 2020
cff40b8
Create npmpublish.yml
BeckyWu220 Mar 27, 2020
8693ae4
Update npmpublish.yml
BeckyWu220 Mar 27, 2020
3496bd1
typescript implementation
mikhailshvets Mar 24, 2020
a181bcb
changed outDir, added dist dir to gitignore, added types and files pr…
mikhailshvets Mar 27, 2020
0b82a87
Removed metro.config.js file that caused error in running example pro…
BeckyWu220 Mar 27, 2020
f77aeb4
Added `npm run build` to npm auto release github action. Updated vers…
BeckyWu220 Mar 27, 2020
006bcff
Merge pull request #64 from tttstudios/improvement/typescript-impleme…
BeckyWu220 Mar 27, 2020
29494b9
Fixed the npm packaging config issue after intergrating typescript.
BeckyWu220 Mar 27, 2020
e15835e
Add keyboardAppearance prop to Text Input
ishanAhuja Apr 6, 2020
111e18a
Add the keyboardAppearance prop to README
ishanAhuja Apr 6, 2020
a0a7ca6
Fix Bug always hightlight first slot even autoFocusOnLoad=false
May 7, 2020
b259c6f
Merge pull request #72 from tttstudios/hotfix/autoFocusOnLoad
BeckyWu220 May 7, 2020
dc5fef8
Merge pull request #65 from ishanAhuja/patch-1
BeckyWu220 May 7, 2020
44f3f32
Added `keyboardAppearance` prop to typescript definition.
BeckyWu220 May 9, 2020
8f92b28
Increase version to v1.3.7
BeckyWu220 May 9, 2020
b46d935
Update README.md
douglasjunior Jun 9, 2020
bdf76f9
Merge pull request #79 from douglasjunior/patch-1
fpena Jun 9, 2020
8c05ac1
migrates Clipboard from react-native core to @react-native-community/…
manishsharma004 Jun 14, 2020
ec620d1
Merge pull request #81 from mannyhappenings/master
ericdao37 Jul 6, 2020
1f6e338
Accept `editable` and pass it to TextInput
UncleBill Jun 17, 2020
0c7feae
Merge pull request #82 from UncleBill/accept-editable
ericdao37 Jul 7, 2020
def2c08
Update publish script in npmpublish.yml
Jul 9, 2020
76aa6b5
Update publish script in tests.yml
Jul 9, 2020
875835e
Update version number
Jul 9, 2020
fe25f38
Update README.md - note about new dependency
Jul 10, 2020
1c4fd4e
Update version 1.3.11
Jul 10, 2020
1e47264
Fix typo in example code
rednebmas Jul 24, 2020
796be60
Merge pull request #91 from rednebmas/patch-1
eric-dao37 Aug 9, 2020
f4da4a6
[Hot-fix] focusField and blurAllFields. Issues related to react-nativ…
Oct 26, 2020
c710090
Revert "[Hot-fix] focusField and blurAllFields. Issues related to rea…
Oct 26, 2020
bd9dd9c
Add Project Status and seek maintainers
Jul 22, 2022
fc7920a
Update Project Status based on feedback
Jul 25, 2022
c8359ac
Merge pull request #192 from tttstudios/update-project-status
Sunnysit Aug 15, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions .github/workflows/npmpublish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
# For more information see: https://help.github.com/actions/language-and-framework-guides/publishing-nodejs-packages

name: Release NPM Package

on:
release:
types: [published]

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: 12
- run: npm install && npm test

publish-npm:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: 12
registry-url: https://registry.npmjs.org/
- run: npm install
- run: npm run build
- run: npm publish
env:
NODE_AUTH_TOKEN: ${{secrets.npm_token}}
26 changes: 26 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Tests

on:
push:
branches:
- master
pull_request:
branches:
- master


jobs:
build:

runs-on: ubuntu-latest

container:
image: node:13.4.0

steps:
- uses: actions/checkout@v1
- name: Run Jest
uses: stefanoeb/jest-action@1.0.2
- name: Run Unit Test
run: npm install && npm test

3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,6 @@ buck-out/
# Environment file
.env
ReactotronConfig.js

# ts build dir
dist
6 changes: 0 additions & 6 deletions .npmignore

This file was deleted.

32 changes: 32 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Introduction

Thank you for considering contributing to `@twotalltotems/react-native-otp-input`. It's people like you that make the library better.

# Ways to Contribute

There are many ways to contribute, from writing tutorials or blog posts, improving the documentation, submitting bug reports and feature requests or writing code which can be incorporated into the library.


# Your First Contribution
If you decided to look into a pending issue, hope the guideline below can help you start.

>1. Create your own fork of the code
>2. Do the changes in your fork
>3. If you like the change and think the project could use it:
* Be sure you have followed the code style for the project.
* Well test your changes and add unit tests if necessary.
* Be sure to run `npm test` before submitting a pull request. This would help us maintain the compatablity of the library.
>4. Send a pull request.

# Code review process
The development team in TTT Studios looks at Pull Requests on a regular basis. Depends on the PR reviewed, we might reach out with some feedback or clarification.

After feedback/clarification has been given we expect responses within two weeks. After two weeks we may close the pull request if it isn't showing any activity.

TTT Studios appreaciate your interest and effort in contributing to the library. Look forward to your great Pull Requests!






101 changes: 81 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,55 @@
![PaginatableList](https://raw.githubusercontent.com/Twotalltotems/react-native-otp-input/master/assets/otp_banner.jpg)

# React Native OTP Input

![Tests](https://github.com/Twotalltotems/react-native-otp-input/workflows/Tests/badge.svg)

**@twotalltotems/react-native-otp-input** is a tiny Javascript library which provides an elegant UI for the end user to input one time passcode (OTP). It handles the input suggestion on iOS when the OTP SMS is received. For Android, it will autofill when the user presses the copy button on the SMS notification bar. It also features a carefully crafted flow to handle edge cases for volatile user gestures. We provide default UI, but you can always customize the appearance as you like.

![demo.gif](https://s3.ca-central-1.amazonaws.com/tttevents/iosvideo.gif)
![demo.gif](https://s3.ca-central-1.amazonaws.com/tttevents/android.gif)

## Project Status
This project is not actively maintained anymore. If you’d like to contribute, we encourage you to fork this repository and improve it for the community.

Here are some alternatives you could try:

- [react-native-otp-inputs](https://www.npmjs.com/package/react-native-otp-inputs)
- [react-native-otp-textinput](https://www.npmjs.com/package/react-native-otp-textinput)

## Installation

`npm install --save @twotalltotems/react-native-otp-input`
or
`yarn add @twotalltotems/react-native-otp-input`

## Dependencies
It does not have additional dependencies except for React Native itself.

### NOTES:
From version 1.3.10: We use @react-native-community/clipboard to handle the clipboard in this package, So you should install @react-native-community/clipboard

`npm install --save @react-native-community/clipboard`
or
`yarn add @react-native-community/clipboard`

## Basic Usage

```js
import OTPInputView from '@twotalltotems/react-native-otp-input'

...

<OTPInputView pinCount={4} />

```

## More Advanced Usage

```js
import OTPInputView from '@twotalltotems/react-native-otp-input'

...

<OTPInputView
style={{width: '80%', height: 200}}
pinCount={4}
Expand All @@ -27,9 +58,9 @@ import OTPInputView from '@twotalltotems/react-native-otp-input'
autoFocusOnLoad
codeInputFieldStyle={styles.underlineStyleBase}
codeInputHighlightStyle={styles.underlineStyleHighLighted}
onCodeFilled = {(code => {
onCodeFilled = {(code) => {
console.log(`Code is ${code}, you are good to go!`)
})}
}}
/>

const styles = StyleSheet.create({
Expand Down Expand Up @@ -58,32 +89,43 @@ const styles = StyleSheet.create({

## Parameters

| Parameter | required | Description |
|-------------|----------|-------------|
| pinCount | YES | Number of digits in the component |
| code | NO | You can use this library as a controlled / uncontrolled component by supplying this prop or not |
| codeInputFieldStyle | NO | The style of the input field which is NOT focused |
| codeInputHighlightStyle | NO | The style of the input field which is focused |
| autoFocusOnLoad | NO | Auto activate the input and bring up the keyboard when component is loaded |
| onCodeChanged | NO | Callback when the digits are changed |
| onCodeFilled | NO | Callback when the last digit is entered |
| secureTextEntry | NO | Hide contents of text fields |
| Parameter | required | Description |
| ----------------------- | -------- | ----------------------------------------------------------------------------------------------- |
| pinCount | YES | Number of digits in the component |
| code | NO | You can use this library as a controlled / uncontrolled component by supplying this prop or not |
| codeInputFieldStyle | NO | The style of the input field which is NOT focused |
| codeInputHighlightStyle | NO | The style of the input field which is focused |
| autoFocusOnLoad | NO | Auto activate the input and bring up the keyboard when component is loaded |
| onCodeChanged | NO | Callback when the digits are changed |
| onCodeFilled | NO | Callback when the last digit is entered |
| secureTextEntry | NO | Hide contents of text fields |
| editable | NO | Set editable for inputs |
| keyboardAppearance | NO | Keyboard appearance ('default', 'dark', 'light') |
| keyboardType | NO | Keyboard type |
| clearInputs | NO | Clear inputs after entering code |
| placeholderCharacter | NO | The character/string that will be used as placeholder in the individual code input fields |
| placeholderTextColor | NO | Color of the placeholderCharacter |

## Notes
The iOS input suggestion requires React Native 0.58+ and works for iOS 12 and above.

On Android, it will be auto filled when you press the copy code button in the notification bar (see above GIF). It will do so only if the code is sent after the view is loaded. So make sure you request the code **AFTER** this view is loaded.
The iOS input suggestion requires React Native 0.58+ and works for iOS 12 and above.

On Android, it will be auto filled when you press the copy code button in the notification bar (see above GIF). It will do so only if the code is sent after the view is loaded. So make sure you request the code **AFTER** this view is loaded.

If you are interested in Android SMS Retriever API, we would suggest @Faizal's repo [React-Native-OTP-Verify](https://github.com/faizalshap/react-native-otp-verify). It looks pretty cool and it should be straight-forward to use React-Native-OTP-Verify along with this library.

## Roadmap
* [ ] Typescript
* [ ] Add unit tests

- [x] Typescript definition file
- [x] Typescript implementation
- [x] Add basic unit tests
- [ ] Add integration tests

## Contributors

<table>
<tr border="0" style="border: none; ">
<th border="0" style="border-left: none; border-right: none;">
<th border="0" style="border-left: none; border-right: none;">
<img src="https://avatars1.githubusercontent.com/u/1243479?s=400&v=4" width="60px;" style="border-radius: 50%;"/>
<br />
<sub><a href="https://github.com/ansonyao">Anson Yao</a></sub> <br />
Expand All @@ -100,6 +142,11 @@ If you are interested in Android SMS Retriever API, we would suggest @Faizal's r
<br />
<sub><a href="https://github.com/fpena">Felipe Peña</a></sub> <br />
</th>
<th border="0" style="border-left: none; border-right: none;">
<img src="https://avatars3.githubusercontent.com/u/60905710?s=400&v=4" width="60px;" style="border-radius: 50%;"/>
<br />
<sub><a href="https://github.com/ericdao-ttt">Eric Dao</a></sub> <br />
</th>
<th border="0" style="border-left: none; border-right: none;">
<img src="https://avatars3.githubusercontent.com/u/3868329?s=460&v=4" width="60px;" style="border-radius: 50%;"/>
<br />
Expand All @@ -118,9 +165,23 @@ If you are interested in Android SMS Retriever API, we would suggest @Faizal's r
</tr>
</table>

## Premium Support By TTT Studios
## External Contributors

<table>
<tr border="0" style="border: none; ">
<th border="0" style="border-left: none; border-right: none;">
<div>
<img src="https://avatars2.githubusercontent.com/u/17710983?s=400&v=4" width="60px;" style="border-radius: 50%;"/>
<br />
<sub><a href="https://github.com/mikhailshvets">Mikhail.sh</a></sub> <br />
</div>
</th>
</tr>
</table>

## About the Creators

OTP input is presented by the mobile team at [TTT Studios](https://ttt.studio). We are a Digital Innovation Studio based out of Vancouver, Canada, delivering custom software and solutions that are designed and developed 100% in-house. The technologies we work with include AR & VR, IoT, AI, security & encryption, and cloud computing.
OTP input is developed by the mobile team at [TTT Studios](https://ttt.studio). We are a Digital Innovation Studio based out of Vancouver, Canada, delivering custom software and solutions that are designed and developed 100% in-house. The technologies we work with include AR & VR, IoT, AI, security & encryption, and cloud computing.

<div align="right">
<img src="https://ttt.studio/wp-content/themes/tttwordpresstheme/imgs/ttt-colour.png" width="200px"/>
Expand Down
122 changes: 122 additions & 0 deletions __tests__/App.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import "react-native"
import React from 'react'
import { shallow, mount } from 'enzyme'
import OTPInputView from '../index'
import {TextInput} from "react-native"

const setup = (props = {}) => {
const wrapper = shallow(<OTPInputView {...props} />)
return wrapper
}

describe('OTPInputView renders correclty.', () => {
let shallowWrapper
it('OTP container view renders correctly.', () => {
shallowWrapper = setup()
const otpInputView = shallowWrapper.find({ testID: 'OTPInputView' })

expect(otpInputView.length).toBe(1)
})

it('Render same amount of input slots as prop `pinCount`', () => {
const pinCount = 6
shallowWrapper = setup({ pinCount })
const inputSlotViews = shallowWrapper.find({ testID: 'inputSlotView' })

expect(inputSlotViews.length).toBe(pinCount)
})

it('Render the slots initial state as `code` prop.', () => {
const code = '123456'
const pinCount = code.length
const reactWrapper = mount(<OTPInputView code={code} pinCount={pinCount} />)
const textInputs = reactWrapper.find({ testID: 'textInput' }).hostNodes()
const chars = code.split('')

textInputs.map((textInput, index) => {
expect(textInput.props().value).toBe(chars[index])
})
})
})

describe('Highlighted Slot Logic', () => {
const pinCount = Math.floor(Math.random() * 50) + 1
it('Input in slots to increase selectedIndex state.', () => {
const reactWrapper = mount(<OTPInputView pinCount={pinCount} />)

const componentInstance = reactWrapper.instance()
componentInstance.handleChangeText(0, "1")

expect(reactWrapper.state("selectedIndex")).toBe(1)
})

it('Stop increasing selectedIndex after inputting in the last slot.', () => {
const numberCharEntered = Math.floor(Math.random() * 100) + pinCount

const reactWrapper = mount(<OTPInputView pinCount={pinCount} />)

const componentInstance = reactWrapper.instance()

for(i=0; i < numberCharEntered; i++) {
componentInstance.handleChangeText(i, "1")
}

expect(reactWrapper.state("selectedIndex")).toBeLessThanOrEqual(pinCount - 1)
})
it('Press backspace in keyboard to decrease selectedIndex state. ', () => {
const numberCharEntered = Math.floor(Math.random() * (pinCount - 1)) + 1

const reactWrapper = mount(<OTPInputView pinCount={pinCount} />)

const componentInstance = reactWrapper.instance()

for(i=0; i < numberCharEntered; i++) {
componentInstance.handleChangeText(i, "1")
}
componentInstance.handleKeyPressTextInput(numberCharEntered, 'Backspace')

expect(reactWrapper.state("selectedIndex")).toBe(numberCharEntered - 1)
})
it('Stop decreasing selectedIndex after deleting the text in the first slot.', () => {
const reactWrapper = mount(<OTPInputView pinCount={pinCount} />)

const componentInstance = reactWrapper.instance()
componentInstance.handleKeyPressTextInput(0, 'Backspace')

expect(reactWrapper.state("selectedIndex")).toBe(0)
})
})

describe('Slot Content Change Logic', () => {
const pinCount = Math.floor(Math.random() * 50) + 1
it('handleChangeText is called with proper index and text param after making content change to a slot.', () => {
const reactWrapper = mount(<OTPInputView pinCount={pinCount} />)
const componentInstance = reactWrapper.instance()

const textParam = "1"
componentInstance.handleChangeText(0, textParam)

reactWrapper.update()

const textInput = reactWrapper.find(TextInput).at(0)
expect(textInput.props().value).toBe(textParam)

})

it('Enter required digits of code triggers onCodeFilled callback method with code string.', () => {
const onCodeFilled = jest.fn()

let passCode = ""

const reactWrapper = mount(<OTPInputView pinCount={pinCount} onCodeFilled={onCodeFilled} />)
const componentInstance = reactWrapper.instance()
for(i=0; i < pinCount; i++) {
componentInstance.handleChangeText(i, "1")
passCode += "1"
}

expect(onCodeFilled).toHaveBeenCalledWith(passCode)
})

})

Loading