From eaf681e09dde48d92cf65b2f78e9368155d9a38b Mon Sep 17 00:00:00 2001 From: Shaun Andrews Date: Tue, 16 Jun 2026 13:04:35 -0400 Subject: [PATCH 1/2] Refactor panel resizing onto a shared drag primitive and a single clamp Co-Authored-By: Claude Opus 4.8 (1M context) --- .../preview-split-frame/index.test.tsx | 241 ++++++++++++++++++ .../components/preview-split-frame/index.tsx | 97 +++---- .../preview-split-frame/style.module.css | 39 +-- apps/ui/src/hooks/use-pointer-drag.ts | 114 +++++++++ apps/ui/src/hooks/use-preview-split.ts | 241 ++++++++++++++++++ .../ui/src/hooks/use-resizable-panel.test.tsx | 93 +++++++ apps/ui/src/hooks/use-resizable-panel.ts | 86 ++----- apps/ui/src/lib/resizable-panels.test.ts | 32 +++ apps/ui/src/lib/resizable-panels.ts | 115 ++++++++- .../router/layout-dashboard/index.tsx | 37 +-- 10 files changed, 941 insertions(+), 154 deletions(-) create mode 100644 apps/ui/src/components/preview-split-frame/index.test.tsx create mode 100644 apps/ui/src/hooks/use-pointer-drag.ts create mode 100644 apps/ui/src/hooks/use-preview-split.ts create mode 100644 apps/ui/src/hooks/use-resizable-panel.test.tsx diff --git a/apps/ui/src/components/preview-split-frame/index.test.tsx b/apps/ui/src/components/preview-split-frame/index.test.tsx new file mode 100644 index 0000000000..e391380341 --- /dev/null +++ b/apps/ui/src/components/preview-split-frame/index.test.tsx @@ -0,0 +1,241 @@ +import { fireEvent, render, screen, waitFor } from '@testing-library/react'; +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; +import { + PREVIEW_CONTENT_WIDTH_STORAGE_KEY, + PREVIEW_PANEL_STORAGE_KEY, +} from '@/lib/resizable-panels'; +import { PreviewSplitFrame } from './index'; + +function getFrameRoot(): HTMLElement { + const root = screen.getByTestId( 'content' ).parentElement?.parentElement; + if ( ! root ) { + throw new Error( 'PreviewSplitFrame root not found' ); + } + return root; +} + +describe( 'PreviewSplitFrame', () => { + let getBoundingClientRectSpy: ReturnType< typeof vi.spyOn >; + let frameWidth: number; + + beforeEach( () => { + frameWidth = 1000; + vi.stubGlobal( 'ResizeObserver', undefined ); + window.localStorage.setItem( PREVIEW_PANEL_STORAGE_KEY, '400' ); + getBoundingClientRectSpy = vi + .spyOn( HTMLElement.prototype, 'getBoundingClientRect' ) + .mockImplementation( () => ( { + x: 0, + y: 0, + width: frameWidth, + height: 700, + top: 0, + right: frameWidth, + bottom: 700, + left: 0, + toJSON: () => ( {} ), + } ) ); + } ); + + afterEach( () => { + getBoundingClientRectSpy.mockRestore(); + window.localStorage.removeItem( PREVIEW_CONTENT_WIDTH_STORAGE_KEY ); + window.localStorage.removeItem( PREVIEW_PANEL_STORAGE_KEY ); + vi.unstubAllGlobals(); + } ); + + it( 'lays out the preview immediately when mounted open', async () => { + render( +