UNPKG

@eccenca/gui-elements

Version:

GUI elements based on other libraries, usable in React application, written in Typescript.

202 lines 10.1 kB
var __read = (this && this.__read) || function (o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; }; import React, { useCallback } from "react"; import { useStoreState } from "react-flow-renderer"; /** Handles the scrolling of the react-flow canvas on all drag operations when the mouse pointer gets near or over the borders. * The return value contains the wrapped react-flow callback functions that need to be handed over to the react-flow component. */ export var useReactFlowScrollOnDragV9 = function (_a) { var reactFlowProps = _a.reactFlowProps, scrollOnDrag = _a.scrollOnDrag; /** Tracks the zoom on drag to border functionality. */ var scrollState = React.useRef({ reactFlowInstance: undefined, currentX: 0, currentY: 0, currentZoom: 1, loggedWarning: false, scrollX: false, scrollY: false, draggingOperationActive: false, }); var useStoreStateInternal = function () { try { return useStoreState(function (state) { return state.transform; }); } catch (ex) { if (reactFlowProps.id && scrollOnDrag) { // eslint-disable-next-line no-console console.warn("Scroll on drag is not correctly working. Reason: " + ex); } return [0, 0, 1]; } }; /** The current position and zoom factor of the view port. */ var _b = __read(useStoreStateInternal(), 3), currentX = _b[0], currentY = _b[1], currentZoom = _b[2]; scrollState.current.currentX = currentX; scrollState.current.currentY = currentY; scrollState.current.currentZoom = currentZoom; var originalOnLoad = reactFlowProps.onLoad; var originalOnNodeDragStart = reactFlowProps.onNodeDragStart; var originalOnNodeDragStop = reactFlowProps.onNodeDragStop; var originalOnConnectStart = reactFlowProps.onConnectStart; var originalOnConnectStop = reactFlowProps.onConnectStop; var originalOnSelectionDragStart = reactFlowProps.onSelectionDragStart; var originalOnSelectionDragStop = reactFlowProps.onSelectionDragStop; var originalOnEdgeUpdateStart = reactFlowProps.onEdgeUpdateStart; var originalOnEdgeUpdateEnd = reactFlowProps.onEdgeUpdateEnd; var scrollInterval = scrollOnDrag === null || scrollOnDrag === void 0 ? void 0 : scrollOnDrag.scrollInterval; var scrollStepSize = scrollOnDrag === null || scrollOnDrag === void 0 ? void 0 : scrollOnDrag.scrollStepSize; var reactFlowInstanceId = reactFlowProps.id; var clearIntervalIfExists = React.useCallback(function () { if (scrollState.current.scrollTaskId) { clearInterval(scrollState.current.scrollTaskId); } }, []); var setScrolling = React.useCallback(function (active) { scrollState.current.draggingOperationActive = active; if (!active) { clearIntervalIfExists(); } }, [clearIntervalIfExists]); // Handle scrolling if any operation is active e.g. connecting or dragging a node React.useEffect(function () { if (scrollInterval && scrollStepSize && reactFlowInstanceId) { var handleScrolling_1 = function (event) { var state = scrollState.current; if (!state.draggingOperationActive) { clearIntervalIfExists(); return; } // Check if mouse pointer is outside of the canvas var canvasElement = document.getElementById(reactFlowInstanceId); if (!canvasElement) { if (!state.loggedWarning) { // eslint-disable-next-line no-console console.warn("No element found with ID " + reactFlowInstanceId); state.loggedWarning = true; } return; } var boundingRect = canvasElement.getBoundingClientRect(); var xStepSize = boundingRect.width * scrollStepSize; var yStepSize = boundingRect.height * scrollStepSize; if (boundingRect.top > event.clientY || boundingRect.bottom < event.clientY || boundingRect.left > event.clientX || boundingRect.right < event.clientX) { var scrollX_1 = boundingRect.left > event.clientX ? xStepSize : boundingRect.right < event.clientX ? -xStepSize : 0; var scrollY_1 = boundingRect.top > event.clientY ? yStepSize : boundingRect.bottom < event.clientY ? -yStepSize : 0; if (state.scrollY === (scrollY_1 !== 0) && state.scrollX === (scrollX_1 !== 0)) { // Nothing has changed, do not change interval function return; } clearIntervalIfExists(); state.scrollTaskId = setInterval(function () { var _a; (_a = state.reactFlowInstance) === null || _a === void 0 ? void 0 : _a.setTransform({ x: state.currentX + scrollX_1, y: state.currentY + scrollY_1, zoom: state.currentZoom, }); }, scrollInterval); } else { clearIntervalIfExists(); } }; var disableScrollingOnMouseUp_1 = function () { scrollState.current.draggingOperationActive = false; clearIntervalIfExists(); }; document.addEventListener("mousemove", handleScrolling_1); document.addEventListener("mouseup", disableScrollingOnMouseUp_1); return function () { document.removeEventListener("mousemove", handleScrolling_1); document.removeEventListener("mouseup", disableScrollingOnMouseUp_1); }; } else { return undefined; } }, [scrollInterval, scrollStepSize, reactFlowInstanceId, clearIntervalIfExists]); var onLoad = useCallback(function (rfi) { scrollState.current.reactFlowInstance = rfi; originalOnLoad === null || originalOnLoad === void 0 ? void 0 : originalOnLoad(rfi); }, [originalOnLoad]); /** Wrap original callbacks to turn scrolling on and off. */ var onConnectStart = React.useCallback(function (event, params) { setScrolling(true); originalOnConnectStart === null || originalOnConnectStart === void 0 ? void 0 : originalOnConnectStart(event, params); }, [originalOnConnectStart, setScrolling]); var onConnectStop = React.useCallback(function (event) { setScrolling(false); originalOnConnectStop === null || originalOnConnectStop === void 0 ? void 0 : originalOnConnectStop(event); }, [originalOnConnectStop, setScrolling]); var onNodeDragStart = React.useCallback(function (event, node) { setScrolling(true); originalOnNodeDragStart === null || originalOnNodeDragStart === void 0 ? void 0 : originalOnNodeDragStart(event, node); }, [originalOnNodeDragStart, setScrolling]); var onNodeDragStop = React.useCallback(function (event, node) { setScrolling(false); originalOnNodeDragStop === null || originalOnNodeDragStop === void 0 ? void 0 : originalOnNodeDragStop(event, node); }, [originalOnNodeDragStop, setScrolling]); var onSelectionDragStart = React.useCallback(function (event, nodes) { setScrolling(true); originalOnSelectionDragStart === null || originalOnSelectionDragStart === void 0 ? void 0 : originalOnSelectionDragStart(event, nodes); }, [originalOnSelectionDragStart, setScrolling]); var onSelectionDragStop = React.useCallback(function (event, nodes) { setScrolling(false); originalOnSelectionDragStop === null || originalOnSelectionDragStop === void 0 ? void 0 : originalOnSelectionDragStop(event, nodes); }, [originalOnSelectionDragStop, setScrolling]); var onEdgeUpdateStart = React.useCallback(function (event, edge) { setScrolling(true); originalOnEdgeUpdateStart === null || originalOnEdgeUpdateStart === void 0 ? void 0 : originalOnEdgeUpdateStart(event, edge); }, [originalOnEdgeUpdateStart, setScrolling]); var onEdgeUpdateEnd = React.useCallback(function (event, edge) { setScrolling(false); originalOnEdgeUpdateEnd === null || originalOnEdgeUpdateEnd === void 0 ? void 0 : originalOnEdgeUpdateEnd(event, edge); }, [originalOnEdgeUpdateEnd, setScrolling]); if (!reactFlowProps.id || !scrollOnDrag) { // No instance ID or config available, return empty object that will not overwrite any react-flow config parameters return {}; } else { return { onLoad: onLoad, onNodeDragStart: onNodeDragStart, onNodeDragStop: onNodeDragStop, onConnectStart: onConnectStart, onConnectStop: onConnectStop, onSelectionDragStart: onSelectionDragStart, onSelectionDragStop: onSelectionDragStop, onEdgeUpdateStart: onEdgeUpdateStart, onEdgeUpdateEnd: onEdgeUpdateEnd, }; } }; /** * @deprecated (v26) Currently it ony supports ReactFlow v9. Better to `useReactFlowScrollOnDragV9` for now. */ export var useReactFlowScrollOnDrag = useReactFlowScrollOnDragV9; //# sourceMappingURL=scrollOnDragHook.js.map