-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.tsx
61 lines (53 loc) · 1.62 KB
/
index.tsx
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
import React from 'react';
export type EventTypes = MouseEvent | TouchEvent | KeyboardEvent;
export type HandlerType = (event: EventTypes) => void;
export type EventContextType = {
subscribe: (handler: HandlerType) => void;
};
export const EventContext = React.createContext<EventContextType | undefined>(
undefined,
);
export type EventProviderProps = {
events?: string[];
children?: React.ReactNode;
};
export function EventProvider({
events = ['click'],
children,
}: EventProviderProps) {
const state = React.useState<HandlerType[]>([]);
const handlers = state[0]; // reduce transpiled array helpers
function onEvent(event: EventTypes) {
handlers.forEach((handler: HandlerType) => handler(event));
}
function subscribe(handler: HandlerType) {
handlers.push(handler);
return () => handlers.splice(handlers.indexOf(handler), 1);
}
React.useEffect(() => {
events.forEach((event) =>
window.document.addEventListener(event, onEvent, true),
);
return () =>
events.forEach((event) =>
window.document.removeEventListener(event, onEvent, true),
);
});
return (
<EventContext.Provider value={{ subscribe }}>
{children}
</EventContext.Provider>
);
}
export function useEvent(handler, dependencies) {
const context = React.useContext(EventContext);
if (!context) {
throw new Error(
'react-dom-event: subscribe not found on context. You might be missing the EventProvider or have multiple instances of react-dom-event',
);
}
React.useEffect(
() => context.subscribe(handler),
[context.subscribe, handler].concat(dependencies),
);
}