From 9d8c0fd2a082f5612081945338643e910f05ff8a Mon Sep 17 00:00:00 2001 From: gopu-bruno Date: Mon, 15 Jun 2026 12:36:54 +0530 Subject: [PATCH] fix(ui): open response pane at a minimum height on expand (#8236) --- .../src/components/RequestTabPanel/index.js | 20 +++++++++++- .../components/RequestTabPanel/paneSize.js | 14 ++++++++ .../RequestTabPanel/paneSize.spec.js | 32 +++++++++++++++++++ 3 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 packages/bruno-app/src/components/RequestTabPanel/paneSize.js create mode 100644 packages/bruno-app/src/components/RequestTabPanel/paneSize.spec.js diff --git a/packages/bruno-app/src/components/RequestTabPanel/index.js b/packages/bruno-app/src/components/RequestTabPanel/index.js index d45f3a4dc..c5d2ccfcd 100644 --- a/packages/bruno-app/src/components/RequestTabPanel/index.js +++ b/packages/bruno-app/src/components/RequestTabPanel/index.js @@ -43,6 +43,7 @@ import GlobalEnvironmentSettings from 'components/Environments/GlobalEnvironment import OpenAPISyncTab from 'components/OpenAPISyncTab'; import OpenAPISpecTab from 'components/OpenAPISpecTab'; import CollapsedPanelIndicator from './CollapsedPanelIndicator'; +import { clampRequestHeightForResponse } from './paneSize'; import { IconLoader2 } from '@tabler/icons'; const MIN_LEFT_PANE_WIDTH = 300; @@ -51,6 +52,8 @@ const MIN_TOP_PANE_HEIGHT = 150; const MIN_BOTTOM_PANE_HEIGHT = 150; const COLLAPSE_EDGE_THRESHOLD = 80; const EXPAND_EDGE_THRESHOLD = 100; +// Minimum response pane height to show placeholder content on click-expand +const RESPONSE_EXPAND_MIN_HEIGHT = 300; const RequestTabPanel = () => { const dispatch = useDispatch(); @@ -262,6 +265,21 @@ const RequestTabPanel = () => { startDragging(e); }, [expandResponse, applyPointerResize, startDragging]); + const handleResponseIndicatorClickExpand = useCallback(() => { + expandResponse(); + if (!isVerticalLayoutRef.current || !mainSectionRef.current) return; + const { height: containerHeight } = mainSectionRef.current.getBoundingClientRect(); + const clampedHeight = clampRequestHeightForResponse( + topPaneHeight, + containerHeight, + RESPONSE_EXPAND_MIN_HEIGHT, + MIN_TOP_PANE_HEIGHT + ); + if (clampedHeight != null) { + setTopPaneHeight(clampedHeight); + } + }, [expandResponse, topPaneHeight, setTopPaneHeight]); + useEffect(() => { document.addEventListener('mouseup', handleMouseUp); document.addEventListener('mousemove', handleMouseMove); @@ -563,7 +581,7 @@ const RequestTabPanel = () => { diff --git a/packages/bruno-app/src/components/RequestTabPanel/paneSize.js b/packages/bruno-app/src/components/RequestTabPanel/paneSize.js new file mode 100644 index 000000000..b9c43c21d --- /dev/null +++ b/packages/bruno-app/src/components/RequestTabPanel/paneSize.js @@ -0,0 +1,14 @@ +/** + * Clamps the request pane height to leave room for the response pane. + * Returns null if no clamping is needed. + */ +export const clampRequestHeightForResponse = ( + currentRequestHeight, + containerHeight, + minResponseHeight, + minRequestHeight +) => { + const maxRequestHeight = containerHeight - minResponseHeight; + if (currentRequestHeight <= maxRequestHeight) return null; + return Math.max(minRequestHeight, maxRequestHeight); +}; diff --git a/packages/bruno-app/src/components/RequestTabPanel/paneSize.spec.js b/packages/bruno-app/src/components/RequestTabPanel/paneSize.spec.js new file mode 100644 index 000000000..3f2c5818c --- /dev/null +++ b/packages/bruno-app/src/components/RequestTabPanel/paneSize.spec.js @@ -0,0 +1,32 @@ +import { clampRequestHeightForResponse } from './paneSize'; + +// Mirrors RequestTabPanel's constants +const MIN_TOP_PANE_HEIGHT = 150; +const RESPONSE_EXPAND_MIN_HEIGHT = 300; + +const clamp = (currentRequestHeight, containerHeight) => + clampRequestHeightForResponse(currentRequestHeight, containerHeight, RESPONSE_EXPAND_MIN_HEIGHT, MIN_TOP_PANE_HEIGHT); + +describe('clampRequestHeightForResponse', () => { + it('shrinks the request pane so the response opens without squishing', () => { + const containerHeight = 800; + const result = clamp(760, containerHeight); + expect(result).toBe(500); + }); + + it('floors at the request minimum in a short window', () => { + const containerHeight = 400; + const result = clamp(380, containerHeight); + expect(result).toBe(MIN_TOP_PANE_HEIGHT); + }); + + it('floors at the request minimum even when the window cannot fit both panes', () => { + // 200px container results in a negative maxRequestHeight, so the MIN_TOP_PANE_HEIGHT is returned. + expect(clamp(380, 200)).toBe(MIN_TOP_PANE_HEIGHT); + }); + + it('returns null when the response already has enough room, no clamping needed', () => { + // Request with height 400 leaves the response with enough room, so no clamping is needed. + expect(clamp(400, 1000)).toBeNull(); + }); +});