refactor: remove passing props to reactive obj instead use props directly again (sort of breaks reactivity in some cases...)

fix: node selection not displaying correct rect after mouseup
This commit is contained in:
Braks
2021-07-17 20:30:58 +02:00
parent 61ab006e94
commit 528f8f4420
7 changed files with 276 additions and 415 deletions
+93 -78
View File
@@ -4,7 +4,7 @@
*/
import { isNode } from '../../utils/graph';
import { Node, RevueFlowStore } from '../../types';
import { computed, inject, ref } from 'vue';
import { computed, defineComponent, inject, PropType, ref } from 'vue';
import Draggable, { DraggableEventHandler } from '@braks/revue-draggable';
export interface NodesSelectionProps {
@@ -14,89 +14,104 @@ export interface NodesSelectionProps {
onSelectionContextMenu?: (event: MouseEvent, nodes: Node[]) => void;
}
const NodesSelection = ({
onSelectionDragStart,
onSelectionDrag,
onSelectionDragStop,
onSelectionContextMenu
}: NodesSelectionProps) => {
const store = inject<RevueFlowStore>('store');
console.log('nodesSelection');
const nodeRef = ref<HTMLElement | undefined>();
const grid = computed(() => (store?.snapToGrid ? store?.snapGrid : [1, 1])! as [number, number]);
const selectedNodes = computed(() =>
store?.selectedElements
? store?.selectedElements.filter(isNode).map((selectedNode) => {
const matchingNode = store?.nodes.find((node) => node.id === selectedNode.id);
return {
...matchingNode,
position: matchingNode?.__rf.position
} as Node;
})
: []
);
const style = computed(() => ({
transform: `translate(${store?.transform[0]}px,${store?.transform[1]}px) scale(${store?.transform[2]})`
}));
const innerStyle = computed(() => ({
width: store?.selectedNodesBbox.width,
height: store?.selectedNodesBbox.height,
top: store?.selectedNodesBbox.y,
left: store?.selectedNodesBbox.x
}));
const onStart: DraggableEventHandler = (event: MouseEvent) => {
onSelectionDragStart?.(event, selectedNodes.value);
};
const onDrag: DraggableEventHandler = (event, data) => {
if (onSelectionDrag) {
onSelectionDrag(event, selectedNodes.value);
const NodesSelection = defineComponent({
props: {
onSelectionDragStart: {
type: Function as unknown as PropType<NodesSelectionProps['onSelectionDragStart']>,
required: false,
default: undefined
},
onSelectionDrag: {
type: Function as unknown as PropType<NodesSelectionProps['onSelectionDrag']>,
required: false,
default: undefined
},
onSelectionDragStop: {
type: Function as unknown as PropType<NodesSelectionProps['onSelectionDragStop']>,
required: false,
default: undefined
},
onSelectionContextMenu: {
type: Function as unknown as PropType<NodesSelectionProps['onSelectionContextMenu']>,
required: false,
default: undefined
}
console.log('dragging', data);
};
},
setup(props) {
const store = inject<RevueFlowStore>('store')!;
const nodeRef = ref<HTMLElement | undefined>();
const grid = computed(() => (store.snapToGrid ? store.snapGrid : [1, 1])! as [number, number]);
const onStop: DraggableEventHandler = (event: MouseEvent) => {
store?.updateNodePosDiff({
isDragging: false
});
const selectedNodes = computed(() =>
store.selectedElements
? store.selectedElements.filter(isNode).map((selectedNode) => {
const matchingNode = store.nodes.find((node) => node.id === selectedNode.id);
onSelectionDragStop?.(event, selectedNodes.value);
};
return {
...matchingNode,
position: matchingNode?.__rf.position
} as Node;
})
: []
);
const onContextMenu = (event: MouseEvent) => {
const selectedNodes = store?.selectedElements
? store?.selectedElements.filter(isNode).map((selectedNode) => store?.nodes.find((node) => node.id === selectedNode.id))
: [];
const style = computed(() => ({
transform: `translate(${store.transform[0]}px,${store.transform[1]}px) scale(${store.transform[2]})`
}));
onSelectionContextMenu?.(event, selectedNodes as any);
};
const innerStyle = computed(() => ({
width: `${store.selectedNodesBbox.width}px`,
height: `${store.selectedNodesBbox.height}px`,
top: `${store.selectedNodesBbox.y}px`,
left: `${store.selectedNodesBbox.x}px`
}));
if (!store?.selectedElements || store?.selectionActive) {
return null;
const onStart: DraggableEventHandler = (event: MouseEvent) => {
props.onSelectionDragStart?.(event, selectedNodes.value);
};
const onDrag: DraggableEventHandler = (event) => {
if (props.onSelectionDrag) {
props.onSelectionDrag(event, selectedNodes.value);
}
};
const onStop: DraggableEventHandler = (event: MouseEvent) => {
store.updateNodePosDiff({
isDragging: false
});
props.onSelectionDragStop?.(event, selectedNodes.value);
};
const onContextMenu = (event: MouseEvent) => {
const selectedNodes = store.selectedElements
? store.selectedElements.filter(isNode).map((selectedNode) => store.nodes.find((node) => node.id === selectedNode.id))
: [];
props.onSelectionContextMenu?.(event, selectedNodes as any);
};
return () => {
return !store.selectedElements || store.selectionActive ? (
''
) : (
<div class="revue-flow__nodesselection" style={style.value}>
<Draggable
scale={store.transform[2]}
grid={grid.value}
onStart={onStart}
onDrag={onDrag}
onStop={onStop}
enableUserSelectHack={false}
nodeRef={nodeRef.value}
>
<div ref={nodeRef} class="revue-flow__nodesselection-rect" onContextmenu={onContextMenu} style={innerStyle.value} />
</Draggable>
</div>
);
};
}
return (
<div class="revue-flow__nodesselection" style={style.value}>
<Draggable
scale={store?.transform[2]}
grid={grid.value}
onStart={onStart}
onDrag={onDrag}
onStop={onStop}
enableUserSelectHack={false}
nodeRef={nodeRef.value}
>
<div ref={nodeRef} class="revue-flow__nodesselection-rect" onContextmenu={onContextMenu} style={innerStyle.value} />
</Draggable>
</div>
);
};
});
export default NodesSelection;