Skip to content

Commit

Permalink
fix(editor): Support middle click to scroll when using a mouse on new…
Browse files Browse the repository at this point in the history
… canvas (#11384)
  • Loading branch information
alexgrozav authored and netroy committed Oct 28, 2024
1 parent 714f618 commit 436b783
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 16 deletions.
16 changes: 16 additions & 0 deletions packages/editor-ui/src/components/canvas/Canvas.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,4 +220,20 @@ describe('Canvas', () => {
expect(container.querySelector('#diagonalHatch')).toBeInTheDocument();
});
});

describe('pane', () => {
describe('onPaneMouseDown', () => {
it('should enable panning when middle mouse button is pressed', async () => {
const { getByTestId } = renderComponent();
const canvas = getByTestId('canvas');
const pane = canvas.querySelector('.vue-flow__pane');

if (!pane) throw new Error('VueFlow pane not in the document');

await fireEvent.mouseDown(canvas, { button: 1, view: window });

expect(canvas).toHaveClass('draggable');
});
});
});
});
41 changes: 36 additions & 5 deletions packages/editor-ui/src/components/canvas/Canvas.vue
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import { onKeyDown, onKeyUp, useDebounceFn } from '@vueuse/core';
import CanvasArrowHeadMarker from './elements/edges/CanvasArrowHeadMarker.vue';
import { CanvasNodeRenderType } from '@/types';
import CanvasBackgroundStripedPattern from './elements/CanvasBackgroundStripedPattern.vue';
import { isMiddleMouseButton } from '@/utils/eventUtils';
const $style = useCssModule();
Expand Down Expand Up @@ -107,6 +108,7 @@ const props = withDefaults(
);
const {
vueFlowRef,
getSelectedNodes: selectedNodes,
addSelectedNodes,
removeSelectedNodes,
Expand Down Expand Up @@ -143,18 +145,16 @@ const disableKeyBindings = computed(() => !props.keyBindings);
* @see https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_key_values#whitespace_keys
*/
const isPanningEnabled = ref(false);
const panningKeyCode = ' ';
const isPanningEnabled = ref(false);
const selectionKeyCode = ref<true | null>(true);
onKeyDown(panningKeyCode, () => {
isPanningEnabled.value = true;
selectionKeyCode.value = null;
setPanningEnabled(true);
});
onKeyUp(panningKeyCode, () => {
isPanningEnabled.value = false;
selectionKeyCode.value = true;
setPanningEnabled(false);
});
const keyMap = computed(() => ({
Expand Down Expand Up @@ -186,6 +186,16 @@ const keyMap = computed(() => ({
useKeybindings(keyMap, { disabled: disableKeyBindings });
function setPanningEnabled(value: boolean) {
if (value) {
isPanningEnabled.value = true;
selectionKeyCode.value = null;
} else {
isPanningEnabled.value = false;
selectionKeyCode.value = true;
}
}
/**
* When the window is focused, the selection key code is lost.
* We trigger a value refresh to ensure that the selection key code is set correctly again.
Expand Down Expand Up @@ -384,12 +394,28 @@ function setReadonly(value: boolean) {
elementsSelectable.value = true;
}
function onPaneMouseDown(event: MouseEvent) {
if (isMiddleMouseButton(event)) {
setPanningEnabled(true);
// Re-emit the event to start panning after setting the panning state to true
// This workaround is necessary because the Vue Flow library does not provide a way to
// start panning programmatically
void nextTick(() =>
vueFlowRef.value
?.querySelector('.vue-flow__pane')
?.dispatchEvent(new MouseEvent('mousedown', event)),
);
}
}
function onPaneMoveStart() {
isPaneMoving.value = true;
}
function onPaneMoveEnd() {
isPaneMoving.value = false;
setPanningEnabled(false);
}
/**
Expand Down Expand Up @@ -559,6 +585,7 @@ provide(CanvasKey, {
@nodes-change="onNodesChange"
@move-start="onPaneMoveStart"
@move-end="onPaneMoveEnd"
@mousedown="onPaneMouseDown"
>
<template #node-canvas-node="canvasNodeProps">
<Node
Expand Down Expand Up @@ -647,6 +674,10 @@ provide(CanvasKey, {
cursor: grab;
}
:global(.vue-flow__pane) {
cursor: default;
}
:global(.vue-flow__pane.dragging) {
cursor: grabbing;
}
Expand Down
11 changes: 0 additions & 11 deletions packages/editor-ui/src/styles/plugins/_vueflow.scss
Original file line number Diff line number Diff line change
Expand Up @@ -58,17 +58,6 @@
}
}

/**
* Pane
*/

.vue-flow__pane {
&,
&.draggable {
cursor: default;
}
}

/**
* Nodes
*/
Expand Down
3 changes: 3 additions & 0 deletions packages/editor-ui/src/utils/eventUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function isMiddleMouseButton(event: MouseEvent) {
return event.which === 2 || event.button === 1;
}

0 comments on commit 436b783

Please sign in to comment.