maska
Version:
Simple zero-dependency input mask for Vanilla JS, Vue, Alpine.js and Svelte
2 lines (1 loc) • 7.05 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 A=(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 k,g,b,d;const e=((k=s.number)==null?void 0:k.unsigned)!==!0&&n.startsWith("-")?"-":"",r=((g=s.number)==null?void 0:g.fraction)??0;let a=C(0,r,s);const u=a.formatToParts(1000.12),p=((b=u.find(o=>o.type==="group"))==null?void 0:b.value)??" ",f=((d=u.find(o=>o.type==="decimal"))==null?void 0:d.value)??".",i=R(n,p,f);if(Number.isNaN(parseFloat(i)))return e;const h=i.split(".");if(h[1]!=null&&h[1].length>=1){const o=h[1].length<=r?h[1].length:r;a=C(o,r,s)}let l=a.format(parseFloat(i));return t?r>0&&i.endsWith(".")&&!i.slice(0,-1).includes(".")&&(l+=f):l=R(l,p,f),e+l};class w{constructor(t={}){A(this,"opts",{});A(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,r)=>e.length-r.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(r=>this.process(t,r,!1).length>=e.length)??""}escapeMask(t){const s=[],e=[];return t.split("").forEach((r,a)=>{r==="!"&&t[a-1]!=="!"?e.push(a-e.length):s.push(r)}),{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 r=`v=${t},mr=${s},m=${e?1:0}`;if(this.memo.has(r))return this.memo.get(r);const{mask:a,escaped:u}=this.escapeMask(s),p=[],f=this.opts.tokens!=null?this.opts.tokens:{},i=this.isReversed()?-1:1,h=this.isReversed()?"unshift":"push",l=this.isReversed()?0:a.length-1,k=this.isReversed()?()=>o>-1&&c>-1:()=>o<a.length&&c<t.length,g=v=>!this.isReversed()&&v<=l||this.isReversed()&&v>=l;let b,d=-1,o=this.isReversed()?a.length-1:0,c=this.isReversed()?t.length-1:0,E=!1;for(;k();){const v=a.charAt(o),m=f[v],M=(m==null?void 0:m.transform)!=null?m.transform(t.charAt(c)):t.charAt(c);if(!u.includes(o)&&m!=null?(M.match(m.pattern)!=null?(p[h](M),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):M===b?b=void 0:m.optional&&(o+=i,c-=i),c+=i):(e&&!this.isEager()&&p[h](v),M===v&&!this.isEager()?c+=i:b=v,this.isEager()||(o+=i)),this.isEager())for(;g(o)&&(f[a.charAt(o)]==null||u.includes(o));){if(e){if(p[h](a.charAt(o)),t.charAt(c)===a.charAt(o)){o+=i,c+=i;continue}}else a.charAt(o)===t.charAt(c)&&(c+=i);o+=i}}return this.memo.set(r,p.join("")),this.memo.get(r)}}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=y(n.dataset.maskaEager)),n.dataset.maskaReversed!=null&&(s.reversed=y(n.dataset.maskaReversed)),n.dataset.maskaTokensReplace!=null&&(s.tokensReplace=y(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=y(n.dataset.maskaNumberUnsigned)),(n.dataset.maskaNumber!=null||Object.values(e).length>0)&&(s.number=e),s},y=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={}){A(this,"items",new Map);A(this,"eventAbortController");A(this,"onInput",t=>{if(t instanceof CustomEvent&&t.type==="input"&&!t.isTrusted&&!t.bubbles)return;const s=t.target,e=this.items.get(s);if(e===void 0)return;const r="inputType"in t&&t.inputType.startsWith("delete"),a=e.isEager(),u=r&&a&&e.unmasked(s.value)===""?"":s.value;this.fixCursor(s,r,()=>this.setValue(s,u))});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){var s;t.value!==""&&t.value!==((s=this.processInput(t))==null?void 0:s.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:a}=this.eventAbortController;e.addEventListener("input",this.onInput,{capture:!0,signal:a})}const r=new w(F(e,s));this.items.set(e,r),queueMicrotask(()=>this.updateValue(e)),e.selectionStart===null&&r.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:r,...a}=t;return a}fixCursor(t,s,e){var k,g;const r=t.selectionStart,a=t.value;if(e(),r===null||r===a.length&&!s)return;const u=t.value,p=a.slice(0,r),f=u.slice(0,r),i=(k=this.processInput(t,p))==null?void 0:k.unmasked,h=(g=this.processInput(t,f))==null?void 0:g.unmasked;if(i===void 0||h===void 0)return;let l=r;p!==f&&(l+=s?u.length-a.length:i.length-h.length),t.setSelectionRange(l,l)}setValue(t,s){const e=this.processInput(t,s);e!==void 0&&(t.value=e.masked,this.options.onMaska!=null&&(Array.isArray(this.options.onMaska)?this.options.onMaska.forEach(r=>r(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);if(e===void 0)return;let r=s??t.value;this.options.preProcess!=null&&(r=this.options.preProcess(r));let a=e.masked(r);return this.options.postProcess!=null&&(a=this.options.postProcess(a)),{masked:a,unmasked:e.unmasked(r),completed:e.completed(r)}}}exports.Mask=w;exports.MaskInput=x;exports.tokens=N;