Fix accessibility issues around the room list and space panel (#10717)

* Fix room sublist group label being read twice in Orca

* Fix room list sublist notification badges always having a tab stop
t3chguy/dedup-icons-17oct
Michael Telatynski 2023-05-05 11:09:41 +01:00 committed by GitHub
parent c824c4a858
commit 43ffd89e58
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 24 additions and 6 deletions

View File

@ -44,7 +44,7 @@ interface IClickableProps extends IProps, React.InputHTMLAttributes<Element> {
/** /**
* If specified will return an AccessibleButton instead of a div. * If specified will return an AccessibleButton instead of a div.
*/ */
onClick?(ev: React.MouseEvent): void; onClick(ev: React.MouseEvent): void;
} }
interface IState { interface IState {
@ -112,7 +112,7 @@ export default class NotificationBadge extends React.PureComponent<XOR<IProps, I
public render(): ReactNode { public render(): ReactNode {
/* eslint @typescript-eslint/no-unused-vars: ["error", { "ignoreRestSiblings": true }] */ /* eslint @typescript-eslint/no-unused-vars: ["error", { "ignoreRestSiblings": true }] */
const { notification, showUnsentTooltip, forceCount, onClick } = this.props; const { notification, showUnsentTooltip, forceCount, onClick, tabIndex } = this.props;
if (notification.isIdle) return null; if (notification.isIdle) return null;
if (forceCount) { if (forceCount) {
@ -135,6 +135,7 @@ export default class NotificationBadge extends React.PureComponent<XOR<IProps, I
onClick={onClick} onClick={onClick}
onMouseOver={this.onMouseOver} onMouseOver={this.onMouseOver}
onMouseLeave={this.onMouseLeave} onMouseLeave={this.onMouseLeave}
tabIndex={tabIndex}
> >
{tooltip} {tooltip}
</StatelessNotificationBadge> </StatelessNotificationBadge>

View File

@ -21,19 +21,32 @@ import { formatCount } from "../../../../utils/FormattingUtils";
import AccessibleButton from "../../elements/AccessibleButton"; import AccessibleButton from "../../elements/AccessibleButton";
import { NotificationColor } from "../../../../stores/notifications/NotificationColor"; import { NotificationColor } from "../../../../stores/notifications/NotificationColor";
import { useSettingValue } from "../../../../hooks/useSettings"; import { useSettingValue } from "../../../../hooks/useSettings";
import { XOR } from "../../../../@types/common";
interface Props { interface Props {
symbol: string | null; symbol: string | null;
count: number; count: number;
color: NotificationColor; color: NotificationColor;
onClick?: (ev: MouseEvent) => void;
onMouseOver?: (ev: MouseEvent) => void; onMouseOver?: (ev: MouseEvent) => void;
onMouseLeave?: (ev: MouseEvent) => void; onMouseLeave?: (ev: MouseEvent) => void;
children?: ReactNode; children?: ReactNode;
label?: string; label?: string;
} }
export function StatelessNotificationBadge({ symbol, count, color, ...props }: Props): JSX.Element { interface ClickableProps extends Props {
/**
* If specified will return an AccessibleButton instead of a div.
*/
onClick(ev: React.MouseEvent): void;
tabIndex?: number;
}
export function StatelessNotificationBadge({
symbol,
count,
color,
...props
}: XOR<Props, ClickableProps>): JSX.Element {
const hideBold = useSettingValue("feature_hidebold"); const hideBold = useSettingValue("feature_hidebold");
// Don't show a badge if we don't need to // Don't show a badge if we don't need to

View File

@ -85,6 +85,10 @@ interface IProps {
onListCollapse?: (isExpanded: boolean) => void; onListCollapse?: (isExpanded: boolean) => void;
} }
function getLabelId(tagId: TagID): string {
return `mx_RoomSublist_label_${tagId}`;
}
// TODO: Use re-resizer's NumberSize when it is exposed as the type // TODO: Use re-resizer's NumberSize when it is exposed as the type
interface ResizeDelta { interface ResizeDelta {
width: number; width: number;
@ -712,7 +716,7 @@ export default class RoomSublist extends React.Component<IProps, IState> {
title={this.props.isMinimized ? this.props.label : undefined} title={this.props.isMinimized ? this.props.label : undefined}
> >
<span className={collapseClasses} /> <span className={collapseClasses} />
<span>{this.props.label}</span> <span id={getLabelId(this.props.tagId)}>{this.props.label}</span>
</Button> </Button>
{this.renderMenu()} {this.renderMenu()}
{this.props.isMinimized ? null : badgeContainer} {this.props.isMinimized ? null : badgeContainer}
@ -880,7 +884,7 @@ export default class RoomSublist extends React.Component<IProps, IState> {
className={classes} className={classes}
role="group" role="group"
aria-hidden={hidden} aria-hidden={hidden}
aria-label={this.props.label} aria-labelledby={getLabelId(this.props.tagId)}
onKeyDown={this.onKeyDown} onKeyDown={this.onKeyDown}
> >
{this.renderHeader()} {this.renderHeader()}