Bin
2025-12-17 d616898802dfe7e5dd648bcf53c6d1f86b6d3642
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import { cn } from "../../utils/bem";
import { isDefined } from "../../utils/utilities";
import { Fragment, useEffect, useState } from "react";
import { Hotkey } from "../../core/Hotkey";
 
const hotkeys = Hotkey("SegmentationToolbar", "Segmentation Tools");
 
const keysDictionary = {
  plus: "+",
  minus: "-",
};
 
const shortcutView = (shortcut) => {
  const sc = hotkeys.lookupKey(shortcut);
 
  if (!isDefined(sc)) return null;
 
  const combos = sc.split(",").map((s) => s.trim());
 
  return (
    <div className={cn("flyoutmenu").elem("shortcut").toClassName()}>
      {combos.map((combo, index) => {
        const keys = combo.split("+");
 
        return (
          <Fragment key={`${keys.join("-")}-${index}`}>
            {keys.map((key) => {
              return (
                <kbd className={cn("flyoutmenu").elem("key").toClassName()} key={key}>
                  {keysDictionary[key] ?? key}
                </kbd>
              );
            })}
          </Fragment>
        );
      })}
    </div>
  );
};
 
export const FlyoutMenu = ({ items, icon }) => {
  const [isClicked, setClicked] = useState(false);
 
  useEffect(() => {
    const removeShortcuts = () => {
      items.forEach((menuItem) => {
        const currentShortcut = menuItem.shortcut;
 
        if (currentShortcut && hotkeys.hasKeyByName(currentShortcut)) {
          hotkeys.removeNamed(currentShortcut);
        }
      });
    };
    const addShortcuts = () => {
      items.forEach((menuItem) => {
        const currentShortcut = menuItem.shortcut;
 
        if (currentShortcut && !hotkeys.hasKeyByName(currentShortcut)) {
          hotkeys.addNamed(currentShortcut, () => {
            console.log("clicked");
            menuItem?.onClick?.();
            setClicked(false);
          });
        }
      });
    };
 
    removeShortcuts();
    addShortcuts();
 
    return () => {
      removeShortcuts();
    };
  }, [items]);
 
  useEffect(() => {
    const windowClickHandler = () => {
      if (isClicked) {
        setClicked(false);
      }
    };
 
    window.addEventListener("click", windowClickHandler);
    return () => {
      window.removeEventListener("click", windowClickHandler);
    };
  });
 
  return (
    <div
      className={cn("flyoutmenu")
        .mix(isClicked ? "hovered" : "")
        .toClassName()}
      onClick={(e) => {
        e.stopPropagation();
        setClicked(!isClicked);
      }}
    >
      <div
        className={cn("flyoutmenu")
          .elem("icon")
          .mix(isClicked ? "isClicked" : "")
          .toClassName()}
        title="Zoom presets (click to see options)"
      >
        {icon}
      </div>
      <div className={cn("tooltips").toClassName()}>
        {items.map((childItem, index) => (
          <div
            className={cn("tooltips").elem("tooltip").toClassName()}
            key={index}
            onClick={(e) => {
              e.stopPropagation();
              childItem?.onClick?.();
              setClicked(false);
            }}
          >
            <div className={cn("tooltips").elem("tooltip-body").toClassName()}>
              <div className={cn("tooltips").elem("label").toClassName()}>{childItem.label}</div>
              {shortcutView(childItem.shortcut)}
            </div>
          </div>
        ))}
      </div>
    </div>
  );
};