diff --git a/packages/shared-components/__vis__/linux/__baselines__/room-list/RoomListView/RoomListView.stories.tsx/toast-over-sticky-section-1.png b/packages/shared-components/__vis__/linux/__baselines__/room-list/RoomListView/RoomListView.stories.tsx/toast-over-sticky-section-1.png new file mode 100644 index 0000000000..2e9a1b62b7 Binary files /dev/null and b/packages/shared-components/__vis__/linux/__baselines__/room-list/RoomListView/RoomListView.stories.tsx/toast-over-sticky-section-1.png differ diff --git a/packages/shared-components/src/room-list/RoomListView/RoomListToast/RoomListToast.module.css b/packages/shared-components/src/room-list/RoomListView/RoomListToast/RoomListToast.module.css index 288ec1000e..0844a1add7 100644 --- a/packages/shared-components/src/room-list/RoomListView/RoomListToast/RoomListToast.module.css +++ b/packages/shared-components/src/room-list/RoomListView/RoomListToast/RoomListToast.module.css @@ -12,4 +12,6 @@ right: var(--cpd-space-3x); width: fit-content; margin: 0 auto; + /* Put the toast over the sticky headers */ + z-index: 3; } diff --git a/packages/shared-components/src/room-list/RoomListView/RoomListView.stories.tsx b/packages/shared-components/src/room-list/RoomListView/RoomListView.stories.tsx index 822b8bc2b4..82f350e0c6 100644 --- a/packages/shared-components/src/room-list/RoomListView/RoomListView.stories.tsx +++ b/packages/shared-components/src/room-list/RoomListView/RoomListView.stories.tsx @@ -6,7 +6,7 @@ */ import React, { type JSX } from "react"; -import { fn } from "storybook/test"; +import { expect, fn, waitFor } from "storybook/test"; import type { Meta, StoryObj } from "@storybook/react-vite"; import type { FilterId } from "../RoomListPrimaryFilters"; @@ -266,3 +266,33 @@ export const UnreadActivityBelow: Story = { toast: "unread_activity", }, }; + +export const ToastOverStickySection: Story = { + tags: ["autodocs", "!snapshot"], + args: { + isFlatList: false, + toast: "unread_activity", + }, + play: async ({ canvas, canvasElement }) => { + // Wait for the virtualized list to mount its rows before scrolling. + await canvas.findByRole("button", { name: "Toggle Favourites section" }); + const scroller = canvasElement.querySelector('[role="treegrid"]')!; + + // Scroll to the end of the list so the last section header ("Low-priority") gets mounted. + scroller.scrollTop = scroller.scrollHeight; + await canvas.findByRole("button", { name: "Toggle Low-priority section" }); + + // Scroll until the header row sits just above the bottom edge of the viewport, overlapping the toast. + const bottomOffset = 28; + await waitFor(() => { + const header = canvas.getByRole("button", { name: "Toggle Low-priority section" }); + const gap = scroller.getBoundingClientRect().bottom - header.getBoundingClientRect().bottom; + if (Math.abs(gap - bottomOffset) > 1) { + scroller.scrollTop -= gap - bottomOffset; + throw new Error(`Header is not parked over the toast yet (gap: ${gap}px)`); + } + }); + + await expect(canvasElement).toMatchImageSnapshot(); + }, +};