react-pin-field
Version:
React component for entering PIN codes
3 lines (2 loc) • 4.71 kB
JavaScript
(function(d,o){typeof exports=="object"&&typeof module<"u"?o(exports,require("react")):typeof define=="function"&&define.amd?define(["exports","react"],o):(d=typeof globalThis<"u"?globalThis:d||self,o(d.PinField={},d.React))})(this,function(d,o){"use strict";function g(){}function w(s,e){return Array.from({length:e},(t,a)=>a+s)}function D(s){try{return(s.webkitMatchesSelector||s.matches).call(s,":focus")}catch{return!1}}const h={length:5,format:s=>s,formatAriaLabel:(s,e)=>`PIN field ${s} of ${e}`,onChange:g,onComplete:g},v={type:"text",inputMode:"text",autoCapitalize:"off",autoCorrect:"off",autoComplete:"off"},k={length:h.length,format:h.format,dir:"ltr",cursor:0,values:Array(h.length),backspace:!1,composition:!1,ready:!1,dirty:!1};function b(s,e){switch(e.type){case"update-props":{const t={...s,...e.props};return t.cursor=Math.min(t.cursor,t.length-1),t.values=t.values.slice(0,t.cursor+1),t.ready=!0,t}case"start-composition":return{...s,dirty:!0,composition:!0};case"end-composition":{const t={...s};e.value?t.values[e.index]=e.value:delete t.values[e.index];const a=t.values[e.index]?1:0;return t.cursor=Math.min(e.index+a,t.length-1),t.composition=!1,t.dirty=!0,t}case"handle-change":{if(s.composition)break;const t={...s};if(e.reset&&t.values.splice(e.index,t.length),e.value){const a=e.value.split("").map(t.format),c=Math.min(t.length-e.index,a.length);t.values.splice(e.index,c,...a.slice(0,c)),t.cursor=Math.min(e.index+c,t.length-1)}else{delete t.values[e.index];const a=t.backspace?0:1;t.cursor=Math.max(0,e.index-a)}return t.backspace=!1,t.dirty=!0,t}case"handle-key-down":{const t=e.key==="Backspace"||e.key==="Delete",a=e.code==="Backspace"||e.code==="Delete",c=e.keyCode===8||e.keyCode===46,m=e.which===8||e.which===46;if(!(t||a||c||m)||s.values[e.index])break;{const f={...s};return f.cursor=Math.max(0,e.index-1),f.backspace=!0,f.dirty=!0,f}}}return s}function A(){const s=o.useRef([]),[e,t]=o.useReducer(b,k),a=o.useMemo(()=>{let m="";for(let E=0;E<e.length;E++)m+=E in e.values?e.values[E]:"";return m},[e]),c=o.useCallback(m=>{t({type:"handle-change",index:0,value:m,reset:!0})},[t,e.cursor]);return o.useMemo(()=>({refs:s,state:e,dispatch:t,value:a,setValue:c}),[s,e,t,a,c])}const K=o.forwardRef(({length:s=h.length,format:e=h.format,formatAriaLabel:t=h.formatAriaLabel,onChange:a=h.onChange,onComplete:c=h.onComplete,handler:m,autoFocus:E,...f},M)=>{const L=A(),{refs:y,state:r,dispatch:l}=m||L;o.useImperativeHandle(M,()=>y.current,[y]);function O(n){return u=>{u&&(y.current[n]=u)}}function F(n){return u=>{const{key:i,code:p,keyCode:C,which:Y}=u;l({type:"handle-key-down",index:n,key:i,code:p,keyCode:C,which:Y})}}function P(n){return u=>{if(u.nativeEvent instanceof InputEvent){const i=u.nativeEvent.data;l({type:"handle-change",index:n,value:i})}else{const{value:i}=u.target;l({type:"handle-change",index:n,value:i,reset:!0})}}}function x(n){return()=>{l({type:"start-composition",index:n})}}function T(n){return u=>{l({type:"end-composition",index:n,value:u.data})}}if(o.useEffect(()=>{var u,i;if(r.ready)return;const n=((u=f.dir)==null?void 0:u.toLowerCase())||((i=document.documentElement.getAttribute("dir"))==null?void 0:i.toLowerCase());l({type:"update-props",props:{length:s,format:e,dir:n}})},[r.ready,l,s,e]),o.useEffect(()=>{r.ready&&s!==r.length&&l({type:"update-props",props:{length:s}})},[r.ready,s,r.length,l]),o.useEffect(()=>{r.ready&&e!==r.format&&l({type:"update-props",props:{format:e}})},[r.ready,e,r.format,l]),o.useEffect(()=>{var u,i;if(!r.ready)return;const n=((u=f.dir)==null?void 0:u.toLowerCase())||((i=document.documentElement.getAttribute("dir"))==null?void 0:i.toLowerCase());n!==r.dir&&l({type:"update-props",props:{dir:n}})},[r.ready,f.dir,r.dir,l]),o.useEffect(()=>{if(!y.current||!r.ready||!r.dirty)return;let n=!1,u=r.values.length==r.length,i="";for(let p=0;p<r.length;p++){const C=p in r.values?r.values[p]:"";y.current[p].value=C,n=n||D(y.current[p]),u=u&&p in r.values&&y.current[p].checkValidity(),i+=C}n&&y.current[r.cursor].focus(),a&&a(i),c&&u&&c(i)},[y,r,a,c]),!r.ready)return null;const _=w(0,r.length).map(n=>o.createElement("input",{...v,...f,key:n,ref:O(n),value:n in r.values?r.values[n]:"",autoFocus:n===0&&E,onKeyDown:F(n),onChange:P(n),onCompositionStart:x(n),onCompositionEnd:T(n),"aria-label":t(n+1,r.length),"aria-required":f.required?"true":void 0,"aria-disabled":f.disabled?"true":void 0,"aria-readonly":f.readOnly?"true":void 0}));return r.dir==="rtl"&&_.reverse(),_});d.default=K,d.defaultNativeProps=v,d.defaultProps=h,d.defaultState=k,d.reducer=b,d.usePinField=A,Object.defineProperties(d,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});
//# sourceMappingURL=react-pin-field.umd.cjs.map