diff --git a/src/renderer/views/collector/CollectorView.tsx b/src/renderer/views/collector/CollectorView.tsx index 470b2c5..2bfc71a 100644 --- a/src/renderer/views/collector/CollectorView.tsx +++ b/src/renderer/views/collector/CollectorView.tsx @@ -1,4 +1,4 @@ -import { memo, useEffect, useState, type ChangeEvent, type ReactElement } from "react"; +import { memo, useEffect, useState, type ChangeEvent, type CSSProperties, type ReactElement } from "react"; import { formatDateTime, formatHosterLabel, humanSize } from "../../download-format"; import { DataTable, DataTableBody, DataTableEmpty, DataTableHeader } from "../../ui/DataTable"; import { Dialog } from "../../ui/Dialog"; @@ -81,6 +81,10 @@ function linkAvailability(availability: "online" | "offline" | "unknown"): strin return "Ungeprüft"; } +export function collectorPackageIntrinsicBlockSize(row: CollectorWorkspacePackageRow): number { + return 46 + (row.collapsed ? 0 : row.links.length * 40); +} + export function toggleAllCollectorPackageIds( packageIds: readonly string[], collapsedPackageIds: ReadonlySet @@ -166,6 +170,10 @@ function CollectorPackageGroup({ row, model, actions, selected }: { const partiallySelected = row.selectedCount > 0 && !allSelected; const animateItems = model.animationsEnabled && row.allLinks.length <= 64; const [renderItems, setRenderItems] = useState(!row.collapsed); + const packageStyle: CSSProperties = { + containIntrinsicBlockSize: `auto ${collectorPackageIntrinsicBlockSize(row)}px`, + flex: "0 0 auto" + }; useEffect(() => { if (!row.collapsed) { setRenderItems(true); @@ -179,7 +187,7 @@ function CollectorPackageGroup({ row, model, actions, selected }: { return () => window.clearTimeout(timer); }, [animateItems, row.collapsed]); return ( -
+
0 ? " is-selected" : ""}`} role="row"> { }); describe("CollectorView", () => { + it("reserves the exact package height while content visibility skips offscreen rows", () => { + const expanded = buildCollectorWorkspaceViewModel([packages[0]], "all", "", false, [], [], "", true).packages[0]; + const collapsed = { ...expanded, collapsed: true }; + + expect(collectorPackageIntrinsicBlockSize(expanded)).toBe(126); + expect(collectorPackageIntrinsicBlockSize(collapsed)).toBe(46); + expect(renderToStaticMarkup()).toContain("contain-intrinsic-block-size:auto 126px"); + }); + it("renders expandable package and file rows with preview columns", () => { const html = renderToStaticMarkup();