File size: 2,193 Bytes
bc20498
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
<script>import { getContext } from 'svelte';
import { Position, getNodeToolbarTransform } from '@xyflow/system';
import portal from '../../actions/portal';
import { useStore } from '../../store';
import { useSvelteFlow } from '../../hooks/useSvelteFlow';
export let nodeId = undefined;
export let position = undefined;
export let align = undefined;
export let offset = undefined;
export let isVisible = undefined;
const { domNode, viewport, nodeLookup, nodes } = useStore();
const { getNodesBounds } = useSvelteFlow();
const contextNodeId = getContext('svelteflow__node_id');
let transform;
let toolbarNodes = [];
let _offset = offset !== undefined ? offset : 10;
let _position = position !== undefined ? position : Position.Top;
let _align = align !== undefined ? align : 'center';
$: {
    // nly needed to trigger updates, $nodeLookup is just a helper that does not trigger any updates
    $nodes;
    const nodeIds = Array.isArray(nodeId) ? nodeId : [nodeId || contextNodeId];
    toolbarNodes = nodeIds.reduce((res, nodeId) => {
        const node = $nodeLookup.get(nodeId);
        if (node) {
            res.push(node);
        }
        return res;
    }, []);
}
$: {
    const nodeRect = getNodesBounds(toolbarNodes);
    if (nodeRect) {
        transform = getNodeToolbarTransform(nodeRect, $viewport, _position, _offset, _align);
    }
}
$: zIndex =
    toolbarNodes.length === 0
        ? 1
        : Math.max(...toolbarNodes.map((node) => (node.internals.z || 5) + 1));
//FIXME: Possible performance bottleneck
$: selectedNodesCount = $nodes.filter((node) => node.selected).length;
// if isVisible is not set, we show the toolbar only if its node is selected and no other node is selected
$: isActive =
    typeof isVisible === 'boolean'
        ? isVisible
        : toolbarNodes.length === 1 && toolbarNodes[0].selected && selectedNodesCount === 1;
</script>

{#if $domNode && isActive && toolbarNodes}
  <div
    data-id={toolbarNodes.reduce((acc, node) => `${acc}${node.id} `, '').trim()}
    class="svelte-flow__node-toolbar"
    use:portal={{ domNode: $domNode }}
    style:position="absolute"
    style:transform
    style:z-index={zIndex}
  >
    <slot />
  </div>
{/if}