aboutsummaryrefslogtreecommitdiff
path: root/FrontEnd/src/views/common/menu/PopupMenu.tsx
blob: b8f249789ad363be1ecf5eaa57eba9644d35802b (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
67
68
69
70
71
import classNames from "classnames";
import React from "react";
import { createPortal } from "react-dom";
import { usePopper } from "react-popper";

import { useClickOutside } from "@/utilities/hooks";

import Menu, { MenuItems } from "./Menu";

import "./PopupMenu.css";

export interface PopupMenuProps {
  items: MenuItems;
  children?: React.ReactNode;
  containerClassName?: string;
  containerStyle?: React.CSSProperties;
}

const PopupMenu: React.FC<PopupMenuProps> = ({
  items,
  children,
  containerClassName,
  containerStyle,
}) => {
  const [show, setShow] = React.useState<boolean>(false);

  const [referenceElement, setReferenceElement] =
    React.useState<HTMLDivElement | null>(null);
  const [popperElement, setPopperElement] =
    React.useState<HTMLDivElement | null>(null);
  const { styles, attributes } = usePopper(referenceElement, popperElement);

  useClickOutside(popperElement, () => setShow(false), true);

  return (
    <>
      <div
        ref={setReferenceElement}
        className={classNames(
          "cru-popup-menu-trigger-container",
          containerClassName
        )}
        style={containerStyle}
        onClick={() => setShow(true)}
      >
        {children}
      </div>
      {show
        ? createPortal(
            <div
              ref={setPopperElement}
              className="cru-popup-menu-menu-container"
              style={styles.popper}
              {...attributes.popper}
            >
              <Menu
                items={items}
                onItemClicked={() => {
                  setShow(false);
                }}
              />
            </div>,
            // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
            document.getElementById("portal")!
          )
        : null}
    </>
  );
};

export default PopupMenu;