mother-mask 3.0.1 → 3.2.0

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/README.md CHANGED
@@ -1,250 +1,148 @@
1
1
  # mother-mask
2
2
 
3
- Lightweight input mask library for browsers. Zero runtime dependencies, TypeScript-first, ships **ESM**, **CJS**, and **UMD**.
3
+ Lightweight input masks for browser forms. Zero runtime dependencies, written in TypeScript, and published with ESM, CJS, and UMD builds.
4
4
 
5
- Published as [`mother-mask` on npm](https://www.npmjs.com/package/mother-mask).
6
-
7
- ## Live demo
8
-
9
- **[Try it on StackBlitz →](https://stackblitz.com/edit/mother-mask-simple-demo?file=src%2Fmain.ts)**
5
+ [npm](https://www.npmjs.com/package/mother-mask) | [Live demo](https://stackblitz.com/edit/mother-mask-simple-demo?file=src%2Fmain.ts)
10
6
 
11
7
  ## Install
12
8
 
13
9
  ```bash
14
10
  npm install mother-mask
15
- # or
16
- pnpm add mother-mask
17
11
  ```
18
12
 
19
- ## Usage
20
-
21
- ### `bind(input, mask, options?)`
22
-
23
- Attach a mask to any input element — this is the main API.
13
+ ```bash
14
+ pnpm add mother-mask
15
+ ```
24
16
 
25
- - **Idempotent** — calling `bind()` again on the same element does nothing (the element is marked with `data-masked`).
26
- - **Returns a dispose function** — call it to remove listeners and attributes so you can bind again later.
27
- - Sets sensible defaults when missing: `autocomplete`, `autocorrect`, `autocapitalize`, `spellcheck`, and `maxlength` from the mask.
17
+ ## Basic Usage
28
18
 
29
19
  ```ts
30
20
  import { bind } from 'mother-mask'
31
21
 
32
- const input = document.getElementById('phone') as HTMLInputElement
22
+ const input = document.querySelector<HTMLInputElement>('#phone')!
33
23
 
34
- // Fixed mask
35
24
  const dispose = bind(input, '(99) 99999-9999')
36
25
 
37
- // Dynamic mask picks the pattern from an ordered list (shortest → longest)
38
- bind(input, ['(99) 9999-9999', '(99) 99999-9999'])
39
-
40
- // Callback after paste or keyboard-driven changes
41
- bind(input, '999.999.999-99', (value) => {
42
- console.log(value) // e.g. "123.456.789-01"
43
- })
44
-
45
- // Or options object (same as callback for a single `onChange`)
46
- bind(input, '999.999.999-99', { onChange: (value) => console.log(value) })
47
-
48
- // Later: allow rebinding
26
+ // Later, remove listeners and allow rebinding.
49
27
  dispose()
50
28
  ```
51
29
 
52
- ### Segmented masks (default) vs. flat/reflow masks
53
-
54
- By default, every mask treats its literal separators as hard boundaries
55
- between independent fields. Selecting "12" in `25/12/2025` and typing a
56
- shorter or longer replacement stays scoped to the month — it never bleeds
57
- digits into the year, and deleting a whole field just leaves it empty
58
- instead of pulling the next field left across the separator:
30
+ Use an ordered mask array for values with more than one length:
59
31
 
60
32
  ```ts
61
- bind(input, '99/99/9999') // segmented by default
33
+ bind(input, ['(99) 9999-9999', '(99) 99999-9999'])
62
34
  ```
63
35
 
64
- This is the right behavior for masks made of independent fields — dates,
65
- times — and it's a safe default everywhere else too, since it never
66
- *discards* data (typing past a field's capacity still flows forward into
67
- the next one; only backward bleed is blocked). A fully raw, unformatted
68
- paste (e.g. `25122025`) still fills every field in one pass, and array
69
- masks that switch pattern width (see below) still reflow correctly.
70
-
71
- Pass `segmented: false` to opt into the classic flat/reflow behavior
72
- instead, where deleting or replacing characters anywhere shifts everything
73
- after it to close the gap — useful when a mask really is one continuous
74
- number with cosmetic separators (e.g. formatting a running total) rather
75
- than independent fields:
36
+ Listen for changes with either a callback or an options object:
76
37
 
77
38
  ```ts
78
- bind(input, '999.999.999-99', { segmented: false })
79
- ```
80
-
81
- `segmented` is also accepted by `applyMask`, `buildMask`, and `process` as
82
- part of an options object.
39
+ bind(input, '999.999.999-99', (value) => {
40
+ document.querySelector<HTMLInputElement>('#cpf-value')!.value = value
41
+ })
83
42
 
84
- ### `bindDecimal(input, options?)`
43
+ bind(input, '999.999.999-99', {
44
+ onChange: (value) => {
45
+ document.querySelector<HTMLInputElement>('#cpf-value')!.value = value
46
+ },
47
+ })
48
+ ```
85
49
 
86
- A second binder for decimal/currency-style inputs — numbers, not
87
- pattern-slot strings. There's no fixed template: the integer part grows and
88
- shrinks freely as the user types, and formatting (grouping, decimal places,
89
- prefix/suffix) is driven entirely by `options`. Same contract as `bind()`:
90
- idempotent, marked with `data-masked`, returns a dispose function.
50
+ ## Decimal Inputs
91
51
 
92
- Typing behaves like a normal number field, not a cents-first calculator:
93
- digits fill the integer part until you type the decimal separator, and the
94
- fixed-width fraction is always shown zero-padded. A lone placeholder "0" in
95
- the integer part (an untouched field showing e.g. "$0.00") is overwritten,
96
- not extended, by the next digit — typing "2" anywhere against that "0" gives
97
- "$2.00", never "$20.00" or "$02.00".
52
+ Use `bindDecimal` for numbers, currency fields, and values where the integer part should grow freely.
98
53
 
99
54
  ```ts
100
55
  import { bindDecimal } from 'mother-mask'
101
56
 
102
- const input = document.querySelector<HTMLInputElement>('#decimal')!
103
-
104
57
  bindDecimal(input, {
105
- decimalPlaces: 2, // fixed fractional digits — default 2
106
- segmented: true, // group the integer part into thousands — default true
107
- separator: ',', // thousands grouping separator — default ','
108
- decimalSeparator: '.', // integer/fraction separator, and its typing trigger — default '.'
58
+ decimalPlaces: 2,
59
+ separator: ',',
60
+ decimalSeparator: '.',
109
61
  prefix: '$',
110
- suffix: '',
111
- allowNegative: false, // allow a leading "-" — default false
62
+ allowNegative: false,
63
+ onChange: (value, numericValue) => {
64
+ document.querySelector<HTMLInputElement>('#amount-label')!.value = value
65
+ document.querySelector<HTMLInputElement>('#amount-value')!.value = String(numericValue)
66
+ },
112
67
  })
68
+ ```
113
69
 
114
- // Typing "42" → "$42.00"
115
- // Typing "423" → "$423.00"
116
- // Typing "423." → "$423.00" (the separator opens the fraction segment)
117
- // Typing "423.4" → "$423.40"
118
- // Typing "423.42" → "$423.42"
119
-
120
- // Editing is segmented, same as bind(): shortening "423.42" to "423.4"
121
- // (deleting the trailing "2") re-pads the fraction instead of reflowing
122
- // digits from the integer part → "$423.40"
123
-
124
- // Either "." or "," opens the fraction, regardless of decimalSeparator —
125
- // handy since numeric keypads often only have ".".
70
+ For Brazilian-style formatting:
126
71
 
127
- // Callback receives both the masked string and its parsed numeric value
72
+ ```ts
128
73
  bindDecimal(input, {
129
- prefix: '$',
130
- onChange: (value, numericValue) => {
131
- console.log(value, numericValue) // "$423.42", 423.42
132
- },
74
+ separator: '.',
75
+ decimalSeparator: ',',
133
76
  })
134
-
135
- // Or a bare callback (legacy style, same as bind())
136
- bindDecimal(input, (value, numericValue) => console.log(value, numericValue))
137
77
  ```
138
78
 
139
- Locale note: `separator` and `decimalSeparator` are independent, so
140
- `{ separator: '.', decimalSeparator: ',' }` gives the `1.234,56` format
141
- common outside the US.
142
-
143
- ## Pattern syntax
79
+ ## Pattern Syntax
144
80
 
145
81
  | Character | Matches |
146
- |-----------|---------|
147
- | `9` | Digit (`0`–`9`) |
148
- | `Z` | Letter (`a`–`z`, `A`–`Z`) |
149
- | `A` | Alphanumeric (digit or letter) |
150
- | Anything else | Literal inserted as the user fills slots |
82
+ | --- | --- |
83
+ | `9` | Digit |
84
+ | `Z` | Letter |
85
+ | `A` | Letter or digit |
86
+ | Anything else | Literal separator |
151
87
 
152
- ## Array masks
88
+ Examples:
153
89
 
154
- Pass an ordered array **shortest → longest** for variable-length inputs. The active mask is chosen from the **count of alphanumeric “data” characters** in the current value, so it works for both progressively masked input and fast typing.
90
+ ```ts
91
+ bind(input, '999.999.999-99')
92
+ bind(input, '99/99/9999')
93
+ bind(input, 'AA.AAA.AAA/AAAA-99')
94
+ ```
95
+
96
+ ## Segmented Editing
97
+
98
+ Masks are segmented by default. Separators behave like boundaries, which keeps fields such as dates from bleeding into each other while editing:
155
99
 
156
100
  ```ts
157
- bind(input, ['(99) 9999-9999', '(99) 99999-9999'])
158
- bind(input, ['999.999.999-99', 'AA.AAA.AAA/AAAA-99'])
101
+ bind(input, '99/99/9999')
159
102
  ```
160
103
 
161
- ## UMD / CDN
104
+ For classic reflow behavior, pass `segmented: false`:
105
+
106
+ ```ts
107
+ bind(input, '999.999.999-99', { segmented: false })
108
+ ```
109
+
110
+ ## CDN
162
111
 
163
112
  ```html
164
113
  <script src="https://unpkg.com/mother-mask/dist/mother-mask.umd.js"></script>
165
114
  <script>
166
- const dispose = MotherMask.bind(document.getElementById('cpf'), '999.999.999-99')
115
+ MotherMask.bind(document.getElementById('cpf'), '999.999.999-99')
167
116
  </script>
168
117
  ```
169
118
 
170
- The global name is **`MotherMask`**.
171
-
172
- ## API reference
173
-
174
- ### `bind` (primary)
175
-
176
- | | |
177
- |--|--|
178
- | **Signature** | `bind(input, mask, options?)` |
179
- | **Returns** | `() => void` — call to remove listeners and attributes so the input can be bound again |
180
- | **Third argument** | `{ onChange?: (value: string) => void }`, or a legacy `(value) => void` callback |
181
-
182
- ### Other exports
119
+ The global name is `MotherMask`.
183
120
 
184
- | Export | Description |
185
- |--------|-------------|
186
- | `buildMask(value, mask, caret?, options?)` | Build a `Mask` instance (array `mask` is resolved to one string first). |
187
- | `getMaxLength(mask)` | Maximum string length for the mask (for array masks, the longest pattern). |
188
- | `applyMask(value, mask, inputCaret?, options?)` | Low-level: apply a **single** mask string; returns `{ value, caret }`. |
189
- | `process(value, mask, options?)` | Apply a mask pattern to a raw value and return just the masked string. |
121
+ ## API
190
122
 
191
- ### `Mask` class
123
+ Main exports:
192
124
 
193
- `buildMask` returns a `Mask` for advanced use. The instance applies the pattern and keeps a `caret` position aligned with the masked output (see TypeScript definitions in the package).
125
+ - `bind(input, mask, options?)`
126
+ - `bindDecimal(input, options?)`
127
+ - `applyMask(value, mask, inputCaret?, options?)`
128
+ - `process(value, mask, options?)`
129
+ - `buildMask(value, mask, caret?, options?)`
130
+ - `getMaxLength(mask)`
131
+ - `applyDecimalMask(value, inputCaret?, options?)`
132
+ - `processDecimal(value, options?)`
133
+ - `unmaskDecimal(value, options?)`
134
+ - `formatDecimalValue(value, options?)`
135
+ - `Mask`
194
136
 
195
- ### `bindDecimal`
196
-
197
- | | |
198
- |--|--|
199
- | **Signature** | `bindDecimal(input, options?)` |
200
- | **Returns** | `() => void` — call to remove listeners and attributes so the input can be bound again |
201
- | **Second argument** | `DecimalMaskOptions & { onChange?: (value: string, numericValue: number) => void }`, or a legacy `(value, numericValue) => void` callback |
202
-
203
- ### Other decimal exports
204
-
205
- | Export | Description |
206
- |--------|-------------|
207
- | `applyDecimalMask(value, inputCaret?, options?)` | Low-level: format a raw/already-masked value; returns `{ value, caret }`. |
208
- | `processDecimal(value, options?)` | Apply a decimal mask to a raw value and return just the masked string. |
209
- | `unmaskDecimal(value, options?)` | Parse a raw or masked decimal string back into a JS `number` (`0` if it has no digits). |
210
- | `formatDecimalValue(value, options?)` | Format a plain JS `number` into its masked display string — useful to pre-populate an input. |
211
-
212
- ### Types
213
-
214
- ```ts
215
- type MaskPattern = string | string[]
216
-
217
- interface MaskResult {
218
- readonly value: string
219
- readonly caret: number
220
- }
221
-
222
- interface ApplyMaskOptions {
223
- /** Hard boundaries between fields — on by default. Pass `false` for flat/reflow. */
224
- segmented?: boolean
225
- }
226
-
227
- interface BindOptions extends ApplyMaskOptions {
228
- onChange?: (value: string) => void
229
- }
230
-
231
- interface DecimalMaskOptions {
232
- decimalPlaces?: number // default 2
233
- segmented?: boolean // group into thousands — default true
234
- separator?: string // thousands separator — default ','
235
- decimalSeparator?: string // default '.'
236
- prefix?: string // default ''
237
- suffix?: string // default ''
238
- allowNegative?: boolean // default false
239
- }
240
-
241
- interface BindDecimalOptions extends DecimalMaskOptions {
242
- onChange?: (value: string, numericValue: number) => void
243
- }
244
- ```
137
+ Exported types:
245
138
 
246
- `MaskPattern`, `MaskResult`, `ApplyMaskOptions`, `BindOptions`, `DecimalMaskOptions`, and `BindDecimalOptions` are exported as types.
139
+ - `MaskPattern`
140
+ - `MaskResult`
141
+ - `ApplyMaskOptions`
142
+ - `BindOptions`
143
+ - `DecimalMaskOptions`
144
+ - `BindDecimalOptions`
247
145
 
248
146
  ## License
249
147
 
250
- MIT [Danilo Celestino de Castro](https://github.com/dan2dev)
148
+ MIT - [Danilo Celestino de Castro](https://github.com/dan2dev)
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});function e(e){return e>=`0`&&e<=`9`}function t(e){return e>=`a`&&e<=`z`||e>=`A`&&e<=`Z`}function n(e){return e===`9`||e===`Z`||e===`A`}function r(n,r){return r===`9`?e(n):r===`Z`?t(n):e(n)||t(n)}function i(e,t,n){let i=``,a=``,o=0,s=0,c=!1;for(let l=0;l<t.length;l++){let u=t[l];if(u!==`9`&&u!==`Z`&&u!==`A`){a+=u;continue}let d=!1;for(;o<e.length;){let t=e[o++];if(r(t,u)){i+=a+t,a=``,d=!0,c||(o<=n?s=i.length:c=!0);break}}if(!d)break}return c||(s=i.length),{value:i,caret:s}}function a(e){let t=[],r=0;for(;r<e.length;){let i=r,a=n(e[r]);for(;r<e.length&&n(e[r])===a;)r++;let o=e.slice(i,r);t.push(a?{kind:`slots`,chars:o}:{kind:`literal`,text:o})}return t}function o(e,t){let n=0;for(let r=t;r<e.length;r++){let t=e[r];t.kind===`slots`&&(n+=t.chars.length)}return n}function s(n,r){let i=0;for(let a=r;a<n.length;a++){let r=n[a];(e(r)||t(r))&&i++}return i}function c(e,t,n){let i=a(t),c=``,l=``,u=0,d=0,f=!1,p=!1;for(let t=0;t<i.length&&!p;t++){let a=i[t];if(a.kind===`literal`){l+=a.text,e.startsWith(a.text,u)&&(u+=a.text.length);continue}let m=i[t+1],h=o(i,t+1);for(let t=0;t<a.chars.length;t++){let i=a.chars[t],o=!1;for(;u<e.length;){let t=e[u];if(r(t,i)){u++,c+=l+t,l=``,o=!0,f||(u<=n?d=c.length:f=!0);break}if(m?.kind===`literal`&&e.startsWith(m.text,u)&&s(e,u)<=h)break;u++}if(!o){u>=e.length&&(p=!0);break}}}return f||(d=c.length),{value:c,caret:d}}function l(e,t,n=0,r){return e?r?.segmented===!1?i(e,t,n):c(e,t,n):{value:``,caret:0}}function u(e){let t=0;for(let n of e)(n>=`0`&&n<=`9`||n>=`a`&&n<=`z`||n>=`A`&&n<=`Z`)&&t++;return t}function d(e){let t=0;for(let n of e)(n===`9`||n===`Z`||n===`A`)&&t++;return t}function f(e,t){if(!Array.isArray(t))return t;let n=u(e),r=0;for(;r<t.length-1&&n>d(t[r]);)r++;return t[r]}function p(e){return Array.isArray(e)?e.length>0?Math.max(...e.map(e=>e.length)):0:e.length}var m=class{caret;_value;_mask;_options;constructor(e,t,n=0,r){this._value=e,this._mask=t,this.caret=n,this._options=r}process(){let e=l(this._value,this._mask,this.caret,this._options);return this.caret=e.caret,e.value}};function h(e,t,n=0,r){return new m(e,f(e,t),n,r)}function g(e,t,n){return h(e,t,0,n).process()}let _;function v(){return _===void 0&&(_=typeof navigator<`u`&&/iPad|iPhone|iPod/i.test(navigator.userAgent)),_}const y=`data-masked`;function b(e){return e==null?{}:typeof e==`function`?{onChange:e}:e}function x(e,t,n){if(e.getAttribute(y)!==null)return()=>{};let{onChange:r,segmented:i}=b(n),a=[],o=(t,n)=>{e.hasAttribute(t)||(e.setAttribute(t,n),a.push(t))};e.setAttribute(y,Array.isArray(t)?t.join(`|`):t),o(`autocomplete`,`off`),o(`autocorrect`,`off`),o(`autocapitalize`,`off`),o(`spellcheck`,`false`),o(`maxlength`,String(p(t)));let s=!1,c=v()?`keyup`:`keydown`,l=e=>{let n=e.target;requestAnimationFrame(()=>{n.value=h(n.value,t,0,{segmented:i}).process(),r?.(n.value)})},u=e=>{let n=e,a=n.target,o=a.value;if(!n.key){s=!0,requestAnimationFrame(()=>{let e=a.selectionStart??999,n=h(a.value,t,e,{segmented:i});a.value=n.process(),a.setSelectionRange(n.caret,n.caret),requestAnimationFrame(()=>{s=!1})});return}if(n.key===`Meta`)return;let c=n.key===`Backspace`,l=n.key===`Delete`,u=n.key.length===1&&!n.ctrlKey&&!n.altKey&&!n.metaKey,d=n.key===`Unidentified`;if(u&&a.selectionStart===a.selectionEnd&&o.length>=p(t)&&!v()){n.preventDefault();return}if(s){n.preventDefault();return}requestAnimationFrame(()=>{let e=a.selectionStart??999,n=h(a.value,t,e,{segmented:i});if(a.value=n.process(),d){let t=a.value.length>o.length?n.caret:e;a.setSelectionRange(t,t)}else if(l){let t=o.length===a.value.length?e+1:e;a.setSelectionRange(t,t)}else c?a.setSelectionRange(e,e):u&&a.setSelectionRange(n.caret,n.caret);r?.(a.value)})};return e.addEventListener(`paste`,l),e.addEventListener(c,u),()=>{e.removeEventListener(`paste`,l),e.removeEventListener(c,u),e.removeAttribute(y);for(let t of a)e.removeAttribute(t)}}function S(e){return e>=`0`&&e<=`9`}function C(e){let t=e?.decimalPlaces??2;return{decimalPlaces:Number.isFinite(t)?Math.max(0,Math.floor(t)):2,segmented:e?.segmented??!0,separator:e?.separator??`,`,decimalSeparator:e?.decimalSeparator??`.`,prefix:e?.prefix??``,suffix:e?.suffix??``,allowNegative:e?.allowNegative??!1}}function w(e){let t=0;for(;t<e.length-1&&e[t]===`0`;)t++;return e.slice(t)}function T(e,t){if(!t||e.length<=3)return e;let n=[],r=e.length;for(;r>3;)n.unshift(e.slice(r-3,r)),r-=3;return n.unshift(e.slice(0,r)),n.join(t)}function E(e,t){if(t<=0)return 0;let n=0;for(let r=0;r<e.length;r++)if(S(e[r])&&(n++,n===t))return r+1;return e.length}function D(e,t){let n=``,r=``,i=!1,a=!1,o=t.decimalPlaces>0;for(let s of e){if(S(s)){a?r.length<t.decimalPlaces&&(r+=s):n+=s;continue}if(o&&!a&&s===t.decimalSeparator){a=!0;continue}s===`-`&&t.allowNegative&&(i=!0)}return{isNegative:i,intDigits:n,fracDigits:r,hasSeparator:a}}function O(e,t,n){let r=n.decimalPlaces>0,i=!1,a=0;for(let o=0;o<t;o++){let t=e[o];if(S(t)){(!i||a<n.decimalPlaces)&&a++;continue}r&&!i&&t===n.decimalSeparator&&(i=!0,a=0)}return{inFraction:i,digitsBefore:a}}function k(e,t=0,n){let r=C(n);if(!e)return{value:``,caret:0};let{isNegative:i,intDigits:a,fracDigits:o,hasSeparator:s}=D(e,r);if(a===``&&o===``&&!s)return{value:``,caret:0};let c=w(a||`0`),l=r.segmented?T(c,r.separator):c,u=r.decimalPlaces>0?o.padEnd(r.decimalPlaces,`0`):``,d=l+(r.decimalPlaces>0?r.decimalSeparator+u:``),f=i?`-`:``,p=f+r.prefix+d+r.suffix,{inFraction:m,digitsBefore:h}=O(e,Math.max(0,Math.min(t,e.length)),r),g=f.length+r.prefix.length;return{value:p,caret:m?g+l.length+r.decimalSeparator.length+h:g+E(l,h)}}function A(e,t){return k(e,e.length,t).value}function j(e,t){let{isNegative:n,intDigits:r,fracDigits:i}=D(e,C(t)),a=Number(i?`${r||`0`}.${i}`:r||`0`);return n?-a:a}function M(e,t){let n=C(t);if(n.decimalPlaces<=0)return null;let{isNegative:r,intDigits:i,hasSeparator:a}=D(e,n);if(a||i.length<n.decimalPlaces+1)return null;let o=i.length-n.decimalPlaces,s=i.slice(o),c=i.slice(0,o-1),l=r?`-`:``;return k(l+c+n.decimalSeparator+s,l.length+c.length,n)}function N(e,t,n,r){let i=C(r),a=t-1;if(a<0||e[a]!==n)return null;let{isNegative:o,intDigits:s,fracDigits:c,hasSeparator:l}=D(e.slice(0,a)+e.slice(t),i);if(s!==`0`)return null;let u=+!!o+i.prefix.length;if(a<u||a>u+1)return null;let d=o?`-`:``;return k(d+n+(l?i.decimalSeparator+c:``),d.length+1,i)}function P(e,t){let n=C(t);if(!Number.isFinite(e))return``;let r=n.allowNegative&&e<0,i=Math.abs(e).toFixed(n.decimalPlaces),a=i.indexOf(`.`),o=a===-1?i:i.slice(0,a),s=a===-1?``:i.slice(a+1),c=w(o||`0`),l=(n.segmented?T(c,n.separator):c)+(n.decimalPlaces>0?n.decimalSeparator+s:``);return(r?`-`:``)+n.prefix+l+n.suffix}const F=`data-masked`;function I(e){return e==null?{}:typeof e==`function`?{onChange:e}:e}function L(e){return e.length===1&&e>=`0`&&e<=`9`}function R(e,t){if(e.getAttribute(F)!==null)return()=>{};let{onChange:n,...r}=I(t),i=r,{decimalSeparator:a,decimalPlaces:o}=C(i),s=[],c=(t,n)=>{e.hasAttribute(t)||(e.setAttribute(t,n),s.push(t))};e.setAttribute(F,`decimal`),c(`autocomplete`,`off`),c(`autocorrect`,`off`),c(`autocapitalize`,`off`),c(`spellcheck`,`false`);let l=!1,u=v()?`keyup`:`keydown`,d=(e,t)=>{e.value=t.value,e.setSelectionRange(t.caret,t.caret),n?.(t.value,j(t.value,i))},f=e=>{let t=e.target;requestAnimationFrame(()=>{d(t,k(t.value,t.value.length,i))})},p=e=>{let t=e,n=t.target;if(!t.key){l=!0,requestAnimationFrame(()=>{let e=n.selectionStart??n.value.length;d(n,k(n.value,e,i)),requestAnimationFrame(()=>{l=!1})});return}if(t.key===`Meta`)return;if(l){t.preventDefault();return}let r=t.key===`Backspace`,s=t.key===`Delete`,c=t.key.length===1&&!t.ctrlKey&&!t.altKey&&!t.metaKey;!r&&!s&&!c||requestAnimationFrame(()=>{let e=n.selectionStart??n.value.length;if(r){let e=M(n.value,i);if(e){d(n,e);return}}o>0&&(t.key===`.`||t.key===`,`)&&t.key!==a&&e>0&&n.value[e-1]===t.key&&(n.value=n.value.slice(0,e-1)+a+n.value.slice(e)),d(n,(L(t.key)?N(n.value,e,t.key,i):null)??k(n.value,e,i))})};return e.addEventListener(`paste`,f),e.addEventListener(u,p),()=>{e.removeEventListener(`paste`,f),e.removeEventListener(u,p),e.removeAttribute(F);for(let t of s)e.removeAttribute(t)}}exports.Mask=m,exports.applyDecimalMask=k,exports.applyMask=l,exports.bind=x,exports.bindDecimal=R,exports.buildMask=h,exports.formatDecimalValue=P,exports.getMaxLength=p,exports.process=g,exports.processDecimal=A,exports.unmaskDecimal=j;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});function e(e){return e>=`0`&&e<=`9`}function t(e){return e>=`a`&&e<=`z`||e>=`A`&&e<=`Z`}function n(e){return e===`9`||e===`Z`||e===`A`}function r(n,r){return r===`9`?e(n):r===`Z`?t(n):e(n)||t(n)}function i(e,t,n){let i=``,a=``,o=0,s=0,c=!1;for(let l=0;l<t.length;l++){let u=t[l];if(u!==`9`&&u!==`Z`&&u!==`A`){a+=u;continue}let d=!1;for(;o<e.length;){let t=e[o++];if(r(t,u)){i+=a+t,a=``,d=!0,c||(o<=n?s=i.length:c=!0);break}}if(!d)break}return c||(s=i.length),{value:i,caret:s}}const a=new Map;function o(e){let t=a.get(e);if(t)return t;let r=[],i=0;for(;i<e.length;){let t=i,a=n(e[i]);for(;i<e.length&&n(e[i])===a;)i++;let o=e.slice(t,i);r.push(a?{kind:`slots`,chars:o}:{kind:`literal`,text:o})}return a.set(e,r),r}function s(e,t){let n=0;for(let r=t;r<e.length;r++){let t=e[r];t.kind===`slots`&&(n+=t.chars.length)}return n}function c(n,r){let i=0;for(let a=r;a<n.length;a++){let r=n[a];(e(r)||t(r))&&i++}return i}function l(e,t,n){let i=o(t),a=``,l=``,u=0,d=0,f=!1,p=!1;for(let t=0;t<i.length&&!p;t++){let o=i[t];if(o.kind===`literal`){l+=o.text,e.startsWith(o.text,u)&&(u+=o.text.length);continue}let m=i[t+1],h=s(i,t+1);for(let t=0;t<o.chars.length;t++){let i=o.chars[t],s=!1;for(;u<e.length;){let t=e[u];if(r(t,i)){u++,a+=l+t,l=``,s=!0,f||(u<=n?d=a.length:f=!0);break}if(m?.kind===`literal`&&e.startsWith(m.text,u)&&c(e,u)<=h)break;u++}if(!s){u>=e.length&&(p=!0);break}}}return f||(d=a.length),{value:a,caret:d}}function u(e,t,n=0,r){return e?r?.segmented===!1?i(e,t,n):l(e,t,n):{value:``,caret:0}}function d(e){let t=0;for(let n of e)(n>=`0`&&n<=`9`||n>=`a`&&n<=`z`||n>=`A`&&n<=`Z`)&&t++;return t}function f(e){let t=0;for(let n of e)(n===`9`||n===`Z`||n===`A`)&&t++;return t}function p(e,t){if(!Array.isArray(t))return t;let n=d(e),r=0;for(;r<t.length-1&&n>f(t[r]);)r++;return t[r]}function m(e){return Array.isArray(e)?e.length>0?Math.max(...e.map(e=>e.length)):0:e.length}var h=class{caret;_value;_mask;_options;constructor(e,t,n=0,r){this._value=e,this._mask=t,this.caret=n,this._options=r}process(){let e=u(this._value,this._mask,this.caret,this._options);return this.caret=e.caret,e.value}};function g(e,t,n=0,r){return new h(e,p(e,t),n,r)}function _(e,t,n){return g(e,t,0,n).process()}let v;function y(){return v===void 0&&(v=typeof navigator<`u`&&/iPad|iPhone|iPod/i.test(navigator.userAgent)),v}const b=`data-masked`;function x(e){return e==null?{}:typeof e==`function`?{onChange:e}:e}function S(e,t,n){if(e.getAttribute(b)!==null)return()=>{};let{onChange:r,segmented:i}=x(n),a=[],o=(t,n)=>{e.hasAttribute(t)||(e.setAttribute(t,n),a.push(t))},s=m(t);e.setAttribute(b,Array.isArray(t)?t.join(`|`):t),o(`autocomplete`,`off`),o(`autocorrect`,`off`),o(`autocapitalize`,`off`),o(`spellcheck`,`false`),o(`maxlength`,String(s));let c=!1,l=y()?`keyup`:`keydown`,u=new Set,d=e=>{let t=requestAnimationFrame(()=>{u.delete(t),e()});u.add(t)},f=e=>{let n=e.target;d(()=>{n.value=g(n.value,t,0,{segmented:i}).process(),r?.(n.value)})},p=e=>{let n=e,a=n.target,o=a.value;if(!n.key){c=!0,d(()=>{let e=a.selectionStart??999,n=g(a.value,t,e,{segmented:i});a.value=n.process(),a.setSelectionRange(n.caret,n.caret),d(()=>{c=!1})});return}if(n.key===`Meta`)return;let l=n.key===`Backspace`,u=n.key===`Delete`,f=n.key.length===1&&!n.ctrlKey&&!n.altKey&&!n.metaKey,p=n.key===`Unidentified`;if(f&&a.selectionStart===a.selectionEnd&&o.length>=s&&!y()){n.preventDefault();return}if(c){n.preventDefault();return}d(()=>{let e=a.selectionStart??999,n=g(a.value,t,e,{segmented:i});if(a.value=n.process(),p){let t=a.value.length>o.length?n.caret:e;a.setSelectionRange(t,t)}else if(u){let t=o.length===a.value.length?e+1:e;a.setSelectionRange(t,t)}else l?a.setSelectionRange(e,e):f&&a.setSelectionRange(n.caret,n.caret);r?.(a.value)})};return e.addEventListener(`paste`,f),e.addEventListener(l,p),()=>{e.removeEventListener(`paste`,f),e.removeEventListener(l,p),e.removeAttribute(b);for(let t of a)e.removeAttribute(t);for(let e of u)cancelAnimationFrame(e);u.clear()}}function C(e){return e>=`0`&&e<=`9`}function w(e){let t=e?.decimalPlaces,n=t!=null&&Number.isFinite(t)?Math.max(0,Math.floor(t)):void 0,r=e?.numberPlaces;return{decimalPlaces:n,numberPlaces:r!=null&&Number.isFinite(r)?Math.max(1,Math.floor(r)):void 0,segmented:e?.segmented??!0,separator:e?.separator??`,`,decimalSeparator:e?.decimalSeparator??`.`,prefix:e?.prefix??``,suffix:e?.suffix??``,allowNegative:e?.allowNegative??!1}}function T(e){let t=0;for(;t<e.length-1&&e[t]===`0`;)t++;return e.slice(t)}function E(e,t){if(!t||e.length<=3)return e;let n=[],r=e.length;for(;r>3;)n.unshift(e.slice(r-3,r)),r-=3;return n.unshift(e.slice(0,r)),n.join(t)}function D(e,t){if(t<=0)return 0;let n=0;for(let r=0;r<e.length;r++)if(C(e[r])&&(n++,n===t))return r+1;return e.length}function O(e,t){let n=``,r=``,i=!1,a=!1,o=t.decimalPlaces!==0;for(let s of e){if(C(s)){a?(t.decimalPlaces==null||r.length<t.decimalPlaces)&&(r+=s):(t.numberPlaces==null||n.length<t.numberPlaces)&&(n+=s);continue}if(o&&!a&&s===t.decimalSeparator){a=!0;continue}s===`-`&&t.allowNegative&&(i=!0)}return{isNegative:i,intDigits:n,fracDigits:r,hasSeparator:a}}function k(e,t,n){let r=n.decimalPlaces!==0,i=!1,a=0;for(let o=0;o<t;o++){let t=e[o];if(C(t)){i?(n.decimalPlaces==null||a<n.decimalPlaces)&&a++:(n.numberPlaces==null||a<n.numberPlaces)&&a++;continue}r&&!i&&t===n.decimalSeparator&&(i=!0,a=0)}return{inFraction:i,digitsBefore:a}}function A(e,t=0,n){let r=w(n);if(!e)return{value:``,caret:0};let{isNegative:i,intDigits:a,fracDigits:o,hasSeparator:s}=O(e,r);if(a===``&&o===``&&!s)return{value:``,caret:0};let c=T(a||`0`),l=r.numberPlaces==null?c:c.padStart(r.numberPlaces,`0`),u=r.segmented?E(l,r.separator):l,d=r.decimalPlaces!=null&&r.decimalPlaces>0?o.padEnd(r.decimalPlaces,`0`):o,f=u+(r.decimalPlaces!==0&&(r.decimalPlaces!=null||s)?r.decimalSeparator+d:``),p=i?`-`:``,m=p+r.prefix+f+r.suffix,{inFraction:h,digitsBefore:g}=k(e,Math.max(0,Math.min(t,e.length)),r),_=p.length+r.prefix.length,v=l.length-c.length;return{value:m,caret:h?_+u.length+r.decimalSeparator.length+g:_+D(u,g+v)}}function j(e,t){return A(e,e.length,t).value}function M(e,t){let{isNegative:n,intDigits:r,fracDigits:i}=O(e,w(t)),a=Number(i?`${r||`0`}.${i}`:r||`0`);return n?-a:a}function N(e,t){let n=w(t);if(n.decimalPlaces==null||n.decimalPlaces<=0)return null;let{isNegative:r,intDigits:i,hasSeparator:a}=O(e,n);if(a||i.length<n.decimalPlaces+1)return null;let o=i.length-n.decimalPlaces,s=i.slice(o),c=i.slice(0,o-1),l=r?`-`:``;return A(l+c+n.decimalSeparator+s,l.length+c.length,n)}function P(e,t,n,r){let i=w(r),a=t-1;if(a<0||e[a]!==n)return null;let{isNegative:o,intDigits:s,fracDigits:c,hasSeparator:l}=O(e.slice(0,a)+e.slice(t),i),u=T(s||`0`),d=u!==`0`,f=d&&i.numberPlaces!=null&&u.length<i.numberPlaces;if(d&&!f)return null;let p=+!!o+i.prefix.length;if(a<p||a>p+s.length)return null;let m=o?`-`:``,h=(d?u:``)+n;return A(m+h+(l?i.decimalSeparator+c:``),m.length+h.length,i)}function F(e,t){let n=w(t);if(!Number.isFinite(e))return``;let r=n.allowNegative&&e<0,i=Math.abs(e),a=n.decimalPlaces==null?String(i):i.toFixed(n.decimalPlaces),o=a.indexOf(`.`),s=o===-1?a:a.slice(0,o),c=o===-1?``:a.slice(o+1),l=T(s||`0`),u=n.numberPlaces==null?l:l.padStart(n.numberPlaces,`0`),d=(n.segmented?E(u,n.separator):u)+(n.decimalPlaces!==0&&c!==``?n.decimalSeparator+c:``);return(r?`-`:``)+n.prefix+d+n.suffix}const I=`data-masked`;function L(e){return e==null?{}:typeof e==`function`?{onChange:e}:e}function R(e){return e.length===1&&e>=`0`&&e<=`9`}function z(e,t){if(e.getAttribute(I)!==null)return()=>{};let{onChange:n,...r}=L(t),i=r,{decimalSeparator:a,decimalPlaces:o}=w(i),s=[],c=(t,n)=>{e.hasAttribute(t)||(e.setAttribute(t,n),s.push(t))};e.setAttribute(I,`decimal`),c(`autocomplete`,`off`),c(`autocorrect`,`off`),c(`autocapitalize`,`off`),c(`spellcheck`,`false`);let l=!1,u=y()?`keyup`:`keydown`,d=new Set,f=e=>{let t=requestAnimationFrame(()=>{d.delete(t),e()});d.add(t)},p=(e,t)=>{e.value=t.value,e.setSelectionRange(t.caret,t.caret),n?.(t.value,M(t.value,i))},m=e=>{let t=e.target;f(()=>{p(t,A(t.value,t.value.length,i))})},h=e=>{let t=e,n=t.target;if(!t.key){l=!0,f(()=>{let e=n.selectionStart??n.value.length;p(n,A(n.value,e,i)),f(()=>{l=!1})});return}if(t.key===`Meta`)return;if(l){t.preventDefault();return}let r=t.key===`Backspace`,s=t.key===`Delete`,c=t.key.length===1&&!t.ctrlKey&&!t.altKey&&!t.metaKey;!r&&!s&&!c||f(()=>{let e=n.selectionStart??n.value.length;if(r){let e=N(n.value,i);if(e){p(n,e);return}}o!==0&&(t.key===`.`||t.key===`,`)&&t.key!==a&&e>0&&n.value[e-1]===t.key&&(n.value=n.value.slice(0,e-1)+a+n.value.slice(e)),p(n,(R(t.key)?P(n.value,e,t.key,i):null)??A(n.value,e,i))})};return e.addEventListener(`paste`,m),e.addEventListener(u,h),()=>{e.removeEventListener(`paste`,m),e.removeEventListener(u,h),e.removeAttribute(I);for(let t of s)e.removeAttribute(t);for(let e of d)cancelAnimationFrame(e);d.clear()}}exports.Mask=h,exports.applyDecimalMask=A,exports.applyMask=u,exports.bind=S,exports.bindDecimal=z,exports.buildMask=g,exports.formatDecimalValue=F,exports.getMaxLength=m,exports.process=_,exports.processDecimal=j,exports.unmaskDecimal=M;
2
2
  //# sourceMappingURL=mother-mask.cjs.map