From e05c1b26f150e49c7c4b107ee48c9de78284db81 Mon Sep 17 00:00:00 2001 From: "kasia.oczkowska" Date: Wed, 10 Jul 2024 12:47:54 +0100 Subject: [PATCH] feat: limit vertical scroll to a reasonable boundary --- .../src/components/EditorNew/EditorNew.jsx | 24 +++++++++++-- .../EditorNew/useScrollBoundaries.js | 36 ++++++++++++++----- 2 files changed, 49 insertions(+), 11 deletions(-) diff --git a/packages/web/src/components/EditorNew/EditorNew.jsx b/packages/web/src/components/EditorNew/EditorNew.jsx index 066d60a4..73d29c51 100644 --- a/packages/web/src/components/EditorNew/EditorNew.jsx +++ b/packages/web/src/components/EditorNew/EditorNew.jsx @@ -1,4 +1,4 @@ -import { useEffect, useCallback, createContext, useRef } from 'react'; +import { useEffect, useCallback, createContext, useRef, useState } from 'react'; import { useMutation } from '@apollo/client'; import { useQueryClient } from '@tanstack/react-query'; import { FlowPropType } from 'propTypes/propTypes'; @@ -45,11 +45,13 @@ const EditorNew = ({ flow }) => { const [edges, setEdges, onEdgesChange] = useEdgesState( generateInitialEdges(flow), ); + const [containerHeight, setContainerHeight] = useState(null); useAutoLayout(); - useScrollBoundaries(); + useScrollBoundaries(containerHeight); const createdStepIdRef = useRef(null); + const containerRef = useRef(null); const openNextStep = useCallback( (currentStepId) => { @@ -229,6 +231,22 @@ const EditorNew = ({ flow }) => { } }, [flow.steps]); + useEffect(function updateContainerHeightOnResize() { + const updateHeight = () => { + if (containerRef.current) { + setContainerHeight(containerRef.current.clientHeight); + } + }; + + updateHeight(); + + window.addEventListener('resize', updateHeight); + + return () => { + window.removeEventListener('resize', updateHeight); + }; + }, []); + return ( { flowActive: flow.active, }} > - + { +const scrollYMargin = 100; + +export const useScrollBoundaries = (containerHeight) => { const { setViewport } = useReactFlow(); const { x, y, zoom } = useViewport(); + const nodes = useNodes(); + const [maxYScroll, setMaxYScroll] = useState(null); - useEffect(() => { - if (y > 0) { - setViewport({ x, y: 0, zoom }); - } - }, [y]); + useEffect( + function updateViewportPosition() { + if (y > 0) { + setViewport({ x, y: 0, zoom }); + } else if (typeof maxYScroll === 'number' && y < maxYScroll) { + setViewport({ x, y: maxYScroll, zoom }); + } + }, + [y, maxYScroll], + ); + + useEffect( + function updateMaxYScroll() { + if (nodes?.length && containerHeight) { + const maxY = + containerHeight - nodes[nodes.length - 1].y - scrollYMargin; + setMaxYScroll(maxY >= 0 ? 0 : maxY); + } + }, + [nodes, containerHeight], + ); };