Implement collapsible panels for the new room list (#32742)

* Add `react-resizable-panels` library

* Implement a custom SeparatorView

* Add a `LeftResizablePanelView`

* Add a custom `GroupView`

* Export everything from shared-components

* Make it possible to track width/collapse state through settings

* Add a view model to drive the views

* Render views without disrupting the old room list

* Fix lint error

* Disable user interaction on collapsed panel

* Prevent widgets fron hijacking pointer events

* Expand to full width on separator click

* Separator should be shown when focused via keyboard

* Update tests

* Use data-attribute for hover

* Write stories for SeperatorView

* Write vite tests for SeparatorView

* Write tests for LeftResizablePanelView

* More tests

* Fix lint errors

* Fix flakey border on the roomlst

* Fix storybook axe violation

* Update snapshots

* Fix playwright tests

* Fix sonarcloud issues

* Use translated string

* Add better js-doc comments

* Rename `ResizerSnapshot` to `ResizerViewSnapshot`

* Externalize react-resizable-panels

* Link figma designs to stories

* Write playwright tests

* Update screenshots

* Fix lint errors

* Update more screenshots

* Update more screenshots

* Fix flaky toast test

* Update apps/web/playwright/e2e/crypto/toasts.spec.ts

Co-authored-by: Andy Balaam <andy.balaam@matrix.org>

* Fix indentation

---------

Co-authored-by: Andy Balaam <andy.balaam@matrix.org>
This commit is contained in:
R Midhun Suresh
2026-03-23 19:03:32 +05:30
committed by GitHub
parent 89261bbe00
commit 99e6ede9f1
197 changed files with 1592 additions and 40 deletions
@@ -49,6 +49,11 @@ test.describe("Audio player", { tag: ["@no-firefox", "@no-webkit"] }, () => {
).toBeVisible();
};
const scrollToBottomOfTimeline = async (page: Page) => {
await page.locator(".mx_RoomView_MessageList").click();
await page.mouse.wheel(0, 100);
};
/**
* Take snapshots of mx_EventTile_last on each layout, outputting log for reference/debugging.
* @param detail The snapshot name. Used for outputting logs too.
@@ -113,10 +118,12 @@ test.describe("Audio player", { tag: ["@no-firefox", "@no-webkit"] }, () => {
`,
mask: [page.getByTestId("audio-player-seek")],
clip: undefined,
hideJumpToBottomButton: true,
};
// Take a snapshot of mx_EventTile_last on IRC layout
screenshotOptions.clip = await page.locator(".mx_EventTile_last").boundingBox();
await scrollToBottomOfTimeline(page);
await expect(page).toMatchScreenshot(`${detail.replaceAll(" ", "-")}-irc-layout.png`, screenshotOptions);
// Take a snapshot on modern/group layout
@@ -125,6 +132,7 @@ test.describe("Audio player", { tag: ["@no-firefox", "@no-webkit"] }, () => {
await groupTile.locator(".mx_MessageTimestamp").click();
await checkPlayerVisibility(groupTile);
screenshotOptions.clip = await page.locator(".mx_EventTile_last").boundingBox();
await scrollToBottomOfTimeline(page);
await expect(page).toMatchScreenshot(`${detail.replaceAll(" ", "-")}-group-layout.png`, screenshotOptions);
// Take a snapshot on bubble layout
@@ -133,6 +141,7 @@ test.describe("Audio player", { tag: ["@no-firefox", "@no-webkit"] }, () => {
await bubbleTile.locator(".mx_MessageTimestamp").click();
await checkPlayerVisibility(bubbleTile);
screenshotOptions.clip = await page.locator(".mx_EventTile_last").boundingBox();
await scrollToBottomOfTimeline(page);
await expect(page).toMatchScreenshot(`${detail.replaceAll(" ", "-")}-bubble-layout.png`, screenshotOptions);
};