react-auth-code-input
Advanced tools
Comparing version 2.1.0 to 3.0.0
import React from 'react'; | ||
declare type Props = { | ||
allowedCharacters?: string; | ||
allowedCharacters?: 'alpha' | 'numeric' | 'alphanumeric'; | ||
ariaLabel?: string; | ||
characters?: number; | ||
length?: number; | ||
containerClassName?: string; | ||
inputClassName?: string; | ||
inputType?: 'number' | 'password' | 'text'; | ||
isPassword?: boolean; | ||
onChange: (res: string) => void; | ||
@@ -10,0 +10,0 @@ }; |
@@ -6,15 +6,35 @@ function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } | ||
var propsMap = { | ||
alpha: { | ||
type: 'text', | ||
inputMode: 'text', | ||
pattern: '[a-zA-Z]{1}' | ||
}, | ||
alphanumeric: { | ||
type: 'text', | ||
inputMode: 'text', | ||
pattern: '[a-zA-Z0-9]{1}' | ||
}, | ||
numeric: { | ||
type: 'number', | ||
inputMode: 'numeric', | ||
pattern: '[0-9]{1}', | ||
min: '0', | ||
max: '9' | ||
} | ||
}; | ||
var AuthCode = function AuthCode(_ref) { | ||
var _ref$allowedCharacter = _ref.allowedCharacters, | ||
allowedCharacters = _ref$allowedCharacter === void 0 ? '[A-Za-z0-9]+' : _ref$allowedCharacter, | ||
allowedCharacters = _ref$allowedCharacter === void 0 ? 'alphanumeric' : _ref$allowedCharacter, | ||
ariaLabel = _ref.ariaLabel, | ||
_ref$characters = _ref.characters, | ||
characters = _ref$characters === void 0 ? 6 : _ref$characters, | ||
_ref$length = _ref.length, | ||
length = _ref$length === void 0 ? 6 : _ref$length, | ||
containerClassName = _ref.containerClassName, | ||
inputClassName = _ref.inputClassName, | ||
_ref$inputType = _ref.inputType, | ||
inputType = _ref$inputType === void 0 ? 'text' : _ref$inputType, | ||
_ref$isPassword = _ref.isPassword, | ||
isPassword = _ref$isPassword === void 0 ? false : _ref$isPassword, | ||
onChange = _ref.onChange; | ||
var inputsRef = React.useRef([]); | ||
var inputMode = inputType === 'number' ? 'numeric' : 'text'; | ||
var inputProps = propsMap[allowedCharacters]; | ||
React.useEffect(function () { | ||
@@ -36,3 +56,5 @@ inputsRef.current[0].focus(); | ||
if (value.match(allowedCharacters)) { | ||
if (value.length > 1) { | ||
e.target.value = value.charAt(0); | ||
if (nextElementSibling !== null) { | ||
@@ -42,3 +64,9 @@ nextElementSibling.focus(); | ||
} else { | ||
e.target.value = ''; | ||
if (value.match(inputProps.pattern)) { | ||
if (nextElementSibling !== null) { | ||
nextElementSibling.focus(); | ||
} | ||
} else { | ||
e.target.value = ''; | ||
} | ||
} | ||
@@ -72,16 +100,22 @@ | ||
var handleOnPaste = function handleOnPaste(e) { | ||
var value = e.clipboardData.getData('Text'); | ||
var pastedValue = e.clipboardData.getData('Text'); | ||
var currentInput = 0; | ||
if (value.match(allowedCharacters)) { | ||
for (var i = 0; i < characters && i < value.length; i++) { | ||
inputsRef.current[i].value = value.charAt(i); | ||
for (var i = 0; i < pastedValue.length; i++) { | ||
var pastedCharacter = pastedValue.charAt(i); | ||
var currentValue = inputsRef.current[currentInput].value; | ||
if (inputsRef.current[i].nextElementSibling !== null) { | ||
inputsRef.current[i].nextElementSibling.focus(); | ||
if (pastedCharacter.match(inputProps.pattern)) { | ||
if (!currentValue) { | ||
inputsRef.current[currentInput].value = pastedCharacter; | ||
if (inputsRef.current[currentInput].nextElementSibling !== null) { | ||
inputsRef.current[currentInput].nextElementSibling.focus(); | ||
currentInput++; | ||
} | ||
} | ||
} | ||
sendResult(); | ||
} | ||
sendResult(); | ||
e.preventDefault(); | ||
@@ -93,3 +127,3 @@ }; | ||
var _loop = function _loop(i) { | ||
inputs.push(React__default.createElement("input", { | ||
inputs.push(React__default.createElement("input", Object.assign({ | ||
key: i, | ||
@@ -99,4 +133,5 @@ onChange: handleOnChange, | ||
onFocus: handleOnFocus, | ||
onPaste: handleOnPaste, | ||
type: inputType, | ||
onPaste: handleOnPaste | ||
}, inputProps, { | ||
type: isPassword ? 'password' : inputProps.type, | ||
ref: function ref(el) { | ||
@@ -107,10 +142,8 @@ return inputsRef.current[i] = el; | ||
className: inputClassName, | ||
inputMode: inputMode, | ||
autoComplete: i === 0 ? 'one-time-code' : 'off', | ||
"aria-label": ariaLabel ? ariaLabel + ". Character " + (i + 1) + "." : "Character " + (i + 1) + ".", | ||
pattern: i === 0 ? allowedCharacters : '' | ||
})); | ||
"aria-label": ariaLabel ? ariaLabel + ". Character " + (i + 1) + "." : "Character " + (i + 1) + "." | ||
}))); | ||
}; | ||
for (var i = 0; i < characters; i++) { | ||
for (var i = 0; i < length; i++) { | ||
_loop(i); | ||
@@ -117,0 +150,0 @@ } |
import React, { useRef, useEffect } from 'react'; | ||
var AuthCode = function AuthCode(_ref) { | ||
var _ref$allowedCharacter = _ref.allowedCharacters, | ||
allowedCharacters = _ref$allowedCharacter === void 0 ? '[A-Za-z0-9]+' : _ref$allowedCharacter, | ||
ariaLabel = _ref.ariaLabel, | ||
_ref$characters = _ref.characters, | ||
characters = _ref$characters === void 0 ? 6 : _ref$characters, | ||
containerClassName = _ref.containerClassName, | ||
inputClassName = _ref.inputClassName, | ||
_ref$inputType = _ref.inputType, | ||
inputType = _ref$inputType === void 0 ? 'text' : _ref$inputType, | ||
onChange = _ref.onChange; | ||
var inputsRef = useRef([]); | ||
var inputMode = inputType === 'number' ? 'numeric' : 'text'; | ||
useEffect(function () { | ||
const propsMap = { | ||
alpha: { | ||
type: 'text', | ||
inputMode: 'text', | ||
pattern: '[a-zA-Z]{1}' | ||
}, | ||
alphanumeric: { | ||
type: 'text', | ||
inputMode: 'text', | ||
pattern: '[a-zA-Z0-9]{1}' | ||
}, | ||
numeric: { | ||
type: 'number', | ||
inputMode: 'numeric', | ||
pattern: '[0-9]{1}', | ||
min: '0', | ||
max: '9' | ||
} | ||
}; | ||
const AuthCode = ({ | ||
allowedCharacters: _allowedCharacters = 'alphanumeric', | ||
ariaLabel, | ||
length: _length = 6, | ||
containerClassName, | ||
inputClassName, | ||
isPassword: _isPassword = false, | ||
onChange | ||
}) => { | ||
const inputsRef = useRef([]); | ||
const inputProps = propsMap[_allowedCharacters]; | ||
useEffect(() => { | ||
inputsRef.current[0].focus(); | ||
}, []); | ||
var sendResult = function sendResult() { | ||
var res = inputsRef.current.map(function (input) { | ||
return input.value; | ||
}).join(''); | ||
const sendResult = () => { | ||
const res = inputsRef.current.map(input => input.value).join(''); | ||
onChange && onChange(res); | ||
}; | ||
var handleOnChange = function handleOnChange(e) { | ||
var _e$target = e.target, | ||
value = _e$target.value, | ||
nextElementSibling = _e$target.nextElementSibling; | ||
const handleOnChange = e => { | ||
const { | ||
target: { | ||
value, | ||
nextElementSibling | ||
} | ||
} = e; | ||
if (value.match(allowedCharacters)) { | ||
if (value.length > 1) { | ||
e.target.value = value.charAt(0); | ||
if (nextElementSibling !== null) { | ||
@@ -37,3 +58,9 @@ nextElementSibling.focus(); | ||
} else { | ||
e.target.value = ''; | ||
if (value.match(inputProps.pattern)) { | ||
if (nextElementSibling !== null) { | ||
nextElementSibling.focus(); | ||
} | ||
} else { | ||
e.target.value = ''; | ||
} | ||
} | ||
@@ -44,5 +71,7 @@ | ||
var handleOnKeyDown = function handleOnKeyDown(e) { | ||
var key = e.key; | ||
var target = e.target; | ||
const handleOnKeyDown = e => { | ||
const { | ||
key | ||
} = e; | ||
const target = e.target; | ||
@@ -63,28 +92,34 @@ if (key === 'Backspace') { | ||
var handleOnFocus = function handleOnFocus(e) { | ||
const handleOnFocus = e => { | ||
e.target.select(); | ||
}; | ||
var handleOnPaste = function handleOnPaste(e) { | ||
var value = e.clipboardData.getData('Text'); | ||
const handleOnPaste = e => { | ||
const pastedValue = e.clipboardData.getData('Text'); | ||
let currentInput = 0; | ||
if (value.match(allowedCharacters)) { | ||
for (var i = 0; i < characters && i < value.length; i++) { | ||
inputsRef.current[i].value = value.charAt(i); | ||
for (let i = 0; i < pastedValue.length; i++) { | ||
const pastedCharacter = pastedValue.charAt(i); | ||
const currentValue = inputsRef.current[currentInput].value; | ||
if (inputsRef.current[i].nextElementSibling !== null) { | ||
inputsRef.current[i].nextElementSibling.focus(); | ||
if (pastedCharacter.match(inputProps.pattern)) { | ||
if (!currentValue) { | ||
inputsRef.current[currentInput].value = pastedCharacter; | ||
if (inputsRef.current[currentInput].nextElementSibling !== null) { | ||
inputsRef.current[currentInput].nextElementSibling.focus(); | ||
currentInput++; | ||
} | ||
} | ||
} | ||
sendResult(); | ||
} | ||
sendResult(); | ||
e.preventDefault(); | ||
}; | ||
var inputs = []; | ||
const inputs = []; | ||
var _loop = function _loop(i) { | ||
inputs.push(React.createElement("input", { | ||
for (let i = 0; i < _length; i++) { | ||
inputs.push(React.createElement("input", Object.assign({ | ||
key: i, | ||
@@ -94,18 +129,11 @@ onChange: handleOnChange, | ||
onFocus: handleOnFocus, | ||
onPaste: handleOnPaste, | ||
type: inputType, | ||
ref: function ref(el) { | ||
return inputsRef.current[i] = el; | ||
}, | ||
onPaste: handleOnPaste | ||
}, inputProps, { | ||
type: _isPassword ? 'password' : inputProps.type, | ||
ref: el => inputsRef.current[i] = el, | ||
maxLength: 1, | ||
className: inputClassName, | ||
inputMode: inputMode, | ||
autoComplete: i === 0 ? 'one-time-code' : 'off', | ||
"aria-label": ariaLabel ? ariaLabel + ". Character " + (i + 1) + "." : "Character " + (i + 1) + ".", | ||
pattern: i === 0 ? allowedCharacters : '' | ||
})); | ||
}; | ||
for (var i = 0; i < characters; i++) { | ||
_loop(i); | ||
"aria-label": ariaLabel ? `${ariaLabel}. Character ${i + 1}.` : `Character ${i + 1}.` | ||
}))); | ||
} | ||
@@ -112,0 +140,0 @@ |
{ | ||
"name": "react-auth-code-input", | ||
"version": "2.1.0", | ||
"description": "A React Component for inputting Auth Codes inspired in Apple Two-Factor Authentication UI. You can type, paste and move backwards using the backspace.", | ||
"version": "3.0.0", | ||
"description": "One-time password (OTP) React input component, uncontrolled, zero dependencies, fully tested.", | ||
"author": "drac94", | ||
@@ -6,0 +6,0 @@ "license": "MIT", |
@@ -5,3 +5,3 @@ ![image](https://user-images.githubusercontent.com/1719915/82956329-2f7e8700-9f76-11ea-978f-ec7135c79311.png) | ||
> A React Component for inputting Auth Codes inspired in Apple Two-Factor Authentication UI. You can type, paste and move backwards using the backspace. | ||
> One-time password (OTP) React input component, uncontrolled, zero dependencies, fully tested. | ||
@@ -44,3 +44,3 @@ [![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) | ||
<AuthCode | ||
characters={5} | ||
length={5} | ||
onChange={handleOnChange} | ||
@@ -54,19 +54,23 @@ containerClassName='container' | ||
### Props | ||
## Props | ||
| 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 | | ||
| 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 | | | ||
## Changelog | ||
### 3.0.0 | ||
- Change the way the allowed characters are handled by using 3 predefined modes: alpha, alphanumeric, and numeric, allowing to have more control when validating the values introduced in the inputs. | ||
- Improved logic. | ||
- Improved tests. | ||
- Improved types. | ||
### 2.1.0 | ||
@@ -102,2 +106,17 @@ | ||
## 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 | ||
@@ -104,0 +123,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
34825
273
123