From a26703c5b74a67954b74d3da1d18dec9b6b7a26d Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 11 Jun 2025 16:24:54 +0100 Subject: [PATCH] Add aria-describedBy to room list menus On VoiceOver this just adds the the name of the room after 'More Options' and 'Notifications' even though it's already been spoken when you focused the room tile, which doesn't seem too helpful to me but it was explicitly requested. --- .../RoomListPanel/RoomListItemMenuView.tsx | 38 +++++++++++++++---- .../rooms/RoomListPanel/RoomListItemView.tsx | 6 ++- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/src/components/views/rooms/RoomListPanel/RoomListItemMenuView.tsx b/src/components/views/rooms/RoomListPanel/RoomListItemMenuView.tsx index fa7a85b54f..b060c6b002 100644 --- a/src/components/views/rooms/RoomListPanel/RoomListItemMenuView.tsx +++ b/src/components/views/rooms/RoomListPanel/RoomListItemMenuView.tsx @@ -38,18 +38,28 @@ interface RoomListItemMenuViewProps { * @param isOpen */ setMenuOpen: (isOpen: boolean) => void; + /** + * If set, the ID of a DOM element that describes the menu buttons in this view. + * Note that this will be the same for each menu button: it is suggested that it is the + * ID of the room list item that this menu is for, ie. containing the room name as text. + */ + describedById?: string; } /** * A view for the room list item menu. */ -export function RoomListItemMenuView({ room, setMenuOpen }: RoomListItemMenuViewProps): JSX.Element { +export function RoomListItemMenuView({ room, setMenuOpen, describedById }: RoomListItemMenuViewProps): JSX.Element { const vm = useRoomListItemMenuViewModel(room); return ( - {vm.showMoreOptionsMenu && } - {vm.showNotificationMenu && } + {vm.showMoreOptionsMenu && ( + + )} + {vm.showNotificationMenu && ( + + )} ); } @@ -64,12 +74,18 @@ interface MoreOptionsMenuProps { * @param isOpen */ setMenuOpen: (isOpen: boolean) => void; + /** + * If set, the ID of a DOM element that describes the menu buttons in this view. + * Note that this will be the same for each menu button: it is suggested that it is the + * ID of the room list item that this menu is for, ie. containing the room name as text. + */ + describedById?: string; } /** * The more options menu for the room list item. */ -function MoreOptionsMenu({ vm, setMenuOpen }: MoreOptionsMenuProps): JSX.Element { +function MoreOptionsMenu({ vm, setMenuOpen, describedById }: MoreOptionsMenuProps): JSX.Element { const [open, setOpen] = useState(false); return ( @@ -82,7 +98,7 @@ function MoreOptionsMenu({ vm, setMenuOpen }: MoreOptionsMenuProps): JSX.Element title={_t("room_list|room|more_options")} showTitle={false} align="start" - trigger={} + trigger={} > {vm.canMarkAsRead && ( void; + /** + * If set, the ID of a DOM element that describes the menu buttons in this view. + * Note that this will be the same for each menu button: it is suggested that it is the + * ID of the room list item that this menu is for, ie. containing the room name as text. + */ + describedById?: string; } -function NotificationMenu({ vm, setMenuOpen }: NotificationMenuProps): JSX.Element { +function NotificationMenu({ vm, setMenuOpen, describedById }: NotificationMenuProps): JSX.Element { const [open, setOpen] = useState(false); const checkComponent = ; @@ -191,7 +213,9 @@ function NotificationMenu({ vm, setMenuOpen }: NotificationMenuProps): JSX.Eleme title={_t("room_list|notification_options")} showTitle={false} align="start" - trigger={} + trigger={ + + } > {/* We truncate the room name when too long. Title here is to show the full name on hover */}
-
+
{vm.name}
{vm.messagePreview}
@@ -92,6 +93,7 @@ export const RoomListItemView = memo(function RoomListItemView({ {showHoverMenu ? ( { if (isOpen) { setIsMenuOpen(isOpen);