fix: replace WidthProvider with ResizeObserver for grid layout

react-grid-layout v2 removed WidthProvider. Use ResizeObserver to
track container width and pass it directly to Responsive component.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
hailin 2026-04-05 01:48:25 -07:00
parent 28ebbbfb82
commit d03ee90f40
1 changed files with 16 additions and 18 deletions

View File

@ -1,6 +1,7 @@
'use client'; 'use client';
import React, { useMemo, useState, useEffect } from 'react'; import React, { useMemo, useRef, useState, useEffect } from 'react';
import { Responsive } from 'react-grid-layout';
import { useAppSelector } from '@/adapters/state/redux/store'; import { useAppSelector } from '@/adapters/state/redux/store';
import { useLayout } from '@/frameworks/hooks/useLayout'; import { useLayout } from '@/frameworks/hooks/useLayout';
import { ChartWrapper } from '@/frameworks/components/charts/ChartWrapper'; import { ChartWrapper } from '@/frameworks/components/charts/ChartWrapper';
@ -41,16 +42,19 @@ function DropZonePlaceholder() {
export function CenterCanvas() { export function CenterCanvas() {
const charts = useAppSelector((s) => s.chart.charts); const charts = useAppSelector((s) => s.chart.charts);
const { layouts, onLayoutChange } = useLayout(); const { layouts, onLayoutChange } = useLayout();
const [GridLayout, setGridLayout] = useState<any>(null); const containerRef = useRef<HTMLDivElement>(null);
const [width, setWidth] = useState(1200);
useEffect(() => { useEffect(() => {
import('react-grid-layout').then((mod: any) => { if (!containerRef.current) return;
const WP = mod.WidthProvider || mod.default?.WidthProvider; const observer = new ResizeObserver((entries) => {
const Resp = mod.Responsive || mod.default?.Responsive; for (const entry of entries) {
if (WP && Resp) { setWidth(entry.contentRect.width);
setGridLayout(() => WP(Resp));
} }
}); });
observer.observe(containerRef.current);
setWidth(containerRef.current.clientWidth);
return () => observer.disconnect();
}, []); }, []);
const gridLayouts = useMemo(() => { const gridLayouts = useMemo(() => {
@ -79,29 +83,23 @@ export function CenterCanvas() {
); );
} }
if (!GridLayout) {
return <div style={{ padding: 16 }}>...</div>;
}
return ( return (
<div style={{ padding: 16, minHeight: '100%' }}> <div ref={containerRef} style={{ padding: 16, minHeight: '100%' }}>
<GridLayout <Responsive
className="layout" className="layout"
width={width}
layouts={{ lg: gridLayouts }} layouts={{ lg: gridLayouts }}
breakpoints={{ lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0 }} breakpoints={{ lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0 }}
cols={{ lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 }} cols={{ lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 }}
rowHeight={80} rowHeight={80}
onLayoutChange={(layout: any[]) => onLayoutChange(layout)} onLayoutChange={(layout: any) => onLayoutChange([...layout])}
isDraggable
isResizable
compactType="vertical"
> >
{charts.map((chart) => ( {charts.map((chart) => (
<div key={chart.id}> <div key={chart.id}>
<ChartWrapper chartId={chart.id} /> <ChartWrapper chartId={chart.id} />
</div> </div>
))} ))}
</GridLayout> </Responsive>
</div> </div>
); );
} }