Migrate react-grid-layout to v2

Merged
EH
2mo ago
+275-199

Context

Second attempt at the v2 migration from #17140, which was closed in January because react-grid-layout v2 had a resize bug: the cursor drifted away from the resize handle while resizing (react-grid-layout#2233).

The root cause was in react-resizable (stale props accumulating between renders) and is fixed in react-resizable 3.2.0 (react-resizable#255). react-grid-layout 2.2.4 depends on react-resizable ^3.1.3, so a fresh lockfile resolution now picks up 3.2.0. The RGL maintainer confirmed on the issue that this combination fixes the drift.

Changes

  • Bump react-grid-layout from ^1.5.2 to ^2.2.4; the lockfile resolves react-resizable to 3.2.0
  • Drop @types/react-grid-layout, v2 ships its own types
  • Replace the WidthProvider HOC with the useContainerWidth hook; its containerRef doubles as the grid container ref used by the drag selector
  • Replace the flat drag/resize props with dragConfig and resizeConfig
  • Replace compactType="vertical" and preventCollision with verticalCompactor; drop the maxCols prop, which was never a real v1 prop and only existed through a type cast
  • Type renames: Layouts to ResponsiveLayouts, single-item Layout to LayoutItem. Breakpoint keys are optional in v2, so the code paths that assumed .desktop/.mobile exist now fall back to empty arrays
  • Guard the drag/resize callbacks: newItem is nullable in v2 and the event is typed Event, narrowed to MouseEvent for the cross-tab drop hit-testing
  • getUpdatedTabLayouts test: {} is a valid ResponsiveLayouts value in v2 (it previously required an as any cast and threw at runtime), so the test now asserts missing breakpoints are treated as empty

Validation

  • Typecheck clean, all 1367 page-layout unit tests pass, diff lint and formatting clean
  • Verified against a running app with seeded dashboards: rendering, edit mode, dragging with placeholder and vertical compaction, resizing via the custom corner handles on react-resizable 3.2.0, save, and layout persistence across reload
  • The v2 runtime keeps the class names our styles target (react-grid-layout, react-grid-item, react-grid-placeholder, react-draggable-dragging, cssTransforms), and react-grid-layout/css/styles.css is unchanged

Generated by Claude Code