From 61ab006e94c5e1fcec8a591ec05e0de727128c44 Mon Sep 17 00:00:00 2001 From: Braks <78412429+bcakmakoglu@users.noreply.github.com> Date: Sat, 17 Jul 2021 19:34:32 +0200 Subject: [PATCH] fix: node selection rect not properly rendering on key press and mousemove * issue came from some reactivity problems; a component shouldn't return null, else it'll basically do nothing ever again if it's not completely remounted * some type fixes, removed some any's --- src/components/NodesSelection/index.tsx | 1 + src/components/UserSelection/index.tsx | 57 +++++++++++-------------- src/container/FlowRenderer/index.tsx | 26 +++++------ src/container/RevueFlow/index.tsx | 4 +- src/container/ZoomPane/index.tsx | 10 ++--- src/hooks/useGlobalKeyHandler.ts | 18 ++++---- tsconfig.json | 1 + 7 files changed, 57 insertions(+), 60 deletions(-) diff --git a/src/components/NodesSelection/index.tsx b/src/components/NodesSelection/index.tsx index 4dabb11d..d817c096 100644 --- a/src/components/NodesSelection/index.tsx +++ b/src/components/NodesSelection/index.tsx @@ -21,6 +21,7 @@ const NodesSelection = ({ onSelectionContextMenu }: NodesSelectionProps) => { const store = inject('store'); + console.log('nodesSelection'); const nodeRef = ref(); diff --git a/src/components/UserSelection/index.tsx b/src/components/UserSelection/index.tsx index 88d12204..8774c16e 100644 --- a/src/components/UserSelection/index.tsx +++ b/src/components/UserSelection/index.tsx @@ -2,11 +2,7 @@ * The user selection rectangle gets displayed when a user drags the mouse while pressing shift */ import { RevueFlowStore, XYPosition } from '../../types'; -import { computed, defineComponent, inject, PropType } from 'vue'; - -type UserSelectionProps = { - selectionKeyPressed: boolean; -}; +import { computed, defineComponent, inject } from 'vue'; function getMousePosition(event: MouseEvent): XYPosition | void { const revueFlowNode = (event.target as Element).closest('.revue-flow'); @@ -26,38 +22,29 @@ const SelectionRect = defineComponent({ setup() { const store = inject('store'); - if (!store?.userSelectionRect.draw) { - return null; - } - - return () => ( -
- ); + return () => { + return store?.userSelectionRect.draw ? ( +
+ ) : ( + '' + ); + }; } }); export default defineComponent({ components: { SelectionRect }, - props: { - selectionKeyPressed: { - type: Boolean as PropType, - required: true - } - }, - setup(props) { + setup() { const store = inject('store')!; - const renderUserSelectionPane = computed(() => { - return props.selectionKeyPressed || store.selectionActive; - }); - const shouldRender = computed(() => renderUserSelectionPane.value || store.elementsSelectable); + const shouldRender = computed(() => store.selectionActive || store.elementsSelectable); if (!shouldRender.value) { return null; @@ -69,11 +56,12 @@ export default defineComponent({ return; } + console.log('mouseDown'); store?.setUserSelection(mousePos); }; const onMouseMove = (event: MouseEvent): void => { - if (!props.selectionKeyPressed || !store?.selectionActive) { + if (!store?.selectionActive) { return; } const mousePos = getMousePosition(event); @@ -81,11 +69,15 @@ export default defineComponent({ if (!mousePos) { return; } + console.log('mousemove'); store?.updateUserSelection(mousePos); }; - const onMouseUp = () => store?.unsetUserSelection(); + const onMouseUp = () => { + console.log('mosueUp'); + store?.unsetUserSelection(); + }; const onMouseLeave = () => { store?.unsetUserSelection(); @@ -97,6 +89,7 @@ export default defineComponent({ class="revue-flow__selectionpane" onMousedown={onMouseDown} onMousemove={onMouseMove} + onClick={onMouseUp} onMouseup={onMouseUp} onMouseleave={onMouseLeave} > diff --git a/src/container/FlowRenderer/index.tsx b/src/container/FlowRenderer/index.tsx index 684f4820..f97b206d 100644 --- a/src/container/FlowRenderer/index.tsx +++ b/src/container/FlowRenderer/index.tsx @@ -27,57 +27,57 @@ const FlowRenderer = defineComponent({ onPaneClick: { type: Function as unknown as PropType, required: false, - default: undefined as any + default: undefined }, onPaneContextMenu: { type: Function as unknown as PropType, required: false, - default: undefined as any + default: undefined }, onPaneScroll: { type: Function as unknown as PropType, required: false, - default: undefined as any + default: undefined }, onElementsRemove: { type: Function as unknown as PropType, required: false, - default: undefined as any + default: undefined }, onMove: { type: Function as unknown as PropType, required: false, - default: undefined as any + default: undefined }, onMoveStart: { type: Function as unknown as PropType, required: false, - default: undefined as any + default: undefined }, onMoveEnd: { type: Function as unknown as PropType, required: false, - default: undefined as any + default: undefined }, onSelectionDragStart: { type: Function as unknown as PropType, required: false, - default: undefined as any + default: undefined }, onSelectionDrag: { type: Function as unknown as PropType, required: false, - default: undefined as any + default: undefined }, onSelectionDragStop: { type: Function as unknown as PropType, required: false, - default: undefined as any + default: undefined }, onSelectionContextMenu: { type: Function as unknown as PropType, required: false, - default: undefined as any + default: undefined }, deleteKeyCode: { type: [Number, String] as PropType, @@ -184,7 +184,7 @@ const FlowRenderer = defineComponent({ onMove={props.onMove} onMoveStart={props.onMoveStart} onMoveEnd={props.onMoveEnd} - selectionKeyPressed={false} + selectionKeyPressed={keyPressed.value} elementsSelectable={props.elementsSelectable} zoomOnScroll={props.zoomOnScroll} zoomOnPinch={props.zoomOnPinch} @@ -199,7 +199,7 @@ const FlowRenderer = defineComponent({ zoomActivationKeyCode={props.zoomActivationKeyCode} > {slots.default ? slots.default() : ''} - {keyPressed.value ? : ''} + {keyPressed.value ? : ''} {store?.nodesSelectionActive && ( any>, required: false, - default: undefined as any + default: undefined }, onDragover: { type: Function as unknown as PropType<(e: DragEvent) => any>, required: false, - default: undefined as any + default: undefined } /* // focus events diff --git a/src/container/ZoomPane/index.tsx b/src/container/ZoomPane/index.tsx index e1abb5a3..f3edb571 100644 --- a/src/container/ZoomPane/index.tsx +++ b/src/container/ZoomPane/index.tsx @@ -3,7 +3,7 @@ import { select, pointer } from 'd3-selection'; import { clamp } from '../../utils'; import { FlowTransform, TranslateExtent, PanOnScrollMode, KeyCode } from '../../types'; -import { defineComponent, onMounted, PropType, ref, watch } from 'vue'; +import { defineComponent, onMounted, PropType, ref, watch, watchEffect } from 'vue'; import store from '../../store'; import useKeyPress from '../../hooks/useKeyPress'; import useResizeHandler from '../../hooks/useResizeHandler'; @@ -193,7 +193,7 @@ const ZoomPane = defineComponent({ } }); - onMounted(() => { + watchEffect(() => { if (pinia.d3Zoom) { if (props.selectionKeyPressed) { pinia.d3Zoom.on('zoom', null); @@ -210,7 +210,7 @@ const ZoomPane = defineComponent({ } }); - onMounted(() => { + watchEffect(() => { if (pinia.d3Zoom) { if (props.onMoveStart) { pinia.d3Zoom.on('start', (event: any) => { @@ -227,7 +227,7 @@ const ZoomPane = defineComponent({ } }); - onMounted(() => { + watchEffect(() => { if (pinia.d3Zoom) { if (props.onMoveEnd) { pinia.d3Zoom.on('end', (event: any) => { @@ -244,7 +244,7 @@ const ZoomPane = defineComponent({ } }); - onMounted(() => { + watchEffect(() => { if (pinia.d3Zoom) { pinia.d3Zoom.filter((event: any) => { const zoomScroll = props.zoomOnScroll; diff --git a/src/hooks/useGlobalKeyHandler.ts b/src/hooks/useGlobalKeyHandler.ts index d778c84d..86d904ed 100644 --- a/src/hooks/useGlobalKeyHandler.ts +++ b/src/hooks/useGlobalKeyHandler.ts @@ -1,7 +1,7 @@ import useKeyPress from './useKeyPress'; import { isNode, getConnectedEdges } from '../utils/graph'; -import { Elements, KeyCode, ElementId, FlowElement, RevueFlowStore } from '../types'; -import { inject, onMounted } from 'vue'; +import { Elements, KeyCode, ElementId, FlowElement, RevueFlowStore, Edge } from '../types'; +import { computed, inject, watch } from 'vue'; interface HookParams { deleteKeyCode: KeyCode; @@ -14,12 +14,14 @@ export default ({ deleteKeyCode, multiSelectionKeyCode, onElementsRemove }: Hook const deleteKeyPressed = useKeyPress(deleteKeyCode); const multiSelectionKeyPressed = useKeyPress(multiSelectionKeyCode); + const selectedElements = computed(() => store?.selectedElements || []); + const edges = computed(() => store?.edges); - onMounted(() => { - if (onElementsRemove && deleteKeyPressed.value && store?.selectedElements) { - const selectedNodes = store?.selectedElements.filter(isNode); - const connectedEdges = getConnectedEdges(selectedNodes, store?.edges); - const elementsToRemove = [...store?.selectedElements, ...connectedEdges].reduce( + watch(selectedElements, () => { + if (onElementsRemove && deleteKeyPressed.value && selectedElements.value.length > 0) { + const selectedNodes = selectedElements.value.filter(isNode); + const connectedEdges = getConnectedEdges(selectedNodes, edges.value as Edge[]); + const elementsToRemove = [...selectedElements.value, ...connectedEdges].reduce( (res, item) => res.set(item.id, item), new Map() ); @@ -30,7 +32,7 @@ export default ({ deleteKeyCode, multiSelectionKeyCode, onElementsRemove }: Hook } }); - onMounted(() => { + watch(multiSelectionKeyPressed, () => { store?.setMultiSelectionActive(multiSelectionKeyPressed.value); }); }; diff --git a/tsconfig.json b/tsconfig.json index 3831c390..db02b28c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,6 +5,7 @@ "moduleResolution": "node", "strict": true, "jsx": "preserve", + "jsxFactory": "", "sourceMap": true, "resolveJsonModule": true, "esModuleInterop": true,