fictoan-react 0.45.2 → 0.45.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/dist/cjs/components/BottomDrawer/BottomDrawer.d.ts +1 -0
- package/dist/cjs/components/BottomDrawer/BottomDrawer.js +1 -1
- package/dist/cjs/components/BottomDrawer/BottomDrawer.js.map +1 -1
- package/dist/cjs/components/PinInputField/PinInputField.js +1 -1
- package/dist/cjs/components/PinInputField/PinInputField.js.map +1 -1
- package/dist/es/components/BottomDrawer/BottomDrawer.d.ts +1 -0
- package/dist/es/components/BottomDrawer/BottomDrawer.js +1 -1
- package/dist/es/components/BottomDrawer/BottomDrawer.js.map +1 -1
- package/dist/es/components/PinInputField/PinInputField.js +1 -1
- package/dist/es/components/PinInputField/PinInputField.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# CHANGELOG
|
|
2
2
|
|
|
3
|
+
### 0.45.4
|
|
4
|
+
- Fix PinInputField behaviour on paste or replace at position
|
|
5
|
+
|
|
6
|
+
### 0.45.3
|
|
7
|
+
- Add optional `isDismissable` prop for showing a close button for `BottomDrawer` *(true by default)*
|
|
8
|
+
|
|
3
9
|
### 0.45.2
|
|
4
10
|
- Fix prop name for disable copy/paste to pasteFromClipboard which takes either enabled or disabled as parameters for `PinInput Field`
|
|
5
11
|
|
|
@@ -7,6 +7,7 @@ export interface BottomDrawerCustomProps {
|
|
|
7
7
|
overlayColour?: ColourPropTypes;
|
|
8
8
|
overlayColor?: ColourPropTypes;
|
|
9
9
|
closeOnClickOutside?: boolean;
|
|
10
|
+
isDismissable?: boolean;
|
|
10
11
|
}
|
|
11
12
|
export declare type BottomDrawerElementType = HTMLDivElement;
|
|
12
13
|
export declare type BottomDrawerProps = Omit<CommonAndHTMLProps<BottomDrawerElementType>, keyof BottomDrawerCustomProps> & BottomDrawerCustomProps;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("../../external/Element.js"),t=require("react"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("../../external/Element.js"),t=require("react"),l=require("./BottomDrawer.styled.js");function r(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}require("styled-components"),require("../../external/helpers.js"),require("../../external/DefaultColours.js");var a=/*#__PURE__*/r(t);const s=a.default.forwardRef(((t,r)=>{var{isOpen:s,children:o,onCloseCallback:n,closeOnClickOutside:i,padding:u,bgColor:d,bgColour:c,isDismissable:m=!0}=t,f=e.__rest(t,["isOpen","children","onCloseCallback","closeOnClickOutside","padding","bgColor","bgColour","isDismissable"]);let b=[];s&&b.push("open");const p=()=>{n&&n()};return!!s&&a.default.createElement(a.default.Fragment,null,a.default.createElement(e.Element,Object.assign({as:l.BottomDrawerStyled,ref:r,classNames:b},f),a.default.createElement(e.Element,{as:"div",classNames:[...b,"rest-of-page-overlay"],onClick:()=>{i&&p()}}),a.default.createElement(e.Element,{as:"div",className:"bottom-drawer-content-wrapper",padding:u,bgColor:d,bgColour:c},m&&a.default.createElement(e.Element,{as:"div",className:"dismiss-button",onClick:p,role:"button"}),o)))}));exports.BottomDrawer=s;
|
|
2
2
|
//# sourceMappingURL=BottomDrawer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BottomDrawer.js","sources":["../../../../src/components/BottomDrawer/BottomDrawer.tsx"],"sourcesContent":["import React from \"react\";\n\nimport { Element } from \"../Element/Element\";\nimport { ColourPropTypes, CommonAndHTMLProps } from \"../Element/constants\";\n\nimport { BottomDrawerStyled } from \"./BottomDrawer.styled\";\n\n// prettier-ignore\nexport interface BottomDrawerCustomProps {\n isOpen ? : boolean;\n onCloseCallback ? : () => void;\n overlayOpacity ? : number;\n overlayColour ? : ColourPropTypes;\n overlayColor ? : ColourPropTypes;\n closeOnClickOutside ? : boolean;\n}\n\nexport type BottomDrawerElementType = HTMLDivElement;\nexport type BottomDrawerProps = Omit<CommonAndHTMLProps<BottomDrawerElementType>, keyof BottomDrawerCustomProps> &\n BottomDrawerCustomProps;\n\nexport const BottomDrawer = React.forwardRef(\n (\n {\n isOpen,\n children,\n onCloseCallback,\n closeOnClickOutside,\n padding,\n bgColor,\n bgColour,\n ...props\n }: BottomDrawerProps,\n ref: React.Ref<BottomDrawerElementType>\n ) => {\n let classNames = [];\n\n if (isOpen) {\n classNames.push(\"open\");\n }\n\n const closeBottomDrawer = () => {\n if (onCloseCallback) {\n onCloseCallback();\n }\n };\n\n return (\n !!isOpen && (\n <>\n <Element<BottomDrawerElementType>\n as={BottomDrawerStyled}\n ref={ref}\n classNames={classNames}\n {...props}\n >\n <Element\n as=\"div\"\n classNames={[...classNames, `rest-of-page-overlay`]}\n onClick={() => {\n if (closeOnClickOutside) closeBottomDrawer();\n }}\n />\n\n <Element\n as=\"div\"\n className=\"bottom-drawer-content-wrapper\"\n padding={padding}\n bgColor={bgColor}\n bgColour={bgColour}\n >\n <Element
|
|
1
|
+
{"version":3,"file":"BottomDrawer.js","sources":["../../../../src/components/BottomDrawer/BottomDrawer.tsx"],"sourcesContent":["import React from \"react\";\n\nimport { Element } from \"../Element/Element\";\nimport { ColourPropTypes, CommonAndHTMLProps } from \"../Element/constants\";\n\nimport { BottomDrawerStyled } from \"./BottomDrawer.styled\";\n\n// prettier-ignore\nexport interface BottomDrawerCustomProps {\n isOpen ? : boolean;\n onCloseCallback ? : () => void;\n overlayOpacity ? : number;\n overlayColour ? : ColourPropTypes;\n overlayColor ? : ColourPropTypes;\n closeOnClickOutside ? : boolean;\n isDismissable ? : boolean;\n}\n\nexport type BottomDrawerElementType = HTMLDivElement;\nexport type BottomDrawerProps = Omit<CommonAndHTMLProps<BottomDrawerElementType>, keyof BottomDrawerCustomProps> &\n BottomDrawerCustomProps;\n\nexport const BottomDrawer = React.forwardRef(\n (\n {\n isOpen,\n children,\n onCloseCallback,\n closeOnClickOutside,\n padding,\n bgColor,\n bgColour,\n isDismissable = true,\n ...props\n }: BottomDrawerProps,\n ref: React.Ref<BottomDrawerElementType>\n ) => {\n let classNames = [];\n\n if (isOpen) {\n classNames.push(\"open\");\n }\n\n const closeBottomDrawer = () => {\n if (onCloseCallback) {\n onCloseCallback();\n }\n };\n\n return (\n !!isOpen && (\n <>\n <Element<BottomDrawerElementType>\n as={BottomDrawerStyled}\n ref={ref}\n classNames={classNames}\n {...props}\n >\n <Element\n as=\"div\"\n classNames={[...classNames, `rest-of-page-overlay`]}\n onClick={() => {\n if (closeOnClickOutside) closeBottomDrawer();\n }}\n />\n\n <Element\n as=\"div\"\n className=\"bottom-drawer-content-wrapper\"\n padding={padding}\n bgColor={bgColor}\n bgColour={bgColour}\n >\n {isDismissable && (\n <Element\n as=\"div\"\n className=\"dismiss-button\"\n onClick={closeBottomDrawer}\n role=\"button\"\n />\n )}\n {children}\n </Element>\n </Element>\n </>\n )\n );\n }\n);\n"],"names":["BottomDrawer","React","forwardRef","_a","ref","isOpen","children","onCloseCallback","closeOnClickOutside","padding","bgColor","bgColour","isDismissable","props","classNames","push","closeBottomDrawer","Element","as","BottomDrawerStyled","onClick","className","role"],"mappings":"4XAsBaA,EAAeC,UAAMC,YAC9B,CACIC,EAWAC,SAXAC,OACIA,EADJC,SAEIA,EAFJC,gBAGIA,EAHJC,oBAIIA,EAJJC,QAKIA,EALJC,QAMIA,EANJC,SAOIA,EAPJC,cAQIA,GAAgB,KACbC,aATP,kHAaIC,EAAa,GAEbT,GACAS,EAAWC,KAAK,cAGdC,EAAoB,KAClBT,GACAA,aAKFF,GACEJ,gDACIA,wBAACgB,yBACGC,GAAIC,qBACJf,IAAKA,EACLU,WAAYA,GACRD,GAEJZ,wBAACgB,WACGC,GAAG,MACHJ,WAAY,IAAIA,0BAChBM,QAAS,KACDZ,GAAqBQ,OAIjCf,wBAACgB,WACGC,GAAG,MACHG,UAAU,gCACVZ,QAASA,EACTC,QAASA,EACTC,SAAUA,GAETC,GACGX,wBAACgB,WACGC,GAAG,MACHG,UAAU,iBACVD,QAASJ,EACTM,KAAK,WAGZhB"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react"),t=require("../../external/Element.js"),r=require("../Form/InputField/InputField.js"),l=require("./PinInputField.styled.js");function n(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}require("../Form/BaseInputComponent/BaseInputComponent.js"),require("../Form/InputLabel/InputLabel.js"),require("../Form/FormItem/FormItem.js"),require("../Form/FormItem/FormItem.styled.js"),require("styled-components"),require("../Form/InputField/InputField.styled.js"),require("../Form/Select/Select.styled.js"),require("../Form/TextArea/TextArea.styled.js"),require("../../external/theme.js"),require("../../external/DefaultColours.js");var u=/*#__PURE__*/n(e);function a(e,t){return("alphanumeric"===t?/^[a-zA-Z0-9]+$/i:/^[0-9]+$/).test(e)}const s=u.default.forwardRef((({numberOfFields:n,onChange:s,type:o="number",mask:i=!1,otp:c=!1,autoFocus:p=!1,pasteFromClipboard:d="enabled",spacing:m="small"},f)=>{const[F,
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react"),t=require("../../external/Element.js"),r=require("../Form/InputField/InputField.js"),l=require("./PinInputField.styled.js");function n(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}require("../Form/BaseInputComponent/BaseInputComponent.js"),require("../Form/InputLabel/InputLabel.js"),require("../Form/FormItem/FormItem.js"),require("../Form/FormItem/FormItem.styled.js"),require("styled-components"),require("../Form/InputField/InputField.styled.js"),require("../Form/Select/Select.styled.js"),require("../Form/TextArea/TextArea.styled.js"),require("../../external/theme.js"),require("../../external/DefaultColours.js");var u=/*#__PURE__*/n(e);function a(e,t){return("alphanumeric"===t?/^[a-zA-Z0-9]+$/i:/^[0-9]+$/).test(e)}const s=u.default.forwardRef((({numberOfFields:n,onChange:s,type:o="number",mask:i=!1,otp:c=!1,autoFocus:p=!1,pasteFromClipboard:d="enabled",spacing:m="small"},f)=>{const[F,h]=e.useState([]),[y,g]=e.useState([]),[v,b]=e.useState(!0),[j,I]=e.useState(-1),q=e.useCallback((e=>{var t;const r=F[e];null===(t=null==r?void 0:r.current)||void 0===t||t.focus()}),[F]);e.useEffect((()=>{h((t=>Array(n).fill(0).map(((r,l)=>{var n;const u=t[l]||e.createRef();return p&&0===l&&(null===(n=u.current)||void 0===n||n.focus()),u}))))}),[n,p]);const A=e.useCallback((e=>{if(!v)return;const t=e+1<n?e+1:null;t&&q(t)}),[q,n,v]),C=e.useCallback(((e,t)=>{const r=[...y];r[t]=e,g(r),null==s||s(r.join(""));""!==e&&r.length===n&&r.every((e=>null!=e&&""!==e))&&t==n-1||(b(!0),A(t))}),[A,n,s,y]),k=()=>{I(-1)};let x=[];return m&&x.push(`spacing-${m}`),u.default.createElement(t.Element,{as:l.PinInputStyled,classNames:x,ref:f},[...Array(n)].map(((e,t)=>u.default.createElement(r.InputField,{key:t,className:"pin-input-field",ref:F[t],type:i?"password":"number"===o?"tel":"text",inputMode:"number"===o?"numeric":"text",onChange:e=>((e,t)=>{const r=e.currentTarget.value,l=y[t];if(""!==r)if(r.length>1&&t<n-1){if(a(r,o)){let u=[];u=""==l?r.split("").filter(((e,r)=>t+r<n)):e.currentTarget.selectionEnd===r.length?r.split("").filter(((e,r)=>r>0&&t+r-1<n)):r.split("").filter(((e,l)=>l<r.length-1&&t+l<n)),g((e=>e.map(((e,r)=>r>=t&&r<t+u.length?u[r-t]:e)))),q(t+u.length<n?t+u.length:n-1),null==s||s(u.join(""))}}else{let e=r;(null==l?void 0:l.length)>0&&(l[0]===r.charAt(0)?e=r.charAt(1):l[0]===r.charAt(1)&&(e=r.charAt(0))),a(e,o)&&C(e,t)}else C("",t)})(e,t),onKeyDown:e=>((e,t)=>{var r;if("Backspace"===e.key)if(""===e.target.value){if(t>0){const e=t-1;C("",e),q(e),b(!0)}}else b(!1);else"Escape"===e.key?(null===(r=F[t].current)||void 0===r||r.blur(),k()):"ArrowRight"===e.key?t<n-1&&q(t+1):"ArrowLeft"===e.key&&t>0&&q(t-1)})(e,t),onFocus:e=>((e,t)=>{I(t)})(0,t),onSelect:e=>(e=>{const t=e.target;setTimeout((()=>{t.setSelectionRange(t.value.length,t.value.length)}),0)})(e),onBlur:k,placeholder:j!==t?"⦁":void 0,autoComplete:c?"one-time-code":"off",value:y[t]||"",autoFocus:p&&0===t,onCopy:e=>"disabled"===d&&e.preventDefault(),onPaste:e=>"disabled"===d&&e.preventDefault()}))))}));exports.PinInputField=s;
|
|
2
2
|
//# sourceMappingURL=PinInputField.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PinInputField.js","sources":["../../../../src/components/PinInputField/PinInputField.tsx"],"sourcesContent":["import React, { createRef, useCallback, useEffect, useState } from \"react\";\n\nimport { Element } from \"../Element/Element\";\nimport { CommonAndHTMLProps, SpacingTypes } from \"../Element/constants\";\nimport { InputField } from \"../Form/InputField/InputField\";\n\nimport { PinInputStyled } from \"./PinInputField.styled\";\n\n// prettier-ignore\ntype PinInputFieldCustomProps = {\n numberOfFields : number;\n onChange ? : (value : string) => void;\n type ? : \"alphanumeric\" | \"number\";\n mask ? : boolean;\n otp ? : boolean;\n autoFocus ? : boolean;\n pasteFromClipboard ? : \"enabled\" | \"disabled\";\n spacing ? : SpacingTypes;\n};\n\nexport type PinInputFieldElementType = HTMLDivElement;\nexport type PinInputFieldProps = Omit<CommonAndHTMLProps<PinInputFieldElementType>, keyof PinInputFieldCustomProps> &\n PinInputFieldCustomProps;\n\nfunction validate(value: string, type: \"alphanumeric\" | \"number\") {\n const NUMERIC_REGEX = /^[0-9]+$/;\n const ALPHA_NUMERIC_REGEX = /^[a-zA-Z0-9]+$/i;\n const regex = type === \"alphanumeric\" ? ALPHA_NUMERIC_REGEX : NUMERIC_REGEX;\n return regex.test(value);\n}\n\nexport const PinInputField = React.forwardRef(\n (\n {\n numberOfFields: length,\n onChange,\n type = \"number\",\n mask = false,\n otp = false,\n autoFocus = false,\n pasteFromClipboard = \"enabled\",\n spacing = \"small\",\n }: PinInputFieldProps,\n ref: React.Ref<PinInputFieldElementType>\n ) => {\n const [inputRefs, setInputRefs] = useState<React.RefObject<HTMLInputElement>[]>([]);\n const [values, setValues] = useState<string[]>([]);\n const [moveFocus, setMoveFocus] = useState<boolean>(true);\n const [focusedIndex, setFocusedIndex] = useState<number>(-1);\n\n const focus = useCallback(\n (index: number) => {\n const ref = inputRefs[index];\n ref?.current?.focus();\n },\n [inputRefs]\n );\n\n useEffect(() => {\n setInputRefs((inputRefs) => {\n const refs = Array(length)\n .fill(0)\n .map((_, i) => {\n const ref = inputRefs[i] || createRef();\n if (autoFocus && i === 0) {\n ref.current?.focus();\n }\n return ref;\n });\n return refs;\n });\n }, [length, autoFocus]);\n\n const focusNext = useCallback(\n (index: number) => {\n if (!moveFocus) return;\n const next = index + 1 < length ? index + 1 : null;\n if (next) {\n focus(next);\n }\n },\n [focus, length, moveFocus]\n );\n\n const setValue = useCallback(\n (value: string, index: number) => {\n const nextValues = [...values];\n nextValues[index] = value;\n setValues(nextValues);\n onChange?.(nextValues.join(\"\"));\n\n const isComplete =\n value !== \"\" &&\n nextValues.length === length &&\n nextValues.every((inputValue) => inputValue != null && inputValue !== \"\");\n\n if (!isComplete) {\n focusNext(index);\n }\n },\n [focusNext, length, onChange, values]\n );\n\n const getNextValue = useCallback((value: string, eventValue: string) => {\n let nextValue = eventValue;\n if (value?.length > 0) {\n if (value[0] === eventValue.charAt(0)) {\n nextValue = eventValue.charAt(1);\n } else if (value[0] === eventValue.charAt(1)) {\n nextValue = eventValue.charAt(0);\n }\n }\n return nextValue;\n }, []);\n\n const handleInputChange = (event: React.FormEvent<HTMLInputElement>, i: number) => {\n const eventValue = event.currentTarget.value;\n const currentValue = values[i];\n const nextValue = getNextValue(currentValue, eventValue);\n\n if (nextValue === \"\") {\n setValue(\"\", i);\n return;\n }\n\n if (eventValue.length > 1 && i < length - 1) {\n if (validate(eventValue, type)) {\n const nextValue = eventValue.split(\"\").filter((_, index) => index < length);\n setValues(nextValue);\n focus(i + nextValue.length < length ? i + nextValue.length : length - 1);\n onChange?.(nextValue.join(\"\"));\n }\n } else {\n if (validate(nextValue, type)) {\n setValue(nextValue, i);\n }\n setMoveFocus(true);\n }\n };\n\n const onKeyDown = (event: React.KeyboardEvent, i: number) => {\n if (event.key === \"Backspace\") {\n if ((event.target as HTMLInputElement).value === \"\") {\n if (i > 0) {\n const newIndex = i - 1;\n setValue(\"\", newIndex);\n focus(newIndex);\n setMoveFocus(true);\n }\n } else {\n setMoveFocus(false);\n }\n } else if (event.key === \"Escape\") {\n inputRefs[i].current?.blur();\n onBlur();\n } else if (event.key === \"ArrowRight\") {\n if (i < length - 1) {\n focus(i + 1);\n }\n } else if (event.key === \"ArrowLeft\") {\n if (i > 0) {\n focus(i - 1);\n }\n }\n };\n\n const onFocus = (e: React.FocusEvent<HTMLInputElement>, i: number) => {\n setFocusedIndex(i);\n setTimeout(() => {\n // https://github.com/facebook/react/issues/6483\n e.target.setSelectionRange(e.target.value.length, e.target.value.length);\n }, 0);\n };\n\n const onBlur = () => {\n setFocusedIndex(-1);\n };\n\n let classNames = [];\n\n if (spacing) {\n classNames.push(`spacing-${spacing}`);\n }\n\n return (\n <Element<PinInputFieldElementType> as={PinInputStyled} classNames={classNames} ref={ref}>\n {[...Array(length)].map((_, i) => (\n <InputField\n key={i}\n className=\"pin-input-field\"\n ref={inputRefs[i]}\n type={mask ? \"password\" : type === \"number\" ? \"tel\" : \"text\"}\n inputMode={type === \"number\" ? \"numeric\" : \"text\"}\n onChange={(e) => handleInputChange(e, i)}\n onKeyDown={(e) => onKeyDown(e, i)}\n onFocus={(e) => onFocus(e, i)}\n onBlur={onBlur}\n placeholder={focusedIndex !== i ? `\\u2981` : undefined}\n autoComplete={otp ? \"one-time-code\" : \"off\"}\n value={values[i] || \"\"}\n autoFocus={autoFocus && i === 0}\n onCopy={e=> pasteFromClipboard === \"disabled\" && e.preventDefault()}\n onPaste={e=> pasteFromClipboard === \"disabled\" && e.preventDefault()}\n />\n ))}\n </Element>\n );\n }\n);\n"],"names":["validate","value","type","test","PinInputField","React","forwardRef","numberOfFields","length","onChange","mask","otp","autoFocus","pasteFromClipboard","spacing","ref","inputRefs","setInputRefs","useState","values","setValues","moveFocus","setMoveFocus","focusedIndex","setFocusedIndex","focus","useCallback","index","current","useEffect","Array","fill","map","_","i","createRef","focusNext","next","setValue","nextValues","join","every","inputValue","getNextValue","eventValue","nextValue","charAt","onBlur","classNames","push","Element","as","PinInputStyled","InputField","key","className","inputMode","e","event","currentTarget","currentValue","split","filter","handleInputChange","onKeyDown","target","newIndex","blur","onFocus","setTimeout","setSelectionRange","placeholder","undefined","autoComplete","onCopy","preventDefault","onPaste"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"PinInputField.js","sources":["../../../../src/components/PinInputField/PinInputField.tsx"],"sourcesContent":["import React, { createRef, useCallback, useEffect, useState } from \"react\";\n\nimport { Element } from \"../Element/Element\";\nimport { CommonAndHTMLProps, SpacingTypes } from \"../Element/constants\";\nimport { InputField } from \"../Form/InputField/InputField\";\n\nimport { PinInputStyled } from \"./PinInputField.styled\";\n\n// prettier-ignore\ntype PinInputFieldCustomProps = {\n numberOfFields : number;\n onChange ? : (value : string) => void;\n type ? : \"alphanumeric\" | \"number\";\n mask ? : boolean;\n otp ? : boolean;\n autoFocus ? : boolean;\n pasteFromClipboard ? : \"enabled\" | \"disabled\";\n spacing ? : SpacingTypes;\n};\n\nexport type PinInputFieldElementType = HTMLDivElement;\nexport type PinInputFieldProps = Omit<CommonAndHTMLProps<PinInputFieldElementType>, keyof PinInputFieldCustomProps> &\n PinInputFieldCustomProps;\n\nfunction validate(value: string, type: \"alphanumeric\" | \"number\") {\n const NUMERIC_REGEX = /^[0-9]+$/;\n const ALPHA_NUMERIC_REGEX = /^[a-zA-Z0-9]+$/i;\n const regex = type === \"alphanumeric\" ? ALPHA_NUMERIC_REGEX : NUMERIC_REGEX;\n return regex.test(value);\n}\n\nexport const PinInputField = React.forwardRef(\n (\n {\n numberOfFields: length,\n onChange,\n type = \"number\",\n mask = false,\n otp = false,\n autoFocus = false,\n pasteFromClipboard = \"enabled\",\n spacing = \"small\",\n }: PinInputFieldProps,\n ref: React.Ref<PinInputFieldElementType>\n ) => {\n const [inputRefs, setInputRefs] = useState<React.RefObject<HTMLInputElement>[]>([]);\n const [values, setValues] = useState<string[]>([]);\n const [moveFocus, setMoveFocus] = useState<boolean>(true);\n const [focusedIndex, setFocusedIndex] = useState<number>(-1);\n\n const focus = useCallback(\n (index: number) => {\n const ref = inputRefs[index];\n ref?.current?.focus();\n },\n [inputRefs]\n );\n\n useEffect(() => {\n setInputRefs((inputRefs) => {\n const refs = Array(length)\n .fill(0)\n .map((_, i) => {\n const ref = inputRefs[i] || createRef();\n if (autoFocus && i === 0) {\n ref.current?.focus();\n }\n return ref;\n });\n return refs;\n });\n }, [length, autoFocus]);\n\n const focusNext = useCallback(\n (index: number) => {\n if (!moveFocus) return;\n const next = index + 1 < length ? index + 1 : null;\n if (next) {\n focus(next);\n }\n },\n [focus, length, moveFocus]\n );\n\n const setValue = useCallback(\n (value: string, index: number) => {\n const nextValues = [...values];\n nextValues[index] = value;\n setValues(nextValues);\n onChange?.(nextValues.join(\"\"));\n\n const isComplete =\n value !== \"\" &&\n nextValues.length === length &&\n nextValues.every((inputValue) => inputValue != null && inputValue !== \"\") &&\n index == length - 1;\n\n if (!isComplete) {\n setMoveFocus(true);\n focusNext(index);\n }\n },\n [focusNext, length, onChange, values]\n );\n\n const handleInputChange = (event: React.FormEvent<HTMLInputElement>, inputFieldIndex: number) => {\n const eventValue = event.currentTarget.value;\n const currentValue = values[inputFieldIndex];\n\n if (eventValue === \"\") {\n setValue(\"\", inputFieldIndex);\n return;\n }\n\n // Handle scenario where multiple characters are entered in a single InputField\n if (eventValue.length > 1 && inputFieldIndex < length - 1) {\n if (validate(eventValue, type)) {\n let nextValue: string[] = [];\n // In all cases, we need to ensure characters longer than the remaining fields are removed.\n if (currentValue == \"\") {\n // Case: Current input field is empty\n nextValue = eventValue.split(\"\").filter((_, j) => inputFieldIndex + j < length);\n } else if (event.currentTarget.selectionEnd === eventValue.length) {\n // Case: Current field has a value and cursor is after it\n nextValue = eventValue.split(\"\").filter((_, j) => j > 0 && inputFieldIndex + j - 1 < length);\n } else {\n // Case: Current field has a value and cursor is before it\n nextValue = eventValue\n .split(\"\")\n .filter((_, j) => j < eventValue.length - 1 && inputFieldIndex + j < length);\n }\n setValues((values) =>\n values.map((v, j) =>\n j >= inputFieldIndex && j < inputFieldIndex + nextValue.length\n ? nextValue[j - inputFieldIndex]\n : v\n )\n );\n focus(\n inputFieldIndex + nextValue.length < length ? inputFieldIndex + nextValue.length : length - 1\n );\n onChange?.(nextValue.join(\"\"));\n }\n } else {\n let nextValue = eventValue;\n if (currentValue?.length > 0) {\n if (currentValue[0] === eventValue.charAt(0)) {\n nextValue = eventValue.charAt(1);\n } else if (currentValue[0] === eventValue.charAt(1)) {\n nextValue = eventValue.charAt(0);\n }\n }\n if (validate(nextValue, type)) {\n setValue(nextValue, inputFieldIndex);\n }\n }\n };\n\n const onKeyDown = (event: React.KeyboardEvent, i: number) => {\n if (event.key === \"Backspace\") {\n if ((event.target as HTMLInputElement).value === \"\") {\n if (i > 0) {\n const newIndex = i - 1;\n setValue(\"\", newIndex);\n focus(newIndex);\n setMoveFocus(true);\n }\n } else {\n setMoveFocus(false);\n }\n } else if (event.key === \"Escape\") {\n inputRefs[i].current?.blur();\n onBlur();\n } else if (event.key === \"ArrowRight\") {\n if (i < length - 1) {\n focus(i + 1);\n }\n } else if (event.key === \"ArrowLeft\") {\n if (i > 0) {\n focus(i - 1);\n }\n }\n };\n\n const onFocus = (e: React.FocusEvent<HTMLInputElement>, i: number) => {\n setFocusedIndex(i);\n };\n\n // When moving around the InputElements using tab key, browsers automatically select\n // the value (if it exists) in the InputElement - which we want to disable. Additionally,\n // when an existing value is selected/highlighted and pasted over, there is no way to\n // clearly distinguish between the other 2 scenarios of pasting by keeping the cursor before\n // and after the existing value. Specific example: If the existing value is 5, the event\n // when highlighting and pasting '567' is the same as placing the cursor before the existing\n // value and pasting '67'. By disabling this, we eliminate one of these cases.\n // Is this a hack? Yes. Is there a better way? IDK. Does it matter? Not unless there is a\n // valid reason for users to need selecting a single InputElement within a PinInput.\n const onSelect = (e: React.SyntheticEvent<HTMLInputElement, Event>) => {\n const target = e.target as HTMLInputElement;\n setTimeout(() => {\n // https://github.com/facebook/react/issues/6483\n target.setSelectionRange(target.value.length, target.value.length);\n }, 0);\n };\n\n const onBlur = () => {\n setFocusedIndex(-1);\n };\n\n let classNames = [];\n\n if (spacing) {\n classNames.push(`spacing-${spacing}`);\n }\n\n return (\n <Element<PinInputFieldElementType> as={PinInputStyled} classNames={classNames} ref={ref}>\n {[...Array(length)].map((_, i) => (\n <InputField\n key={i}\n className=\"pin-input-field\"\n ref={inputRefs[i]}\n type={mask ? \"password\" : type === \"number\" ? \"tel\" : \"text\"}\n inputMode={type === \"number\" ? \"numeric\" : \"text\"}\n onChange={(e) => handleInputChange(e, i)}\n onKeyDown={(e) => onKeyDown(e, i)}\n onFocus={(e) => onFocus(e, i)}\n onSelect={(e) => onSelect(e)}\n onBlur={onBlur}\n placeholder={focusedIndex !== i ? `\\u2981` : undefined}\n autoComplete={otp ? \"one-time-code\" : \"off\"}\n value={values[i] || \"\"}\n autoFocus={autoFocus && i === 0}\n onCopy={(e) => pasteFromClipboard === \"disabled\" && e.preventDefault()}\n onPaste={(e) => pasteFromClipboard === \"disabled\" && e.preventDefault()}\n />\n ))}\n </Element>\n );\n }\n);\n"],"names":["validate","value","type","test","PinInputField","React","forwardRef","numberOfFields","length","onChange","mask","otp","autoFocus","pasteFromClipboard","spacing","ref","inputRefs","setInputRefs","useState","values","setValues","moveFocus","setMoveFocus","focusedIndex","setFocusedIndex","focus","useCallback","index","current","useEffect","Array","fill","map","_","i","createRef","focusNext","next","setValue","nextValues","join","every","inputValue","onBlur","classNames","push","Element","as","PinInputStyled","InputField","key","className","inputMode","e","event","inputFieldIndex","eventValue","currentTarget","currentValue","nextValue","split","filter","j","selectionEnd","v","charAt","handleInputChange","onKeyDown","target","newIndex","blur","onFocus","onSelect","setTimeout","setSelectionRange","placeholder","undefined","autoComplete","onCopy","preventDefault","onPaste"],"mappings":"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"}
|
|
@@ -7,6 +7,7 @@ export interface BottomDrawerCustomProps {
|
|
|
7
7
|
overlayColour?: ColourPropTypes;
|
|
8
8
|
overlayColor?: ColourPropTypes;
|
|
9
9
|
closeOnClickOutside?: boolean;
|
|
10
|
+
isDismissable?: boolean;
|
|
10
11
|
}
|
|
11
12
|
export declare type BottomDrawerElementType = HTMLDivElement;
|
|
12
13
|
export declare type BottomDrawerProps = Omit<CommonAndHTMLProps<BottomDrawerElementType>, keyof BottomDrawerCustomProps> & BottomDrawerCustomProps;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{_ as e,E as
|
|
1
|
+
import{_ as e,E as s}from"../../external/Element.js";import o from"react";import{BottomDrawerStyled as l}from"./BottomDrawer.styled.js";import"styled-components";import"../../external/helpers.js";import"../../external/DefaultColours.js";const r=/*#__PURE__*/o.forwardRef(((r,t)=>{var{isOpen:a,children:n,onCloseCallback:i,closeOnClickOutside:m,padding:c,bgColor:p,bgColour:d,isDismissable:C=!0}=r,b=e(r,["isOpen","children","onCloseCallback","closeOnClickOutside","padding","bgColor","bgColour","isDismissable"]);let g=[];a&&g.push("open");const u=()=>{i&&i()};return!!a&&/*#__PURE__*/o.createElement(o.Fragment,null,/*#__PURE__*/o.createElement(s,Object.assign({as:l,ref:t,classNames:g},b),/*#__PURE__*/o.createElement(s,{as:"div",classNames:[...g,"rest-of-page-overlay"],onClick:()=>{m&&u()}}),/*#__PURE__*/o.createElement(s,{as:"div",className:"bottom-drawer-content-wrapper",padding:c,bgColor:p,bgColour:d},C&&/*#__PURE__*/o.createElement(s,{as:"div",className:"dismiss-button",onClick:u,role:"button"}),n)))}));export{r as BottomDrawer};
|
|
2
2
|
//# sourceMappingURL=BottomDrawer.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BottomDrawer.js","sources":["../../../../src/components/BottomDrawer/BottomDrawer.tsx"],"sourcesContent":["import React from \"react\";\n\nimport { Element } from \"../Element/Element\";\nimport { ColourPropTypes, CommonAndHTMLProps } from \"../Element/constants\";\n\nimport { BottomDrawerStyled } from \"./BottomDrawer.styled\";\n\n// prettier-ignore\nexport interface BottomDrawerCustomProps {\n isOpen ? : boolean;\n onCloseCallback ? : () => void;\n overlayOpacity ? : number;\n overlayColour ? : ColourPropTypes;\n overlayColor ? : ColourPropTypes;\n closeOnClickOutside ? : boolean;\n}\n\nexport type BottomDrawerElementType = HTMLDivElement;\nexport type BottomDrawerProps = Omit<CommonAndHTMLProps<BottomDrawerElementType>, keyof BottomDrawerCustomProps> &\n BottomDrawerCustomProps;\n\nexport const BottomDrawer = React.forwardRef(\n (\n {\n isOpen,\n children,\n onCloseCallback,\n closeOnClickOutside,\n padding,\n bgColor,\n bgColour,\n ...props\n }: BottomDrawerProps,\n ref: React.Ref<BottomDrawerElementType>\n ) => {\n let classNames = [];\n\n if (isOpen) {\n classNames.push(\"open\");\n }\n\n const closeBottomDrawer = () => {\n if (onCloseCallback) {\n onCloseCallback();\n }\n };\n\n return (\n !!isOpen && (\n <>\n <Element<BottomDrawerElementType>\n as={BottomDrawerStyled}\n ref={ref}\n classNames={classNames}\n {...props}\n >\n <Element\n as=\"div\"\n classNames={[...classNames, `rest-of-page-overlay`]}\n onClick={() => {\n if (closeOnClickOutside) closeBottomDrawer();\n }}\n />\n\n <Element\n as=\"div\"\n className=\"bottom-drawer-content-wrapper\"\n padding={padding}\n bgColor={bgColor}\n bgColour={bgColour}\n >\n <Element
|
|
1
|
+
{"version":3,"file":"BottomDrawer.js","sources":["../../../../src/components/BottomDrawer/BottomDrawer.tsx"],"sourcesContent":["import React from \"react\";\n\nimport { Element } from \"../Element/Element\";\nimport { ColourPropTypes, CommonAndHTMLProps } from \"../Element/constants\";\n\nimport { BottomDrawerStyled } from \"./BottomDrawer.styled\";\n\n// prettier-ignore\nexport interface BottomDrawerCustomProps {\n isOpen ? : boolean;\n onCloseCallback ? : () => void;\n overlayOpacity ? : number;\n overlayColour ? : ColourPropTypes;\n overlayColor ? : ColourPropTypes;\n closeOnClickOutside ? : boolean;\n isDismissable ? : boolean;\n}\n\nexport type BottomDrawerElementType = HTMLDivElement;\nexport type BottomDrawerProps = Omit<CommonAndHTMLProps<BottomDrawerElementType>, keyof BottomDrawerCustomProps> &\n BottomDrawerCustomProps;\n\nexport const BottomDrawer = React.forwardRef(\n (\n {\n isOpen,\n children,\n onCloseCallback,\n closeOnClickOutside,\n padding,\n bgColor,\n bgColour,\n isDismissable = true,\n ...props\n }: BottomDrawerProps,\n ref: React.Ref<BottomDrawerElementType>\n ) => {\n let classNames = [];\n\n if (isOpen) {\n classNames.push(\"open\");\n }\n\n const closeBottomDrawer = () => {\n if (onCloseCallback) {\n onCloseCallback();\n }\n };\n\n return (\n !!isOpen && (\n <>\n <Element<BottomDrawerElementType>\n as={BottomDrawerStyled}\n ref={ref}\n classNames={classNames}\n {...props}\n >\n <Element\n as=\"div\"\n classNames={[...classNames, `rest-of-page-overlay`]}\n onClick={() => {\n if (closeOnClickOutside) closeBottomDrawer();\n }}\n />\n\n <Element\n as=\"div\"\n className=\"bottom-drawer-content-wrapper\"\n padding={padding}\n bgColor={bgColor}\n bgColour={bgColour}\n >\n {isDismissable && (\n <Element\n as=\"div\"\n className=\"dismiss-button\"\n onClick={closeBottomDrawer}\n role=\"button\"\n />\n )}\n {children}\n </Element>\n </Element>\n </>\n )\n );\n }\n);\n"],"names":["BottomDrawer","React","forwardRef","_a","ref","isOpen","children","onCloseCallback","closeOnClickOutside","padding","bgColor","bgColour","isDismissable","props","classNames","push","closeBottomDrawer","Element","as","BottomDrawerStyled","onClick","className","role"],"mappings":"mPAsBaA,eAAeC,EAAMC,YAC9B,CACIC,EAWAC,SAXAC,OACIA,EADJC,SAEIA,EAFJC,gBAGIA,EAHJC,oBAIIA,EAJJC,QAKIA,EALJC,QAMIA,EANJC,SAOIA,EAPJC,cAQIA,GAAgB,KACbC,MATP,kHAaIC,EAAa,GAEbT,GACAS,EAAWC,KAAK,cAGdC,EAAoB,KAClBT,GACAA,aAKFF,gBACEJ,6CACIA,gBAACgB,iBACGC,GAAIC,EACJf,IAAKA,EACLU,WAAYA,GACRD,gBAEJZ,gBAACgB,GACGC,GAAG,MACHJ,WAAY,IAAIA,0BAChBM,QAAS,KACDZ,GAAqBQ,oBAIjCf,gBAACgB,GACGC,GAAG,MACHG,UAAU,gCACVZ,QAASA,EACTC,QAASA,EACTC,SAAUA,GAETC,gBACGX,gBAACgB,GACGC,GAAG,MACHG,UAAU,iBACVD,QAASJ,EACTM,KAAK,WAGZhB"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import e,{useState as t,useCallback as r,useEffect as
|
|
1
|
+
import e,{useState as t,useCallback as r,useEffect as n,createRef as l}from"react";import{E as o}from"../../external/Element.js";import{InputField as s}from"../Form/InputField/InputField.js";import{PinInputStyled as a}from"./PinInputField.styled.js";import"../Form/BaseInputComponent/BaseInputComponent.js";import"../Form/InputLabel/InputLabel.js";import"../Form/FormItem/FormItem.js";import"../Form/FormItem/FormItem.styled.js";import"styled-components";import"../Form/InputField/InputField.styled.js";import"../Form/Select/Select.styled.js";import"../Form/TextArea/TextArea.styled.js";import"../../external/theme.js";import"../../external/DefaultColours.js";function i(e,t){return("alphanumeric"===t?/^[a-zA-Z0-9]+$/i:/^[0-9]+$/).test(e)}const m=/*#__PURE__*/e.forwardRef((({numberOfFields:m,onChange:u,type:p="number",mask:c=!1,otp:d=!1,autoFocus:f=!1,pasteFromClipboard:F="enabled",spacing:h="small"},g)=>{const[y,v]=t([]),[j,I]=t([]),[b,A]=t(!0),[x,C]=t(-1),k=r((e=>{var t;const r=y[e];null===(t=null==r?void 0:r.current)||void 0===t||t.focus()}),[y]);n((()=>{v((e=>Array(m).fill(0).map(((t,r)=>{var n;const o=e[r]||/*#__PURE__*/l();return f&&0===r&&(null===(n=o.current)||void 0===n||n.focus()),o}))))}),[m,f]);const E=r((e=>{if(!b)return;const t=e+1<m?e+1:null;t&&k(t)}),[k,m,b]),w=r(((e,t)=>{const r=[...j];r[t]=e,I(r),null==u||u(r.join(""));""!==e&&r.length===m&&r.every((e=>null!=e&&""!==e))&&t==m-1||(A(!0),E(t))}),[E,m,u,j]),T=()=>{C(-1)};let B=[];return h&&B.push(`spacing-${h}`),/*#__PURE__*/e.createElement(o,{as:a,classNames:B,ref:g},[...Array(m)].map(((t,r)=>/*#__PURE__*/e.createElement(s,{key:r,className:"pin-input-field",ref:y[r],type:c?"password":"number"===p?"tel":"text",inputMode:"number"===p?"numeric":"text",onChange:e=>((e,t)=>{const r=e.currentTarget.value,n=j[t];if(""!==r)if(r.length>1&&t<m-1){if(i(r,p)){let l=[];l=""==n?r.split("").filter(((e,r)=>t+r<m)):e.currentTarget.selectionEnd===r.length?r.split("").filter(((e,r)=>r>0&&t+r-1<m)):r.split("").filter(((e,n)=>n<r.length-1&&t+n<m)),I((e=>e.map(((e,r)=>r>=t&&r<t+l.length?l[r-t]:e)))),k(t+l.length<m?t+l.length:m-1),null==u||u(l.join(""))}}else{let e=r;(null==n?void 0:n.length)>0&&(n[0]===r.charAt(0)?e=r.charAt(1):n[0]===r.charAt(1)&&(e=r.charAt(0))),i(e,p)&&w(e,t)}else w("",t)})(e,r),onKeyDown:e=>((e,t)=>{var r;if("Backspace"===e.key)if(""===e.target.value){if(t>0){const e=t-1;w("",e),k(e),A(!0)}}else A(!1);else"Escape"===e.key?(null===(r=y[t].current)||void 0===r||r.blur(),T()):"ArrowRight"===e.key?t<m-1&&k(t+1):"ArrowLeft"===e.key&&t>0&&k(t-1)})(e,r),onFocus:e=>((e,t)=>{C(t)})(0,r),onSelect:e=>(e=>{const t=e.target;setTimeout((()=>{t.setSelectionRange(t.value.length,t.value.length)}),0)})(e),onBlur:T,placeholder:x!==r?"⦁":void 0,autoComplete:d?"one-time-code":"off",value:j[r]||"",autoFocus:f&&0===r,onCopy:e=>"disabled"===F&&e.preventDefault(),onPaste:e=>"disabled"===F&&e.preventDefault()}))))}));export{m as PinInputField};
|
|
2
2
|
//# sourceMappingURL=PinInputField.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PinInputField.js","sources":["../../../../src/components/PinInputField/PinInputField.tsx"],"sourcesContent":["import React, { createRef, useCallback, useEffect, useState } from \"react\";\n\nimport { Element } from \"../Element/Element\";\nimport { CommonAndHTMLProps, SpacingTypes } from \"../Element/constants\";\nimport { InputField } from \"../Form/InputField/InputField\";\n\nimport { PinInputStyled } from \"./PinInputField.styled\";\n\n// prettier-ignore\ntype PinInputFieldCustomProps = {\n numberOfFields : number;\n onChange ? : (value : string) => void;\n type ? : \"alphanumeric\" | \"number\";\n mask ? : boolean;\n otp ? : boolean;\n autoFocus ? : boolean;\n pasteFromClipboard ? : \"enabled\" | \"disabled\";\n spacing ? : SpacingTypes;\n};\n\nexport type PinInputFieldElementType = HTMLDivElement;\nexport type PinInputFieldProps = Omit<CommonAndHTMLProps<PinInputFieldElementType>, keyof PinInputFieldCustomProps> &\n PinInputFieldCustomProps;\n\nfunction validate(value: string, type: \"alphanumeric\" | \"number\") {\n const NUMERIC_REGEX = /^[0-9]+$/;\n const ALPHA_NUMERIC_REGEX = /^[a-zA-Z0-9]+$/i;\n const regex = type === \"alphanumeric\" ? ALPHA_NUMERIC_REGEX : NUMERIC_REGEX;\n return regex.test(value);\n}\n\nexport const PinInputField = React.forwardRef(\n (\n {\n numberOfFields: length,\n onChange,\n type = \"number\",\n mask = false,\n otp = false,\n autoFocus = false,\n pasteFromClipboard = \"enabled\",\n spacing = \"small\",\n }: PinInputFieldProps,\n ref: React.Ref<PinInputFieldElementType>\n ) => {\n const [inputRefs, setInputRefs] = useState<React.RefObject<HTMLInputElement>[]>([]);\n const [values, setValues] = useState<string[]>([]);\n const [moveFocus, setMoveFocus] = useState<boolean>(true);\n const [focusedIndex, setFocusedIndex] = useState<number>(-1);\n\n const focus = useCallback(\n (index: number) => {\n const ref = inputRefs[index];\n ref?.current?.focus();\n },\n [inputRefs]\n );\n\n useEffect(() => {\n setInputRefs((inputRefs) => {\n const refs = Array(length)\n .fill(0)\n .map((_, i) => {\n const ref = inputRefs[i] || createRef();\n if (autoFocus && i === 0) {\n ref.current?.focus();\n }\n return ref;\n });\n return refs;\n });\n }, [length, autoFocus]);\n\n const focusNext = useCallback(\n (index: number) => {\n if (!moveFocus) return;\n const next = index + 1 < length ? index + 1 : null;\n if (next) {\n focus(next);\n }\n },\n [focus, length, moveFocus]\n );\n\n const setValue = useCallback(\n (value: string, index: number) => {\n const nextValues = [...values];\n nextValues[index] = value;\n setValues(nextValues);\n onChange?.(nextValues.join(\"\"));\n\n const isComplete =\n value !== \"\" &&\n nextValues.length === length &&\n nextValues.every((inputValue) => inputValue != null && inputValue !== \"\");\n\n if (!isComplete) {\n focusNext(index);\n }\n },\n [focusNext, length, onChange, values]\n );\n\n const getNextValue = useCallback((value: string, eventValue: string) => {\n let nextValue = eventValue;\n if (value?.length > 0) {\n if (value[0] === eventValue.charAt(0)) {\n nextValue = eventValue.charAt(1);\n } else if (value[0] === eventValue.charAt(1)) {\n nextValue = eventValue.charAt(0);\n }\n }\n return nextValue;\n }, []);\n\n const handleInputChange = (event: React.FormEvent<HTMLInputElement>, i: number) => {\n const eventValue = event.currentTarget.value;\n const currentValue = values[i];\n const nextValue = getNextValue(currentValue, eventValue);\n\n if (nextValue === \"\") {\n setValue(\"\", i);\n return;\n }\n\n if (eventValue.length > 1 && i < length - 1) {\n if (validate(eventValue, type)) {\n const nextValue = eventValue.split(\"\").filter((_, index) => index < length);\n setValues(nextValue);\n focus(i + nextValue.length < length ? i + nextValue.length : length - 1);\n onChange?.(nextValue.join(\"\"));\n }\n } else {\n if (validate(nextValue, type)) {\n setValue(nextValue, i);\n }\n setMoveFocus(true);\n }\n };\n\n const onKeyDown = (event: React.KeyboardEvent, i: number) => {\n if (event.key === \"Backspace\") {\n if ((event.target as HTMLInputElement).value === \"\") {\n if (i > 0) {\n const newIndex = i - 1;\n setValue(\"\", newIndex);\n focus(newIndex);\n setMoveFocus(true);\n }\n } else {\n setMoveFocus(false);\n }\n } else if (event.key === \"Escape\") {\n inputRefs[i].current?.blur();\n onBlur();\n } else if (event.key === \"ArrowRight\") {\n if (i < length - 1) {\n focus(i + 1);\n }\n } else if (event.key === \"ArrowLeft\") {\n if (i > 0) {\n focus(i - 1);\n }\n }\n };\n\n const onFocus = (e: React.FocusEvent<HTMLInputElement>, i: number) => {\n setFocusedIndex(i);\n setTimeout(() => {\n // https://github.com/facebook/react/issues/6483\n e.target.setSelectionRange(e.target.value.length, e.target.value.length);\n }, 0);\n };\n\n const onBlur = () => {\n setFocusedIndex(-1);\n };\n\n let classNames = [];\n\n if (spacing) {\n classNames.push(`spacing-${spacing}`);\n }\n\n return (\n <Element<PinInputFieldElementType> as={PinInputStyled} classNames={classNames} ref={ref}>\n {[...Array(length)].map((_, i) => (\n <InputField\n key={i}\n className=\"pin-input-field\"\n ref={inputRefs[i]}\n type={mask ? \"password\" : type === \"number\" ? \"tel\" : \"text\"}\n inputMode={type === \"number\" ? \"numeric\" : \"text\"}\n onChange={(e) => handleInputChange(e, i)}\n onKeyDown={(e) => onKeyDown(e, i)}\n onFocus={(e) => onFocus(e, i)}\n onBlur={onBlur}\n placeholder={focusedIndex !== i ? `\\u2981` : undefined}\n autoComplete={otp ? \"one-time-code\" : \"off\"}\n value={values[i] || \"\"}\n autoFocus={autoFocus && i === 0}\n onCopy={e=> pasteFromClipboard === \"disabled\" && e.preventDefault()}\n onPaste={e=> pasteFromClipboard === \"disabled\" && e.preventDefault()}\n />\n ))}\n </Element>\n );\n }\n);\n"],"names":["validate","value","type","test","PinInputField","React","forwardRef","numberOfFields","length","onChange","mask","otp","autoFocus","pasteFromClipboard","spacing","ref","inputRefs","setInputRefs","useState","values","setValues","moveFocus","setMoveFocus","focusedIndex","setFocusedIndex","focus","useCallback","index","current","useEffect","Array","fill","map","_","i","createRef","focusNext","next","setValue","nextValues","join","every","inputValue","getNextValue","eventValue","nextValue","charAt","onBlur","classNames","push","Element","as","PinInputStyled","InputField","key","className","inputMode","e","event","currentTarget","currentValue","split","filter","handleInputChange","onKeyDown","target","newIndex","blur","onFocus","setTimeout","setSelectionRange","placeholder","undefined","autoComplete","onCopy","preventDefault","onPaste"],"mappings":"opBAwBA,SAASA,EAASC,EAAeC,UAGN,iBAATA,EADc,kBADN,YAGTC,KAAKF,SAGTG,eAAgBC,EAAMC,YAC/B,EAEQC,eAAgBC,EAChBC,SAAAA,EACAP,KAAAA,EAAO,SACPQ,KAAAA,GAAO,EACPC,IAAAA,GAAM,EACNC,UAAAA,GAAY,EACZC,mBAAAA,EAAqB,UACrBC,QAAAA,EAAU,SAEdC,WAEOC,EAAWC,GAAgBC,EAA8C,KACzEC,EAAQC,GAAaF,EAAmB,KACxCG,EAAWC,GAAgBJ,GAAkB,IAC7CK,EAAcC,GAAmBN,GAAkB,GAEpDO,EAAQC,GACTC,gBACSZ,EAAMC,EAAUW,aACtBZ,MAAAA,SAAAA,EAAKa,wBAASH,UAElB,CAACT,IAGLa,GAAU,KACNZ,GAAcD,GACGc,MAAMtB,GACduB,KAAK,GACLC,KAAI,CAACC,EAAGC,iBACCnB,EAAMC,EAAUkB,iBAAMC,WACxBvB,GAAmB,IAANsB,cACbnB,EAAIa,wBAASH,SAEVV,SAIpB,CAACP,EAAQI,UAENwB,EAAYV,GACbC,QACQN,EAAW,aACVgB,EAAOV,EAAQ,EAAInB,EAASmB,EAAQ,EAAI,KAC1CU,GACAZ,EAAMY,KAGd,CAACZ,EAAOjB,EAAQa,IAGdiB,EAAWZ,GACb,CAACzB,EAAe0B,WACNY,EAAa,IAAIpB,GACvBoB,EAAWZ,GAAS1B,EACpBmB,EAAUmB,GACV9B,MAAAA,GAAAA,EAAW8B,EAAWC,KAAK,KAGb,KAAVvC,GACAsC,EAAW/B,SAAWA,GACtB+B,EAAWE,OAAOC,GAA6B,MAAdA,GAAqC,KAAfA,KAGvDN,EAAUT,KAGlB,CAACS,EAAW5B,EAAQC,EAAUU,IAG5BwB,EAAejB,GAAY,CAACzB,EAAe2C,SACzCC,EAAYD,SACZ3C,MAAAA,SAAAA,EAAOO,QAAS,IACZP,EAAM,KAAO2C,EAAWE,OAAO,GAC/BD,EAAYD,EAAWE,OAAO,GACvB7C,EAAM,KAAO2C,EAAWE,OAAO,KACtCD,EAAYD,EAAWE,OAAO,KAG/BD,IACR,IA6DGE,EAAS,KACXvB,GAAiB,QAGjBwB,EAAa,UAEblC,GACAkC,EAAWC,gBAAgBnC,kBAI3BT,gBAAC6C,GAAkCC,GAAIC,EAAgBJ,WAAYA,EAAYjC,IAAKA,GAC/E,IAAIe,MAAMtB,IAASwB,KAAI,CAACC,EAAGC,iBACxB7B,gBAACgD,GACGC,IAAKpB,EACLqB,UAAU,kBACVxC,IAAKC,EAAUkB,GACfhC,KAAMQ,EAAO,WAAsB,WAATR,EAAoB,MAAQ,OACtDsD,UAAoB,WAATtD,EAAoB,UAAY,OAC3CO,SAAWgD,GA9ED,EAACC,EAA0CxB,WAC3DU,EAAac,EAAMC,cAAc1D,MACjC2D,EAAezC,EAAOe,GACtBW,EAAYF,EAAaiB,EAAchB,MAE3B,KAAdC,KAKAD,EAAWpC,OAAS,GAAK0B,EAAI1B,EAAS,MAClCR,EAAS4C,EAAY1C,GAAO,OACtB2C,EAAYD,EAAWiB,MAAM,IAAIC,QAAO,CAAC7B,EAAGN,IAAUA,EAAQnB,IACpEY,EAAUyB,GACVpB,EAAMS,EAAIW,EAAUrC,OAASA,EAAS0B,EAAIW,EAAUrC,OAASA,EAAS,GACtEC,MAAAA,GAAAA,EAAWoC,EAAUL,KAAK,WAG1BxC,EAAS6C,EAAW3C,IACpBoC,EAASO,EAAWX,GAExBZ,GAAa,QAfbgB,EAAS,GAAIJ,IAwEY6B,CAAkBN,EAAGvB,GACtC8B,UAAYP,GAtDV,EAACC,EAA4BxB,cACzB,cAAdwB,EAAMJ,OAC2C,KAA5CI,EAAMO,OAA4BhE,UAC/BiC,EAAI,EAAG,OACDgC,EAAWhC,EAAI,EACrBI,EAAS,GAAI4B,GACbzC,EAAMyC,GACN5C,GAAa,SAGjBA,GAAa,OAEI,WAAdoC,EAAMJ,eACbtC,EAAUkB,GAAGN,wBAASuC,OACtBpB,KACqB,eAAdW,EAAMJ,IACTpB,EAAI1B,EAAS,GACbiB,EAAMS,EAAI,GAEO,cAAdwB,EAAMJ,KACTpB,EAAI,GACJT,EAAMS,EAAI,IAiCY8B,CAAUP,EAAGvB,GAC/BkC,QAAUX,GA7BV,EAACA,EAAuCvB,KACpDV,EAAgBU,GAChBmC,YAAW,KAEPZ,EAAEQ,OAAOK,kBAAkBb,EAAEQ,OAAOhE,MAAMO,OAAQiD,EAAEQ,OAAOhE,MAAMO,UAClE,IAwByB4D,CAAQX,EAAGvB,GAC3Ba,OAAQA,EACRwB,YAAahD,IAAiBW,WAAesC,EAC7CC,aAAc9D,EAAM,gBAAkB,MACtCV,MAAOkB,EAAOe,IAAM,GACpBtB,UAAWA,GAAmB,IAANsB,EACxBwC,OAAQjB,GAA2B,aAAvB5C,GAAqC4C,EAAEkB,iBACnDC,QAASnB,GAA2B,aAAvB5C,GAAqC4C,EAAEkB"}
|
|
1
|
+
{"version":3,"file":"PinInputField.js","sources":["../../../../src/components/PinInputField/PinInputField.tsx"],"sourcesContent":["import React, { createRef, useCallback, useEffect, useState } from \"react\";\n\nimport { Element } from \"../Element/Element\";\nimport { CommonAndHTMLProps, SpacingTypes } from \"../Element/constants\";\nimport { InputField } from \"../Form/InputField/InputField\";\n\nimport { PinInputStyled } from \"./PinInputField.styled\";\n\n// prettier-ignore\ntype PinInputFieldCustomProps = {\n numberOfFields : number;\n onChange ? : (value : string) => void;\n type ? : \"alphanumeric\" | \"number\";\n mask ? : boolean;\n otp ? : boolean;\n autoFocus ? : boolean;\n pasteFromClipboard ? : \"enabled\" | \"disabled\";\n spacing ? : SpacingTypes;\n};\n\nexport type PinInputFieldElementType = HTMLDivElement;\nexport type PinInputFieldProps = Omit<CommonAndHTMLProps<PinInputFieldElementType>, keyof PinInputFieldCustomProps> &\n PinInputFieldCustomProps;\n\nfunction validate(value: string, type: \"alphanumeric\" | \"number\") {\n const NUMERIC_REGEX = /^[0-9]+$/;\n const ALPHA_NUMERIC_REGEX = /^[a-zA-Z0-9]+$/i;\n const regex = type === \"alphanumeric\" ? ALPHA_NUMERIC_REGEX : NUMERIC_REGEX;\n return regex.test(value);\n}\n\nexport const PinInputField = React.forwardRef(\n (\n {\n numberOfFields: length,\n onChange,\n type = \"number\",\n mask = false,\n otp = false,\n autoFocus = false,\n pasteFromClipboard = \"enabled\",\n spacing = \"small\",\n }: PinInputFieldProps,\n ref: React.Ref<PinInputFieldElementType>\n ) => {\n const [inputRefs, setInputRefs] = useState<React.RefObject<HTMLInputElement>[]>([]);\n const [values, setValues] = useState<string[]>([]);\n const [moveFocus, setMoveFocus] = useState<boolean>(true);\n const [focusedIndex, setFocusedIndex] = useState<number>(-1);\n\n const focus = useCallback(\n (index: number) => {\n const ref = inputRefs[index];\n ref?.current?.focus();\n },\n [inputRefs]\n );\n\n useEffect(() => {\n setInputRefs((inputRefs) => {\n const refs = Array(length)\n .fill(0)\n .map((_, i) => {\n const ref = inputRefs[i] || createRef();\n if (autoFocus && i === 0) {\n ref.current?.focus();\n }\n return ref;\n });\n return refs;\n });\n }, [length, autoFocus]);\n\n const focusNext = useCallback(\n (index: number) => {\n if (!moveFocus) return;\n const next = index + 1 < length ? index + 1 : null;\n if (next) {\n focus(next);\n }\n },\n [focus, length, moveFocus]\n );\n\n const setValue = useCallback(\n (value: string, index: number) => {\n const nextValues = [...values];\n nextValues[index] = value;\n setValues(nextValues);\n onChange?.(nextValues.join(\"\"));\n\n const isComplete =\n value !== \"\" &&\n nextValues.length === length &&\n nextValues.every((inputValue) => inputValue != null && inputValue !== \"\") &&\n index == length - 1;\n\n if (!isComplete) {\n setMoveFocus(true);\n focusNext(index);\n }\n },\n [focusNext, length, onChange, values]\n );\n\n const handleInputChange = (event: React.FormEvent<HTMLInputElement>, inputFieldIndex: number) => {\n const eventValue = event.currentTarget.value;\n const currentValue = values[inputFieldIndex];\n\n if (eventValue === \"\") {\n setValue(\"\", inputFieldIndex);\n return;\n }\n\n // Handle scenario where multiple characters are entered in a single InputField\n if (eventValue.length > 1 && inputFieldIndex < length - 1) {\n if (validate(eventValue, type)) {\n let nextValue: string[] = [];\n // In all cases, we need to ensure characters longer than the remaining fields are removed.\n if (currentValue == \"\") {\n // Case: Current input field is empty\n nextValue = eventValue.split(\"\").filter((_, j) => inputFieldIndex + j < length);\n } else if (event.currentTarget.selectionEnd === eventValue.length) {\n // Case: Current field has a value and cursor is after it\n nextValue = eventValue.split(\"\").filter((_, j) => j > 0 && inputFieldIndex + j - 1 < length);\n } else {\n // Case: Current field has a value and cursor is before it\n nextValue = eventValue\n .split(\"\")\n .filter((_, j) => j < eventValue.length - 1 && inputFieldIndex + j < length);\n }\n setValues((values) =>\n values.map((v, j) =>\n j >= inputFieldIndex && j < inputFieldIndex + nextValue.length\n ? nextValue[j - inputFieldIndex]\n : v\n )\n );\n focus(\n inputFieldIndex + nextValue.length < length ? inputFieldIndex + nextValue.length : length - 1\n );\n onChange?.(nextValue.join(\"\"));\n }\n } else {\n let nextValue = eventValue;\n if (currentValue?.length > 0) {\n if (currentValue[0] === eventValue.charAt(0)) {\n nextValue = eventValue.charAt(1);\n } else if (currentValue[0] === eventValue.charAt(1)) {\n nextValue = eventValue.charAt(0);\n }\n }\n if (validate(nextValue, type)) {\n setValue(nextValue, inputFieldIndex);\n }\n }\n };\n\n const onKeyDown = (event: React.KeyboardEvent, i: number) => {\n if (event.key === \"Backspace\") {\n if ((event.target as HTMLInputElement).value === \"\") {\n if (i > 0) {\n const newIndex = i - 1;\n setValue(\"\", newIndex);\n focus(newIndex);\n setMoveFocus(true);\n }\n } else {\n setMoveFocus(false);\n }\n } else if (event.key === \"Escape\") {\n inputRefs[i].current?.blur();\n onBlur();\n } else if (event.key === \"ArrowRight\") {\n if (i < length - 1) {\n focus(i + 1);\n }\n } else if (event.key === \"ArrowLeft\") {\n if (i > 0) {\n focus(i - 1);\n }\n }\n };\n\n const onFocus = (e: React.FocusEvent<HTMLInputElement>, i: number) => {\n setFocusedIndex(i);\n };\n\n // When moving around the InputElements using tab key, browsers automatically select\n // the value (if it exists) in the InputElement - which we want to disable. Additionally,\n // when an existing value is selected/highlighted and pasted over, there is no way to\n // clearly distinguish between the other 2 scenarios of pasting by keeping the cursor before\n // and after the existing value. Specific example: If the existing value is 5, the event\n // when highlighting and pasting '567' is the same as placing the cursor before the existing\n // value and pasting '67'. By disabling this, we eliminate one of these cases.\n // Is this a hack? Yes. Is there a better way? IDK. Does it matter? Not unless there is a\n // valid reason for users to need selecting a single InputElement within a PinInput.\n const onSelect = (e: React.SyntheticEvent<HTMLInputElement, Event>) => {\n const target = e.target as HTMLInputElement;\n setTimeout(() => {\n // https://github.com/facebook/react/issues/6483\n target.setSelectionRange(target.value.length, target.value.length);\n }, 0);\n };\n\n const onBlur = () => {\n setFocusedIndex(-1);\n };\n\n let classNames = [];\n\n if (spacing) {\n classNames.push(`spacing-${spacing}`);\n }\n\n return (\n <Element<PinInputFieldElementType> as={PinInputStyled} classNames={classNames} ref={ref}>\n {[...Array(length)].map((_, i) => (\n <InputField\n key={i}\n className=\"pin-input-field\"\n ref={inputRefs[i]}\n type={mask ? \"password\" : type === \"number\" ? \"tel\" : \"text\"}\n inputMode={type === \"number\" ? \"numeric\" : \"text\"}\n onChange={(e) => handleInputChange(e, i)}\n onKeyDown={(e) => onKeyDown(e, i)}\n onFocus={(e) => onFocus(e, i)}\n onSelect={(e) => onSelect(e)}\n onBlur={onBlur}\n placeholder={focusedIndex !== i ? `\\u2981` : undefined}\n autoComplete={otp ? \"one-time-code\" : \"off\"}\n value={values[i] || \"\"}\n autoFocus={autoFocus && i === 0}\n onCopy={(e) => pasteFromClipboard === \"disabled\" && e.preventDefault()}\n onPaste={(e) => pasteFromClipboard === \"disabled\" && e.preventDefault()}\n />\n ))}\n </Element>\n );\n }\n);\n"],"names":["validate","value","type","test","PinInputField","React","forwardRef","numberOfFields","length","onChange","mask","otp","autoFocus","pasteFromClipboard","spacing","ref","inputRefs","setInputRefs","useState","values","setValues","moveFocus","setMoveFocus","focusedIndex","setFocusedIndex","focus","useCallback","index","current","useEffect","Array","fill","map","_","i","createRef","focusNext","next","setValue","nextValues","join","every","inputValue","onBlur","classNames","push","Element","as","PinInputStyled","InputField","key","className","inputMode","e","event","inputFieldIndex","eventValue","currentTarget","currentValue","nextValue","split","filter","j","selectionEnd","v","charAt","handleInputChange","onKeyDown","target","newIndex","blur","onFocus","onSelect","setTimeout","setSelectionRange","placeholder","undefined","autoComplete","onCopy","preventDefault","onPaste"],"mappings":"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"}
|