Skip to content

Commit b48d7b4

Browse files
committed
✨(frontend) replace react-resizable-panels with allotment to fix flickering
prevents UI flickering caused by react-resizable-panels during resizing Signed-off-by: Cyril <c.gromoff@gmail.com>
1 parent a2f14e4 commit b48d7b4

File tree

3 files changed

+112
-354
lines changed

3 files changed

+112
-354
lines changed

src/frontend/apps/impress/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
"@sentry/nextjs": "10.22.0",
4444
"@tanstack/react-query": "5.90.6",
4545
"@tiptap/extensions": "3.10.1",
46+
"allotment": "^1.20.4",
4647
"canvg": "4.0.3",
4748
"clsx": "2.1.1",
4849
"cmdk": "1.1.1",
Lines changed: 11 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,4 @@
1-
import { useEffect, useRef, useState } from 'react';
2-
import {
3-
ImperativePanelHandle,
4-
Panel,
5-
PanelGroup,
6-
PanelResizeHandle,
7-
} from 'react-resizable-panels';
8-
9-
import { useCunninghamTheme } from '@/cunningham';
10-
11-
// Convert a target pixel width to a percentage of the current viewport width.
12-
const pxToPercent = (px: number) => {
13-
return (px / window.innerWidth) * 100;
14-
};
1+
import { Allotment } from 'allotment';
152

163
type ResizableLeftPanelProps = {
174
leftPanel: React.ReactNode;
@@ -26,63 +13,16 @@ export const ResizableLeftPanel = ({
2613
minPanelSizePx = 300,
2714
maxPanelSizePx = 450,
2815
}: ResizableLeftPanelProps) => {
29-
const { colorsTokens } = useCunninghamTheme();
30-
const ref = useRef<ImperativePanelHandle>(null);
31-
const savedWidthPxRef = useRef<number>(minPanelSizePx);
32-
33-
const [panelSizePercent, setPanelSizePercent] = useState(() =>
34-
pxToPercent(minPanelSizePx),
35-
);
36-
37-
const minPanelSizePercent = pxToPercent(minPanelSizePx);
38-
const maxPanelSizePercent = Math.min(pxToPercent(maxPanelSizePx), 40);
39-
40-
// Keep pixel width constant on window resize
41-
useEffect(() => {
42-
const handleResize = () => {
43-
const newPercent = pxToPercent(savedWidthPxRef.current);
44-
setPanelSizePercent(newPercent);
45-
if (ref.current) {
46-
ref.current.resize?.(newPercent - (ref.current.getSize() || 0));
47-
}
48-
};
49-
50-
window.addEventListener('resize', handleResize);
51-
return () => {
52-
window.removeEventListener('resize', handleResize);
53-
};
54-
}, []);
55-
56-
const handleResize = (sizePercent: number) => {
57-
const widthPx = (sizePercent / 100) * window.innerWidth;
58-
savedWidthPxRef.current = widthPx;
59-
setPanelSizePercent(sizePercent);
60-
};
61-
6216
return (
63-
<>
64-
<PanelGroup direction="horizontal">
65-
<Panel
66-
ref={ref}
67-
order={0}
68-
defaultSize={panelSizePercent}
69-
minSize={minPanelSizePercent}
70-
maxSize={maxPanelSizePercent}
71-
onResize={handleResize}
72-
>
73-
{leftPanel}
74-
</Panel>
75-
<PanelResizeHandle
76-
style={{
77-
borderRightWidth: '1px',
78-
borderRightStyle: 'solid',
79-
borderRightColor: colorsTokens['greyscale-200'],
80-
width: '1px',
81-
cursor: 'col-resize',
82-
}}
83-
/>
84-
<Panel order={1}>{children}</Panel>
85-
</PanelGroup>
86-
</>
17+
<Allotment proportionalLayout={false}>
18+
<Allotment.Pane
19+
minSize={minPanelSizePx}
20+
maxSize={maxPanelSizePx}
21+
preferredSize={minPanelSizePx}
22+
>
23+
{leftPanel}
24+
</Allotment.Pane>
25+
<Allotment.Pane>{children}</Allotment.Pane>
26+
</Allotment>
8727
);
8828
};

0 commit comments

Comments
 (0)