Keep horizontal scrollbar in main workspace

This commit is contained in:
2026-08-05 23:29:05 +02:00
parent 19c6ee90e1
commit aa138b62ad
4 changed files with 22 additions and 3 deletions
+2
View File
@@ -57,6 +57,8 @@ This project replaces the Excel/VBA workflow named `Catalog maker - 20` with a N
- Runtime button labels must update the existing direct child label span instead of replacing `button.textContent`; state changes must never remove the button icon. - Runtime button labels must update the existing direct child label span instead of replacing `button.textContent`; state changes must never remove the button icon.
- Parser tools are always visible in the left panel. Do not hide, collapse or replace the parser action buttons with a toggle; the user must see the complete parser action set at all times. - Parser tools are always visible in the left panel. Do not hide, collapse or replace the parser action buttons with a toggle; the user must see the complete parser action set at all times.
- Mapping status and mapping source details belong beside the database connection status at the bottom of the sidebar. Style it as a shared sidebar section header with icon, centered status and a fixed right chevron; keep the existing mapping behavior. - Mapping status and mapping source details belong beside the database connection status at the bottom of the sidebar. Style it as a shared sidebar section header with icon, centered status and a fixed right chevron; keep the existing mapping behavior.
- Wide working data areas, especially the main workspace combinations grid, must keep a visible bottom horizontal scrollbar. The workspace should use a fixed header plus a scrollable content area so users can move sideways through all columns without losing the panel layout.
- Add or update Playwright checks for wide-data layout changes by asserting that the scroll container has horizontal overflow (`scrollWidth > clientWidth`) and `overflow-x: auto`.
## TypeScript workflow ## TypeScript workflow
+1 -1
View File
File diff suppressed because one or more lines are too long
+2 -2
View File
@@ -165,9 +165,9 @@
.field-label { @apply bg-slate-200 text-slate-800; } .field-label { @apply bg-slate-200 text-slate-800; }
.field-value { @apply bg-teal-50 text-right text-slate-900; } .field-value { @apply bg-teal-50 text-right text-slate-900; }
.field-value[data-field="manufacturer_name"] { @apply font-medium; } .field-value[data-field="manufacturer_name"] { @apply font-medium; }
.main-workspace { @apply min-w-0 overflow-hidden bg-catalog-surface; } .main-workspace { @apply flex max-h-screen min-w-0 flex-col overflow-hidden bg-catalog-surface; }
.data-panel { @apply min-w-0 overflow-hidden bg-catalog-surface; } .data-panel { @apply min-w-0 overflow-hidden bg-catalog-surface; }
.table-wrap { @apply h-full overflow-auto; } .table-wrap { @apply min-h-0 flex-1 overflow-auto; scrollbar-gutter: stable; }
.variant-grid { @apply min-w-0 text-[11px]; min-width: var(--variant-min-width, 820px); } .variant-grid { @apply min-w-0 text-[11px]; min-width: var(--variant-min-width, 820px); }
.variant-header, .variant-row { @apply grid; grid-template-columns: var(--variant-columns); } .variant-header, .variant-row { @apply grid; grid-template-columns: var(--variant-columns); }
.variant-header { @apply sticky top-0 z-10; } .variant-header { @apply sticky top-0 z-10; }
+17
View File
@@ -121,6 +121,23 @@ test("workspace columns collapse and expand without leaving a gap", async ({ pag
await expect(page.locator(".catalog-screen")).not.toHaveClass(/workspace-collapsed/); await expect(page.locator(".catalog-screen")).not.toHaveClass(/workspace-collapsed/);
}); });
test("main workspace keeps a bottom horizontal scrollbar for wide data", async ({ page }) => {
await page.setViewportSize({ width: 1061, height: 912 });
await page.goto("/");
const scrollState = await page.locator(".main-workspace .table-wrap").evaluate((element) => {
const style = getComputedStyle(element);
return {
overflowX: style.overflowX,
clientWidth: element.clientWidth,
scrollWidth: element.scrollWidth,
};
});
expect(scrollState.overflowX).toBe("auto");
expect(scrollState.scrollWidth).toBeGreaterThan(scrollState.clientWidth);
});
test("uses one shared height for the top panel headers", async ({ page }) => { test("uses one shared height for the top panel headers", async ({ page }) => {
await page.goto("/"); await page.goto("/");
const heights = await page.locator("#sidebarDrawer .sidebar-drawer-header, .secondary-panel .column-header, .main-workspace .column-header").evaluateAll((elements) => elements.map((element) => Math.round(element.getBoundingClientRect().height))); const heights = await page.locator("#sidebarDrawer .sidebar-drawer-header, .secondary-panel .column-header, .main-workspace .column-header").evaluateAll((elements) => elements.map((element) => Math.round(element.getBoundingClientRect().height)));