diff --git a/src/components/views/rooms/ExtraTile.tsx b/src/components/views/rooms/ExtraTile.tsx index f7a0926120..83f7b179ea 100644 --- a/src/components/views/rooms/ExtraTile.tsx +++ b/src/components/views/rooms/ExtraTile.tsx @@ -1,5 +1,5 @@ /* -Copyright 2020, 2021 The Matrix.org Foundation C.I.C. +Copyright 2020 - 2023 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -21,8 +21,9 @@ import { RovingAccessibleButton, RovingAccessibleTooltipButton } from "../../../ import NotificationBadge from "./NotificationBadge"; import { NotificationState } from "../../../stores/notifications/NotificationState"; import { ButtonEvent } from "../elements/AccessibleButton"; +import useHover from "../../../hooks/useHover"; -interface IProps { +interface ExtraTileProps { isMinimized: boolean; isSelected: boolean; displayName: string; @@ -31,83 +32,68 @@ interface IProps { onClick: (ev: ButtonEvent) => void; } -interface IState { - hover: boolean; -} +export default function ExtraTile({ + isSelected, + isMinimized, + notificationState, + displayName, + onClick, + avatar, +}: ExtraTileProps): JSX.Element { + const [, { onMouseOver, onMouseLeave }] = useHover(() => false); -export default class ExtraTile extends React.Component { - public constructor(props: IProps) { - super(props); + // XXX: We copy classes because it's easier + const classes = classNames({ + mx_ExtraTile: true, + mx_RoomTile: true, + mx_RoomTile_selected: isSelected, + mx_RoomTile_minimized: isMinimized, + }); - this.state = { - hover: false, - }; + let badge: JSX.Element | null = null; + if (notificationState) { + badge = ; } - private onTileMouseEnter = (): void => { - this.setState({ hover: true }); - }; + let name = displayName; + if (typeof name !== "string") name = ""; + name = name.replace(":", ":\u200b"); // add a zero-width space to allow linewrapping after the colon - private onTileMouseLeave = (): void => { - this.setState({ hover: false }); - }; + const nameClasses = classNames({ + mx_RoomTile_title: true, + mx_RoomTile_titleHasUnreadEvents: notificationState?.isUnread, + }); - public render(): React.ReactElement { - // XXX: We copy classes because it's easier - const classes = classNames({ - mx_ExtraTile: true, - mx_RoomTile: true, - mx_RoomTile_selected: this.props.isSelected, - mx_RoomTile_minimized: this.props.isMinimized, - }); + let nameContainer: JSX.Element | null = ( +
+
+ {name} +
+
+ ); + if (isMinimized) nameContainer = null; - let badge; - if (this.props.notificationState) { - badge = ; - } + let Button = RovingAccessibleButton; + if (isMinimized) { + Button = RovingAccessibleTooltipButton; + } - let name = this.props.displayName; - if (typeof name !== "string") name = ""; - name = name.replace(":", ":\u200b"); // add a zero-width space to allow linewrapping after the colon - - const nameClasses = classNames({ - mx_RoomTile_title: true, - mx_RoomTile_titleHasUnreadEvents: this.props.notificationState?.isUnread, - }); - - let nameContainer = ( -
-
- {name} + return ( + - - ); - } + + ); } diff --git a/src/components/views/rooms/RoomSublist.tsx b/src/components/views/rooms/RoomSublist.tsx index 1dd25cbff5..9adf1d7e20 100644 --- a/src/components/views/rooms/RoomSublist.tsx +++ b/src/components/views/rooms/RoomSublist.tsx @@ -82,7 +82,7 @@ interface IProps { alwaysVisible?: boolean; forceExpanded?: boolean; resizeNotifier: ResizeNotifier; - extraTiles?: ReactComponentElement[]; + extraTiles?: ReactComponentElement[] | null; onListCollapse?: (isExpanded: boolean) => void; } @@ -170,7 +170,7 @@ export default class RoomSublist extends React.Component { return RoomSublist.calcNumTiles(this.state.rooms, this.extraTiles); } - private static calcNumTiles(rooms: Room[], extraTiles: any[]): number { + private static calcNumTiles(rooms: Room[], extraTiles?: any[] | null): number { return (rooms || []).length + (extraTiles || []).length; } diff --git a/test/components/views/rooms/ExtraTile-test.tsx b/test/components/views/rooms/ExtraTile-test.tsx new file mode 100644 index 0000000000..70a439110c --- /dev/null +++ b/test/components/views/rooms/ExtraTile-test.tsx @@ -0,0 +1,61 @@ +/* +Copyright 2023 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import { getByRole, render } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; +import React, { ComponentProps } from "react"; + +import ExtraTile from "../../../../src/components/views/rooms/ExtraTile"; + +describe("ExtraTile", () => { + function renderComponent(props: Partial> = {}) { + const defaultProps: ComponentProps = { + isMinimized: false, + isSelected: false, + displayName: "test", + avatar: , + onClick: () => {}, + }; + return render(); + } + + it("renders", () => { + const { asFragment } = renderComponent(); + expect(asFragment()).toMatchSnapshot(); + }); + + it("hides text when minimized", () => { + const { container } = renderComponent({ + isMinimized: true, + displayName: "testDisplayName", + }); + expect(container).not.toHaveTextContent("testDisplayName"); + }); + + it("registers clicks", async () => { + const onClick = jest.fn(); + + const { container } = renderComponent({ + onClick, + }); + + const btn = getByRole(container, "treeitem"); + + await userEvent.click(btn); + + expect(onClick).toHaveBeenCalledTimes(1); + }); +}); diff --git a/test/components/views/rooms/__snapshots__/ExtraTile-test.tsx.snap b/test/components/views/rooms/__snapshots__/ExtraTile-test.tsx.snap new file mode 100644 index 0000000000..137dde1745 --- /dev/null +++ b/test/components/views/rooms/__snapshots__/ExtraTile-test.tsx.snap @@ -0,0 +1,38 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`ExtraTile renders 1`] = ` + +
+
+
+
+
+
+ test +
+
+
+
+
+
+ +`;