react-auth-code-input
Advanced tools
Comparing version 3.0.0 to 3.1.0
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 @@ | ||
![image](https://user-images.githubusercontent.com/1719915/82956329-2f7e8700-9f76-11ea-978f-ec7135c79311.png) | ||
![image](https://user-images.githubusercontent.com/1719915/159336862-113dfbdd-e415-4237-afdb-f9df6628aaf7.png) | ||
# 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 @@ [![NPM](https://img.shields.io/npm/v/react-auth-code-input.svg)](https://www.npmjs.com/package/react-auth-code-input) [![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
42003
338
184