react-auth-code-input
Advanced tools
Comparing version
import React from 'react'; | ||
declare const allowedCharactersValues: readonly ["alpha", "numeric", "alphanumeric"]; | ||
declare type Props = { | ||
allowedCharacters?: 'alpha' | 'numeric' | 'alphanumeric'; | ||
allowedCharacters?: typeof allowedCharactersValues[number]; | ||
ariaLabel?: string; | ||
autoFocus?: boolean; | ||
length?: number; | ||
@@ -11,3 +13,7 @@ containerClassName?: string; | ||
}; | ||
declare const AuthCode: React.FC<Props>; | ||
export declare type AuthCodeRef = { | ||
focus: () => void; | ||
clear: () => void; | ||
}; | ||
declare const AuthCode: React.ForwardRefExoticComponent<Props & React.RefAttributes<AuthCodeRef>>; | ||
export default AuthCode; |
@@ -6,2 +6,3 @@ function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } | ||
var allowedCharactersValues = ['alpha', 'numeric', 'alphanumeric']; | ||
var propsMap = { | ||
@@ -26,7 +27,8 @@ alpha: { | ||
}; | ||
var AuthCode = function AuthCode(_ref) { | ||
var AuthCode = React.forwardRef(function (_ref, ref) { | ||
var _ref$allowedCharacter = _ref.allowedCharacters, | ||
allowedCharacters = _ref$allowedCharacter === void 0 ? 'alphanumeric' : _ref$allowedCharacter, | ||
ariaLabel = _ref.ariaLabel, | ||
_ref$autoFocus = _ref.autoFocus, | ||
autoFocus = _ref$autoFocus === void 0 ? true : _ref$autoFocus, | ||
_ref$length = _ref.length, | ||
@@ -39,6 +41,39 @@ length = _ref$length === void 0 ? 6 : _ref$length, | ||
onChange = _ref.onChange; | ||
if (isNaN(length) || length < 1) { | ||
throw new Error('Length should be a number and greater than 0'); | ||
} | ||
if (!allowedCharactersValues.some(function (value) { | ||
return value === allowedCharacters; | ||
})) { | ||
throw new Error('Invalid value for allowedCharacters. Use alpha, numeric, or alphanumeric'); | ||
} | ||
var inputsRef = React.useRef([]); | ||
var inputProps = propsMap[allowedCharacters]; | ||
React.useImperativeHandle(ref, function () { | ||
return { | ||
focus: function focus() { | ||
if (inputsRef.current) { | ||
inputsRef.current[0].focus(); | ||
} | ||
}, | ||
clear: function clear() { | ||
if (inputsRef.current) { | ||
for (var i = 0; i < inputsRef.current.length; i++) { | ||
inputsRef.current[i].value = ''; | ||
} | ||
inputsRef.current[0].focus(); | ||
} | ||
sendResult(); | ||
} | ||
}; | ||
}); | ||
React.useEffect(function () { | ||
inputsRef.current[0].focus(); | ||
if (autoFocus) { | ||
inputsRef.current[0].focus(); | ||
} | ||
}, []); | ||
@@ -135,3 +170,3 @@ | ||
ref: function ref(el) { | ||
return inputsRef.current[i] = el; | ||
inputsRef.current[i] = el; | ||
}, | ||
@@ -152,5 +187,5 @@ maxLength: 1, | ||
}, inputs); | ||
}; | ||
}); | ||
module.exports = AuthCode; | ||
//# sourceMappingURL=index.js.map |
@@ -1,3 +0,4 @@ | ||
import React, { useRef, useEffect } from 'react'; | ||
import React, { forwardRef, useRef, useImperativeHandle, useEffect } from 'react'; | ||
const allowedCharactersValues = ['alpha', 'numeric', 'alphanumeric']; | ||
const propsMap = { | ||
@@ -22,6 +23,6 @@ alpha: { | ||
}; | ||
const AuthCode = ({ | ||
const AuthCode = forwardRef(({ | ||
allowedCharacters: _allowedCharacters = 'alphanumeric', | ||
ariaLabel, | ||
autoFocus: _autoFocus = true, | ||
length: _length = 6, | ||
@@ -32,7 +33,35 @@ containerClassName, | ||
onChange | ||
}) => { | ||
}, ref) => { | ||
if (isNaN(_length) || _length < 1) { | ||
throw new Error('Length should be a number and greater than 0'); | ||
} | ||
if (!allowedCharactersValues.some(value => value === _allowedCharacters)) { | ||
throw new Error('Invalid value for allowedCharacters. Use alpha, numeric, or alphanumeric'); | ||
} | ||
const inputsRef = useRef([]); | ||
const inputProps = propsMap[_allowedCharacters]; | ||
useImperativeHandle(ref, () => ({ | ||
focus: () => { | ||
if (inputsRef.current) { | ||
inputsRef.current[0].focus(); | ||
} | ||
}, | ||
clear: () => { | ||
if (inputsRef.current) { | ||
for (let i = 0; i < inputsRef.current.length; i++) { | ||
inputsRef.current[i].value = ''; | ||
} | ||
inputsRef.current[0].focus(); | ||
} | ||
sendResult(); | ||
} | ||
})); | ||
useEffect(() => { | ||
inputsRef.current[0].focus(); | ||
if (_autoFocus) { | ||
inputsRef.current[0].focus(); | ||
} | ||
}, []); | ||
@@ -131,3 +160,5 @@ | ||
type: _isPassword ? 'password' : inputProps.type, | ||
ref: el => inputsRef.current[i] = el, | ||
ref: el => { | ||
inputsRef.current[i] = el; | ||
}, | ||
maxLength: 1, | ||
@@ -143,5 +174,5 @@ className: inputClassName, | ||
}, inputs); | ||
}; | ||
}); | ||
export default AuthCode; | ||
//# sourceMappingURL=index.modern.js.map |
{ | ||
"name": "react-auth-code-input", | ||
"version": "3.0.0", | ||
"version": "3.1.0", | ||
"description": "One-time password (OTP) React input component, uncontrolled, zero dependencies, fully tested.", | ||
@@ -28,3 +28,3 @@ "author": "drac94", | ||
"peerDependencies": { | ||
"react": "^16.0.0" | ||
"react": ">=16.0.0" | ||
}, | ||
@@ -31,0 +31,0 @@ "devDependencies": { |
133
README.md
@@ -1,6 +0,6 @@ | ||
 | ||
 | ||
# React Auth Code Input | ||
> One-time password (OTP) React input component, uncontrolled, zero dependencies, fully tested. | ||
> One-time password (OTP) React component, zero dependencies, fully tested. | ||
@@ -29,5 +29,5 @@ [](https://www.npmjs.com/package/react-auth-code-input) [](https://standardjs.com) | ||
## Usage | ||
## Basic Usage | ||
```jsx | ||
```tsx | ||
import React, { useState } from 'react'; | ||
@@ -37,3 +37,3 @@ import AuthCode from 'react-auth-code-input'; | ||
const App = () => { | ||
const [result, setResult] = useState(''); | ||
const [result, setResult] = useState(); | ||
const handleOnChange = (res: string) => { | ||
@@ -43,9 +43,48 @@ setResult(res); | ||
return <AuthCode onChange={handleOnChange} />; | ||
}; | ||
``` | ||
## Mode | ||
By default you can type anything in the inputs as the `allowedCharacters` prop is defaulted to `alphanumeric` but you can also choose between allowing only letters or only numbers by setting the prop to `alpha` or `numeric` respectively. | ||
```tsx | ||
import React, { useState } from 'react'; | ||
import AuthCode from 'react-auth-code-input'; | ||
const App = () => { | ||
const [result, setResult] = useState(); | ||
const handleOnChange = (res: string) => { | ||
setResult(res); | ||
}; | ||
return <AuthCode allowedCharacters='numeric' onChange={handleOnChange} />; | ||
}; | ||
``` | ||
## Focus | ||
By default the first input is focused when the component is mounted, you can opt-out from this by setting the `autoFocus` prop to `false`, and then you can handle the focus manually by passing a reference. | ||
```tsx | ||
import React, { useRef, useState } from 'react'; | ||
import AuthCode, { AuthCodeRef } from 'react-auth-code-input'; | ||
const App = () => { | ||
const AuthInputRef = useRef<AuthCodeRef>(null); | ||
const [result, setResult] = useState(); | ||
const handleOnChange = (res: string) => { | ||
setResult(res); | ||
}; | ||
return ( | ||
<AuthCode | ||
length={5} | ||
onChange={handleOnChange} | ||
containerClassName='container' | ||
inputClassName='input' | ||
/> | ||
<> | ||
<AuthCode | ||
autoFocus={false} | ||
onChange={handleOnChange} | ||
ref={AuthInputRef} | ||
/> | ||
<button onClick={() => AuthInputRef.current?.focus()}>Focus</button> | ||
</> | ||
); | ||
@@ -55,16 +94,53 @@ }; | ||
## Clear | ||
You can clear all the inputs by passing a reference and then calling the `clear` method. | ||
```tsx | ||
import React, { useRef, useState } from 'react'; | ||
import AuthCode, { AuthCodeRef } from 'react-auth-code-input'; | ||
const App = () => { | ||
const AuthInputRef = useRef<AuthCodeRef>(null); | ||
const [result, setResult] = useState(); | ||
const handleOnChange = (res: string) => { | ||
setResult(res); | ||
}; | ||
return ( | ||
<> | ||
<AuthCode onChange={handleOnChange} ref={AuthInputRef} /> | ||
<button onClick={() => AuthInputRef.current?.clear()}>Clear</button> | ||
</> | ||
); | ||
}; | ||
``` | ||
## SMS Autofill | ||
This component supports autofill from SMS's received, tested on Safari and Chrome in iOS. | ||
## Props | ||
| Prop | Type | Description | Default Value | Observations | | ||
| :------------------- | :---------------------- | :---------------------------------------------------------- | :------------- | :--------------------------------- | | ||
| `allowedCharacters` | String | Type of allowed characters for your code. | `alphanumeric` | `alpha`, `alphanumeric`, `numeric` | | ||
| `ariaLabel` | String | Accessibility. | | | | ||
| `length` | Number | The number of inputs to display. | 6 | | | ||
| `containerClassName` | String | The styles to be applied to the container. | | | | ||
| `inputClassName` | String | The styles to be applied to each input. | | | | ||
| `onChange` | Function(value: String) | Callback function called every time an input value changes. | | | | ||
| `isPassword` | Boolean | Whether to display the inputs as passwords or not. | false | | | ||
| Prop | Type | Description | Default Value | Observations | | ||
| :------------------- | :---------------------- | :---------------------------------------------------------- | :------------- | :----------------------------------------------- | | ||
| `allowedCharacters` | String | Type of allowed characters for your code. | `alphanumeric` | Valid values: `alpha`, `alphanumeric`, `numeric` | | ||
| `ariaLabel` | String | Accessibility. | | | | ||
| `autoFocus` | Boolean | Wether the first input is focused on mount or not.. | true | | | ||
| `length` | Number | The number of inputs to display. | 6 | | | ||
| `containerClassName` | String | The styles to be applied to the container. | | | | ||
| `inputClassName` | String | The styles to be applied to each input. | | | | ||
| `onChange` | Function(value: String) | Callback function called every time an input value changes. | | Required | | ||
| `isPassword` | Boolean | Whether to display the inputs as passwords or not. | false | | | ||
## Changelog | ||
### 3.1.0 | ||
- Add `autoFocus` prop set to true by default to not break current usages. | ||
- Expose a `focus` method to handle the focus of the first input manually. | ||
- Expose a `clear` method to clear the input programmatically. | ||
- Add validations for when not using typescript. | ||
- Update React peerDependency to use any version 16+. | ||
### 3.0.0 | ||
@@ -105,19 +181,4 @@ | ||
- Initial Version. | ||
- Initial Version. | | deprecated since version 1.2.0 | | ||
## Props versions 1 and 2 | ||
| Prop | Type | Description | Default Value | Observations | | ||
| :------------------- | :---------------------- | :------------------------------------------------------------------------------ | :------------- | :----------------------------- | | ||
| `allowedCharacters` | String | Regex for allowed characters | `[A-Za-z0-9]+` | | | ||
| `ariaLabel` | String | Accessibility | | | | ||
| `characters` | Number | The number of inputs to display | 6 | | | ||
| `containerClassName` | String | The styles to be applied to the container | | | | ||
| `inputClassName` | String | The styles to be applied to each input | | | | ||
| `inputType` | String | The type of the inputs | text | text, number or password | | ||
| `onChange` | Function(value: String) | Callback function called every time an input value changes | | | | ||
| ~~`password`~~ | Boolean | If present changes the type of the input to password, by default is set to text | false | deprecated since version 2.0.0 | | ||
| ~~`inputStyle`~~ | Object | The styles to be applied to each input | | deprecated since version 1.2.0 | | ||
| ~~`containerStyle`~~ | Object | The styles to be applied to the container | | deprecated since version 1.2.0 | | ||
## License | ||
@@ -124,0 +185,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
42003
20.61%338
23.81%184
49.59%