fix(ui): pin the OPERATIONS tab bar while panel content scrolls (#31)
CI / build + unit + e2e (pull_request) Successful in 2m47s
CI / build + unit + e2e (pull_request) Successful in 2m47s
The TabsList is now position:sticky top:0 with a z-index above the panel content. In wide mode it pins to the top of the OPERATIONS scroll area (#21's center-pane scroller); in narrow mode, where the body scrolls and there is no inner scroll container, it pins to the viewport. The existing opaque background keeps scrolled content from showing through.
This commit is contained in:
@@ -82,6 +82,36 @@ test('active tab survives a page reload (#27)', async ({ page }) => {
|
||||
await expect(page.getByRole('tab', { name: 'CREW' })).toHaveAttribute('aria-selected', 'true');
|
||||
});
|
||||
|
||||
test('tab bar stays pinned while panel content scrolls (#31)', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
// Shrink the viewport so the center pane's content overflows its scroll area regardless of save state.
|
||||
await page.setViewportSize({ width: 1280, height: 560 });
|
||||
|
||||
// WORLD MAP is always tall enough to overflow (fixed-height chart) — deterministic across retries.
|
||||
await page.getByRole('tab', { name: 'WORLD MAP' }).click();
|
||||
|
||||
const tablist = page.getByRole('tablist');
|
||||
await expect(tablist).toBeVisible();
|
||||
const before = await tablist.boundingBox();
|
||||
expect(before).not.toBeNull();
|
||||
|
||||
// Scroll the nearest scroll container above the tab list all the way down.
|
||||
const scrolled = await page.evaluate(() => {
|
||||
let el = document.querySelector('[role="tablist"]')?.parentElement ?? null;
|
||||
while (el && !['auto', 'scroll'].includes(getComputedStyle(el).overflowY)) el = el.parentElement;
|
||||
if (!el) throw new Error('no scroll container above the tab list');
|
||||
el.scrollTop = el.scrollHeight;
|
||||
return el.scrollTop;
|
||||
});
|
||||
expect(scrolled).toBeGreaterThan(50); // content really overflowed — guards against a vacuous pass
|
||||
|
||||
await expect(tablist).toBeVisible();
|
||||
const after = await tablist.boundingBox();
|
||||
expect(after).not.toBeNull();
|
||||
// Pinned: the tab bar's viewport position is unchanged even though the content scrolled away (#31).
|
||||
expect(Math.abs(after!.y - before!.y)).toBeLessThan(2);
|
||||
});
|
||||
|
||||
test('world map shows the generated starting system and its neighbours', async ({ page }) => {
|
||||
const world = (await (await page.request.get('/api/world')).json()) as WorldState;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user