UNPKG

@eccenca/gui-elements

Version:

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

212 lines 10.8 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.useReactFlowScrollOnDrag = exports.useReactFlowScrollOnDragV9 = void 0; const react_1 = __importStar(require("react")); const react_flow_renderer_1 = require("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. */ const useReactFlowScrollOnDragV9 = ({ reactFlowProps, scrollOnDrag }) => { /** Tracks the zoom on drag to border functionality. */ const scrollState = react_1.default.useRef({ reactFlowInstance: undefined, currentX: 0, currentY: 0, currentZoom: 1, loggedWarning: false, scrollX: false, scrollY: false, draggingOperationActive: false, }); const useStoreStateInternal = () => { try { return (0, react_flow_renderer_1.useStoreState)((state) => 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. */ const [currentX, currentY, currentZoom] = useStoreStateInternal(); scrollState.current.currentX = currentX; scrollState.current.currentY = currentY; scrollState.current.currentZoom = currentZoom; const originalOnLoad = reactFlowProps.onLoad; const originalOnNodeDragStart = reactFlowProps.onNodeDragStart; const originalOnNodeDragStop = reactFlowProps.onNodeDragStop; const originalOnConnectStart = reactFlowProps.onConnectStart; const originalOnConnectStop = reactFlowProps.onConnectStop; const originalOnSelectionDragStart = reactFlowProps.onSelectionDragStart; const originalOnSelectionDragStop = reactFlowProps.onSelectionDragStop; const originalOnEdgeUpdateStart = reactFlowProps.onEdgeUpdateStart; const originalOnEdgeUpdateEnd = reactFlowProps.onEdgeUpdateEnd; const scrollInterval = scrollOnDrag === null || scrollOnDrag === void 0 ? void 0 : scrollOnDrag.scrollInterval; const scrollStepSize = scrollOnDrag === null || scrollOnDrag === void 0 ? void 0 : scrollOnDrag.scrollStepSize; const reactFlowInstanceId = reactFlowProps.id; const clearIntervalIfExists = react_1.default.useCallback(() => { if (scrollState.current.scrollTaskId) { clearInterval(scrollState.current.scrollTaskId); } }, []); const setScrolling = react_1.default.useCallback((active) => { scrollState.current.draggingOperationActive = active; if (!active) { clearIntervalIfExists(); } }, [clearIntervalIfExists]); // Handle scrolling if any operation is active e.g. connecting or dragging a node react_1.default.useEffect(() => { if (scrollInterval && scrollStepSize && reactFlowInstanceId) { const handleScrolling = (event) => { const state = scrollState.current; if (!state.draggingOperationActive) { clearIntervalIfExists(); return; } // Check if mouse pointer is outside of the canvas const 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; } const boundingRect = canvasElement.getBoundingClientRect(); const xStepSize = boundingRect.width * scrollStepSize; const yStepSize = boundingRect.height * scrollStepSize; if (boundingRect.top > event.clientY || boundingRect.bottom < event.clientY || boundingRect.left > event.clientX || boundingRect.right < event.clientX) { const scrollX = boundingRect.left > event.clientX ? xStepSize : boundingRect.right < event.clientX ? -xStepSize : 0; const scrollY = boundingRect.top > event.clientY ? yStepSize : boundingRect.bottom < event.clientY ? -yStepSize : 0; if (state.scrollY === (scrollY !== 0) && state.scrollX === (scrollX !== 0)) { // Nothing has changed, do not change interval function return; } clearIntervalIfExists(); state.scrollTaskId = setInterval(() => { var _a; (_a = state.reactFlowInstance) === null || _a === void 0 ? void 0 : _a.setTransform({ x: state.currentX + scrollX, y: state.currentY + scrollY, zoom: state.currentZoom, }); }, scrollInterval); } else { clearIntervalIfExists(); } }; const disableScrollingOnMouseUp = () => { scrollState.current.draggingOperationActive = false; clearIntervalIfExists(); }; document.addEventListener("mousemove", handleScrolling); document.addEventListener("mouseup", disableScrollingOnMouseUp); return () => { document.removeEventListener("mousemove", handleScrolling); document.removeEventListener("mouseup", disableScrollingOnMouseUp); }; } else { return undefined; } }, [scrollInterval, scrollStepSize, reactFlowInstanceId, clearIntervalIfExists]); const onLoad = (0, react_1.useCallback)((rfi) => { scrollState.current.reactFlowInstance = rfi; originalOnLoad === null || originalOnLoad === void 0 ? void 0 : originalOnLoad(rfi); }, [originalOnLoad]); /** Wrap original callbacks to turn scrolling on and off. */ const onConnectStart = react_1.default.useCallback((event, params) => { setScrolling(true); originalOnConnectStart === null || originalOnConnectStart === void 0 ? void 0 : originalOnConnectStart(event, params); }, [originalOnConnectStart, setScrolling]); const onConnectStop = react_1.default.useCallback((event) => { setScrolling(false); originalOnConnectStop === null || originalOnConnectStop === void 0 ? void 0 : originalOnConnectStop(event); }, [originalOnConnectStop, setScrolling]); const onNodeDragStart = react_1.default.useCallback((event, node) => { setScrolling(true); originalOnNodeDragStart === null || originalOnNodeDragStart === void 0 ? void 0 : originalOnNodeDragStart(event, node); }, [originalOnNodeDragStart, setScrolling]); const onNodeDragStop = react_1.default.useCallback((event, node) => { setScrolling(false); originalOnNodeDragStop === null || originalOnNodeDragStop === void 0 ? void 0 : originalOnNodeDragStop(event, node); }, [originalOnNodeDragStop, setScrolling]); const onSelectionDragStart = react_1.default.useCallback((event, nodes) => { setScrolling(true); originalOnSelectionDragStart === null || originalOnSelectionDragStart === void 0 ? void 0 : originalOnSelectionDragStart(event, nodes); }, [originalOnSelectionDragStart, setScrolling]); const onSelectionDragStop = react_1.default.useCallback((event, nodes) => { setScrolling(false); originalOnSelectionDragStop === null || originalOnSelectionDragStop === void 0 ? void 0 : originalOnSelectionDragStop(event, nodes); }, [originalOnSelectionDragStop, setScrolling]); const onEdgeUpdateStart = react_1.default.useCallback((event, edge) => { setScrolling(true); originalOnEdgeUpdateStart === null || originalOnEdgeUpdateStart === void 0 ? void 0 : originalOnEdgeUpdateStart(event, edge); }, [originalOnEdgeUpdateStart, setScrolling]); const onEdgeUpdateEnd = react_1.default.useCallback((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, onNodeDragStart, onNodeDragStop, onConnectStart, onConnectStop, onSelectionDragStart, onSelectionDragStop, onEdgeUpdateStart, onEdgeUpdateEnd, }; } }; exports.useReactFlowScrollOnDragV9 = useReactFlowScrollOnDragV9; /** * @deprecated (v26) Currently it ony supports ReactFlow v9. Better to `useReactFlowScrollOnDragV9` for now. */ exports.useReactFlowScrollOnDrag = exports.useReactFlowScrollOnDragV9; //# sourceMappingURL=scrollOnDragHook.js.map