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:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user