-
Notifications
You must be signed in to change notification settings - Fork 40
/
Copy pathcontent-overlay-controller.tsx
61 lines (52 loc) · 1.63 KB
/
content-overlay-controller.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 { type FC, useEffect, useRef } from 'react';
import { type OverlayItemContext } from '../store';
type OverlayControllerProps<C extends OverlayItemContext> = {
overlayId: string;
isOpen: boolean;
close: () => void;
unmount: () => void;
context: C;
};
type OverlayAsyncControllerProps<T, C extends OverlayItemContext> = Omit<OverlayControllerProps<C>, 'close'> & {
close: (param: T) => void;
};
export type OverlayControllerComponent<C extends OverlayItemContext> = FC<OverlayControllerProps<C>>;
export type OverlayAsyncControllerComponent<T, C extends OverlayItemContext> = FC<OverlayAsyncControllerProps<T, C>>;
type ContentOverlayControllerProps<C extends OverlayItemContext> = {
isOpen: boolean;
current: string | null;
overlayId: string;
onMounted: () => void;
onCloseModal: () => void;
onExitModal: () => void;
controller: OverlayControllerComponent<C>;
context: C;
};
export function ContentOverlayController<C extends OverlayItemContext>({
isOpen,
current,
overlayId,
onMounted,
onCloseModal,
onExitModal,
controller: Controller,
context,
}: ContentOverlayControllerProps<C>) {
const prevCurrent = useRef(current);
const onMountedRef = useRef(onMounted);
/**
* @description Executes when closing and reopening an overlay without unmounting.
*/
if (prevCurrent.current !== current) {
prevCurrent.current = current;
if (current === overlayId) {
onMountedRef.current();
}
}
useEffect(() => {
onMountedRef.current();
}, []);
return (
<Controller overlayId={overlayId} isOpen={isOpen} close={onCloseModal} unmount={onExitModal} context={context} />
);
}