Skip to content

Conversation

Ovgodd
Copy link
Collaborator

@Ovgodd Ovgodd commented Oct 7, 2025

Purpose

EDIT & FINAL: Following a discussion with @rl-83, we replaced the horizontal scroll approach with an adjustable panel bar using react-resizable-panels.

This change improves usability by allowing users to resize the document tree panel within defined limits. It ensures better visibility of nested documents without using scrollbars and aligns with the implementation used in our shared UI Kit (where resizing is handled via the MainLayout, not inside the document tree component).

added e2e tests to cover this new resizable behavior too.

issue : 1180

ajustbar.mp4

Proposal

  • Add react-resizable-panels (v3.0.6) dependency
  • Implement PanelGroup with a horizontal resize handle in MainLayout
  • Persist panel size in localStorage
  • Set min width to 300px, max width to 450px (capped at 40% of viewport)
  • Keep mobile behavior unchanged (no resize handle)
  • Add e2e tests for resizable panel behavior

@Ovgodd Ovgodd requested a review from AntoLC October 7, 2025 09:05
@Ovgodd Ovgodd self-assigned this Oct 7, 2025
@Ovgodd Ovgodd added bug Something isn't working frontend triage multipages labels Oct 7, 2025
@Ovgodd Ovgodd force-pushed the fix/1180-make-horizontal-overflow-panel branch from 0abe61e to f0c1194 Compare October 7, 2025 09:06
@Ovgodd Ovgodd marked this pull request as ready for review October 7, 2025 09:06
@Ovgodd Ovgodd marked this pull request as draft October 8, 2025 08:44
@Ovgodd Ovgodd force-pushed the fix/1180-make-horizontal-overflow-panel branch 5 times, most recently from 3e294e9 to c255024 Compare October 13, 2025 12:30
@Ovgodd Ovgodd marked this pull request as ready for review October 13, 2025 12:31
@Ovgodd Ovgodd force-pushed the fix/1180-make-horizontal-overflow-panel branch from c255024 to 3406fee Compare October 13, 2025 12:31
Copy link

github-actions bot commented Oct 13, 2025

Size Change: +11.9 kB (+0.33%)

Total Size: 3.67 MB

Filename Size Change
apps/impress/out/_next/static/81d297b5/_buildManifest.js 0 B -881 B (removed) 🏆
apps/impress/out/_next/static/chunks/pages/404.js 1.9 kB +507 B (+36.4%) 🚨
apps/impress/out/_next/static/chunks/pages/docs.js 1.47 kB +512 B (+53.5%) 🆘
apps/impress/out/_next/static/chunks/pages/index.js 1.49 kB +515 B (+52.87%) 🆘
apps/impress/out/_next/static/chunks/pages/offline.js 6.61 kB +554 B (+9.14%) 🔍
apps/impress/out/_next/static/92acae69/_buildManifest.js 903 B +903 B (new file) 🆕
apps/impress/out/_next/static/chunks/7437.js 8.8 kB +8.8 kB (new file) 🆕

compressed-size-action

@Ovgodd Ovgodd force-pushed the fix/1180-make-horizontal-overflow-panel branch from 3406fee to f059014 Compare October 13, 2025 12:43
Copy link
Collaborator

@AntoLC AntoLC left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The feature works great, I think we can improve the code though, by separating more the components in MainLayout.

I can see we can move the left panel on the grid page as well, I thought it was only with the tree part, is it as expected ?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The yarn.lock gives changes in local.

Comment on lines 119 to 123
display: ${menuOpen || !isDesktop ? 'flex' : 'none'};
position: absolute;
display: flex;
position: sticky;
right: 0;
opacity: ${menuOpen || !isDesktop ? '1' : '0'};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By doing like that the name is cropped far before needed, because the actions button take place even when not displayed.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not introduce in this PR but I can see there is differences on how the actions buttons are displayed between the top parent and the children, I think it should be &:focus-visible here.

