maska
Version:
Simple zero-dependency input mask for Vanilla JS, Vue, Alpine.js and Svelte
2 lines (1 loc) • 6.88 kB
JavaScript
"use strict";var S=Object.defineProperty;var P=(n,t,s)=>t in n?S(n,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):n[t]=s;var b=(n,t,s)=>P(n,typeof t!="symbol"?t+"":t,s);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const N={"#":{pattern:/[0-9]/},"@":{pattern:/[a-zA-Z]/},"*":{pattern:/[a-zA-Z0-9]/}},R=(n,t,s)=>n.replaceAll(t,"").replace(s,".").replace("..",".").replace(/[^.\d]/g,""),C=(n,t,s)=>{var e;return new Intl.NumberFormat(((e=s.number)==null?void 0:e.locale)??"en",{minimumFractionDigits:n,maximumFractionDigits:t,roundingMode:"trunc"})},T=(n,t=!0,s)=>{var A,M,g,d;const e=((A=s.number)==null?void 0:A.unsigned)!==!0&&n.startsWith("-")?"-":"",a=((M=s.number)==null?void 0:M.fraction)??0;let r=C(0,a,s);const h=r.formatToParts(1000.12),u=((g=h.find(o=>o.type==="group"))==null?void 0:g.value)??" ",f=((d=h.find(o=>o.type==="decimal"))==null?void 0:d.value)??".",i=R(n,u,f);if(Number.isNaN(parseFloat(i)))return e;const p=i.split(".");if(p[1]!=null&&p[1].length>=1){const o=p[1].length<=a?p[1].length:a;r=C(o,a,s)}let l=r.format(parseFloat(i));return t?a>0&&i.endsWith(".")&&!i.slice(0,-1).includes(".")&&(l+=f):l=R(l,u,f),e+l};class w{constructor(t={}){b(this,"opts",{});b(this,"memo",new Map);const s={...t};if(s.tokens!=null){s.tokens=s.tokensReplace?{...s.tokens}:{...N,...s.tokens};for(const e of Object.values(s.tokens))typeof e.pattern=="string"&&(e.pattern=new RegExp(e.pattern))}else s.tokens=N;Array.isArray(s.mask)&&(s.mask.length>1?s.mask=[...s.mask].sort((e,a)=>e.length-a.length):s.mask=s.mask[0]??""),s.mask===""&&(s.mask=null),this.opts=s}masked(t){return this.process(String(t),this.findMask(String(t)))}unmasked(t){return this.process(String(t),this.findMask(String(t)),!1)}isEager(){return this.opts.eager===!0}isReversed(){return this.opts.reversed===!0}completed(t){const s=this.findMask(String(t));if(this.opts.mask==null||s==null)return!1;const e=this.process(String(t),s).length;return typeof this.opts.mask=="string"?e>=this.opts.mask.length:e>=s.length}findMask(t){const s=this.opts.mask;if(s==null)return null;if(typeof s=="string")return s;if(typeof s=="function")return s(t);const e=this.process(t,s.slice(-1).pop()??"",!1);return s.find(a=>this.process(t,a,!1).length>=e.length)??""}escapeMask(t){const s=[],e=[];return t.split("").forEach((a,r)=>{a==="!"&&t[r-1]!=="!"?e.push(r-e.length):s.push(a)}),{mask:s.join(""),escaped:e}}process(t,s,e=!0){if(this.opts.number!=null)return T(t,e,this.opts);if(s==null)return t;const a=`v=${t},mr=${s},m=${e?1:0}`;if(this.memo.has(a))return this.memo.get(a);const{mask:r,escaped:h}=this.escapeMask(s),u=[],f=this.opts.tokens!=null?this.opts.tokens:{},i=this.isReversed()?-1:1,p=this.isReversed()?"unshift":"push",l=this.isReversed()?0:r.length-1,A=this.isReversed()?()=>o>-1&&c>-1:()=>o<r.length&&c<t.length,M=k=>!this.isReversed()&&k<=l||this.isReversed()&&k>=l;let g,d=-1,o=this.isReversed()?r.length-1:0,c=this.isReversed()?t.length-1:0,E=!1;for(;A();){const k=r.charAt(o),m=f[k],y=(m==null?void 0:m.transform)!=null?m.transform(t.charAt(c)):t.charAt(c);if(!h.includes(o)&&m!=null?(y.match(m.pattern)!=null?(u[p](y),m.repeated?(d===-1?d=o:o===l&&o!==d&&(o=d-i),l===d&&(o-=i)):m.multiple&&(E=!0,o-=i),o+=i):m.multiple?E&&(o+=i,c-=i,E=!1):y===g?g=void 0:m.optional&&(o+=i,c-=i),c+=i):(e&&!this.isEager()&&u[p](k),y===k&&!this.isEager()?c+=i:g=k,this.isEager()||(o+=i)),this.isEager())for(;M(o)&&(f[r.charAt(o)]==null||h.includes(o));){if(e){if(u[p](r.charAt(o)),t.charAt(c)===r.charAt(o)){o+=i,c+=i;continue}}else r.charAt(o)===t.charAt(c)&&(c+=i);o+=i}}return this.memo.set(a,u.join("")),this.memo.get(a)}}const I=n=>JSON.parse(n.replaceAll("'",'"')),F=(n,t={})=>{const s={...t};n.dataset.maska!=null&&n.dataset.maska!==""&&(s.mask=O(n.dataset.maska)),n.dataset.maskaEager!=null&&(s.eager=v(n.dataset.maskaEager)),n.dataset.maskaReversed!=null&&(s.reversed=v(n.dataset.maskaReversed)),n.dataset.maskaTokensReplace!=null&&(s.tokensReplace=v(n.dataset.maskaTokensReplace)),n.dataset.maskaTokens!=null&&(s.tokens=W(n.dataset.maskaTokens));const e={};return n.dataset.maskaNumberLocale!=null&&(e.locale=n.dataset.maskaNumberLocale),n.dataset.maskaNumberFraction!=null&&(e.fraction=parseInt(n.dataset.maskaNumberFraction)),n.dataset.maskaNumberUnsigned!=null&&(e.unsigned=v(n.dataset.maskaNumberUnsigned)),(n.dataset.maskaNumber!=null||Object.values(e).length>0)&&(s.number=e),s},v=n=>n!==""?!!JSON.parse(n):!0,O=n=>n.startsWith("[")&&n.endsWith("]")?I(n):n,W=n=>{if(n.startsWith("{")&&n.endsWith("}"))return I(n);const t={};return n.split("|").forEach(s=>{const e=s.split(":");t[e[0]]={pattern:new RegExp(e[1]),optional:e[2]==="optional",multiple:e[2]==="multiple",repeated:e[2]==="repeated"}}),t};class x{constructor(t,s={}){b(this,"items",new Map);b(this,"eventAbortController");b(this,"onInput",t=>{if(t instanceof CustomEvent&&t.type==="input"&&!t.isTrusted&&!t.bubbles)return;const s=t.target,e=this.items.get(s),a="inputType"in t&&t.inputType.startsWith("delete"),r=e.isEager(),h=a&&r&&e.unmasked(s.value)===""?"":s.value;this.fixCursor(s,a,()=>this.setValue(s,h))});this.options=s,this.eventAbortController=new AbortController,this.init(this.getInputs(t))}update(t={}){this.options={...t},this.init(Array.from(this.items.keys()))}updateValue(t){t.value!==""&&t.value!==this.processInput(t).masked&&this.setValue(t,t.value)}destroy(){this.eventAbortController.abort(),this.items.clear()}init(t){const s=this.getOptions(this.options);for(const e of t){if(!this.items.has(e)){const{signal:r}=this.eventAbortController;e.addEventListener("input",this.onInput,{capture:!0,signal:r})}const a=new w(F(e,s));this.items.set(e,a),queueMicrotask(()=>this.updateValue(e)),e.selectionStart===null&&a.isEager()&&console.warn("Maska: input of `%s` type is not supported",e.type)}}getInputs(t){return typeof t=="string"?Array.from(document.querySelectorAll(t)):"length"in t?Array.from(t):[t]}getOptions(t){const{onMaska:s,preProcess:e,postProcess:a,...r}=t;return r}fixCursor(t,s,e){const a=t.selectionStart,r=t.value;if(e(),a===null||a===r.length&&!s)return;const h=t.value,u=r.slice(0,a),f=h.slice(0,a),i=this.processInput(t,u).unmasked,p=this.processInput(t,f).unmasked;let l=a;u!==f&&(l+=s?h.length-r.length:i.length-p.length),t.setSelectionRange(l,l)}setValue(t,s){const e=this.processInput(t,s);t.value=e.masked,this.options.onMaska!=null&&(Array.isArray(this.options.onMaska)?this.options.onMaska.forEach(a=>a(e)):this.options.onMaska(e)),t.dispatchEvent(new CustomEvent("maska",{detail:e})),t.dispatchEvent(new CustomEvent("input",{detail:e.masked}))}processInput(t,s){const e=this.items.get(t);let a=s??t.value;this.options.preProcess!=null&&(a=this.options.preProcess(a));let r=e.masked(a);return this.options.postProcess!=null&&(r=this.options.postProcess(r)),{masked:r,unmasked:e.unmasked(a),completed:e.completed(a)}}}exports.Mask=w;exports.MaskInput=x;exports.tokens=N;