diff --git a/README.md b/README.md
index 4aa6c34..84bde97 100644
--- a/README.md
+++ b/README.md
@@ -114,6 +114,22 @@ const App = () => {
};
```
+## Passing a value
+
+```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 ;
+};
+```
+
## SMS Autofill
This component supports autofill from SMS's received, tested on Safari and Chrome in iOS.
@@ -137,6 +153,11 @@ This component supports autofill from SMS's received, tested on Safari and Chrom
### 3.2.1
+- Block tab if current code position is not filled
+- Added possibility to pass a value prop
+
+### 3.2.1
+
- Fix allowing non-numeric characters being introduced in numeric mode on Safari and Firefox.
### 3.2.0
diff --git a/dist/index.js b/dist/index.js
index f75d74a..7fb9af0 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -23,6 +23,17 @@ var propsMap = {
max: '9'
}
};
+var valueValidation = {
+ alpha: function alpha(value) {
+ return /^[a-zA-Z]*$/.test(value);
+ },
+ alphanumeric: function alphanumeric(value) {
+ return /^[a-zA-Z0-9]*$/.test(value);
+ },
+ numeric: function numeric(value) {
+ return /^[0-9]*$/.test(value);
+ }
+};
var AuthCode = React.forwardRef(function (_ref, ref) {
var _ref$allowedCharacter = _ref.allowedCharacters,
allowedCharacters = _ref$allowedCharacter === void 0 ? 'alphanumeric' : _ref$allowedCharacter,
@@ -37,7 +48,9 @@ var AuthCode = React.forwardRef(function (_ref, ref) {
_ref$length = _ref.length,
length = _ref$length === void 0 ? 6 : _ref$length,
placeholder = _ref.placeholder,
- onChange = _ref.onChange;
+ onChange = _ref.onChange,
+ value = _ref.value;
+ var values = value ? value.split('') : [];
if (isNaN(length) || length < 1) {
throw new Error('Length should be a number and greater than 0');
@@ -49,6 +62,14 @@ var AuthCode = React.forwardRef(function (_ref, ref) {
throw new Error('Invalid value for allowedCharacters. Use alpha, numeric, or alphanumeric');
}
+ if (value && value.length > length) {
+ throw new Error('Value length should not be greater than length');
+ }
+
+ if (value && !valueValidation[allowedCharacters](value)) {
+ throw new Error("Value should only contain " + allowedCharacters + " characters");
+ }
+
var inputsRef = React.useRef([]);
var inputProps = propsMap[allowedCharacters];
React.useImperativeHandle(ref, function () {
@@ -126,6 +147,10 @@ var AuthCode = React.forwardRef(function (_ref, ref) {
sendResult();
}
+
+ if (key === 'Tab' && target.value === '') {
+ e.preventDefault();
+ }
};
var handleOnFocus = function handleOnFocus(e) {
@@ -175,7 +200,8 @@ var AuthCode = React.forwardRef(function (_ref, ref) {
autoComplete: i === 0 ? 'one-time-code' : 'off',
"aria-label": ariaLabel ? ariaLabel + ". Character " + (i + 1) + "." : "Character " + (i + 1) + ".",
disabled: disabled,
- placeholder: placeholder
+ placeholder: placeholder,
+ defaultValue: values[i] || ''
})));
};
diff --git a/dist/index.js.map b/dist/index.js.map
index c55ecd6..1d6009b 100644
--- a/dist/index.js.map
+++ b/dist/index.js.map
@@ -1 +1 @@
-{"version":3,"file":"index.js","sources":["../src/index.tsx"],"sourcesContent":["import React, {\n useRef,\n useEffect,\n useImperativeHandle,\n forwardRef\n} from 'react';\n\nconst allowedCharactersValues = ['alpha', 'numeric', 'alphanumeric'] as const;\n\nexport type AuthCodeProps = {\n allowedCharacters?: typeof allowedCharactersValues[number];\n ariaLabel?: string;\n autoFocus?: boolean;\n containerClassName?: string;\n disabled?: boolean;\n inputClassName?: string;\n isPassword?: boolean;\n length?: number;\n placeholder?: string;\n onChange: (res: string) => void;\n};\n\ntype InputMode = 'text' | 'numeric';\n\ntype InputType = 'text' | 'tel' | 'password';\n\ntype InputProps = {\n type: InputType;\n inputMode: InputMode;\n pattern: string;\n min?: string;\n max?: string;\n};\n\nexport type AuthCodeRef = {\n focus: () => void;\n clear: () => void;\n};\n\nconst propsMap: { [key: string]: InputProps } = {\n alpha: {\n type: 'text',\n inputMode: 'text',\n pattern: '[a-zA-Z]{1}'\n },\n\n alphanumeric: {\n type: 'text',\n inputMode: 'text',\n pattern: '[a-zA-Z0-9]{1}'\n },\n\n numeric: {\n type: 'tel',\n inputMode: 'numeric',\n pattern: '[0-9]{1}',\n min: '0',\n max: '9'\n }\n};\n\nconst AuthCode = forwardRef(\n (\n {\n allowedCharacters = 'alphanumeric',\n ariaLabel,\n autoFocus = true,\n containerClassName,\n disabled,\n inputClassName,\n isPassword = false,\n length = 6,\n placeholder,\n onChange\n },\n ref\n ) => {\n if (isNaN(length) || length < 1) {\n throw new Error('Length should be a number and greater than 0');\n }\n\n if (!allowedCharactersValues.some((value) => value === allowedCharacters)) {\n throw new Error(\n 'Invalid value for allowedCharacters. Use alpha, numeric, or alphanumeric'\n );\n }\n\n const inputsRef = useRef>([]);\n const inputProps = propsMap[allowedCharacters];\n\n useImperativeHandle(ref, () => ({\n focus: () => {\n if (inputsRef.current) {\n inputsRef.current[0].focus();\n }\n },\n clear: () => {\n if (inputsRef.current) {\n for (let i = 0; i < inputsRef.current.length; i++) {\n inputsRef.current[i].value = '';\n }\n inputsRef.current[0].focus();\n }\n sendResult();\n }\n }));\n\n useEffect(() => {\n if (autoFocus) {\n inputsRef.current[0].focus();\n }\n }, []);\n\n const sendResult = () => {\n const res = inputsRef.current.map((input) => input.value).join('');\n onChange && onChange(res);\n };\n\n const handleOnChange = (e: React.ChangeEvent) => {\n const {\n target: { value, nextElementSibling }\n } = e;\n if (value.length > 1) {\n e.target.value = value.charAt(0);\n if (nextElementSibling !== null) {\n (nextElementSibling as HTMLInputElement).focus();\n }\n } else {\n if (value.match(inputProps.pattern)) {\n if (nextElementSibling !== null) {\n (nextElementSibling as HTMLInputElement).focus();\n }\n } else {\n e.target.value = '';\n }\n }\n sendResult();\n };\n\n const handleOnKeyDown = (e: React.KeyboardEvent) => {\n const { key } = e;\n const target = e.target as HTMLInputElement;\n if (key === 'Backspace') {\n if (target.value === '') {\n if (target.previousElementSibling !== null) {\n const t = target.previousElementSibling as HTMLInputElement;\n t.value = '';\n t.focus();\n e.preventDefault();\n }\n } else {\n target.value = '';\n }\n sendResult();\n }\n };\n\n const handleOnFocus = (e: React.FocusEvent) => {\n e.target.select();\n };\n\n const handleOnPaste = (e: React.ClipboardEvent) => {\n const pastedValue = e.clipboardData.getData('Text');\n\n let currentInput = 0;\n\n for (let i = 0; i < pastedValue.length; i++) {\n const pastedCharacter = pastedValue.charAt(i);\n const currentValue = inputsRef.current[currentInput].value;\n if (pastedCharacter.match(inputProps.pattern)) {\n if (!currentValue) {\n inputsRef.current[currentInput].value = pastedCharacter;\n if (inputsRef.current[currentInput].nextElementSibling !== null) {\n (inputsRef.current[currentInput]\n .nextElementSibling as HTMLInputElement).focus();\n currentInput++;\n }\n }\n }\n }\n sendResult();\n\n e.preventDefault();\n };\n\n const inputs = [];\n for (let i = 0; i < length; i++) {\n inputs.push(\n {\n inputsRef.current[i] = el;\n }}\n maxLength={1}\n className={inputClassName}\n autoComplete={i === 0 ? 'one-time-code' : 'off'}\n aria-label={\n ariaLabel\n ? `${ariaLabel}. Character ${i + 1}.`\n : `Character ${i + 1}.`\n }\n disabled={disabled}\n placeholder={placeholder}\n />\n );\n }\n\n return {inputs}
;\n }\n);\n\nexport default AuthCode;\n"],"names":["allowedCharactersValues","propsMap","alpha","type","inputMode","pattern","alphanumeric","numeric","min","max","AuthCode","forwardRef","ref","allowedCharacters","ariaLabel","autoFocus","containerClassName","disabled","inputClassName","isPassword","length","placeholder","onChange","isNaN","Error","some","value","inputsRef","useRef","inputProps","useImperativeHandle","focus","current","clear","i","sendResult","useEffect","res","map","input","join","handleOnChange","e","target","nextElementSibling","charAt","match","handleOnKeyDown","key","previousElementSibling","t","preventDefault","handleOnFocus","select","handleOnPaste","pastedValue","clipboardData","getData","currentInput","pastedCharacter","currentValue","inputs","push","React","onKeyDown","onFocus","onPaste","el","maxLength","className","autoComplete"],"mappings":";;;;;AAOA,IAAMA,uBAAuB,GAAG,CAAC,OAAD,EAAU,SAAV,EAAqB,cAArB,CAAhC;AAgCA,IAAMC,QAAQ,GAAkC;AAC9CC,EAAAA,KAAK,EAAE;AACLC,IAAAA,IAAI,EAAE,MADD;AAELC,IAAAA,SAAS,EAAE,MAFN;AAGLC,IAAAA,OAAO,EAAE;AAHJ,GADuC;AAO9CC,EAAAA,YAAY,EAAE;AACZH,IAAAA,IAAI,EAAE,MADM;AAEZC,IAAAA,SAAS,EAAE,MAFC;AAGZC,IAAAA,OAAO,EAAE;AAHG,GAPgC;AAa9CE,EAAAA,OAAO,EAAE;AACPJ,IAAAA,IAAI,EAAE,KADC;AAEPC,IAAAA,SAAS,EAAE,SAFJ;AAGPC,IAAAA,OAAO,EAAE,UAHF;AAIPG,IAAAA,GAAG,EAAE,GAJE;AAKPC,IAAAA,GAAG,EAAE;AALE;AAbqC,CAAhD;AAsBA,IAAMC,QAAQ,GAAGC,gBAAU,CACzB,gBAaEC,GAbF;mCAEIC;MAAAA,uDAAoB;MACpBC,iBAAAA;4BACAC;MAAAA,wCAAY;MACZC,0BAAAA;MACAC,gBAAAA;MACAC,sBAAAA;6BACAC;MAAAA,0CAAa;yBACbC;MAAAA,kCAAS;MACTC,mBAAAA;MACAC,gBAAAA;;AAIF,MAAIC,KAAK,CAACH,MAAD,CAAL,IAAiBA,MAAM,GAAG,CAA9B,EAAiC;AAC/B,UAAM,IAAII,KAAJ,CAAU,8CAAV,CAAN;AACD;;AAED,MAAI,CAACxB,uBAAuB,CAACyB,IAAxB,CAA6B,UAACC,KAAD;AAAA,WAAWA,KAAK,KAAKb,iBAArB;AAAA,GAA7B,CAAL,EAA2E;AACzE,UAAM,IAAIW,KAAJ,CACJ,0EADI,CAAN;AAGD;;AAED,MAAMG,SAAS,GAAGC,YAAM,CAA0B,EAA1B,CAAxB;AACA,MAAMC,UAAU,GAAG5B,QAAQ,CAACY,iBAAD,CAA3B;AAEAiB,EAAAA,yBAAmB,CAAClB,GAAD,EAAM;AAAA,WAAO;AAC9BmB,MAAAA,KAAK,EAAE;AACL,YAAIJ,SAAS,CAACK,OAAd,EAAuB;AACrBL,UAAAA,SAAS,CAACK,OAAV,CAAkB,CAAlB,EAAqBD,KAArB;AACD;AACF,OAL6B;AAM9BE,MAAAA,KAAK,EAAE;AACL,YAAIN,SAAS,CAACK,OAAd,EAAuB;AACrB,eAAK,IAAIE,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAGP,SAAS,CAACK,OAAV,CAAkBZ,MAAtC,EAA8Cc,CAAC,EAA/C,EAAmD;AACjDP,YAAAA,SAAS,CAACK,OAAV,CAAkBE,CAAlB,EAAqBR,KAArB,GAA6B,EAA7B;AACD;;AACDC,UAAAA,SAAS,CAACK,OAAV,CAAkB,CAAlB,EAAqBD,KAArB;AACD;;AACDI,QAAAA,UAAU;AACX;AAd6B,KAAP;AAAA,GAAN,CAAnB;AAiBAC,EAAAA,eAAS,CAAC;AACR,QAAIrB,SAAJ,EAAe;AACbY,MAAAA,SAAS,CAACK,OAAV,CAAkB,CAAlB,EAAqBD,KAArB;AACD;AACF,GAJQ,EAIN,EAJM,CAAT;;AAMA,MAAMI,UAAU,GAAG,SAAbA,UAAa;AACjB,QAAME,GAAG,GAAGV,SAAS,CAACK,OAAV,CAAkBM,GAAlB,CAAsB,UAACC,KAAD;AAAA,aAAWA,KAAK,CAACb,KAAjB;AAAA,KAAtB,EAA8Cc,IAA9C,CAAmD,EAAnD,CAAZ;AACAlB,IAAAA,QAAQ,IAAIA,QAAQ,CAACe,GAAD,CAApB;AACD,GAHD;;AAKA,MAAMI,cAAc,GAAG,SAAjBA,cAAiB,CAACC,CAAD;oBAGjBA,EADFC;QAAUjB,kBAAAA;QAAOkB,+BAAAA;;AAEnB,QAAIlB,KAAK,CAACN,MAAN,GAAe,CAAnB,EAAsB;AACpBsB,MAAAA,CAAC,CAACC,MAAF,CAASjB,KAAT,GAAiBA,KAAK,CAACmB,MAAN,CAAa,CAAb,CAAjB;;AACA,UAAID,kBAAkB,KAAK,IAA3B,EAAiC;AAC9BA,QAAAA,kBAAuC,CAACb,KAAxC;AACF;AACF,KALD,MAKO;AACL,UAAIL,KAAK,CAACoB,KAAN,CAAYjB,UAAU,CAACxB,OAAvB,CAAJ,EAAqC;AACnC,YAAIuC,kBAAkB,KAAK,IAA3B,EAAiC;AAC9BA,UAAAA,kBAAuC,CAACb,KAAxC;AACF;AACF,OAJD,MAIO;AACLW,QAAAA,CAAC,CAACC,MAAF,CAASjB,KAAT,GAAiB,EAAjB;AACD;AACF;;AACDS,IAAAA,UAAU;AACX,GAnBD;;AAqBA,MAAMY,eAAe,GAAG,SAAlBA,eAAkB,CAACL,CAAD;QACdM,MAAQN,EAARM;AACR,QAAML,MAAM,GAAGD,CAAC,CAACC,MAAjB;;AACA,QAAIK,GAAG,KAAK,WAAZ,EAAyB;AACvB,UAAIL,MAAM,CAACjB,KAAP,KAAiB,EAArB,EAAyB;AACvB,YAAIiB,MAAM,CAACM,sBAAP,KAAkC,IAAtC,EAA4C;AAC1C,cAAMC,CAAC,GAAGP,MAAM,CAACM,sBAAjB;AACAC,UAAAA,CAAC,CAACxB,KAAF,GAAU,EAAV;AACAwB,UAAAA,CAAC,CAACnB,KAAF;AACAW,UAAAA,CAAC,CAACS,cAAF;AACD;AACF,OAPD,MAOO;AACLR,QAAAA,MAAM,CAACjB,KAAP,GAAe,EAAf;AACD;;AACDS,MAAAA,UAAU;AACX;AACF,GAhBD;;AAkBA,MAAMiB,aAAa,GAAG,SAAhBA,aAAgB,CAACV,CAAD;AACpBA,IAAAA,CAAC,CAACC,MAAF,CAASU,MAAT;AACD,GAFD;;AAIA,MAAMC,aAAa,GAAG,SAAhBA,aAAgB,CAACZ,CAAD;AACpB,QAAMa,WAAW,GAAGb,CAAC,CAACc,aAAF,CAAgBC,OAAhB,CAAwB,MAAxB,CAApB;AAEA,QAAIC,YAAY,GAAG,CAAnB;;AAEA,SAAK,IAAIxB,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAGqB,WAAW,CAACnC,MAAhC,EAAwCc,CAAC,EAAzC,EAA6C;AAC3C,UAAMyB,eAAe,GAAGJ,WAAW,CAACV,MAAZ,CAAmBX,CAAnB,CAAxB;AACA,UAAM0B,YAAY,GAAGjC,SAAS,CAACK,OAAV,CAAkB0B,YAAlB,EAAgChC,KAArD;;AACA,UAAIiC,eAAe,CAACb,KAAhB,CAAsBjB,UAAU,CAACxB,OAAjC,CAAJ,EAA+C;AAC7C,YAAI,CAACuD,YAAL,EAAmB;AACjBjC,UAAAA,SAAS,CAACK,OAAV,CAAkB0B,YAAlB,EAAgChC,KAAhC,GAAwCiC,eAAxC;;AACA,cAAIhC,SAAS,CAACK,OAAV,CAAkB0B,YAAlB,EAAgCd,kBAAhC,KAAuD,IAA3D,EAAiE;AAC9DjB,YAAAA,SAAS,CAACK,OAAV,CAAkB0B,YAAlB,EACEd,kBADF,CAC0Cb,KAD1C;AAED2B,YAAAA,YAAY;AACb;AACF;AACF;AACF;;AACDvB,IAAAA,UAAU;AAEVO,IAAAA,CAAC,CAACS,cAAF;AACD,GAtBD;;AAwBA,MAAMU,MAAM,GAAG,EAAf;;6BACS3B;AACP2B,IAAAA,MAAM,CAACC,IAAP,CACEC,4BAAA,QAAA;AACEf,MAAAA,GAAG,EAAEd;AACLZ,MAAAA,QAAQ,EAAEmB;AACVuB,MAAAA,SAAS,EAAEjB;AACXkB,MAAAA,OAAO,EAAEb;AACTc,MAAAA,OAAO,EAAEZ;OACLzB;AACJ1B,MAAAA,IAAI,EAAEgB,UAAU,GAAG,UAAH,GAAgBU,UAAU,CAAC1B;AAC3CS,MAAAA,GAAG,EAAE,aAACuD,EAAD;AACHxC,QAAAA,SAAS,CAACK,OAAV,CAAkBE,CAAlB,IAAuBiC,EAAvB;AACD;AACDC,MAAAA,SAAS,EAAE;AACXC,MAAAA,SAAS,EAAEnD;AACXoD,MAAAA,YAAY,EAAEpC,CAAC,KAAK,CAAN,GAAU,eAAV,GAA4B;oBAExCpB,SAAS,GACFA,SADE,qBACsBoB,CAAC,GAAG,CAD1B,0BAEQA,CAAC,GAAG,CAFZ;AAIXjB,MAAAA,QAAQ,EAAEA;AACVI,MAAAA,WAAW,EAAEA;MApBf,CADF;;;AADF,OAAK,IAAIa,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAGd,MAApB,EAA4Bc,CAAC,EAA7B,EAAiC;AAAA,UAAxBA,CAAwB;AAyBhC;;AAED,SAAO6B,4BAAA,MAAA;AAAKM,IAAAA,SAAS,EAAErD;GAAhB,EAAqC6C,MAArC,CAAP;AACD,CAzJwB,CAA3B;;;;"}
\ No newline at end of file
+{"version":3,"file":"index.js","sources":["../src/index.tsx"],"sourcesContent":["import React, {\n forwardRef,\n useEffect,\n useImperativeHandle,\n useRef\n} from 'react';\n\nconst allowedCharactersValues = ['alpha', 'numeric', 'alphanumeric'] as const;\n\nexport type AuthCodeProps = {\n allowedCharacters?: typeof allowedCharactersValues[number];\n ariaLabel?: string;\n autoFocus?: boolean;\n containerClassName?: string;\n disabled?: boolean;\n inputClassName?: string;\n isPassword?: boolean;\n length?: number;\n placeholder?: string;\n onChange: (res: string) => void;\n value?: string;\n};\n\ntype InputMode = 'text' | 'numeric';\n\ntype InputType = 'text' | 'tel' | 'password';\n\ntype InputProps = {\n type: InputType;\n inputMode: InputMode;\n pattern: string;\n min?: string;\n max?: string;\n};\n\nexport type AuthCodeRef = {\n focus: () => void;\n clear: () => void;\n};\n\nconst propsMap: { [key: string]: InputProps } = {\n alpha: {\n type: 'text',\n inputMode: 'text',\n pattern: '[a-zA-Z]{1}'\n },\n\n alphanumeric: {\n type: 'text',\n inputMode: 'text',\n pattern: '[a-zA-Z0-9]{1}'\n },\n\n numeric: {\n type: 'tel',\n inputMode: 'numeric',\n pattern: '[0-9]{1}',\n min: '0',\n max: '9'\n }\n};\n\nconst valueValidation = {\n alpha: (value: string) => /^[a-zA-Z]*$/.test(value),\n alphanumeric: (value: string) => /^[a-zA-Z0-9]*$/.test(value),\n numeric: (value: string) => /^[0-9]*$/.test(value)\n};\n\nconst AuthCode = forwardRef(\n (\n {\n allowedCharacters = 'alphanumeric',\n ariaLabel,\n autoFocus = true,\n containerClassName,\n disabled,\n inputClassName,\n isPassword = false,\n length = 6,\n placeholder,\n onChange,\n value\n },\n ref\n ) => {\n const values = value ? value.split('') : [];\n\n if (isNaN(length) || length < 1) {\n throw new Error('Length should be a number and greater than 0');\n }\n\n if (!allowedCharactersValues.some((value) => value === allowedCharacters)) {\n throw new Error(\n 'Invalid value for allowedCharacters. Use alpha, numeric, or alphanumeric'\n );\n }\n\n if (value && value.length > length) {\n throw new Error('Value length should not be greater than length');\n }\n\n if (value && !valueValidation[allowedCharacters](value)) {\n throw new Error(\n `Value should only contain ${allowedCharacters} characters`\n );\n }\n\n const inputsRef = useRef>([]);\n const inputProps = propsMap[allowedCharacters];\n\n useImperativeHandle(ref, () => ({\n focus: () => {\n if (inputsRef.current) {\n inputsRef.current[0].focus();\n }\n },\n clear: () => {\n if (inputsRef.current) {\n for (let i = 0; i < inputsRef.current.length; i++) {\n inputsRef.current[i].value = '';\n }\n inputsRef.current[0].focus();\n }\n sendResult();\n }\n }));\n\n useEffect(() => {\n if (autoFocus) {\n inputsRef.current[0].focus();\n }\n }, []);\n\n const sendResult = () => {\n const res = inputsRef.current.map((input) => input.value).join('');\n onChange && onChange(res);\n };\n\n const handleOnChange = (e: React.ChangeEvent) => {\n const {\n target: { value, nextElementSibling }\n } = e;\n if (value.length > 1) {\n e.target.value = value.charAt(0);\n if (nextElementSibling !== null) {\n (nextElementSibling as HTMLInputElement).focus();\n }\n } else {\n if (value.match(inputProps.pattern)) {\n if (nextElementSibling !== null) {\n (nextElementSibling as HTMLInputElement).focus();\n }\n } else {\n e.target.value = '';\n }\n }\n sendResult();\n };\n\n const handleOnKeyDown = (e: React.KeyboardEvent) => {\n const { key } = e;\n const target = e.target as HTMLInputElement;\n if (key === 'Backspace') {\n if (target.value === '') {\n if (target.previousElementSibling !== null) {\n const t = target.previousElementSibling as HTMLInputElement;\n t.value = '';\n t.focus();\n e.preventDefault();\n }\n } else {\n target.value = '';\n }\n sendResult();\n }\n\n if (key === 'Tab' && target.value === '') {\n e.preventDefault();\n }\n };\n\n const handleOnFocus = (e: React.FocusEvent) => {\n e.target.select();\n };\n\n const handleOnPaste = (e: React.ClipboardEvent) => {\n const pastedValue = e.clipboardData.getData('Text');\n\n let currentInput = 0;\n\n for (let i = 0; i < pastedValue.length; i++) {\n const pastedCharacter = pastedValue.charAt(i);\n const currentValue = inputsRef.current[currentInput].value;\n if (pastedCharacter.match(inputProps.pattern)) {\n if (!currentValue) {\n inputsRef.current[currentInput].value = pastedCharacter;\n if (inputsRef.current[currentInput].nextElementSibling !== null) {\n (inputsRef.current[currentInput]\n .nextElementSibling as HTMLInputElement).focus();\n currentInput++;\n }\n }\n }\n }\n sendResult();\n\n e.preventDefault();\n };\n\n const inputs = [];\n for (let i = 0; i < length; i++) {\n inputs.push(\n {\n inputsRef.current[i] = el;\n }}\n maxLength={1}\n className={inputClassName}\n autoComplete={i === 0 ? 'one-time-code' : 'off'}\n aria-label={\n ariaLabel\n ? `${ariaLabel}. Character ${i + 1}.`\n : `Character ${i + 1}.`\n }\n disabled={disabled}\n placeholder={placeholder}\n defaultValue={values[i] || ''}\n />\n );\n }\n\n return {inputs}
;\n }\n);\n\nexport default AuthCode;\n"],"names":["allowedCharactersValues","propsMap","alpha","type","inputMode","pattern","alphanumeric","numeric","min","max","valueValidation","value","test","AuthCode","forwardRef","ref","allowedCharacters","ariaLabel","autoFocus","containerClassName","disabled","inputClassName","isPassword","length","placeholder","onChange","values","split","isNaN","Error","some","inputsRef","useRef","inputProps","useImperativeHandle","focus","current","clear","i","sendResult","useEffect","res","map","input","join","handleOnChange","e","target","nextElementSibling","charAt","match","handleOnKeyDown","key","previousElementSibling","t","preventDefault","handleOnFocus","select","handleOnPaste","pastedValue","clipboardData","getData","currentInput","pastedCharacter","currentValue","inputs","push","React","onKeyDown","onFocus","onPaste","el","maxLength","className","autoComplete","defaultValue"],"mappings":"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"}
\ No newline at end of file
diff --git a/dist/index.modern.js b/dist/index.modern.js
index 34f10f7..38c01b3 100644
--- a/dist/index.modern.js
+++ b/dist/index.modern.js
@@ -1,7 +1,7 @@
import React, { forwardRef, useRef, useImperativeHandle, useEffect } from 'react';
-var allowedCharactersValues = ['alpha', 'numeric', 'alphanumeric'];
-var propsMap = {
+const allowedCharactersValues = ['alpha', 'numeric', 'alphanumeric'];
+const propsMap = {
alpha: {
type: 'text',
inputMode: 'text',
@@ -20,71 +20,80 @@ var propsMap = {
max: '9'
}
};
-var AuthCode = 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,
- containerClassName = _ref.containerClassName,
- disabled = _ref.disabled,
- inputClassName = _ref.inputClassName,
- _ref$isPassword = _ref.isPassword,
- isPassword = _ref$isPassword === void 0 ? false : _ref$isPassword,
- _ref$length = _ref.length,
- length = _ref$length === void 0 ? 6 : _ref$length,
- placeholder = _ref.placeholder,
- onChange = _ref.onChange;
-
- if (isNaN(length) || length < 1) {
+const valueValidation = {
+ alpha: value => /^[a-zA-Z]*$/.test(value),
+ alphanumeric: value => /^[a-zA-Z0-9]*$/.test(value),
+ numeric: value => /^[0-9]*$/.test(value)
+};
+const AuthCode = forwardRef(({
+ allowedCharacters: _allowedCharacters = 'alphanumeric',
+ ariaLabel,
+ autoFocus: _autoFocus = true,
+ containerClassName,
+ disabled,
+ inputClassName,
+ isPassword: _isPassword = false,
+ length: _length = 6,
+ placeholder,
+ onChange,
+ value
+}, ref) => {
+ const values = value ? value.split('') : [];
+
+ 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;
- })) {
+ if (!allowedCharactersValues.some(value => value === _allowedCharacters)) {
throw new Error('Invalid value for allowedCharacters. Use alpha, numeric, or alphanumeric');
}
- var inputsRef = useRef([]);
- var inputProps = propsMap[allowedCharacters];
- 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 = '';
- }
+ if (value && value.length > _length) {
+ throw new Error('Value length should not be greater than length');
+ }
+
+ if (value && !valueValidation[_allowedCharacters](value)) {
+ throw new Error(`Value should only contain ${_allowedCharacters} characters`);
+ }
- inputsRef.current[0].focus();
+ 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 = '';
}
- sendResult();
+ inputsRef.current[0].focus();
}
- };
- });
- useEffect(function () {
- if (autoFocus) {
+
+ sendResult();
+ }
+ }));
+ useEffect(() => {
+ if (_autoFocus) {
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.length > 1) {
e.target.value = value.charAt(0);
@@ -105,14 +114,16 @@ var AuthCode = forwardRef(function (_ref, ref) {
sendResult();
};
- var handleOnKeyDown = function handleOnKeyDown(e) {
- var key = e.key;
- var target = e.target;
+ const handleOnKeyDown = e => {
+ const {
+ key
+ } = e;
+ const target = e.target;
if (key === 'Backspace') {
if (target.value === '') {
if (target.previousElementSibling !== null) {
- var t = target.previousElementSibling;
+ const t = target.previousElementSibling;
t.value = '';
t.focus();
e.preventDefault();
@@ -123,19 +134,23 @@ var AuthCode = forwardRef(function (_ref, ref) {
sendResult();
}
+
+ if (key === 'Tab' && target.value === '') {
+ e.preventDefault();
+ }
};
- var handleOnFocus = function handleOnFocus(e) {
+ const handleOnFocus = e => {
e.target.select();
};
- var handleOnPaste = function handleOnPaste(e) {
- var pastedValue = e.clipboardData.getData('Text');
- var currentInput = 0;
+ const handleOnPaste = e => {
+ const pastedValue = e.clipboardData.getData('Text');
+ let currentInput = 0;
- for (var i = 0; i < pastedValue.length; i++) {
- var pastedCharacter = pastedValue.charAt(i);
- var currentValue = inputsRef.current[currentInput].value;
+ for (let i = 0; i < pastedValue.length; i++) {
+ const pastedCharacter = pastedValue.charAt(i);
+ const currentValue = inputsRef.current[currentInput].value;
if (pastedCharacter.match(inputProps.pattern)) {
if (!currentValue) {
@@ -153,9 +168,9 @@ var AuthCode = forwardRef(function (_ref, ref) {
e.preventDefault();
};
- var inputs = [];
+ const inputs = [];
- var _loop = function _loop(i) {
+ for (let i = 0; i < _length; i++) {
inputs.push(React.createElement("input", Object.assign({
key: i,
onChange: handleOnChange,
@@ -163,21 +178,18 @@ var AuthCode = forwardRef(function (_ref, ref) {
onFocus: handleOnFocus,
onPaste: handleOnPaste
}, inputProps, {
- type: isPassword ? 'password' : inputProps.type,
- ref: function ref(el) {
+ type: _isPassword ? 'password' : inputProps.type,
+ ref: el => {
inputsRef.current[i] = el;
},
maxLength: 1,
className: inputClassName,
autoComplete: i === 0 ? 'one-time-code' : 'off',
- "aria-label": ariaLabel ? ariaLabel + ". Character " + (i + 1) + "." : "Character " + (i + 1) + ".",
+ "aria-label": ariaLabel ? `${ariaLabel}. Character ${i + 1}.` : `Character ${i + 1}.`,
disabled: disabled,
- placeholder: placeholder
+ placeholder: placeholder,
+ defaultValue: values[i] || ''
})));
- };
-
- for (var i = 0; i < length; i++) {
- _loop(i);
}
return React.createElement("div", {
diff --git a/dist/index.modern.js.map b/dist/index.modern.js.map
index 9e457ca..be3e5b2 100644
--- a/dist/index.modern.js.map
+++ b/dist/index.modern.js.map
@@ -1 +1 @@
-{"version":3,"file":"index.modern.js","sources":["../src/index.tsx"],"sourcesContent":["import React, {\n useRef,\n useEffect,\n useImperativeHandle,\n forwardRef\n} from 'react';\n\nconst allowedCharactersValues = ['alpha', 'numeric', 'alphanumeric'] as const;\n\nexport type AuthCodeProps = {\n allowedCharacters?: typeof allowedCharactersValues[number];\n ariaLabel?: string;\n autoFocus?: boolean;\n containerClassName?: string;\n disabled?: boolean;\n inputClassName?: string;\n isPassword?: boolean;\n length?: number;\n placeholder?: string;\n onChange: (res: string) => void;\n};\n\ntype InputMode = 'text' | 'numeric';\n\ntype InputType = 'text' | 'tel' | 'password';\n\ntype InputProps = {\n type: InputType;\n inputMode: InputMode;\n pattern: string;\n min?: string;\n max?: string;\n};\n\nexport type AuthCodeRef = {\n focus: () => void;\n clear: () => void;\n};\n\nconst propsMap: { [key: string]: InputProps } = {\n alpha: {\n type: 'text',\n inputMode: 'text',\n pattern: '[a-zA-Z]{1}'\n },\n\n alphanumeric: {\n type: 'text',\n inputMode: 'text',\n pattern: '[a-zA-Z0-9]{1}'\n },\n\n numeric: {\n type: 'tel',\n inputMode: 'numeric',\n pattern: '[0-9]{1}',\n min: '0',\n max: '9'\n }\n};\n\nconst AuthCode = forwardRef(\n (\n {\n allowedCharacters = 'alphanumeric',\n ariaLabel,\n autoFocus = true,\n containerClassName,\n disabled,\n inputClassName,\n isPassword = false,\n length = 6,\n placeholder,\n onChange\n },\n ref\n ) => {\n if (isNaN(length) || length < 1) {\n throw new Error('Length should be a number and greater than 0');\n }\n\n if (!allowedCharactersValues.some((value) => value === allowedCharacters)) {\n throw new Error(\n 'Invalid value for allowedCharacters. Use alpha, numeric, or alphanumeric'\n );\n }\n\n const inputsRef = useRef>([]);\n const inputProps = propsMap[allowedCharacters];\n\n useImperativeHandle(ref, () => ({\n focus: () => {\n if (inputsRef.current) {\n inputsRef.current[0].focus();\n }\n },\n clear: () => {\n if (inputsRef.current) {\n for (let i = 0; i < inputsRef.current.length; i++) {\n inputsRef.current[i].value = '';\n }\n inputsRef.current[0].focus();\n }\n sendResult();\n }\n }));\n\n useEffect(() => {\n if (autoFocus) {\n inputsRef.current[0].focus();\n }\n }, []);\n\n const sendResult = () => {\n const res = inputsRef.current.map((input) => input.value).join('');\n onChange && onChange(res);\n };\n\n const handleOnChange = (e: React.ChangeEvent) => {\n const {\n target: { value, nextElementSibling }\n } = e;\n if (value.length > 1) {\n e.target.value = value.charAt(0);\n if (nextElementSibling !== null) {\n (nextElementSibling as HTMLInputElement).focus();\n }\n } else {\n if (value.match(inputProps.pattern)) {\n if (nextElementSibling !== null) {\n (nextElementSibling as HTMLInputElement).focus();\n }\n } else {\n e.target.value = '';\n }\n }\n sendResult();\n };\n\n const handleOnKeyDown = (e: React.KeyboardEvent) => {\n const { key } = e;\n const target = e.target as HTMLInputElement;\n if (key === 'Backspace') {\n if (target.value === '') {\n if (target.previousElementSibling !== null) {\n const t = target.previousElementSibling as HTMLInputElement;\n t.value = '';\n t.focus();\n e.preventDefault();\n }\n } else {\n target.value = '';\n }\n sendResult();\n }\n };\n\n const handleOnFocus = (e: React.FocusEvent) => {\n e.target.select();\n };\n\n const handleOnPaste = (e: React.ClipboardEvent) => {\n const pastedValue = e.clipboardData.getData('Text');\n\n let currentInput = 0;\n\n for (let i = 0; i < pastedValue.length; i++) {\n const pastedCharacter = pastedValue.charAt(i);\n const currentValue = inputsRef.current[currentInput].value;\n if (pastedCharacter.match(inputProps.pattern)) {\n if (!currentValue) {\n inputsRef.current[currentInput].value = pastedCharacter;\n if (inputsRef.current[currentInput].nextElementSibling !== null) {\n (inputsRef.current[currentInput]\n .nextElementSibling as HTMLInputElement).focus();\n currentInput++;\n }\n }\n }\n }\n sendResult();\n\n e.preventDefault();\n };\n\n const inputs = [];\n for (let i = 0; i < length; i++) {\n inputs.push(\n {\n inputsRef.current[i] = el;\n }}\n maxLength={1}\n className={inputClassName}\n autoComplete={i === 0 ? 'one-time-code' : 'off'}\n aria-label={\n ariaLabel\n ? `${ariaLabel}. Character ${i + 1}.`\n : `Character ${i + 1}.`\n }\n disabled={disabled}\n placeholder={placeholder}\n />\n );\n }\n\n return {inputs}
;\n }\n);\n\nexport default AuthCode;\n"],"names":["allowedCharactersValues","propsMap","alpha","type","inputMode","pattern","alphanumeric","numeric","min","max","AuthCode","forwardRef","ref","allowedCharacters","ariaLabel","autoFocus","containerClassName","disabled","inputClassName","isPassword","length","placeholder","onChange","isNaN","Error","some","value","inputsRef","useRef","inputProps","useImperativeHandle","focus","current","clear","i","sendResult","useEffect","res","map","input","join","handleOnChange","e","target","nextElementSibling","charAt","match","handleOnKeyDown","key","previousElementSibling","t","preventDefault","handleOnFocus","select","handleOnPaste","pastedValue","clipboardData","getData","currentInput","pastedCharacter","currentValue","inputs","push","React","onKeyDown","onFocus","onPaste","el","maxLength","className","autoComplete"],"mappings":"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"}
\ No newline at end of file
+{"version":3,"file":"index.modern.js","sources":["../src/index.tsx"],"sourcesContent":["import React, {\n forwardRef,\n useEffect,\n useImperativeHandle,\n useRef\n} from 'react';\n\nconst allowedCharactersValues = ['alpha', 'numeric', 'alphanumeric'] as const;\n\nexport type AuthCodeProps = {\n allowedCharacters?: typeof allowedCharactersValues[number];\n ariaLabel?: string;\n autoFocus?: boolean;\n containerClassName?: string;\n disabled?: boolean;\n inputClassName?: string;\n isPassword?: boolean;\n length?: number;\n placeholder?: string;\n onChange: (res: string) => void;\n value?: string;\n};\n\ntype InputMode = 'text' | 'numeric';\n\ntype InputType = 'text' | 'tel' | 'password';\n\ntype InputProps = {\n type: InputType;\n inputMode: InputMode;\n pattern: string;\n min?: string;\n max?: string;\n};\n\nexport type AuthCodeRef = {\n focus: () => void;\n clear: () => void;\n};\n\nconst propsMap: { [key: string]: InputProps } = {\n alpha: {\n type: 'text',\n inputMode: 'text',\n pattern: '[a-zA-Z]{1}'\n },\n\n alphanumeric: {\n type: 'text',\n inputMode: 'text',\n pattern: '[a-zA-Z0-9]{1}'\n },\n\n numeric: {\n type: 'tel',\n inputMode: 'numeric',\n pattern: '[0-9]{1}',\n min: '0',\n max: '9'\n }\n};\n\nconst valueValidation = {\n alpha: (value: string) => /^[a-zA-Z]*$/.test(value),\n alphanumeric: (value: string) => /^[a-zA-Z0-9]*$/.test(value),\n numeric: (value: string) => /^[0-9]*$/.test(value)\n};\n\nconst AuthCode = forwardRef(\n (\n {\n allowedCharacters = 'alphanumeric',\n ariaLabel,\n autoFocus = true,\n containerClassName,\n disabled,\n inputClassName,\n isPassword = false,\n length = 6,\n placeholder,\n onChange,\n value\n },\n ref\n ) => {\n const values = value ? value.split('') : [];\n\n if (isNaN(length) || length < 1) {\n throw new Error('Length should be a number and greater than 0');\n }\n\n if (!allowedCharactersValues.some((value) => value === allowedCharacters)) {\n throw new Error(\n 'Invalid value for allowedCharacters. Use alpha, numeric, or alphanumeric'\n );\n }\n\n if (value && value.length > length) {\n throw new Error('Value length should not be greater than length');\n }\n\n if (value && !valueValidation[allowedCharacters](value)) {\n throw new Error(\n `Value should only contain ${allowedCharacters} characters`\n );\n }\n\n const inputsRef = useRef>([]);\n const inputProps = propsMap[allowedCharacters];\n\n useImperativeHandle(ref, () => ({\n focus: () => {\n if (inputsRef.current) {\n inputsRef.current[0].focus();\n }\n },\n clear: () => {\n if (inputsRef.current) {\n for (let i = 0; i < inputsRef.current.length; i++) {\n inputsRef.current[i].value = '';\n }\n inputsRef.current[0].focus();\n }\n sendResult();\n }\n }));\n\n useEffect(() => {\n if (autoFocus) {\n inputsRef.current[0].focus();\n }\n }, []);\n\n const sendResult = () => {\n const res = inputsRef.current.map((input) => input.value).join('');\n onChange && onChange(res);\n };\n\n const handleOnChange = (e: React.ChangeEvent) => {\n const {\n target: { value, nextElementSibling }\n } = e;\n if (value.length > 1) {\n e.target.value = value.charAt(0);\n if (nextElementSibling !== null) {\n (nextElementSibling as HTMLInputElement).focus();\n }\n } else {\n if (value.match(inputProps.pattern)) {\n if (nextElementSibling !== null) {\n (nextElementSibling as HTMLInputElement).focus();\n }\n } else {\n e.target.value = '';\n }\n }\n sendResult();\n };\n\n const handleOnKeyDown = (e: React.KeyboardEvent) => {\n const { key } = e;\n const target = e.target as HTMLInputElement;\n if (key === 'Backspace') {\n if (target.value === '') {\n if (target.previousElementSibling !== null) {\n const t = target.previousElementSibling as HTMLInputElement;\n t.value = '';\n t.focus();\n e.preventDefault();\n }\n } else {\n target.value = '';\n }\n sendResult();\n }\n\n if (key === 'Tab' && target.value === '') {\n e.preventDefault();\n }\n };\n\n const handleOnFocus = (e: React.FocusEvent) => {\n e.target.select();\n };\n\n const handleOnPaste = (e: React.ClipboardEvent) => {\n const pastedValue = e.clipboardData.getData('Text');\n\n let currentInput = 0;\n\n for (let i = 0; i < pastedValue.length; i++) {\n const pastedCharacter = pastedValue.charAt(i);\n const currentValue = inputsRef.current[currentInput].value;\n if (pastedCharacter.match(inputProps.pattern)) {\n if (!currentValue) {\n inputsRef.current[currentInput].value = pastedCharacter;\n if (inputsRef.current[currentInput].nextElementSibling !== null) {\n (inputsRef.current[currentInput]\n .nextElementSibling as HTMLInputElement).focus();\n currentInput++;\n }\n }\n }\n }\n sendResult();\n\n e.preventDefault();\n };\n\n const inputs = [];\n for (let i = 0; i < length; i++) {\n inputs.push(\n {\n inputsRef.current[i] = el;\n }}\n maxLength={1}\n className={inputClassName}\n autoComplete={i === 0 ? 'one-time-code' : 'off'}\n aria-label={\n ariaLabel\n ? `${ariaLabel}. Character ${i + 1}.`\n : `Character ${i + 1}.`\n }\n disabled={disabled}\n placeholder={placeholder}\n defaultValue={values[i] || ''}\n />\n );\n }\n\n return {inputs}
;\n }\n);\n\nexport default AuthCode;\n"],"names":["allowedCharactersValues","propsMap","alpha","type","inputMode","pattern","alphanumeric","numeric","min","max","valueValidation","value","test","AuthCode","forwardRef","allowedCharacters","ariaLabel","autoFocus","containerClassName","disabled","inputClassName","isPassword","length","placeholder","onChange","ref","values","split","isNaN","Error","some","inputsRef","useRef","inputProps","useImperativeHandle","focus","current","clear","i","sendResult","useEffect","res","map","input","join","handleOnChange","e","target","nextElementSibling","charAt","match","handleOnKeyDown","key","previousElementSibling","t","preventDefault","handleOnFocus","select","handleOnPaste","pastedValue","clipboardData","getData","currentInput","pastedCharacter","currentValue","inputs","push","React","onKeyDown","onFocus","onPaste","el","maxLength","className","autoComplete","defaultValue"],"mappings":"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"}
\ No newline at end of file
diff --git a/example/src/App.tsx b/example/src/App.tsx
index 6a8b712..cc35fd1 100644
--- a/example/src/App.tsx
+++ b/example/src/App.tsx
@@ -1,6 +1,6 @@
import React, { useRef, useState } from 'react';
-import AuthCode, { AuthCodeRef, AuthCodeProps } from 'react-auth-code-input';
+import AuthCode, { AuthCodeProps, AuthCodeRef } from 'react-auth-code-input';
import './index.css';
const allowedCharactersMap = [
@@ -63,10 +63,10 @@ const App = () => {
-
+
Two-Factor
Authentication
-
+
{
Code: {result}
-
+
{
/>
-
+
+
{
/>
+
+
+
{allowedCharactersMap.map((aC) => (
-
+
* {
margin-right: 8px;
}
+
+a {
+ color: #0071e3;
+ text-decoration: none;
+ padding: 0.5rem;
+}
+
+a:hover {
+ text-decoration: underline;
+}
+
+a:focus {
+ box-shadow: 0 0 0 3px rgb(131 192 253 / 50%);
+}
+
.container {
padding: 16px;
}
@@ -31,15 +54,21 @@ body {
text-align: center;
margin-right: 12px;
text-transform: uppercase;
- color: #494949;
+ color: #e1e1e6;
font-family: SF Pro Text, SF Pro Icons, Helvetica Neue, Helvetica, Arial,
sans-serif;
- border: 1px solid #d6d6d6;
+ border: 1px solid #202024;
border-radius: 4px;
- background: #fff;
+ background: #202024;
background-clip: padding-box;
}
+.input:disabled {
+ background: #29292e;
+ color: #e1e1e6;
+ cursor: not-allowed;
+}
+
.input:focus {
appearance: none;
outline: 0;
@@ -47,6 +76,7 @@ body {
}
button {
+ cursor: pointer;
appearance: none;
background: #0071e3;
border-radius: 980px;
@@ -60,6 +90,7 @@ button {
p {
font-size: 17px;
line-height: 1.47059;
+ margin: 0.5rem;
}
.props {
@@ -76,3 +107,15 @@ p {
.allowed-characters {
text-align: left;
}
+
+.props-input-container {
+ display: flex;
+ align-items: center;
+ gap: 0.25rem;
+}
+
+.allowed-characters {
+ display: flex;
+ flex-direction: column;
+ gap: 0.25rem;
+}
diff --git a/package.json b/package.json
index 02cdea8..e60e2b5 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "react-auth-code-input",
- "version": "3.2.1",
+ "version": "3.2.2",
"description": "One-time password (OTP) React input component, uncontrolled, zero dependencies, fully tested.",
"author": "drac94",
"license": "MIT",
diff --git a/src/index.tsx b/src/index.tsx
index 8b92566..53615ef 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -1,8 +1,8 @@
import React, {
- useRef,
+ forwardRef,
useEffect,
useImperativeHandle,
- forwardRef
+ useRef
} from 'react';
const allowedCharactersValues = ['alpha', 'numeric', 'alphanumeric'] as const;
@@ -18,6 +18,7 @@ export type AuthCodeProps = {
length?: number;
placeholder?: string;
onChange: (res: string) => void;
+ value?: string;
};
type InputMode = 'text' | 'numeric';
@@ -59,6 +60,12 @@ const propsMap: { [key: string]: InputProps } = {
}
};
+const valueValidation = {
+ alpha: (value: string) => /^[a-zA-Z]*$/.test(value),
+ alphanumeric: (value: string) => /^[a-zA-Z0-9]*$/.test(value),
+ numeric: (value: string) => /^[0-9]*$/.test(value)
+};
+
const AuthCode = forwardRef
(
(
{
@@ -71,10 +78,13 @@ const AuthCode = forwardRef(
isPassword = false,
length = 6,
placeholder,
- onChange
+ onChange,
+ value
},
ref
) => {
+ const values = value ? value.split('') : [];
+
if (isNaN(length) || length < 1) {
throw new Error('Length should be a number and greater than 0');
}
@@ -85,6 +95,16 @@ const AuthCode = forwardRef(
);
}
+ if (value && value.length > length) {
+ throw new Error('Value length should not be greater than length');
+ }
+
+ if (value && !valueValidation[allowedCharacters](value)) {
+ throw new Error(
+ `Value should only contain ${allowedCharacters} characters`
+ );
+ }
+
const inputsRef = useRef>([]);
const inputProps = propsMap[allowedCharacters];
@@ -153,6 +173,10 @@ const AuthCode = forwardRef(
}
sendResult();
}
+
+ if (key === 'Tab' && target.value === '') {
+ e.preventDefault();
+ }
};
const handleOnFocus = (e: React.FocusEvent) => {
@@ -207,6 +231,7 @@ const AuthCode = forwardRef(
}
disabled={disabled}
placeholder={placeholder}
+ defaultValue={values[i] || ''}
/>
);
}