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
|
import { useState } from "react";
export { default as Dialog } from "./Dialog";
export { default as FullPageDialog } from "./FullPageDialog";
export { default as OperationDialog } from "./OperationDialog";
export { default as ConfirmDialog } from "./ConfirmDialog";
type DialogMap<D extends string, V> = {
[K in D]: V;
};
type DialogKeyMap<D extends string> = DialogMap<D, number>;
type DialogPropsMap<D extends string> = DialogMap<
D,
{ key: number | string; open: boolean; onClose: () => void }
>;
export function useDialog<D extends string>(
dialogs: D[],
options?: {
initDialog?: D | null;
onClose?: {
[K in D]?: () => void;
};
},
): {
dialog: D | null;
switchDialog: (newDialog: D | null) => void;
dialogPropsMap: DialogPropsMap<D>;
createDialogSwitch: (newDialog: D | null) => () => void;
} {
const [dialog, setDialog] = useState<D | null>(options?.initDialog ?? null);
const [dialogKeys, setDialogKeys] = useState<DialogKeyMap<D>>(
() => Object.fromEntries(dialogs.map((d) => [d, 0])) as DialogKeyMap<D>,
);
const switchDialog = (newDialog: D | null) => {
if (dialog !== null) {
setDialogKeys({ ...dialogKeys, [dialog]: dialogKeys[dialog] + 1 });
}
setDialog(newDialog);
};
return {
dialog,
switchDialog,
dialogPropsMap: Object.fromEntries(
dialogs.map((d) => [
d,
{
key: `${d}-${dialogKeys[d]}`,
open: dialog === d,
onClose: () => {
switchDialog(null);
options?.onClose?.[d]?.();
},
},
]),
) as DialogPropsMap<D>,
createDialogSwitch: (newDialog: D | null) => () => switchDialog(newDialog),
};
}
|