diff --git a/example/src/Layouting/index.js b/example/src/Layouting/index.js index 1d094e63..97028dde 100644 --- a/example/src/Layouting/index.js +++ b/example/src/Layouting/index.js @@ -46,7 +46,7 @@ const LayoutFlow = () => { useEffect(() => { onLayout('TB'); - }, []); + }, [onLayout]); return (
diff --git a/src/container/FlowRenderer/index.tsx b/src/container/FlowRenderer/index.tsx index cae1998a..c98486f9 100644 --- a/src/container/FlowRenderer/index.tsx +++ b/src/container/FlowRenderer/index.tsx @@ -37,6 +37,7 @@ const FlowRenderer = ({ onMoveEnd, selectionKeyCode, multiSelectionKeyCode, + zoomActivationKeyCode, elementsSelectable, zoomOnScroll, panOnScroll, @@ -99,6 +100,7 @@ const FlowRenderer = ({ defaultPosition={defaultPosition} defaultZoom={defaultZoom} translateExtent={translateExtent} + zoomActivationKeyCode={zoomActivationKeyCode} > {children} diff --git a/src/container/GraphView/index.tsx b/src/container/GraphView/index.tsx index 944e3883..04ed7fb9 100644 --- a/src/container/GraphView/index.tsx +++ b/src/container/GraphView/index.tsx @@ -51,6 +51,7 @@ const GraphView = ({ connectionLineComponent, selectionKeyCode, multiSelectionKeyCode, + zoomActivationKeyCode, onElementsRemove, deleteKeyCode, onConnect, @@ -205,6 +206,7 @@ const GraphView = ({ deleteKeyCode={deleteKeyCode} selectionKeyCode={selectionKeyCode} multiSelectionKeyCode={multiSelectionKeyCode} + zoomActivationKeyCode={zoomActivationKeyCode} elementsSelectable={elementsSelectable} onMove={onMove} onMoveStart={onMoveStart} diff --git a/src/container/ReactFlow/index.tsx b/src/container/ReactFlow/index.tsx index 4a86fea8..24445308 100644 --- a/src/container/ReactFlow/index.tsx +++ b/src/container/ReactFlow/index.tsx @@ -82,6 +82,7 @@ export interface ReactFlowProps extends Omit, 'on deleteKeyCode?: KeyCode; selectionKeyCode?: KeyCode; multiSelectionKeyCode?: KeyCode; + zoomActivationKeyCode?: KeyCode; snapToGrid?: boolean; snapGrid?: [number, number]; onlyRenderVisibleElements?: boolean; @@ -138,6 +139,7 @@ const ReactFlow = ({ deleteKeyCode = 'Backspace', selectionKeyCode = 'Shift', multiSelectionKeyCode = 'Meta', + zoomActivationKeyCode = 'Meta', snapToGrid = false, snapGrid = [15, 15], onlyRenderVisibleElements = true, @@ -194,6 +196,7 @@ const ReactFlow = ({ onElementsRemove={onElementsRemove} deleteKeyCode={deleteKeyCode} multiSelectionKeyCode={multiSelectionKeyCode} + zoomActivationKeyCode={zoomActivationKeyCode} onConnect={onConnect} onConnectStart={onConnectStart} onConnectStop={onConnectStop} diff --git a/src/container/ZoomPane/index.tsx b/src/container/ZoomPane/index.tsx index 82aae20d..435d7989 100644 --- a/src/container/ZoomPane/index.tsx +++ b/src/container/ZoomPane/index.tsx @@ -1,12 +1,12 @@ import React, { useEffect, useRef, ReactNode } from 'react'; - import { zoom, zoomIdentity } from 'd3-zoom'; import { select } from 'd3-selection'; -import { clamp } from '../../utils'; +import { clamp } from '../../utils'; +import useKeyPress from '../../hooks/useKeyPress'; import useResizeHandler from '../../hooks/useResizeHandler'; import { useStoreState, useStoreActions, useStore } from '../../store/hooks'; -import { FlowTransform, TranslateExtent, PanOnScrollMode } from '../../types'; +import { FlowTransform, TranslateExtent, PanOnScrollMode, KeyCode } from '../../types'; interface ZoomPaneProps { selectionKeyPressed: boolean; @@ -23,6 +23,7 @@ interface ZoomPaneProps { onMove?: (flowTransform?: FlowTransform) => void; onMoveStart?: (flowTransform?: FlowTransform) => void; onMoveEnd?: (flowTransform?: FlowTransform) => void; + zoomActivationKeyCode?: KeyCode; children: ReactNode; } @@ -52,6 +53,7 @@ const ZoomPane = ({ defaultPosition = [0, 0], defaultZoom = 1, translateExtent, + zoomActivationKeyCode, children, }: ZoomPaneProps) => { const zoomPane = useRef(null); @@ -65,6 +67,8 @@ const ZoomPane = ({ const initD3Zoom = useStoreActions((actions) => actions.initD3Zoom); const updateTransform = useStoreActions((actions) => actions.updateTransform); + const zoomActivationKeyPressed = useKeyPress(zoomActivationKeyCode); + useResizeHandler(zoomPane); useEffect(() => { @@ -93,7 +97,7 @@ const ZoomPane = ({ useEffect(() => { if (d3Selection && d3Zoom) { - if (panOnScroll) { + if (panOnScroll && !zoomActivationKeyPressed) { d3Selection .on('wheel', (event: any) => { event.preventDefault(); @@ -117,7 +121,7 @@ const ZoomPane = ({ d3Selection.on('wheel', null).on('wheel.zoom', d3ZoomHandler); } } - }, [panOnScroll, panOnScrollMode, d3Selection, d3Zoom, d3ZoomHandler]); + }, [panOnScroll, panOnScrollMode, d3Selection, d3Zoom, d3ZoomHandler, zoomActivationKeyPressed]); useEffect(() => { if (d3Zoom) { diff --git a/src/hooks/useKeyPress.ts b/src/hooks/useKeyPress.ts index 80685137..358a6d1a 100644 --- a/src/hooks/useKeyPress.ts +++ b/src/hooks/useKeyPress.ts @@ -3,35 +3,37 @@ import { useState, useEffect } from 'react'; import { isInputDOMNode } from '../utils'; import { KeyCode } from '../types'; -export default (keyCode: KeyCode): boolean => { +export default (keyCode?: KeyCode): boolean => { const [keyPressed, setKeyPressed] = useState(false); useEffect(() => { - const downHandler = (event: KeyboardEvent) => { - if (!isInputDOMNode(event) && (event.key === keyCode || event.keyCode === keyCode)) { - event.preventDefault(); + if (typeof keyCode !== 'undefined') { + const downHandler = (event: KeyboardEvent) => { + if (!isInputDOMNode(event) && (event.key === keyCode || event.keyCode === keyCode)) { + event.preventDefault(); - setKeyPressed(true); - } - }; + setKeyPressed(true); + } + }; - const upHandler = (event: KeyboardEvent) => { - if (!isInputDOMNode(event) && (event.key === keyCode || event.keyCode === keyCode)) { - setKeyPressed(false); - } - }; + const upHandler = (event: KeyboardEvent) => { + if (!isInputDOMNode(event) && (event.key === keyCode || event.keyCode === keyCode)) { + setKeyPressed(false); + } + }; - const resetHandler = () => setKeyPressed(false); + const resetHandler = () => setKeyPressed(false); - window.addEventListener('keydown', downHandler); - window.addEventListener('keyup', upHandler); - window.addEventListener('blur', resetHandler); + window.addEventListener('keydown', downHandler); + window.addEventListener('keyup', upHandler); + window.addEventListener('blur', resetHandler); - return () => { - window.removeEventListener('keydown', downHandler); - window.removeEventListener('keyup', upHandler); - window.removeEventListener('blur', resetHandler); - }; + return () => { + window.removeEventListener('keydown', downHandler); + window.removeEventListener('keyup', upHandler); + window.removeEventListener('blur', resetHandler); + }; + } }, [keyCode, setKeyPressed]); return keyPressed; diff --git a/tsconfig.json b/tsconfig.json index 71d07c92..49d832a7 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -16,11 +16,11 @@ "alwaysStrict": true, "noUnusedLocals": true, "noUnusedParameters": true, - "noImplicitReturns": true, + "noImplicitReturns": false, "noFallthroughCasesInSwitch": true, "allowSyntheticDefaultImports": true, "esModuleInterop": true }, "include": ["src"], "exclude": ["node_modules", "build", "dist", "example", "rollup.config.js"] -} \ No newline at end of file +}