-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathuse-ref-mask.ts
69 lines (61 loc) · 1.73 KB
/
use-ref-mask.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import React from 'react';
import { useMask } from './use-mask';
import type { MaskGenerator } from '../types/mask-generator';
const useCombinedRefs = <T>(
innerRef: React.MutableRefObject<T | null>,
fwdRef: React.ForwardedRef<T> | undefined,
) => {
React.useEffect(() => {
[innerRef, fwdRef].forEach((ref) => {
if (ref) {
if (typeof ref === 'function') {
ref(innerRef.current || null);
} else {
ref.current = innerRef.current || null;
}
}
});
}, [innerRef, fwdRef]);
return innerRef;
};
export interface UseRefMaskProps<T> {
maskGenerator?: MaskGenerator;
value?: string;
onChange?: (value: string) => void;
keepMask?: boolean;
getCursorPosition: (el: T | undefined) => number;
setCursorPosition: (cursorPosition: number, el: T | undefined) => void;
ref?: React.ForwardedRef<T>;
}
export const useRefMask = <T>({
maskGenerator,
value: outerValue,
onChange,
keepMask,
ref,
getCursorPosition: getCursorPositionOuter,
setCursorPosition: setCursorPositionOuter,
}: UseRefMaskProps<T>) => {
const innerRef = React.useRef<T>(null);
const combinedRefs = useCombinedRefs(innerRef, ref);
const getCursorPosition = React.useCallback(() => {
const el = combinedRefs?.current;
return getCursorPositionOuter(el ?? undefined);
}, [combinedRefs, getCursorPositionOuter]);
const setCursorPosition = React.useCallback(
(cursorPosition: number) => {
const el = combinedRefs?.current;
setCursorPositionOuter(cursorPosition, el ?? undefined);
},
[combinedRefs, setCursorPositionOuter],
);
const { displayValue, setDisplayValue } = useMask({
outerValue,
maskGenerator,
getCursorPosition,
setCursorPosition,
onChange,
keepMask,
});
return { displayValue, setDisplayValue, ref: combinedRefs };
};