aboutsummaryrefslogtreecommitdiff
path: root/FrontEnd/src/components/dialog/index.tsx
blob: 7b24fc573ce900ba044213e71e842aeb41287c12 (plain)
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 { 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";
export { default as DialogContainer } from "./DialogContainer";

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,
        {
          // TODO: Fix the animation problem, maybe we have to use a better way to re-enable this.
          //key: `${d}-${dialogKeys[d]}`,
          open: dialog === d,
          onClose: () => {
            switchDialog(null);
            options?.onClose?.[d]?.();
          },
        },
      ]),
    ) as DialogPropsMap<D>,
    createDialogSwitch: (newDialog: D | null) => () => switchDialog(newDialog),
  };
}