diff --git a/src/components/SplitPane.test.tsx b/src/components/SplitPane.test.tsx
index 1120dbd5..704988cb 100644
--- a/src/components/SplitPane.test.tsx
+++ b/src/components/SplitPane.test.tsx
@@ -235,4 +235,47 @@ describe('SplitPane initial size calculation', () => {
// Second pane: remaining 624px
expect(panes[1]).toHaveStyle({ width: `${CONTAINER_WIDTH - 400}px` });
});
+
+ it('updates pane sizes when controlled size prop changes', async () => {
+ const ControlledComponent = ({ sizes }: { sizes: number[] }) => (
+
+ Pane 1
+ Pane 2
+
+ );
+
+ const { container, rerender } = render(
+
+ );
+
+ await act(async () => {
+ await vi.runAllTimersAsync();
+ });
+
+ const panes = container.querySelectorAll('[data-pane="true"]');
+ expect(panes).toHaveLength(2);
+ expect(panes[0]).toHaveStyle({ width: '200px' });
+ expect(panes[1]).toHaveStyle({ width: '400px' });
+
+ // Change sizes (simulates parent state update after drag)
+ rerender();
+
+ await act(async () => {
+ await vi.runAllTimersAsync();
+ });
+
+ expect(panes[0]).toHaveStyle({ width: '300px' });
+ expect(panes[1]).toHaveStyle({ width: '300px' });
+
+ // Reset to initial values (simulates clicking "Reset" button)
+ rerender();
+
+ await act(async () => {
+ await vi.runAllTimersAsync();
+ });
+
+ // This is the bug: sizes should update to [200, 400]
+ expect(panes[0]).toHaveStyle({ width: '200px' });
+ expect(panes[1]).toHaveStyle({ width: '400px' });
+ });
});
diff --git a/src/components/SplitPane.tsx b/src/components/SplitPane.tsx
index b9aeb734..c4bab238 100644
--- a/src/components/SplitPane.tsx
+++ b/src/components/SplitPane.tsx
@@ -152,6 +152,30 @@ export function SplitPane(props: SplitPaneProps) {
calculateInitialSizes(containerSize)
);
+ // Sync paneSizes with controlled size props when they change
+ // This handles the case where parent state is reset (e.g., clicking a "Reset" button)
+ useEffect(() => {
+ if (containerSize === 0) return;
+
+ // Check if any pane has a controlled size prop
+ const hasControlledSizes = paneConfigs.some(
+ (config) => config.size !== undefined
+ );
+ if (!hasControlledSizes) return;
+
+ // Calculate what sizes should be based on current props
+ const expectedSizes = calculateInitialSizes(containerSize);
+
+ // Only update if sizes actually differ (avoid unnecessary re-renders)
+ setPaneSizes((currentSizes) => {
+ const sizesMatch =
+ currentSizes.length === expectedSizes.length &&
+ currentSizes.every((size, i) => size === expectedSizes[i]);
+
+ return sizesMatch ? currentSizes : expectedSizes;
+ });
+ }, [containerSize, paneConfigs, calculateInitialSizes]);
+
// Handle container size changes - update sizes proportionally
// Using a ref comparison to avoid effect dependency issues
const handleContainerSizeChange = useCallback(