Skip to content

Commit 9f57735

Browse files
committed
Sync the input-mask changes
1 parent 8dc039c commit 9f57735

File tree

1 file changed

+39
-29
lines changed

1 file changed

+39
-29
lines changed

src/index.ts

Lines changed: 39 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {ChangeEvent, useCallback, useMemo, useRef, useState} from "react";
1+
import {ChangeEvent, KeyboardEvent, useCallback, useMemo, useRef, useState} from "react";
22

33
import {PhoneNumber, usePhoneOptions} from "./types";
44

@@ -74,6 +74,43 @@ export const parsePhoneNumber = (formattedNumber: string, countriesList: typeof
7474
return {countryCode, areaCode, phoneNumber, isoCode};
7575
}
7676

77+
export const useMask = (pattern: string) => {
78+
const backRef = useRef<boolean>(false);
79+
80+
const clean = useCallback((input: any) => {
81+
return cleanInput(input, pattern.replaceAll(/\d/g, "."));
82+
}, [pattern])
83+
84+
const first = useMemo(() => {
85+
return [...pattern].findIndex(c => slots.has(c));
86+
}, [pattern])
87+
88+
const prev = useMemo((j = 0) => {
89+
return Array.from(pattern.replaceAll(/\d/g, "."), (c, i) => {
90+
return slots.has(c) ? j = i + 1 : j;
91+
});
92+
}, [pattern])
93+
94+
const onKeyDown = useCallback((event: KeyboardEvent<HTMLInputElement>) => {
95+
backRef.current = event.key === "Backspace";
96+
}, [])
97+
98+
const onInput = useCallback(({target}: ChangeEvent<HTMLInputElement>) => {
99+
const [i, j] = [target.selectionStart, target.selectionEnd].map((i: any) => {
100+
i = clean(target.value.slice(0, i)).findIndex(c => slots.has(c));
101+
return i < 0 ? prev[prev.length - 1] : backRef.current ? prev[i - 1] || first : i;
102+
});
103+
target.value = getFormattedNumber(target.value, pattern);
104+
target.setSelectionRange(i, j);
105+
backRef.current = false;
106+
}, [clean, first, pattern, prev])
107+
108+
return {
109+
onInput,
110+
onKeyDown,
111+
}
112+
}
113+
77114
export const usePhone = ({
78115
query = "",
79116
country = "",
@@ -87,7 +124,6 @@ export const usePhone = ({
87124
const defaultMetadata = getMetadata(defaultValue) || countries.find(([iso]) => iso === country);
88125
const defaultValueState = defaultValue || countries.find(([iso]) => iso === defaultMetadata?.[0])?.[2] as string;
89126

90-
const backRef = useRef<boolean>(false);
91127
const [value, setValue] = useState<string>(defaultValueState);
92128

93129
const countriesOnly = useMemo(() => {
@@ -121,35 +157,9 @@ export const usePhone = ({
121157
return metadata?.[3] || defaultMetadata?.[3] || "";
122158
}, [defaultMetadata, metadata])
123159

124-
const clean = useCallback((input: any) => {
125-
return cleanInput(input, pattern.replaceAll(/\d/g, "."));
126-
}, [pattern])
127-
128-
const first = useMemo(() => {
129-
return [...pattern].findIndex(c => slots.has(c));
130-
}, [pattern])
131-
132-
const prev = useMemo((j = 0) => {
133-
return Array.from(pattern.replaceAll(/\d/g, "."), (c, i) => {
134-
return slots.has(c) ? j = i + 1 : j;
135-
});
136-
}, [pattern])
137-
138-
const format = useCallback(({target}: ChangeEvent<HTMLInputElement>) => {
139-
const [i, j] = [target.selectionStart, target.selectionEnd].map((i: any) => {
140-
i = clean(target.value.slice(0, i)).findIndex(c => slots.has(c));
141-
return i < 0 ? prev[prev.length - 1] : backRef.current ? prev[i - 1] || first : i;
142-
});
143-
target.value = getFormattedNumber(target.value, pattern);
144-
target.setSelectionRange(i, j);
145-
backRef.current = false;
146-
setValue(target.value);
147-
}, [clean, first, pattern, prev])
148-
149160
return {
150-
clean,
151161
value,
152-
format,
162+
pattern,
153163
metadata,
154164
setValue,
155165
countriesList,

0 commit comments

Comments
 (0)