aboutsummaryrefslogtreecommitdiff
path: root/FrontEnd/src/views/common/menu/PopupMenu.tsx
blob: 851f3bee4eb25105565f0de9e7ba08d17bc6b1ab (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
72
73
74
75
76
77
78
79
import classNames from "classnames";
import React from "react";
import { usePopper } from "react-popper";

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);

  React.useEffect(() => {
    const handler = (event: MouseEvent): void => {
      let element: HTMLElement | null = event.target as HTMLElement;
      while (element) {
        if (element == referenceElement || element == popperElement) {
          return;
        }
        element = element.parentElement;
      }
      setShow(false);
    };
    document.addEventListener("click", handler);
    return () => {
      document.removeEventListener("click", handler);
    };
  }, [referenceElement, popperElement]);

  return (
    <>
      <div
        ref={setReferenceElement}
        className={classNames(
          "cru-popup-menu-trigger-container",
          containerClassName
        )}
        style={containerStyle}
        onClick={() => setShow(true)}
      >
        {children}
      </div>
      {show ? (
        <div
          ref={setPopperElement}
          className="cru-popup-menu-menu-container"
          style={styles.popper}
          {...attributes.popper}
        >
          <Menu
            items={items}
            onItemClicked={() => {
              setShow(false);
            }}
          />
        </div>
      ) : null}
    </>
  );
};

export default PopupMenu;