react-input-mask-format 2.0.0 → 2.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 +164 -1
- package/dist/chunk-CEZXZ7IJ.js +42 -0
- package/dist/chunk-CEZXZ7IJ.js.map +1 -0
- package/dist/index.cjs +276 -18
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -51
- package/dist/index.d.ts +7 -51
- package/dist/index.js +257 -33
- package/dist/index.js.map +1 -1
- package/dist/number.cjs +342 -0
- package/dist/number.cjs.map +1 -0
- package/dist/number.d.cts +46 -0
- package/dist/number.d.ts +46 -0
- package/dist/number.js +280 -0
- package/dist/number.js.map +1 -0
- package/dist/presets.cjs +86 -0
- package/dist/presets.cjs.map +1 -0
- package/dist/presets.d.cts +18 -0
- package/dist/presets.d.ts +18 -0
- package/dist/presets.js +55 -0
- package/dist/presets.js.map +1 -0
- package/dist/types-BTNqtchO.d.cts +77 -0
- package/dist/types-BTNqtchO.d.ts +77 -0
- package/dist/validators.cjs +99 -0
- package/dist/validators.cjs.map +1 -0
- package/dist/validators.d.cts +6 -0
- package/dist/validators.d.ts +6 -0
- package/dist/validators.js +71 -0
- package/dist/validators.js.map +1 -0
- package/package.json +17 -2
package/dist/index.js
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getInputSelection,
|
|
3
|
+
isInputFocused,
|
|
4
|
+
setInputSelection,
|
|
5
|
+
setNativeValue
|
|
6
|
+
} from "./chunk-CEZXZ7IJ.js";
|
|
7
|
+
|
|
1
8
|
// src/index.tsx
|
|
2
9
|
import React, { useLayoutEffect as useLayoutEffect2, forwardRef } from "react";
|
|
3
10
|
|
|
@@ -14,27 +21,6 @@ function cancelDefer(deferId) {
|
|
|
14
21
|
}
|
|
15
22
|
}
|
|
16
23
|
|
|
17
|
-
// src/utils/input.ts
|
|
18
|
-
function setInputSelection(input, start, end) {
|
|
19
|
-
if (end === void 0) {
|
|
20
|
-
end = start;
|
|
21
|
-
}
|
|
22
|
-
input.setSelectionRange(start, end);
|
|
23
|
-
}
|
|
24
|
-
function getInputSelection(input) {
|
|
25
|
-
const start = input.selectionStart;
|
|
26
|
-
const end = input.selectionEnd;
|
|
27
|
-
return {
|
|
28
|
-
start,
|
|
29
|
-
end,
|
|
30
|
-
length: (end != null ? end : 0) - (start != null ? start : 0)
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
function isInputFocused(input) {
|
|
34
|
-
const inputDocument = input.ownerDocument;
|
|
35
|
-
return inputDocument.hasFocus() && inputDocument.activeElement === input;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
24
|
// src/utils/helpers.ts
|
|
39
25
|
function getElementDocument(element) {
|
|
40
26
|
return element == null ? void 0 : element.ownerDocument;
|
|
@@ -231,6 +217,12 @@ var defaultFormatChars = {
|
|
|
231
217
|
a: /[A-Za-z]/,
|
|
232
218
|
"*": /[A-Za-z0-9]/
|
|
233
219
|
};
|
|
220
|
+
var extendedFormatChars = {
|
|
221
|
+
...defaultFormatChars,
|
|
222
|
+
A: /[A-Z]/,
|
|
223
|
+
"\u042F": /[А-Яа-яЁёӘәҒғҚқҢңӨөҰұҮүҺһІі]/,
|
|
224
|
+
"#": /[0-9A-Fa-f]/
|
|
225
|
+
};
|
|
234
226
|
|
|
235
227
|
// src/validate-props.ts
|
|
236
228
|
function warnDev(condition, message) {
|
|
@@ -457,13 +449,14 @@ var MaskUtils = class {
|
|
|
457
449
|
if (position >= mask.length) {
|
|
458
450
|
return value;
|
|
459
451
|
}
|
|
460
|
-
const
|
|
452
|
+
const transformedCharacter = this.transform && this.isPositionEditable(position) ? this.transform(character, position) : character;
|
|
453
|
+
const isAllowed = this.isCharacterAllowedAtPosition(transformedCharacter, position);
|
|
461
454
|
const isEditable = this.isPositionEditable(position);
|
|
462
455
|
const nextEditablePosition = this.getRightEditablePosition(position);
|
|
463
|
-
const isNextPlaceholder = maskPlaceholder && nextEditablePosition ?
|
|
456
|
+
const isNextPlaceholder = maskPlaceholder && nextEditablePosition ? transformedCharacter === maskPlaceholder[nextEditablePosition] : null;
|
|
464
457
|
const valueBefore = value.slice(0, position);
|
|
465
458
|
if (isAllowed || !isEditable) {
|
|
466
|
-
const insertedCharacter = isAllowed ?
|
|
459
|
+
const insertedCharacter = isAllowed ? transformedCharacter : mask[position];
|
|
467
460
|
value = valueBefore + insertedCharacter;
|
|
468
461
|
}
|
|
469
462
|
if (!isAllowed && !isEditable && !isNextPlaceholder) {
|
|
@@ -558,6 +551,7 @@ var MaskUtils = class {
|
|
|
558
551
|
};
|
|
559
552
|
};
|
|
560
553
|
this.maskOptions = parseMask(options);
|
|
554
|
+
this.transform = options.transform;
|
|
561
555
|
}
|
|
562
556
|
};
|
|
563
557
|
|
|
@@ -575,15 +569,22 @@ function resolveMaskPlaceholder(maskPlaceholder, maskChar) {
|
|
|
575
569
|
}
|
|
576
570
|
return maskChar;
|
|
577
571
|
}
|
|
578
|
-
function
|
|
572
|
+
function normalizeFormatChars(formatChars) {
|
|
579
573
|
if (!formatChars) {
|
|
580
|
-
return void 0;
|
|
574
|
+
return { formatChars: void 0, hasLegacyString: false };
|
|
581
575
|
}
|
|
582
576
|
const result = {};
|
|
577
|
+
let hasLegacyString = false;
|
|
583
578
|
for (const key of Object.keys(formatChars)) {
|
|
584
|
-
|
|
579
|
+
const value = formatChars[key];
|
|
580
|
+
if (typeof value === "string") {
|
|
581
|
+
hasLegacyString = true;
|
|
582
|
+
result[key] = new RegExp(value);
|
|
583
|
+
} else {
|
|
584
|
+
result[key] = value;
|
|
585
|
+
}
|
|
585
586
|
}
|
|
586
|
-
return result;
|
|
587
|
+
return { formatChars: result, hasLegacyString };
|
|
587
588
|
}
|
|
588
589
|
function createBeforeMaskedStateChangeAdapter(beforeMaskedValueChange, maskOptions) {
|
|
589
590
|
return ({ previousState, currentState, nextState }) => {
|
|
@@ -597,6 +598,220 @@ function createBeforeMaskedStateChangeAdapter(beforeMaskedValueChange, maskOptio
|
|
|
597
598
|
};
|
|
598
599
|
}
|
|
599
600
|
|
|
601
|
+
// src/utils/transform.ts
|
|
602
|
+
function resolveTransform(transform) {
|
|
603
|
+
if (!transform) {
|
|
604
|
+
return void 0;
|
|
605
|
+
}
|
|
606
|
+
if (transform === "uppercase") {
|
|
607
|
+
return (char) => char.toUpperCase();
|
|
608
|
+
}
|
|
609
|
+
if (transform === "lowercase") {
|
|
610
|
+
return (char) => char.toLowerCase();
|
|
611
|
+
}
|
|
612
|
+
if (typeof transform === "function") {
|
|
613
|
+
return transform;
|
|
614
|
+
}
|
|
615
|
+
if (process.env.NODE_ENV !== "production") {
|
|
616
|
+
console.error(
|
|
617
|
+
`react-input-mask-format: invalid transform "${String(
|
|
618
|
+
transform
|
|
619
|
+
)}", expected "uppercase" | "lowercase" | (char, position) => char`
|
|
620
|
+
);
|
|
621
|
+
}
|
|
622
|
+
return void 0;
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
// src/use-mask.ts
|
|
626
|
+
import { useRef as useRef2, useCallback as useCallback2, useEffect as useEffect2 } from "react";
|
|
627
|
+
|
|
628
|
+
// src/bind-mask.ts
|
|
629
|
+
var IS_JSDOM = typeof navigator !== "undefined" && navigator.userAgent.includes("jsdom");
|
|
630
|
+
function createMaskController(maskUtils, options) {
|
|
631
|
+
let input = null;
|
|
632
|
+
let lastValue = "";
|
|
633
|
+
let lastSelection = { start: null, end: null };
|
|
634
|
+
function getInputState() {
|
|
635
|
+
return { value: input.value, selection: getInputSelection(input) };
|
|
636
|
+
}
|
|
637
|
+
function getLastInputState() {
|
|
638
|
+
return { value: lastValue, selection: lastSelection };
|
|
639
|
+
}
|
|
640
|
+
function setInputState({ value, selection }) {
|
|
641
|
+
setNativeValue(input, value);
|
|
642
|
+
lastValue = value;
|
|
643
|
+
if (input && isInputFocused(input) && selection.start !== null && selection.end !== null) {
|
|
644
|
+
setInputSelection(input, selection.start, selection.end);
|
|
645
|
+
lastSelection = getInputSelection(input);
|
|
646
|
+
} else {
|
|
647
|
+
lastSelection = selection;
|
|
648
|
+
}
|
|
649
|
+
if (IS_JSDOM) {
|
|
650
|
+
const resyncValue = value;
|
|
651
|
+
const resyncSelection = selection;
|
|
652
|
+
queueMicrotask(() => {
|
|
653
|
+
if (!input || input.value !== resyncValue) return;
|
|
654
|
+
input.value = resyncValue;
|
|
655
|
+
if (isInputFocused(input) && resyncSelection.start !== null && resyncSelection.end !== null) {
|
|
656
|
+
setInputSelection(input, resyncSelection.start, resyncSelection.end);
|
|
657
|
+
}
|
|
658
|
+
});
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
function handleInput() {
|
|
662
|
+
const currentState = getInputState();
|
|
663
|
+
const previousState = getLastInputState();
|
|
664
|
+
let nextState = maskUtils.processChange(currentState, previousState);
|
|
665
|
+
if (options.beforeMaskedStateChange) {
|
|
666
|
+
nextState = options.beforeMaskedStateChange({ currentState, previousState, nextState });
|
|
667
|
+
}
|
|
668
|
+
setInputState(nextState);
|
|
669
|
+
}
|
|
670
|
+
function handleFocus() {
|
|
671
|
+
const currentValue = getInputState().value;
|
|
672
|
+
if (!maskUtils.isValueFilled(currentValue)) {
|
|
673
|
+
const newValue = maskUtils.formatValue(currentValue);
|
|
674
|
+
const newSelection = maskUtils.getDefaultSelectionForValue(newValue);
|
|
675
|
+
let nextState = { value: newValue, selection: newSelection };
|
|
676
|
+
if (options.beforeMaskedStateChange) {
|
|
677
|
+
nextState = options.beforeMaskedStateChange({ currentState: getInputState(), nextState });
|
|
678
|
+
}
|
|
679
|
+
setInputState(nextState);
|
|
680
|
+
defer(() => {
|
|
681
|
+
if (input && isInputFocused(input)) {
|
|
682
|
+
setInputSelection(input, lastSelection.start, lastSelection.end);
|
|
683
|
+
}
|
|
684
|
+
});
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
function handleBlur() {
|
|
688
|
+
const lastValueOnBlur = getLastInputState().value;
|
|
689
|
+
if (!options.alwaysShowMask && maskUtils.isValueEmpty(lastValueOnBlur)) {
|
|
690
|
+
let nextState = { value: "", selection: { start: null, end: null } };
|
|
691
|
+
if (options.beforeMaskedStateChange) {
|
|
692
|
+
nextState = options.beforeMaskedStateChange({ currentState: getInputState(), nextState });
|
|
693
|
+
}
|
|
694
|
+
setInputState(nextState);
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
function handleMouseDown(event) {
|
|
698
|
+
if (!input) return;
|
|
699
|
+
const { value } = getInputState();
|
|
700
|
+
const inputDocument = getElementDocument(input);
|
|
701
|
+
if (!isInputFocused(input) && !maskUtils.isValueFilled(value)) {
|
|
702
|
+
const mouseDownX = event.clientX;
|
|
703
|
+
const mouseDownY = event.clientY;
|
|
704
|
+
const mouseDownTime = (/* @__PURE__ */ new Date()).getTime();
|
|
705
|
+
const mouseUpHandler = (mouseUpEvent) => {
|
|
706
|
+
inputDocument.removeEventListener("mouseup", mouseUpHandler);
|
|
707
|
+
if (!input || !isInputFocused(input)) return;
|
|
708
|
+
const deltaX = Math.abs(mouseUpEvent.clientX - mouseDownX);
|
|
709
|
+
const deltaY = Math.abs(mouseUpEvent.clientY - mouseDownY);
|
|
710
|
+
const axisDelta = Math.max(deltaX, deltaY);
|
|
711
|
+
const timeDelta = (/* @__PURE__ */ new Date()).getTime() - mouseDownTime;
|
|
712
|
+
if (axisDelta <= 10 && timeDelta <= 200 || axisDelta <= 5 && timeDelta <= 300) {
|
|
713
|
+
const newSelection = maskUtils.getDefaultSelectionForValue(lastValue);
|
|
714
|
+
if (newSelection.start !== null && newSelection.end !== null) {
|
|
715
|
+
setInputSelection(input, newSelection.start, newSelection.end);
|
|
716
|
+
lastSelection = getInputSelection(input);
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
};
|
|
720
|
+
inputDocument.addEventListener("mouseup", mouseUpHandler);
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
function bind(el) {
|
|
724
|
+
input = el;
|
|
725
|
+
lastValue = el.value;
|
|
726
|
+
lastSelection = getInputSelection(el);
|
|
727
|
+
const formatted = maskUtils.formatValue(el.value);
|
|
728
|
+
if (!maskUtils.isValueEmpty(formatted) || options.alwaysShowMask) {
|
|
729
|
+
setNativeValue(el, formatted);
|
|
730
|
+
lastValue = formatted;
|
|
731
|
+
}
|
|
732
|
+
el.addEventListener("input", handleInput);
|
|
733
|
+
el.addEventListener("focus", handleFocus);
|
|
734
|
+
el.addEventListener("blur", handleBlur);
|
|
735
|
+
el.addEventListener("mousedown", handleMouseDown);
|
|
736
|
+
}
|
|
737
|
+
function unbind() {
|
|
738
|
+
if (input) {
|
|
739
|
+
input.removeEventListener("input", handleInput);
|
|
740
|
+
input.removeEventListener("focus", handleFocus);
|
|
741
|
+
input.removeEventListener("blur", handleBlur);
|
|
742
|
+
input.removeEventListener("mousedown", handleMouseDown);
|
|
743
|
+
}
|
|
744
|
+
input = null;
|
|
745
|
+
}
|
|
746
|
+
function update(nextMaskUtils, nextOptions) {
|
|
747
|
+
maskUtils = nextMaskUtils;
|
|
748
|
+
options = nextOptions;
|
|
749
|
+
}
|
|
750
|
+
return { bind, unbind, update };
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
// src/use-mask.ts
|
|
754
|
+
function useMask(options) {
|
|
755
|
+
const {
|
|
756
|
+
mask,
|
|
757
|
+
maskPlaceholder: maskPlaceholderProp,
|
|
758
|
+
alwaysShowMask = false,
|
|
759
|
+
formatChars,
|
|
760
|
+
transform,
|
|
761
|
+
beforeMaskedStateChange: beforeMaskedStateChangeProp,
|
|
762
|
+
beforeMaskedValueChange
|
|
763
|
+
} = options;
|
|
764
|
+
if (beforeMaskedValueChange !== void 0) {
|
|
765
|
+
warnDeprecatedOnce(
|
|
766
|
+
"beforeMaskedValueChange",
|
|
767
|
+
"beforeMaskedValueChange is deprecated, use beforeMaskedStateChange."
|
|
768
|
+
);
|
|
769
|
+
}
|
|
770
|
+
const resolvedPlaceholder = resolveMaskPlaceholder(maskPlaceholderProp, void 0);
|
|
771
|
+
const maskPlaceholder = resolvedPlaceholder === void 0 ? "_" : resolvedPlaceholder;
|
|
772
|
+
const { formatChars: normalizedFormatChars, hasLegacyString } = normalizeFormatChars(formatChars);
|
|
773
|
+
if (hasLegacyString) {
|
|
774
|
+
warnDeprecatedOnce(
|
|
775
|
+
"formatChars",
|
|
776
|
+
"string values in formatChars are deprecated, pass RegExp values instead."
|
|
777
|
+
);
|
|
778
|
+
}
|
|
779
|
+
const maskUtils = new MaskUtils({
|
|
780
|
+
mask: mask != null ? mask : null,
|
|
781
|
+
maskPlaceholder,
|
|
782
|
+
formatChars: normalizedFormatChars,
|
|
783
|
+
transform: resolveTransform(transform)
|
|
784
|
+
});
|
|
785
|
+
let beforeMaskedStateChange = beforeMaskedStateChangeProp;
|
|
786
|
+
if (!beforeMaskedStateChange && beforeMaskedValueChange) {
|
|
787
|
+
const v2MaskOptions = {
|
|
788
|
+
mask: mask != null ? mask : void 0,
|
|
789
|
+
maskChar: maskPlaceholder,
|
|
790
|
+
alwaysShowMask,
|
|
791
|
+
formatChars: formatChars != null ? formatChars : { "9": "[0-9]", a: "[A-Za-z]", "*": "[A-Za-z0-9]" },
|
|
792
|
+
permanents: maskUtils.maskOptions.permanents
|
|
793
|
+
};
|
|
794
|
+
beforeMaskedStateChange = createBeforeMaskedStateChangeAdapter(beforeMaskedValueChange, v2MaskOptions);
|
|
795
|
+
}
|
|
796
|
+
const controllerOptions = { alwaysShowMask, beforeMaskedStateChange };
|
|
797
|
+
const controllerRef = useRef2(null);
|
|
798
|
+
useEffect2(() => {
|
|
799
|
+
var _a;
|
|
800
|
+
(_a = controllerRef.current) == null ? void 0 : _a.update(maskUtils, controllerOptions);
|
|
801
|
+
});
|
|
802
|
+
return useCallback2((el) => {
|
|
803
|
+
var _a;
|
|
804
|
+
if (el) {
|
|
805
|
+
const controller = createMaskController(maskUtils, controllerOptions);
|
|
806
|
+
controller.bind(el);
|
|
807
|
+
controllerRef.current = controller;
|
|
808
|
+
} else {
|
|
809
|
+
(_a = controllerRef.current) == null ? void 0 : _a.unbind();
|
|
810
|
+
controllerRef.current = null;
|
|
811
|
+
}
|
|
812
|
+
}, []);
|
|
813
|
+
}
|
|
814
|
+
|
|
600
815
|
// src/index.tsx
|
|
601
816
|
var InputMask = forwardRef(function InputMask2(props, forwardedRef) {
|
|
602
817
|
const {
|
|
@@ -605,6 +820,7 @@ var InputMask = forwardRef(function InputMask2(props, forwardedRef) {
|
|
|
605
820
|
mask,
|
|
606
821
|
maskPlaceholder: maskPlaceholderProp,
|
|
607
822
|
beforeMaskedStateChange: beforeMaskedStateChangeProp,
|
|
823
|
+
transform,
|
|
608
824
|
maskChar,
|
|
609
825
|
formatChars,
|
|
610
826
|
beforeMaskedValueChange,
|
|
@@ -613,9 +829,6 @@ var InputMask = forwardRef(function InputMask2(props, forwardedRef) {
|
|
|
613
829
|
if (maskChar !== void 0) {
|
|
614
830
|
warnDeprecatedOnce("maskChar", "maskChar is deprecated, use maskPlaceholder instead. See migration guide: https://github.com/Temirtator/react-input-mask-format#migrating-from-react-input-mask");
|
|
615
831
|
}
|
|
616
|
-
if (formatChars !== void 0) {
|
|
617
|
-
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");
|
|
618
|
-
}
|
|
619
832
|
if (beforeMaskedValueChange !== void 0) {
|
|
620
833
|
warnDeprecatedOnce("beforeMaskedValueChange", "beforeMaskedValueChange is deprecated, use beforeMaskedStateChange. See migration guide: https://github.com/Temirtator/react-input-mask-format#migrating-from-react-input-mask");
|
|
621
834
|
}
|
|
@@ -623,10 +836,18 @@ var InputMask = forwardRef(function InputMask2(props, forwardedRef) {
|
|
|
623
836
|
const maskPlaceholder = resolvedPlaceholder === void 0 ? "_" : resolvedPlaceholder;
|
|
624
837
|
validateMaxLength(props);
|
|
625
838
|
validateMaskPlaceholder({ ...props, maskPlaceholder });
|
|
839
|
+
const { formatChars: normalizedFormatChars, hasLegacyString } = normalizeFormatChars(formatChars);
|
|
840
|
+
if (hasLegacyString) {
|
|
841
|
+
warnDeprecatedOnce(
|
|
842
|
+
"formatChars",
|
|
843
|
+
'string values in formatChars are deprecated, pass RegExp values instead (e.g. { "#": /[0-9]/ }). See migration guide: https://github.com/Temirtator/react-input-mask-format#migrating-from-react-input-mask'
|
|
844
|
+
);
|
|
845
|
+
}
|
|
626
846
|
const maskUtils = new MaskUtils({
|
|
627
847
|
mask,
|
|
628
848
|
maskPlaceholder,
|
|
629
|
-
formatChars:
|
|
849
|
+
formatChars: normalizedFormatChars,
|
|
850
|
+
transform: resolveTransform(transform)
|
|
630
851
|
});
|
|
631
852
|
let beforeMaskedStateChange = beforeMaskedStateChangeProp;
|
|
632
853
|
if (!beforeMaskedStateChange && beforeMaskedValueChange) {
|
|
@@ -847,6 +1068,9 @@ var InputMask = forwardRef(function InputMask2(props, forwardedRef) {
|
|
|
847
1068
|
InputMask.displayName = "InputMask";
|
|
848
1069
|
var src_default = InputMask;
|
|
849
1070
|
export {
|
|
850
|
-
src_default as default
|
|
1071
|
+
src_default as default,
|
|
1072
|
+
defaultFormatChars,
|
|
1073
|
+
extendedFormatChars,
|
|
1074
|
+
useMask
|
|
851
1075
|
};
|
|
852
1076
|
//# sourceMappingURL=index.js.map
|