-
Notifications
You must be signed in to change notification settings - Fork 3k
/
index.tsx
91 lines (86 loc) · 2.7 KB
/
index.tsx
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
import { useEffect, useState } from "react";
import { useHotkeys } from "react-hotkeys-hook";
import { NodeToolbar } from "reactflow";
import { Button } from "../../../../components/ui/button";
import { GradientGroup } from "../../../../icons/GradientSparkles";
import useFlowStore from "../../../../stores/flowStore";
import { validateSelection } from "../../../../utils/reactflowUtils";
export default function SelectionMenu({
onClick,
nodes,
isVisible,
lastSelection,
}) {
const edges = useFlowStore((state) => state.edges);
const unselectAll = useFlowStore((state) => state.unselectAll);
const [disable, setDisable] = useState<boolean>(
lastSelection && edges.length > 0
? validateSelection(lastSelection!, edges).length > 0
: false,
);
const [isOpen, setIsOpen] = useState(false);
const [isTransitioning, setIsTransitioning] = useState(false);
const [lastNodes, setLastNodes] = useState(nodes);
useHotkeys("esc", unselectAll, { preventDefault: true });
useEffect(() => {
if (isOpen) {
return setDisable(validateSelection(lastSelection!, edges).length > 0);
}
setDisable(false);
}, [isOpen, setIsOpen]);
// nodes get saved to not be gone after the toolbar closes
useEffect(() => {
setLastNodes(nodes);
}, [isOpen]);
// transition starts after and ends before the toolbar closes
useEffect(() => {
if (isVisible) {
setIsOpen(true);
setTimeout(() => {
setIsTransitioning(true);
}, 50);
} else {
setIsTransitioning(false);
setTimeout(() => {
setIsOpen(false);
}, 500);
}
}, [isVisible]);
return (
<NodeToolbar
isVisible={isOpen}
offset={5}
nodeId={
lastNodes && lastNodes.length > 0 ? lastNodes.map((n) => n.id) : []
}
>
<div className="h-10 w-28 overflow-hidden">
<div
className={
"duration-400 h-10 w-24 rounded-md border border-indigo-300 bg-background px-2.5 text-primary shadow-inner transition-all ease-in-out" +
(isTransitioning ? " opacity-100" : " opacity-0")
}
>
<Button
unstyled
className={`${
disable
? "flex h-full w-full cursor-not-allowed items-center justify-between text-sm text-muted-foreground"
: "flex h-full w-full items-center justify-between text-sm"
}`}
onClick={onClick}
disabled={disable}
>
<GradientGroup
strokeWidth={1.5}
size={22}
className="text-primary"
disabled={disable}
/>
Group
</Button>
</div>
</div>
</NodeToolbar>
);
}