-
Notifications
You must be signed in to change notification settings - Fork 0
/
useChangeHandler.ts
99 lines (88 loc) · 2.7 KB
/
useChangeHandler.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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import { ChangeEvent, useMemo } from "react";
import { DeepIndex } from "../types/DeepIndex";
import { ValuesFields } from "../types/ValuesFields";
import useEventCallback from "use-event-callback";
import {
UseFieldChangeValueArg,
UseFieldChangeValueReturn,
} from "./useFieldChangeValue";
import { BaseValues } from "../types/BaseValues";
export interface UseChangeHandlerArg<Name> {
name: Name;
}
export interface UseChangeHandlerReturn<
Values extends BaseValues,
Name extends ValuesFields<Values>
> extends UseFieldChangeValueReturn<Values, Name> {
/**
* Handle a change event for a native input. Only supports string values.
*
* @param {ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>} event
*/
handleChangeEvent: DeepIndex<Values, Name> extends string
? (
event: ChangeEvent<
HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement
>
) => void
: never;
/**
* Handle a change event for a native checkbox. Only supports boolean values.
*
* @param {ChangeEvent<HTMLInputElement>} event
*/
handleCheckboxEvent: DeepIndex<Values, Name> extends boolean
? (event: ChangeEvent<HTMLInputElement>) => void
: never;
}
/**
* @private
*/
export interface CreateUseChangeHandlerDependencies<Values extends BaseValues> {
useFieldChangeValue: <Name extends ValuesFields<Values>>(
arg: UseFieldChangeValueArg<Name>
) => UseFieldChangeValueReturn<Values, Name>;
}
/**
* @private
*/
export const createUseChangeHandler = <Values extends BaseValues>({
useFieldChangeValue,
}: CreateUseChangeHandlerDependencies<Values>) => {
/**
* Get native change handlers for a field.
*
* @param {UseChangeHandlerArg<Name>} arg
* @returns {UseChangeHandlerReturn<Values, Name>}
*/
const useChangeHandler = <Name extends ValuesFields<Values>>({
name,
}: UseChangeHandlerArg<Name>): UseChangeHandlerReturn<Values, Name> => {
const { changeValue } = useFieldChangeValue<Name>({ name });
const handleChangeEvent: any = useEventCallback(
(
event: ChangeEvent<
HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement
>
) => {
const { value } = event.target || event.currentTarget;
changeValue(value as any);
}
);
const handleCheckboxEvent: any = useEventCallback(
(event: ChangeEvent<HTMLInputElement>) => {
const { checked } = event.target || event.currentTarget;
changeValue(checked as any);
}
);
return useMemo(
() => ({
changeValue,
handleChangeEvent,
handleCheckboxEvent,
}),
[changeValue, handleChangeEvent, handleCheckboxEvent]
);
};
return useChangeHandler;
};