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
This commit is contained in:
Braks
2021-07-17 19:34:32 +02:00
parent 087eb52f1f
commit 61ab006e94
7 changed files with 57 additions and 60 deletions

View File

@@ -21,6 +21,7 @@ const NodesSelection = ({
onSelectionContextMenu
}: NodesSelectionProps) => {
const store = inject<RevueFlowStore>('store');
console.log('nodesSelection');
const nodeRef = ref<HTMLElement | undefined>();

View File

@@ -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<RevueFlowStore>('store');
if (!store?.userSelectionRect.draw) {
return null;
}
return () => (
<div
class="revue-flow__selection"
style={{
width: `${store?.userSelectionRect.width}px`,
height: `${store?.userSelectionRect.height}px`,
transform: `translate(${store?.userSelectionRect.x}px, ${store?.userSelectionRect.y}px)`
}}
/>
);
return () => {
return store?.userSelectionRect.draw ? (
<div
class="revue-flow__selection"
style={{
width: `${store?.userSelectionRect.width}px`,
height: `${store?.userSelectionRect.height}px`,
transform: `translate(${store?.userSelectionRect.x}px, ${store?.userSelectionRect.y}px)`
}}
/>
) : (
''
);
};
}
});
export default defineComponent({
components: { SelectionRect },
props: {
selectionKeyPressed: {
type: Boolean as PropType<UserSelectionProps['selectionKeyPressed']>,
required: true
}
},
setup(props) {
setup() {
const store = inject<RevueFlowStore>('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}
>

View File

@@ -27,57 +27,57 @@ const FlowRenderer = defineComponent({
onPaneClick: {
type: Function as unknown as PropType<FlowRendererProps['onPaneClick']>,
required: false,
default: undefined as any
default: undefined
},
onPaneContextMenu: {
type: Function as unknown as PropType<FlowRendererProps['onPaneContextMenu']>,
required: false,
default: undefined as any
default: undefined
},
onPaneScroll: {
type: Function as unknown as PropType<FlowRendererProps['onPaneScroll']>,
required: false,
default: undefined as any
default: undefined
},
onElementsRemove: {
type: Function as unknown as PropType<FlowRendererProps['onElementsRemove']>,
required: false,
default: undefined as any
default: undefined
},
onMove: {
type: Function as unknown as PropType<FlowRendererProps['onMove']>,
required: false,
default: undefined as any
default: undefined
},
onMoveStart: {
type: Function as unknown as PropType<FlowRendererProps['onMoveStart']>,
required: false,
default: undefined as any
default: undefined
},
onMoveEnd: {
type: Function as unknown as PropType<FlowRendererProps['onMoveEnd']>,
required: false,
default: undefined as any
default: undefined
},
onSelectionDragStart: {
type: Function as unknown as PropType<FlowRendererProps['onSelectionDragStart']>,
required: false,
default: undefined as any
default: undefined
},
onSelectionDrag: {
type: Function as unknown as PropType<FlowRendererProps['onSelectionDrag']>,
required: false,
default: undefined as any
default: undefined
},
onSelectionDragStop: {
type: Function as unknown as PropType<FlowRendererProps['onSelectionDragStop']>,
required: false,
default: undefined as any
default: undefined
},
onSelectionContextMenu: {
type: Function as unknown as PropType<FlowRendererProps['onSelectionContextMenu']>,
required: false,
default: undefined as any
default: undefined
},
deleteKeyCode: {
type: [Number, String] as PropType<FlowRendererProps['deleteKeyCode']>,
@@ -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 ? <UserSelection selectionKeyPressed={keyPressed.value} /> : ''}
{keyPressed.value ? <UserSelection track-by={'selection'} /> : ''}
{store?.nodesSelectionActive && (
<NodesSelection
onSelectionDragStart={props.onSelectionDragStart}

View File

@@ -485,12 +485,12 @@ const RevueFlow = defineComponent({
onDrop: {
type: Function as unknown as PropType<(e: DragEvent) => 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

View File

@@ -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;

View File

@@ -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<ElementId, FlowElement>()
);
@@ -30,7 +32,7 @@ export default ({ deleteKeyCode, multiSelectionKeyCode, onElementsRemove }: Hook
}
});
onMounted(() => {
watch(multiSelectionKeyPressed, () => {
store?.setMultiSelectionActive(multiSelectionKeyPressed.value);
});
};

View File

@@ -5,6 +5,7 @@
"moduleResolution": "node",
"strict": true,
"jsx": "preserve",
"jsxFactory": "",
"sourceMap": true,
"resolveJsonModule": true,
"esModuleInterop": true,