forked from ionic-team/ionic-framework
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathuseController.ts
66 lines (53 loc) · 2.15 KB
/
useController.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
import type { OverlayEventDetail } from '@ionic/core/components';
import { useCallback, useMemo, useRef } from 'react';
import { attachProps } from '../components/react-component-lib/utils';
import type { HookOverlayOptions } from './HookOverlayOptions';
interface OverlayBase extends HTMLElement {
present: () => Promise<void>;
dismiss: (data?: any, role?: string | undefined) => Promise<boolean>;
}
export function useController<OptionsType, OverlayType extends OverlayBase>(
displayName: string,
controller: { create: (options: OptionsType) => Promise<OverlayType> },
defineCustomElement: () => void
) {
const overlayRef = useRef<OverlayType>();
const didDismissEventName = useMemo(() => `on${displayName}DidDismiss`, [displayName]);
const didPresentEventName = useMemo(() => `on${displayName}DidPresent`, [displayName]);
const willDismissEventName = useMemo(() => `on${displayName}WillDismiss`, [displayName]);
const willPresentEventName = useMemo(() => `on${displayName}WillPresent`, [displayName]);
defineCustomElement();
const present = useCallback(
async (options: OptionsType & HookOverlayOptions) => {
if (overlayRef.current) {
return;
}
const { onDidDismiss, onWillDismiss, onDidPresent, onWillPresent, ...rest } = options;
const handleDismiss = (event: CustomEvent<OverlayEventDetail<any>>) => {
if (onDidDismiss) {
onDidDismiss(event);
}
overlayRef.current = undefined;
};
overlayRef.current = await controller.create({
...(rest as any),
});
attachProps(overlayRef.current, {
[didDismissEventName]: handleDismiss,
[didPresentEventName]: (e: CustomEvent) => onDidPresent && onDidPresent(e),
[willDismissEventName]: (e: CustomEvent) => onWillDismiss && onWillDismiss(e),
[willPresentEventName]: (e: CustomEvent) => onWillPresent && onWillPresent(e),
});
overlayRef.current.present();
},
[controller]
);
const dismiss = useCallback(async () => {
overlayRef.current && (await overlayRef.current.dismiss());
overlayRef.current = undefined;
}, []);
return {
present,
dismiss,
};
}