Files
next-tjwater-frontend/src/features/workbench/hooks/use-chart-window-layout.ts
T
jiang 0ae0a41e61
Generic Container CI/CD / test-build-publish (push) Successful in 2m7s
Frontend CI/CD / build-test-publish-and-deploy (push) Successful in 2m8s
feat(charts): manage investigation charts in a scrolling workspace
2026-11-10 17:56:23 +08:00

44 lines
1.5 KiB
TypeScript

import { useLayoutEffect, useState } from "react";
import { columnsForLayout, reconcileChartSlots, swapChartSlots, type ChartLayout, type ChartSlot } from "../utils/chart-window-slots";
/** Keep chart identities in fixed positions throughout the scrolling grid. */
export function useChartWindowLayout(ids: string[]) {
const [container, setContainer] = useState<HTMLElement | null>(null);
const [narrow, setNarrow] = useState(window.innerWidth < 760);
const [preferredLayout, setPreferredLayout] = useState<ChartLayout>("four");
const layout = narrow ? "one" : preferredLayout;
const columns = columnsForLayout(layout);
const [slots, setSlots] = useState<ChartSlot[]>([]);
const available = reconcileChartSlots(slots, ids, columns);
if (available !== slots) setSlots(available);
useLayoutEffect(() => {
if (!container) return;
const measure = () => setNarrow(container.clientWidth < 720);
measure();
const observer = new ResizeObserver(measure);
observer.observe(container);
return () => observer.disconnect();
}, [container]);
return {
containerRef: setContainer,
layout,
preferredLayout,
narrow,
setLayout: setPreferredLayout,
slots: available,
columns,
move: (id: string, target: number) => {
const source = available.indexOf(id);
const next = swapChartSlots(available, source, target);
if (next !== available) {
setSlots(next);
}
},
reset: () => {
setSlots(reconcileChartSlots([], ids, columns));
}
};
}