-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.ts
65 lines (51 loc) · 2 KB
/
index.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
import { useEffect, useState } from "react";
type UsePopupHooks<OpenParams, CloseParams> = {
open?: (detail: OpenParams) => void;
close?: (detail: CloseParams) => void;
}
const prefix: Record<"popupOpen" | "popupClose", string> = {
popupOpen: 'popup-open::',
popupClose: 'popup-close::'
};
export const popupOpenEventName = (intent: string) => (prefix.popupOpen + intent) as keyof WindowEventMap;
export const popupCloseEventName = (intent: string) => (prefix.popupClose + intent) as keyof WindowEventMap;
/** call for open popup */
export const openPopup = <OpenParams>(intent: string, detail?: OpenParams) => {
const name = popupOpenEventName(intent);
const event = new CustomEvent<OpenParams>(name, { detail });
window.dispatchEvent(event);
};
/** call for close popup */
export const closePopup = <CloseParams>(intent: string, detail?: CloseParams) => {
const name = popupCloseEventName(intent);
const event = new CustomEvent<CloseParams>(name, { detail });
window.dispatchEvent(event);
};
/** manage concrete popup state */
export const usePopup = <OpenParams, CloseParams>(intent: string, hooks: UsePopupHooks<OpenParams, CloseParams> = {}): boolean => {
const { open, close } = hooks;
const [visible, visibleSet] = useState(false);
/* onOpen subscription */
useEffect(() => {
const openHandler = (e: CustomEvent<OpenParams>) => {
visibleSet(true);
open?.(e.detail);
};
const name = popupOpenEventName(intent);
const handler = openHandler as EventListener;
window.addEventListener(name, handler);
return () => window.removeEventListener(name, handler);
}, [open]);
/* onClose subscription */
useEffect(() => {
const closeHandler = (e: CustomEvent<CloseParams>) => {
visibleSet(false);
close?.(e.detail);
};
const name = popupCloseEventName(intent);
const handler = closeHandler as EventListener;
window.addEventListener(name, handler);
return () => window.removeEventListener(name, handler);
}, [close]);
return visible;
}