mirror of
https://github.com/vector-im/element-web.git
synced 2026-05-06 04:36:21 +02:00
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.
This commit is contained in:
parent
e28b197868
commit
a26703c5b7
@ -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 (
|
||||
<Flex className="mx_RoomListItemMenuView" align="center" gap="var(--cpd-space-1x)">
|
||||
{vm.showMoreOptionsMenu && <MoreOptionsMenu setMenuOpen={setMenuOpen} vm={vm} />}
|
||||
{vm.showNotificationMenu && <NotificationMenu setMenuOpen={setMenuOpen} vm={vm} />}
|
||||
{vm.showMoreOptionsMenu && (
|
||||
<MoreOptionsMenu setMenuOpen={setMenuOpen} vm={vm} describedById={describedById} />
|
||||
)}
|
||||
{vm.showNotificationMenu && (
|
||||
<NotificationMenu setMenuOpen={setMenuOpen} vm={vm} describedById={describedById} />
|
||||
)}
|
||||
</Flex>
|
||||
);
|
||||
}
|
||||
@ -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={<MoreOptionsButton size="24px" />}
|
||||
trigger={<MoreOptionsButton size="24px" aria-describedby={describedById} />}
|
||||
>
|
||||
{vm.canMarkAsRead && (
|
||||
<MenuItem
|
||||
@ -174,9 +190,15 @@ interface NotificationMenuProps {
|
||||
* @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;
|
||||
}
|
||||
|
||||
function NotificationMenu({ vm, setMenuOpen }: NotificationMenuProps): JSX.Element {
|
||||
function NotificationMenu({ vm, setMenuOpen, describedById }: NotificationMenuProps): JSX.Element {
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
const checkComponent = <CheckIcon width="24px" height="24px" color="var(--cpd-color-icon-primary)" />;
|
||||
@ -191,7 +213,9 @@ function NotificationMenu({ vm, setMenuOpen }: NotificationMenuProps): JSX.Eleme
|
||||
title={_t("room_list|notification_options")}
|
||||
showTitle={false}
|
||||
align="start"
|
||||
trigger={<NotificationButton isRoomMuted={vm.isNotificationMute} size="24px" />}
|
||||
trigger={
|
||||
<NotificationButton isRoomMuted={vm.isNotificationMute} size="24px" aria-describedby={describedById} />
|
||||
}
|
||||
>
|
||||
<MenuItem
|
||||
aria-selected={vm.isNotificationAllMessage}
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import React, { type JSX, memo, useCallback, useRef, useState } from "react";
|
||||
import React, { type JSX, memo, useCallback, useId, useRef, useState } from "react";
|
||||
import { type Room } from "matrix-js-sdk/src/matrix";
|
||||
import classNames from "classnames";
|
||||
|
||||
@ -46,6 +46,7 @@ export const RoomListItemView = memo(function RoomListItemView({
|
||||
// Using display: none; and then display:flex when hovered in CSS causes the menu to be misaligned
|
||||
const showHoverDecoration = isMenuOpen || isHover;
|
||||
const showHoverMenu = showHoverDecoration && vm.showHoverMenu;
|
||||
const roomNameId = useId();
|
||||
|
||||
return (
|
||||
<button
|
||||
@ -84,7 +85,7 @@ export const RoomListItemView = memo(function RoomListItemView({
|
||||
>
|
||||
{/* We truncate the room name when too long. Title here is to show the full name on hover */}
|
||||
<div className="mx_RoomListItemView_text">
|
||||
<div className="mx_RoomListItemView_roomName" title={vm.name}>
|
||||
<div className="mx_RoomListItemView_roomName" title={vm.name} id={roomNameId}>
|
||||
{vm.name}
|
||||
</div>
|
||||
<div className="mx_RoomListItemView_messagePreview">{vm.messagePreview}</div>
|
||||
@ -92,6 +93,7 @@ export const RoomListItemView = memo(function RoomListItemView({
|
||||
{showHoverMenu ? (
|
||||
<RoomListItemMenuView
|
||||
room={room}
|
||||
describedById={roomNameId}
|
||||
setMenuOpen={(isOpen) => {
|
||||
if (isOpen) {
|
||||
setIsMenuOpen(isOpen);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user