diff --git a/src/components/views/rooms/RoomListPanel/RoomListPrimaryFilters.tsx b/src/components/views/rooms/RoomListPanel/RoomListPrimaryFilters.tsx index a14a39cdc1..e3039bf1cf 100644 --- a/src/components/views/rooms/RoomListPanel/RoomListPrimaryFilters.tsx +++ b/src/components/views/rooms/RoomListPanel/RoomListPrimaryFilters.tsx @@ -103,7 +103,7 @@ function useCollapseFilters( // If the previous element is on the left element of the current one, it means that the filter is wrapping const previousSibling = child.previousElementSibling as HTMLElement | null; - if (previousSibling && child.offsetLeft < previousSibling.offsetLeft) { + if (previousSibling && child.offsetLeft <= previousSibling.offsetLeft) { if (!isWrapping) setWrappingIndex(i); isWrapping = true; } diff --git a/test/unit-tests/components/views/rooms/RoomListPanel/RoomListPrimaryFilters-test.tsx b/test/unit-tests/components/views/rooms/RoomListPanel/RoomListPrimaryFilters-test.tsx index d7d4e8314f..8276c7340f 100644 --- a/test/unit-tests/components/views/rooms/RoomListPanel/RoomListPrimaryFilters-test.tsx +++ b/test/unit-tests/components/views/rooms/RoomListPanel/RoomListPrimaryFilters-test.tsx @@ -35,15 +35,26 @@ describe("", () => { vm = { primaryFilters: [ - { name: "People", active: false, toggle: filterToggleMocks[0], key: FilterKey.PeopleFilter }, - { name: "Rooms", active: true, toggle: filterToggleMocks[1], key: FilterKey.RoomsFilter }, + { name: "People", active: true, toggle: filterToggleMocks[0], key: FilterKey.PeopleFilter }, + { name: "Rooms", active: false, toggle: filterToggleMocks[1], key: FilterKey.RoomsFilter }, { name: "Unreads", active: false, toggle: filterToggleMocks[2], key: FilterKey.UnreadFilter }, ], } as unknown as RoomListViewState; }); + function mockFiltersOffsetLeft() { + // Use `getByText` instead of `getByRole` to bypass the aria-hidden + jest.spyOn(screen.getByText("People"), "offsetLeft", "get").mockReturnValue(0); + jest.spyOn(screen.getByText("Rooms"), "offsetLeft", "get").mockReturnValue(30); + jest.spyOn(screen.getByText("Unreads"), "offsetLeft", "get").mockReturnValue(60); + + // @ts-ignore + act(() => resizeCallback([{ target: screen.getByRole("listbox", { name: "Room list filters" }) }])); + } + it("should renders all filters correctly", () => { const { asFragment } = render(); + mockFiltersOffsetLeft(); // Check that all filters are rendered expect(screen.getByRole("option", { name: "People" })).toBeInTheDocument(); @@ -51,8 +62,8 @@ describe("", () => { expect(screen.getByRole("option", { name: "Unreads" })).toBeInTheDocument(); // Check that the active filter is marked as selected - expect(screen.getByRole("option", { name: "Rooms" })).toHaveAttribute("aria-selected", "true"); - expect(screen.getByRole("option", { name: "People" })).toHaveAttribute("aria-selected", "false"); + expect(screen.getByRole("option", { name: "People" })).toHaveAttribute("aria-selected", "true"); + expect(screen.getByRole("option", { name: "Rooms" })).toHaveAttribute("aria-selected", "false"); expect(screen.getByRole("option", { name: "Unreads" })).toHaveAttribute("aria-selected", "false"); expect(asFragment()).toMatchSnapshot(); @@ -61,6 +72,7 @@ describe("", () => { it("should call toggle function when a filter is clicked", async () => { const user = userEvent.setup(); render(); + mockFiltersOffsetLeft(); // Click on an inactive filter await user.click(screen.getByRole("option", { name: "People" })); @@ -69,24 +81,27 @@ describe("", () => { expect(filterToggleMocks[0]).toHaveBeenCalledTimes(1); }); - function mockFiltersOffsetLeft() { - jest.spyOn(screen.getByRole("option", { name: "People" }), "offsetLeft", "get").mockReturnValue(0); - jest.spyOn(screen.getByRole("option", { name: "Rooms" }), "offsetLeft", "get").mockReturnValue(30); + function makeUnreadWrapping() { + // Use `getByText` instead of `getByRole` to bypass the aria-hidden + jest.spyOn(screen.getByText("People"), "offsetLeft", "get").mockReturnValue(0); + jest.spyOn(screen.getByText("Rooms"), "offsetLeft", "get").mockReturnValue(30); // Unreads is wrapping - jest.spyOn(screen.getByRole("option", { name: "Unreads" }), "offsetLeft", "get").mockReturnValue(0); + jest.spyOn(screen.getByText("Unreads"), "offsetLeft", "get").mockReturnValue(0); + + // @ts-ignore + act(() => resizeCallback([{ target: screen.getByRole("listbox", { name: "Room list filters" }) }])); } it("should hide or display filters if they are wrapping", async () => { const user = userEvent.setup(); render(); + mockFiltersOffsetLeft(); // No filter is wrapping, so chevron shouldn't be visible expect(screen.queryByRole("button", { name: "Expand filter list" })).toBeNull(); expect(screen.queryByRole("option", { name: "Unreads" })).toBeVisible(); - mockFiltersOffsetLeft(); - // @ts-ignore - act(() => resizeCallback([{ target: screen.getByRole("listbox", { name: "Room list filters" }) }])); + makeUnreadWrapping(); // The Unreads filter is wrapping, it should not be visible expect(screen.queryByRole("option", { name: "Unreads" })).toBeNull(); @@ -107,9 +122,7 @@ describe("", () => { const user = userEvent.setup(); render(); - mockFiltersOffsetLeft(); - // @ts-ignore - act(() => resizeCallback([{ target: screen.getByRole("listbox", { name: "Room list filters" }) }])); + makeUnreadWrapping(); // Unread filter should be moved to the first position expect(screen.getByRole("listbox", { name: "Room list filters" }).children[0]).toBe( @@ -122,4 +135,21 @@ describe("", () => { screen.getByRole("option", { name: "Unreads" }), ); }); + + it("should hide the filter is the previous is on the same vertical position", async () => { + render(); + mockFiltersOffsetLeft(); + + jest.spyOn(screen.getByRole("option", { name: "People" }), "offsetLeft", "get").mockReturnValue(0); + // Rooms is wrapping + jest.spyOn(screen.getByRole("option", { name: "Rooms" }), "offsetLeft", "get").mockReturnValue(0); + + // @ts-ignore + act(() => resizeCallback([{ target: screen.getByRole("listbox", { name: "Room list filters" }) }])); + + // The Unreads filter is wrapping, it should not be visible + expect(screen.queryByRole("option", { name: "Rooms" })).toBeNull(); + // Now filters are wrapping, so chevron should be visible + expect(screen.getByRole("button", { name: "Expand filter list" })).toBeVisible(); + }); }); diff --git a/test/unit-tests/components/views/rooms/RoomListPanel/__snapshots__/RoomListPrimaryFilters-test.tsx.snap b/test/unit-tests/components/views/rooms/RoomListPanel/__snapshots__/RoomListPrimaryFilters-test.tsx.snap index 601a3eb325..cbfab6e2d2 100644 --- a/test/unit-tests/components/views/rooms/RoomListPanel/__snapshots__/RoomListPrimaryFilters-test.tsx.snap +++ b/test/unit-tests/components/views/rooms/RoomListPanel/__snapshots__/RoomListPrimaryFilters-test.tsx.snap @@ -16,7 +16,7 @@ exports[` should renders all filters correctly 1`] = ` >