&:focus-within {
.doc-tree-root-item-actions {
opacity: 1;
}

Comment on lines 123 to 172
<PanelGroup
autoSaveId="docs-left-panel-persistence"
direction="horizontal"
>
<Panel
ref={ref}
order={0}
defaultSize={minPanelSize}
minSize={minPanelSize}
maxSize={maxPanelSize}
>
<LeftPanel />
</Panel>
<PanelResizeHandle
className="border-clr-surface-primary"
style={{
borderRightWidth: '1px',
borderRightStyle: 'solid',
borderRightColor: colorsTokens['greyscale-200'],
width: '1px',
cursor: 'col-resize',
}}
/>
<Panel order={1}>
<Box
as="main"
role="main"
aria-label={t('Main content')}
id={MAIN_LAYOUT_ID}
$align="center"
$width="100%"
$height={`calc(100dvh - ${HEADER_HEIGHT}px)`}
$padding={{
all: 'base',
}}
$background={
currentBackgroundColor === 'white'
? colorsTokens['greyscale-000']
: colorsTokens['greyscale-050']
}
$css={css`
overflow-y: auto;
overflow-x: clip;
`}
>
{children}
</Box>
</Panel>
</PanelGroup>
) : (
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should have its own component I think.

Comment on lines 147 to 170
<Box
as="main"
role="main"
aria-label={t('Main content')}
id={MAIN_LAYOUT_ID}
$align="center"
$width="100%"
$height={`calc(100dvh - ${HEADER_HEIGHT}px)`}
$padding={{
all: 'base',
}}
$background={
currentBackgroundColor === 'white'
? colorsTokens['greyscale-000']
: colorsTokens['greyscale-050']
}
$css={css`
overflow-y: auto;
overflow-x: clip;
`}
>
{children}
</Box>
</Panel>
Copy link
Collaborator

@AntoLC AntoLC Oct 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can see the code almost the same for the mobile part under, can we factorize this part.

<LeftPanel />
</Panel>
<PanelResizeHandle
className="border-clr-surface-primary"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure we use it.

Comment on lines 62 to 104
useEffect(() => {
const handleResizeStart = () => {
setIsResizing(true);
if (resizeTimeoutRef.current) {
clearTimeout(resizeTimeoutRef.current);
}
resizeTimeoutRef.current = window.setTimeout(() => {
setIsResizing(false);
}, 150);
};

window.addEventListener('resize', handleResizeStart);

return () => {
window.removeEventListener('resize', handleResizeStart);
if (resizeTimeoutRef.current) {
clearTimeout(resizeTimeoutRef.current);
}
};
}, []);

// Keep pixel-based constraints while the library works in percentages.
// We translate px -> % on mount and on viewport resizes so that:
// - min stays ~300px, max stays ~450px (capped to 40% on small screens)
// - on mobile, the left panel collapses (min = 0)
// - when enableResize is false, we lock the size by setting max == min
useEffect(() => {
const updatePanelSize = () => {
const min = Math.round(calculateDefaultSize(MIN_PANEL_SIZE, isDesktop));
const max = Math.round(
Math.min(calculateDefaultSize(MAX_PANEL_SIZE, isDesktop), 40),
);
setMinPanelSize(isDesktop ? min : 0);
enableResize ? setMaxPanelSize(max) : setMaxPanelSize(min);
};

updatePanelSize();
window.addEventListener('resize', updatePanelSize);

return () => {
window.removeEventListener('resize', updatePanelSize);
};
}, [isDesktop, enableResize]);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This part can be improve I think, we use twice the same listener (resize), we could use only one.
If isDesktop is false, I have the feeling we don't need to listen anything.

When using useEffect, it is good practice to use useCallback around the function called inside, calculateDefaultSize should be inside a useCallback.

I think by having its own component we will be able to remove this notion of isDesktop, this component will be called only when desktop, removing complexity.

@AntoLC AntoLC linked an issue Oct 15, 2025 that may be closed by this pull request
@Ovgodd Ovgodd force-pushed the fix/1180-make-horizontal-overflow-panel branch 3 times, most recently from e7d810f to 9f7648b Compare October 16, 2025 07:50
mainlayout and leftpanel updated with resizable panel saved in localstorage

Signed-off-by: Cyril <[email protected]>

✨(frontend) show full nested doc names with horizontal scroll support

horizontal overflow enabled and opacity used for sticky actions visibility

Signed-off-by: Cyril <[email protected]>

✨(frontend) show full nested doc names with horizontal scroll support

horizontal overflow enabled and opacity used for sticky actions visibility

Signed-off-by: Cyril <[email protected]>

✨(frontend) add resizable-panels lib also used in our shared ui kit

needed for adaptable ui consistent with our shared ui kit components

Signed-off-by: Cyril <[email protected]>
@Ovgodd Ovgodd force-pushed the fix/1180-make-horizontal-overflow-panel branch from 6d49207 to 3326f02 Compare October 16, 2025 08:50
@Ovgodd Ovgodd requested a review from AntoLC October 16, 2025 08:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🐛 Panel bar adjustable

2 participants