@energma/input-mask-react
Version:
A React component for input mask with dynamic formatting. Fully compatible with React and Next.js.
2 lines (1 loc) • 3.19 kB
JavaScript
(function(k,g){typeof exports=="object"&&typeof module<"u"?g(exports,require("react/jsx-runtime"),require("react")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react"],g):(k=typeof globalThis<"u"?globalThis:k||self,g(k["@energma/input-mask-react"]={},k.jsxRuntime,k.React))})(this,(function(k,g,y){"use strict";const D=(e,d)=>{const u=[];for(let f=0;f<e.length;f++)e[f]!==d&&u.push(f);return u},R=(e,d)=>{switch(d){case"numbers":return/\d/.test(e);case"letters":return/[a-zA-Z]/.test(e);case"mixed":default:return/[a-zA-Z0-9]/.test(e)}},I=(e,d,u,f)=>{let m="",c=0;for(let s=0;s<d.length;s++)u.includes(s)?m+=d[s]:c<e.length?(m+=e[c],c++):m+=f;return m},P=(e,d,u)=>{let f=0,m=0;for(let c=0;c<d.length;c++)if(u.includes(c))f++;else if(m<e.length)m++,f++;else break;return f},j=y.forwardRef(({schema:e,value:d="",onChange:u,placeholder:f,...m},c)=>{const s=y.useRef(null),[a,w]=y.useState(d),[B,F]=y.useState(!1),x=y.useMemo(()=>D(e.mask,e.symbol),[e.mask]),A=(t=e.mask,n=0)=>{if(!e.mask)return{formatted:"",newCursorPos:0};let l=t.split(""),r=n;const o=t[n-1]||"";if(n>e.mask.length||n<0)return{formatted:t.slice(0,e.mask.length),newCursorPos:n};if(n>=0&&!R(o,e.type))return{formatted:a,newCursorPos:n-1};for(let i=0;i<=n;i++)if(x.includes(r-1)){const p=l[r-1];l[r-1]=e.mask[r-1],l[r]=p}else l[i]=t[i],n==x.filter(p=>p==n)[0]&&r++;for(let i=n;i<=e.mask.length;i++)a[i]&&a[i]!==e.symbol?l[i]=a[i]:l[i]=e.mask[i];return{formatted:l.join(""),newCursorPos:r}},M=t=>{t.stopPropagation(),t.preventDefault();const n=t.target,l=t.nativeEvent,r=n.value,o=n.selectionStart||0,i=l.inputType==="insertFromPaste";let p,b;if(i){const v=Array.from(r).filter(S=>R(S,e.type)).join("");p=I(v,e.mask,x,e.symbol),w(p),u==null||u({...t,target:{...t.target,value:p}}),b=P(v,e.mask,x),requestAnimationFrame(()=>{s.current&&s.current.setSelectionRange(b,b)})}else{const{formatted:v,newCursorPos:S}=A(r,o);w(v),u==null||u({...t,target:{...t.target,value:v}}),requestAnimationFrame(()=>{s.current&&s.current.setSelectionRange(S,S)})}},V=t=>{var l,r;const n=((l=s.current)==null?void 0:l.selectionStart)??0;if(t.ctrlKey&&t.key==="a"){if(t.preventDefault(),s.current){const o=a.length;s.current.setSelectionRange(0,o)}return}if(t.key==="Backspace"&&n===0&&((r=s.current)==null?void 0:r.selectionEnd)===a.length){t.preventDefault(),w("");return}if(t.key==="Backspace"&&(t.preventDefault(),n>0)){let o=n-1;for(;o>0&&x.includes(o);)o--;const i=a.substring(0,o)+e.mask[o]+a.substring(o+1);w(i),requestAnimationFrame(()=>{var p;(p=s.current)==null||p.setSelectionRange(o,o)})}},q=t=>{t.stopPropagation(),t.preventDefault(),F(!0);let n=-1;const l=a.length;for(let r=0;r<e.mask.length;r++)if(e.mask[r]===e.symbol&&(!a[r]||a[r]===e.symbol)){n=r;break}requestAnimationFrame(()=>{s.current&&n!==-1?s.current.setSelectionRange(n,n):s.current.setSelectionRange(l,l)})},E=t=>{t.stopPropagation(),t.preventDefault(),F(!1),a===e.mask&&w("")};return g.jsx("input",{...m,ref:t=>{typeof c=="function"?c(t):c&&(c.current=t),s.current=t},value:a,onChange:M,onKeyDown:V,onKeyUp:()=>{},onFocus:q,onBlur:E,placeholder:f})});k.MaskedInput=j,Object.defineProperty(k,Symbol.toStringTag,{value:"Module"})}));