react-input-mask-format 1.0.4 → 2.0.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/dist/index.cjs ADDED
@@ -0,0 +1,883 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.tsx
31
+ var src_exports = {};
32
+ __export(src_exports, {
33
+ default: () => src_default
34
+ });
35
+ module.exports = __toCommonJS(src_exports);
36
+ var import_react2 = __toESM(require("react"), 1);
37
+
38
+ // src/hooks.ts
39
+ var import_react = require("react");
40
+
41
+ // src/utils/defer.ts
42
+ function defer(fn) {
43
+ return requestAnimationFrame(fn);
44
+ }
45
+ function cancelDefer(deferId) {
46
+ if (deferId !== null) {
47
+ cancelAnimationFrame(deferId);
48
+ }
49
+ }
50
+
51
+ // src/utils/input.ts
52
+ function setInputSelection(input, start, end) {
53
+ if (end === void 0) {
54
+ end = start;
55
+ }
56
+ input.setSelectionRange(start, end);
57
+ }
58
+ function getInputSelection(input) {
59
+ const start = input.selectionStart;
60
+ const end = input.selectionEnd;
61
+ return {
62
+ start,
63
+ end,
64
+ length: (end != null ? end : 0) - (start != null ? start : 0)
65
+ };
66
+ }
67
+ function isInputFocused(input) {
68
+ const inputDocument = input.ownerDocument;
69
+ return inputDocument.hasFocus() && inputDocument.activeElement === input;
70
+ }
71
+
72
+ // src/utils/helpers.ts
73
+ function getElementDocument(element) {
74
+ return element == null ? void 0 : element.ownerDocument;
75
+ }
76
+ function getElementWindow(element) {
77
+ var _a;
78
+ return (_a = getElementDocument(element)) == null ? void 0 : _a.defaultView;
79
+ }
80
+ function isDOMElement(element) {
81
+ const elementWindow = getElementWindow(element);
82
+ return !!elementWindow && element instanceof elementWindow.HTMLElement;
83
+ }
84
+ function isFunction(value) {
85
+ return typeof value === "function";
86
+ }
87
+ function findLastIndex(array, predicate) {
88
+ for (let i = array.length - 1; i >= 0; i--) {
89
+ const x = array[i];
90
+ if (predicate(x, i)) {
91
+ return i;
92
+ }
93
+ }
94
+ return -1;
95
+ }
96
+ function repeat(string, n = 1) {
97
+ let result = "";
98
+ for (let i = 0; i < n; i++) {
99
+ result += string;
100
+ }
101
+ return result;
102
+ }
103
+ function toString(value) {
104
+ return `${value}`;
105
+ }
106
+
107
+ // src/hooks.ts
108
+ function useInputElement(inputRef) {
109
+ return (0, import_react.useCallback)(() => {
110
+ let input = inputRef.current;
111
+ const isDOMNode = typeof window !== "undefined" && isDOMElement(input);
112
+ if (!input || !isDOMNode) {
113
+ return null;
114
+ }
115
+ if (input.nodeName !== "INPUT") {
116
+ input = input.querySelector("input");
117
+ }
118
+ if (!input) {
119
+ throw new Error("react-input-mask: inputComponent doesn't contain input node");
120
+ }
121
+ return input;
122
+ }, [inputRef]);
123
+ }
124
+ function useDeferLoop(callback) {
125
+ const deferIdRef = (0, import_react.useRef)(null);
126
+ const runLoop = (0, import_react.useCallback)(() => {
127
+ if (deferIdRef.current !== null) {
128
+ return;
129
+ }
130
+ function loop() {
131
+ callback();
132
+ deferIdRef.current = defer(loop);
133
+ }
134
+ loop();
135
+ }, [callback]);
136
+ const stopLoop = (0, import_react.useCallback)(() => {
137
+ cancelDefer(deferIdRef.current);
138
+ deferIdRef.current = null;
139
+ }, []);
140
+ (0, import_react.useEffect)(() => {
141
+ if (deferIdRef.current) {
142
+ stopLoop();
143
+ runLoop();
144
+ }
145
+ }, [runLoop, stopLoop]);
146
+ (0, import_react.useEffect)(() => cancelDefer(deferIdRef.current), []);
147
+ return [runLoop, stopLoop];
148
+ }
149
+ function useSelection(inputRef, isMasked) {
150
+ const selectionRef = (0, import_react.useRef)({ start: null, end: null });
151
+ const getInputElement = useInputElement(inputRef);
152
+ const getSelection = (0, import_react.useCallback)(() => {
153
+ const input = getInputElement();
154
+ return getInputSelection(input);
155
+ }, [getInputElement]);
156
+ const getLastSelection = (0, import_react.useCallback)(() => {
157
+ return selectionRef.current;
158
+ }, []);
159
+ const setSelection = (0, import_react.useCallback)(
160
+ (selection) => {
161
+ const input = getInputElement();
162
+ if (!input || !isInputFocused(input)) {
163
+ return;
164
+ }
165
+ setInputSelection(input, selection.start, selection.end);
166
+ selectionRef.current = getSelection();
167
+ },
168
+ [getInputElement, getSelection]
169
+ );
170
+ const selectionLoop = (0, import_react.useCallback)(() => {
171
+ selectionRef.current = getSelection();
172
+ }, [getSelection]);
173
+ const [runSelectionLoop, stopSelectionLoop] = useDeferLoop(selectionLoop);
174
+ (0, import_react.useLayoutEffect)(() => {
175
+ if (!isMasked) {
176
+ return;
177
+ }
178
+ const input = getInputElement();
179
+ if (!input) return;
180
+ input.addEventListener("focus", runSelectionLoop);
181
+ input.addEventListener("blur", stopSelectionLoop);
182
+ if (isInputFocused(input)) {
183
+ runSelectionLoop();
184
+ }
185
+ return () => {
186
+ input.removeEventListener("focus", runSelectionLoop);
187
+ input.removeEventListener("blur", stopSelectionLoop);
188
+ stopSelectionLoop();
189
+ };
190
+ });
191
+ return { getSelection, getLastSelection, setSelection };
192
+ }
193
+ function useValue(inputRef, initialValue) {
194
+ const getInputElement = useInputElement(inputRef);
195
+ const valueRef = (0, import_react.useRef)(initialValue);
196
+ const getValue = (0, import_react.useCallback)(() => {
197
+ return getInputElement().value;
198
+ }, [getInputElement]);
199
+ const getLastValue = (0, import_react.useCallback)(() => {
200
+ return valueRef.current;
201
+ }, []);
202
+ const setValue = (0, import_react.useCallback)(
203
+ (newValue) => {
204
+ valueRef.current = newValue;
205
+ const input = getInputElement();
206
+ if (input) {
207
+ input.value = newValue;
208
+ }
209
+ },
210
+ [getInputElement]
211
+ );
212
+ return {
213
+ getValue,
214
+ getLastValue,
215
+ setValue
216
+ };
217
+ }
218
+ function useInputState(initialValue, isMasked) {
219
+ const inputRef = (0, import_react.useRef)(null);
220
+ const { getSelection, getLastSelection, setSelection } = useSelection(inputRef, isMasked);
221
+ const { getValue, getLastValue, setValue } = useValue(inputRef, initialValue);
222
+ function getLastInputState() {
223
+ return {
224
+ value: getLastValue(),
225
+ selection: getLastSelection()
226
+ };
227
+ }
228
+ function getInputState() {
229
+ return {
230
+ value: getValue(),
231
+ selection: getSelection()
232
+ };
233
+ }
234
+ function setInputState({ value, selection }) {
235
+ setValue(value);
236
+ setSelection(selection);
237
+ }
238
+ return {
239
+ inputRef,
240
+ getInputState,
241
+ getLastInputState,
242
+ setInputState
243
+ };
244
+ }
245
+ function usePrevious(value) {
246
+ const ref = (0, import_react.useRef)(void 0);
247
+ (0, import_react.useEffect)(() => {
248
+ ref.current = value;
249
+ });
250
+ return ref.current;
251
+ }
252
+
253
+ // src/constants.ts
254
+ var CONTROLLED_PROPS = [
255
+ "disabled",
256
+ "onBlur",
257
+ "onChange",
258
+ "onFocus",
259
+ "onMouseDown",
260
+ "readOnly",
261
+ "value"
262
+ ];
263
+ var defaultFormatChars = {
264
+ "9": /[0-9]/,
265
+ a: /[A-Za-z]/,
266
+ "*": /[A-Za-z0-9]/
267
+ };
268
+
269
+ // src/validate-props.ts
270
+ function warnDev(condition, message) {
271
+ if (process.env.NODE_ENV !== "production" && !condition) {
272
+ console.error(`react-input-mask-format: ${message}`);
273
+ }
274
+ }
275
+ function invariant(condition, message) {
276
+ if (!condition) {
277
+ throw new Error(`react-input-mask-format: ${message}`);
278
+ }
279
+ }
280
+ function validateMaxLength(props) {
281
+ warnDev(
282
+ !props.maxLength || !props.mask,
283
+ "maxLength property shouldn't be passed to the masked input. It breaks masking and unnecessary because length is limited by the mask length."
284
+ );
285
+ }
286
+ function validateMaskPlaceholder(props) {
287
+ const { mask, maskPlaceholder } = props;
288
+ invariant(
289
+ !mask || !maskPlaceholder || maskPlaceholder.length === 1 || maskPlaceholder.length === mask.length,
290
+ `maskPlaceholder should either be a single character or have the same length as the mask:
291
+ mask: ${mask}
292
+ maskPlaceholder: ${maskPlaceholder}`
293
+ );
294
+ }
295
+ function validateChildren(props, inputElement) {
296
+ const conflictProps = CONTROLLED_PROPS.filter(
297
+ (propId) => inputElement.props[propId] != null && inputElement.props[propId] !== props[propId]
298
+ );
299
+ invariant(
300
+ !conflictProps.length,
301
+ `the following props should be passed to the InputMask component, not to children: ${conflictProps.join(",")}`
302
+ );
303
+ }
304
+
305
+ // src/utils/parse-mask.ts
306
+ function parseMask({
307
+ mask,
308
+ maskPlaceholder,
309
+ formatChars = defaultFormatChars
310
+ }) {
311
+ const permanents = [];
312
+ if (!mask) {
313
+ return {
314
+ maskPlaceholder: null,
315
+ mask: null,
316
+ prefix: null,
317
+ lastEditablePosition: null,
318
+ permanents: []
319
+ };
320
+ }
321
+ let parsedMask;
322
+ if (typeof mask === "string") {
323
+ let isPermanent = false;
324
+ let parsedMaskString = "";
325
+ mask.split("").forEach((character) => {
326
+ if (!isPermanent && character === "\\") {
327
+ isPermanent = true;
328
+ } else {
329
+ if (isPermanent || !formatChars[character]) {
330
+ permanents.push(parsedMaskString.length);
331
+ }
332
+ parsedMaskString += character;
333
+ isPermanent = false;
334
+ }
335
+ });
336
+ parsedMask = parsedMaskString.split("").map((character, index) => {
337
+ if (permanents.indexOf(index) === -1) {
338
+ return formatChars[character];
339
+ }
340
+ return character;
341
+ });
342
+ } else {
343
+ mask.forEach((character, index) => {
344
+ if (typeof character === "string") {
345
+ permanents.push(index);
346
+ }
347
+ });
348
+ parsedMask = mask;
349
+ }
350
+ let parsedPlaceholder = maskPlaceholder != null ? maskPlaceholder : null;
351
+ if (parsedPlaceholder) {
352
+ let placeholderChars;
353
+ if (parsedPlaceholder.length === 1) {
354
+ placeholderChars = parsedMask.map((character, index) => {
355
+ if (permanents.indexOf(index) !== -1) {
356
+ return character;
357
+ }
358
+ return parsedPlaceholder;
359
+ });
360
+ } else {
361
+ placeholderChars = parsedPlaceholder.split("");
362
+ }
363
+ permanents.forEach((position) => {
364
+ placeholderChars[position] = parsedMask[position];
365
+ });
366
+ parsedPlaceholder = placeholderChars.join("");
367
+ }
368
+ const prefix = permanents.filter((position, index) => position === index).map((position) => parsedMask[position]).join("");
369
+ let lastEditablePosition = parsedMask.length - 1;
370
+ while (permanents.indexOf(lastEditablePosition) !== -1) {
371
+ lastEditablePosition--;
372
+ }
373
+ return {
374
+ maskPlaceholder: parsedPlaceholder,
375
+ prefix,
376
+ mask: parsedMask,
377
+ lastEditablePosition,
378
+ permanents
379
+ };
380
+ }
381
+
382
+ // src/utils/mask.ts
383
+ var MaskUtils = class {
384
+ constructor(options) {
385
+ this.isCharacterAllowedAtPosition = (character, position) => {
386
+ const { maskPlaceholder } = this.maskOptions;
387
+ if (this.isCharacterFillingPosition(character, position)) {
388
+ return true;
389
+ }
390
+ if (!maskPlaceholder) {
391
+ return false;
392
+ }
393
+ return maskPlaceholder[position] === character;
394
+ };
395
+ this.isCharacterFillingPosition = (character, position) => {
396
+ const { mask } = this.maskOptions;
397
+ if (!character || position >= mask.length) {
398
+ return false;
399
+ }
400
+ if (!this.isPositionEditable(position)) {
401
+ return mask[position] === character;
402
+ }
403
+ const charRule = mask[position];
404
+ return new RegExp(charRule).test(character);
405
+ };
406
+ this.isPositionEditable = (position) => {
407
+ const { mask, permanents } = this.maskOptions;
408
+ return position < mask.length && permanents.indexOf(position) === -1;
409
+ };
410
+ this.isValueEmpty = (value) => {
411
+ return value.split("").every((character, position) => {
412
+ return !this.isPositionEditable(position) || !this.isCharacterFillingPosition(character, position);
413
+ });
414
+ };
415
+ this.isValueFilled = (value) => {
416
+ return this.getFilledLength(value) === this.maskOptions.lastEditablePosition + 1;
417
+ };
418
+ this.getDefaultSelectionForValue = (value) => {
419
+ const filledLength = this.getFilledLength(value);
420
+ const cursorPosition = this.getRightEditablePosition(filledLength);
421
+ return { start: cursorPosition, end: cursorPosition };
422
+ };
423
+ this.getFilledLength = (value) => {
424
+ const characters = value.split("");
425
+ const lastFilledIndex = findLastIndex(characters, (character, position) => {
426
+ return this.isPositionEditable(position) && this.isCharacterFillingPosition(character, position);
427
+ });
428
+ return lastFilledIndex + 1;
429
+ };
430
+ this.getStringFillingLengthAtPosition = (string, position) => {
431
+ const characters = string.split("");
432
+ const insertedValue = characters.reduce((value, character) => {
433
+ return this.insertCharacterAtPosition(value, character, value.length);
434
+ }, repeat(" ", position));
435
+ return insertedValue.length - position;
436
+ };
437
+ this.getLeftEditablePosition = (position) => {
438
+ for (let i = position; i >= 0; i--) {
439
+ if (this.isPositionEditable(i)) {
440
+ return i;
441
+ }
442
+ }
443
+ return null;
444
+ };
445
+ this.getRightEditablePosition = (position) => {
446
+ const { mask } = this.maskOptions;
447
+ for (let i = position; i < mask.length; i++) {
448
+ if (this.isPositionEditable(i)) {
449
+ return i;
450
+ }
451
+ }
452
+ return null;
453
+ };
454
+ this.formatValue = (value) => {
455
+ const { maskPlaceholder, mask } = this.maskOptions;
456
+ if (!maskPlaceholder) {
457
+ value = this.insertStringAtPosition("", value, 0);
458
+ while (value.length < mask.length && !this.isPositionEditable(value.length)) {
459
+ value += mask[value.length];
460
+ }
461
+ return value;
462
+ }
463
+ return this.insertStringAtPosition(maskPlaceholder, value, 0);
464
+ };
465
+ this.clearRange = (value, start, len) => {
466
+ if (!len) {
467
+ return value;
468
+ }
469
+ const end = start + len;
470
+ const { maskPlaceholder, mask } = this.maskOptions;
471
+ const clearedValue = value.split("").map((character, i) => {
472
+ const isEditable = this.isPositionEditable(i);
473
+ if (!maskPlaceholder && i >= end && !isEditable) {
474
+ return "";
475
+ }
476
+ if (i < start || i >= end) {
477
+ return character;
478
+ }
479
+ if (!isEditable) {
480
+ return mask[i];
481
+ }
482
+ if (maskPlaceholder) {
483
+ return maskPlaceholder[i];
484
+ }
485
+ return "";
486
+ }).join("");
487
+ return this.formatValue(clearedValue);
488
+ };
489
+ this.insertCharacterAtPosition = (value, character, position) => {
490
+ const { mask, maskPlaceholder } = this.maskOptions;
491
+ if (position >= mask.length) {
492
+ return value;
493
+ }
494
+ const isAllowed = this.isCharacterAllowedAtPosition(character, position);
495
+ const isEditable = this.isPositionEditable(position);
496
+ const nextEditablePosition = this.getRightEditablePosition(position);
497
+ const isNextPlaceholder = maskPlaceholder && nextEditablePosition ? character === maskPlaceholder[nextEditablePosition] : null;
498
+ const valueBefore = value.slice(0, position);
499
+ if (isAllowed || !isEditable) {
500
+ const insertedCharacter = isAllowed ? character : mask[position];
501
+ value = valueBefore + insertedCharacter;
502
+ }
503
+ if (!isAllowed && !isEditable && !isNextPlaceholder) {
504
+ value = this.insertCharacterAtPosition(value, character, position + 1);
505
+ }
506
+ return value;
507
+ };
508
+ this.insertStringAtPosition = (value, string, position) => {
509
+ const { mask, maskPlaceholder } = this.maskOptions;
510
+ if (!string || position >= mask.length) {
511
+ return value;
512
+ }
513
+ const characters = string.split("");
514
+ const isFixedLength = this.isValueFilled(value) || !!maskPlaceholder;
515
+ const valueAfter = value.slice(position);
516
+ value = characters.reduce((value2, character) => {
517
+ return this.insertCharacterAtPosition(value2, character, value2.length);
518
+ }, value.slice(0, position));
519
+ if (isFixedLength) {
520
+ value += valueAfter.slice(value.length - position);
521
+ } else if (this.isValueFilled(value)) {
522
+ value += mask.slice(value.length).join("");
523
+ } else {
524
+ const editableCharactersAfter = valueAfter.split("").filter((character, i) => {
525
+ return this.isPositionEditable(position + i);
526
+ });
527
+ value = editableCharactersAfter.reduce((value2, character) => {
528
+ const nextEditablePosition = this.getRightEditablePosition(
529
+ value2.length
530
+ );
531
+ if (nextEditablePosition === null) {
532
+ return value2;
533
+ }
534
+ if (!this.isPositionEditable(value2.length)) {
535
+ value2 += mask.slice(value2.length, nextEditablePosition).join("");
536
+ }
537
+ return this.insertCharacterAtPosition(value2, character, value2.length);
538
+ }, value);
539
+ }
540
+ return value;
541
+ };
542
+ this.processChange = (currentState, previousState) => {
543
+ const { mask, prefix, lastEditablePosition } = this.maskOptions;
544
+ const { value, selection } = currentState;
545
+ const previousValue = previousState.value;
546
+ const previousSelection = previousState.selection;
547
+ let newValue = value;
548
+ let enteredString = "";
549
+ let formattedEnteredStringLength = 0;
550
+ let removedLength = 0;
551
+ let cursorPosition = Math.min(previousSelection.start, selection.start);
552
+ if (selection.end > previousSelection.start) {
553
+ enteredString = newValue.slice(previousSelection.start, selection.end);
554
+ formattedEnteredStringLength = this.getStringFillingLengthAtPosition(
555
+ enteredString,
556
+ cursorPosition
557
+ );
558
+ if (!formattedEnteredStringLength) {
559
+ removedLength = 0;
560
+ } else {
561
+ removedLength = previousSelection.length;
562
+ }
563
+ } else if (newValue.length < previousValue.length) {
564
+ removedLength = previousValue.length - newValue.length;
565
+ }
566
+ newValue = previousValue;
567
+ if (removedLength) {
568
+ if (removedLength === 1 && !previousSelection.length) {
569
+ const deleteFromRight = previousSelection.start === selection.start;
570
+ cursorPosition = deleteFromRight ? this.getRightEditablePosition(selection.start) : this.getLeftEditablePosition(selection.start);
571
+ }
572
+ newValue = this.clearRange(newValue, cursorPosition, removedLength);
573
+ }
574
+ newValue = this.insertStringAtPosition(
575
+ newValue,
576
+ enteredString,
577
+ cursorPosition
578
+ );
579
+ cursorPosition += formattedEnteredStringLength;
580
+ if (cursorPosition >= mask.length) {
581
+ cursorPosition = mask.length;
582
+ } else if (cursorPosition < prefix.length && !formattedEnteredStringLength) {
583
+ cursorPosition = prefix.length;
584
+ } else if (cursorPosition >= prefix.length && cursorPosition < lastEditablePosition && formattedEnteredStringLength) {
585
+ cursorPosition = this.getRightEditablePosition(cursorPosition);
586
+ }
587
+ newValue = this.formatValue(newValue);
588
+ return {
589
+ value: newValue,
590
+ enteredString,
591
+ selection: { start: cursorPosition, end: cursorPosition }
592
+ };
593
+ };
594
+ this.maskOptions = parseMask(options);
595
+ }
596
+ };
597
+
598
+ // src/v2-compat.ts
599
+ var warned = /* @__PURE__ */ new Set();
600
+ function warnDeprecatedOnce(prop, message) {
601
+ if (process.env.NODE_ENV !== "production" && !warned.has(prop)) {
602
+ warned.add(prop);
603
+ console.warn(`react-input-mask-format: ${message}`);
604
+ }
605
+ }
606
+ function resolveMaskPlaceholder(maskPlaceholder, maskChar) {
607
+ if (maskPlaceholder !== void 0) {
608
+ return maskPlaceholder;
609
+ }
610
+ return maskChar;
611
+ }
612
+ function toRegExpFormatChars(formatChars) {
613
+ if (!formatChars) {
614
+ return void 0;
615
+ }
616
+ const result = {};
617
+ for (const key of Object.keys(formatChars)) {
618
+ result[key] = new RegExp(formatChars[key]);
619
+ }
620
+ return result;
621
+ }
622
+ function createBeforeMaskedStateChangeAdapter(beforeMaskedValueChange, maskOptions) {
623
+ return ({ previousState, currentState, nextState }) => {
624
+ var _a, _b;
625
+ return beforeMaskedValueChange(
626
+ nextState,
627
+ (_a = previousState != null ? previousState : currentState) != null ? _a : null,
628
+ (_b = nextState.enteredString) != null ? _b : null,
629
+ maskOptions
630
+ );
631
+ };
632
+ }
633
+
634
+ // src/index.tsx
635
+ var InputMask = (0, import_react2.forwardRef)(function InputMask2(props, forwardedRef) {
636
+ const {
637
+ alwaysShowMask = false,
638
+ children,
639
+ mask,
640
+ maskPlaceholder: maskPlaceholderProp,
641
+ beforeMaskedStateChange: beforeMaskedStateChangeProp,
642
+ maskChar,
643
+ formatChars,
644
+ beforeMaskedValueChange,
645
+ ...restProps
646
+ } = props;
647
+ if (maskChar !== void 0) {
648
+ warnDeprecatedOnce("maskChar", "maskChar is deprecated, use maskPlaceholder instead. See migration guide: https://github.com/Temirtator/react-input-mask-format#migrating-from-react-input-mask");
649
+ }
650
+ if (formatChars !== void 0) {
651
+ warnDeprecatedOnce("formatChars", "formatChars is deprecated, prefer an array mask with RegExps. See migration guide: https://github.com/Temirtator/react-input-mask-format#migrating-from-react-input-mask");
652
+ }
653
+ if (beforeMaskedValueChange !== void 0) {
654
+ warnDeprecatedOnce("beforeMaskedValueChange", "beforeMaskedValueChange is deprecated, use beforeMaskedStateChange. See migration guide: https://github.com/Temirtator/react-input-mask-format#migrating-from-react-input-mask");
655
+ }
656
+ const resolvedPlaceholder = resolveMaskPlaceholder(maskPlaceholderProp, maskChar);
657
+ const maskPlaceholder = resolvedPlaceholder === void 0 ? "_" : resolvedPlaceholder;
658
+ validateMaxLength(props);
659
+ validateMaskPlaceholder({ ...props, maskPlaceholder });
660
+ const maskUtils = new MaskUtils({
661
+ mask,
662
+ maskPlaceholder,
663
+ formatChars: toRegExpFormatChars(formatChars)
664
+ });
665
+ let beforeMaskedStateChange = beforeMaskedStateChangeProp;
666
+ if (!beforeMaskedStateChange && beforeMaskedValueChange) {
667
+ const v2MaskOptions = {
668
+ mask,
669
+ maskChar: maskPlaceholder,
670
+ alwaysShowMask,
671
+ formatChars: formatChars != null ? formatChars : { "9": "[0-9]", a: "[A-Za-z]", "*": "[A-Za-z0-9]" },
672
+ permanents: maskUtils.maskOptions.permanents
673
+ };
674
+ beforeMaskedStateChange = createBeforeMaskedStateChangeAdapter(
675
+ beforeMaskedValueChange,
676
+ v2MaskOptions
677
+ );
678
+ }
679
+ const isMasked = !!mask;
680
+ const isEditable = !restProps.disabled && !restProps.readOnly;
681
+ const isControlled = props.value !== null && props.value !== void 0;
682
+ const previousIsMasked = usePrevious(isMasked);
683
+ const initialValue = toString(
684
+ (isControlled ? props.value : props.defaultValue) || ""
685
+ );
686
+ const {
687
+ inputRef,
688
+ getInputState,
689
+ setInputState,
690
+ getLastInputState
691
+ } = useInputState(initialValue, isMasked);
692
+ const getInputElement = useInputElement(inputRef);
693
+ function onChange(event) {
694
+ const currentState = getInputState();
695
+ const previousState = getLastInputState();
696
+ let newInputState = maskUtils.processChange(currentState, previousState);
697
+ if (beforeMaskedStateChange) {
698
+ newInputState = beforeMaskedStateChange({
699
+ currentState,
700
+ previousState,
701
+ nextState: newInputState
702
+ });
703
+ }
704
+ setInputState(newInputState);
705
+ if (props.onChange) {
706
+ props.onChange(event);
707
+ }
708
+ }
709
+ function onFocus(event) {
710
+ inputRef.current = event.target;
711
+ const currentValue = getInputState().value;
712
+ if (isMasked && !maskUtils.isValueFilled(currentValue)) {
713
+ let newValue = maskUtils.formatValue(currentValue);
714
+ let newSelection = maskUtils.getDefaultSelectionForValue(newValue);
715
+ let newInputState = {
716
+ value: newValue,
717
+ selection: newSelection
718
+ };
719
+ if (beforeMaskedStateChange) {
720
+ newInputState = beforeMaskedStateChange({
721
+ currentState: getInputState(),
722
+ nextState: newInputState
723
+ });
724
+ newValue = newInputState.value;
725
+ newSelection = newInputState.selection;
726
+ }
727
+ setInputState(newInputState);
728
+ if (newValue !== currentValue && props.onChange) {
729
+ props.onChange(event);
730
+ }
731
+ defer(() => {
732
+ setInputState(getLastInputState());
733
+ });
734
+ }
735
+ if (props.onFocus) {
736
+ props.onFocus(event);
737
+ }
738
+ }
739
+ function onBlur(event) {
740
+ const currentValue = getInputState().value;
741
+ const lastValue = getLastInputState().value;
742
+ if (isMasked && !alwaysShowMask && maskUtils.isValueEmpty(lastValue)) {
743
+ let newValue = "";
744
+ let newInputState = {
745
+ value: newValue,
746
+ selection: { start: null, end: null }
747
+ };
748
+ if (beforeMaskedStateChange) {
749
+ newInputState = beforeMaskedStateChange({
750
+ currentState: getInputState(),
751
+ nextState: newInputState
752
+ });
753
+ newValue = newInputState.value;
754
+ }
755
+ setInputState(newInputState);
756
+ if (newValue !== currentValue && props.onChange) {
757
+ props.onChange(event);
758
+ }
759
+ }
760
+ if (props.onBlur) {
761
+ props.onBlur(event);
762
+ }
763
+ }
764
+ function onMouseDown(event) {
765
+ const input = getInputElement();
766
+ const { value } = getInputState();
767
+ const inputDocument = getElementDocument(input);
768
+ if (!isInputFocused(input) && !maskUtils.isValueFilled(value)) {
769
+ const mouseDownX = event.clientX;
770
+ const mouseDownY = event.clientY;
771
+ const mouseDownTime = (/* @__PURE__ */ new Date()).getTime();
772
+ const mouseUpHandler = (mouseUpEvent) => {
773
+ inputDocument.removeEventListener("mouseup", mouseUpHandler);
774
+ if (!isInputFocused(input)) {
775
+ return;
776
+ }
777
+ const deltaX = Math.abs(mouseUpEvent.clientX - mouseDownX);
778
+ const deltaY = Math.abs(mouseUpEvent.clientY - mouseDownY);
779
+ const axisDelta = Math.max(deltaX, deltaY);
780
+ const timeDelta = (/* @__PURE__ */ new Date()).getTime() - mouseDownTime;
781
+ if (axisDelta <= 10 && timeDelta <= 200 || axisDelta <= 5 && timeDelta <= 300) {
782
+ const lastState = getLastInputState();
783
+ const newSelection = maskUtils.getDefaultSelectionForValue(
784
+ lastState.value
785
+ );
786
+ const newState = {
787
+ ...lastState,
788
+ selection: newSelection
789
+ };
790
+ setInputState(newState);
791
+ }
792
+ };
793
+ inputDocument.addEventListener("mouseup", mouseUpHandler);
794
+ }
795
+ if (props.onMouseDown) {
796
+ props.onMouseDown(event);
797
+ }
798
+ }
799
+ let renderValue = props.value;
800
+ if (isMasked && isControlled) {
801
+ const input = getInputElement();
802
+ const isFocused = !!input && isInputFocused(input);
803
+ let newValue = isFocused || alwaysShowMask || props.value ? maskUtils.formatValue(props.value) : props.value;
804
+ if (beforeMaskedStateChange) {
805
+ newValue = beforeMaskedStateChange({
806
+ nextState: { value: newValue, selection: { start: null, end: null } }
807
+ }).value;
808
+ }
809
+ renderValue = newValue;
810
+ }
811
+ const lastSelection = getLastInputState().selection;
812
+ (0, import_react2.useLayoutEffect)(() => {
813
+ if (isMasked && isControlled) {
814
+ setInputState({
815
+ ...getLastInputState(),
816
+ value: renderValue
817
+ });
818
+ }
819
+ });
820
+ (0, import_react2.useLayoutEffect)(() => {
821
+ if (!isMasked) {
822
+ return;
823
+ }
824
+ const input = getInputElement();
825
+ const isFocused = isInputFocused(input);
826
+ const previousSelection = lastSelection;
827
+ const currentState = getInputState();
828
+ let newInputState = { ...currentState };
829
+ if (!isControlled) {
830
+ const currentValue = currentState.value;
831
+ const formattedValue = maskUtils.formatValue(currentValue);
832
+ const isValueEmpty = maskUtils.isValueEmpty(formattedValue);
833
+ const shouldFormatValue = !isValueEmpty || isFocused || alwaysShowMask;
834
+ if (shouldFormatValue) {
835
+ newInputState.value = formattedValue;
836
+ } else if (isValueEmpty && !isFocused) {
837
+ newInputState.value = "";
838
+ }
839
+ }
840
+ if (isFocused && !previousIsMasked) {
841
+ newInputState.selection = maskUtils.getDefaultSelectionForValue(
842
+ newInputState.value
843
+ );
844
+ } else if (isControlled && isFocused && previousSelection) {
845
+ if (previousSelection.start !== null && previousSelection.end !== null) {
846
+ newInputState.selection = previousSelection;
847
+ }
848
+ }
849
+ if (beforeMaskedStateChange) {
850
+ newInputState = beforeMaskedStateChange({
851
+ currentState,
852
+ nextState: newInputState
853
+ });
854
+ }
855
+ setInputState(newInputState);
856
+ });
857
+ const inputProps = {
858
+ ...restProps,
859
+ onFocus,
860
+ onBlur,
861
+ onChange: isMasked && isEditable ? onChange : props.onChange,
862
+ onMouseDown: isMasked && isEditable ? onMouseDown : props.onMouseDown,
863
+ // `ref` may target either the plain <input> DOM node or, when custom
864
+ // children are used, whatever node the child's own ref forwards to.
865
+ ref: (ref) => {
866
+ inputRef.current = ref;
867
+ if (isFunction(forwardedRef)) {
868
+ forwardedRef(ref);
869
+ } else if (forwardedRef !== null && typeof forwardedRef === "object") {
870
+ forwardedRef.current = ref;
871
+ }
872
+ },
873
+ value: isMasked && isControlled ? renderValue : props.value
874
+ };
875
+ if (children) {
876
+ validateChildren(props, children);
877
+ return import_react2.default.cloneElement(children, inputProps);
878
+ }
879
+ return /* @__PURE__ */ import_react2.default.createElement("input", { ...inputProps });
880
+ });
881
+ InputMask.displayName = "InputMask";
882
+ var src_default = InputMask;
883
+ //# sourceMappingURL=index.cjs.map