Improve ThreadPanel ctx menu accessibility (#7217)

This commit is contained in:
Michael Telatynski
2021-11-29 17:42:53 +00:00
committed by GitHub
parent 9727a82a12
commit fe24c8ad2a
20 changed files with 35 additions and 48 deletions

View File

@@ -103,7 +103,7 @@ interface IState {
// all options inside the menu should be of role=menuitem/menuitemcheckbox/menuitemradiobutton and have tabIndex={-1}
// this will allow the ContextMenu to manage its own focus using arrow keys as per the ARIA guidelines.
@replaceableComponent("structures.ContextMenu")
export class ContextMenu extends React.PureComponent<IProps, IState> {
export default class ContextMenu extends React.PureComponent<IProps, IState> {
private readonly initialFocus: HTMLElement;
static defaultProps = {
@@ -411,6 +411,7 @@ export class ContextMenu extends React.PureComponent<IProps, IState> {
onClick={this.onClick}
onContextMenu={this.onContextMenuPreventBubbling}
>
{ background }
<div
className={menuClasses}
style={menuStyle}
@@ -419,7 +420,6 @@ export class ContextMenu extends React.PureComponent<IProps, IState> {
>
{ body }
</div>
{ background }
</div>
);
}
@@ -530,30 +530,22 @@ export const useContextMenu = <T extends any = HTMLElement>(): ContextMenuTuple<
return [isOpen, button, open, close, setIsOpen];
};
@replaceableComponent("structures.LegacyContextMenu")
export default class LegacyContextMenu extends ContextMenu {
render() {
return this.renderMenu(false);
}
}
// XXX: Deprecated, used only for dynamic Tooltips. Avoid using at all costs.
export function createMenu(ElementClass, props) {
const onFinished = function(...args) {
ReactDOM.unmountComponentAtNode(getOrCreateContainer());
if (props && props.onFinished) {
props.onFinished.apply(null, args);
}
props?.onFinished?.apply(null, args);
};
const menu = <LegacyContextMenu
const menu = <ContextMenu
{...props}
mountAsChild={true}
hasBackground={false}
onFinished={onFinished} // eslint-disable-line react/jsx-no-bind
windowResize={onFinished} // eslint-disable-line react/jsx-no-bind
>
<ElementClass {...props} onFinished={onFinished} />
</LegacyContextMenu>;
</ContextMenu>;
ReactDOM.render(menu, getOrCreateContainer());

View File

@@ -24,12 +24,11 @@ import ResizeNotifier from '../../utils/ResizeNotifier';
import MatrixClientContext from '../../contexts/MatrixClientContext';
import { _t } from '../../languageHandler';
import { ContextMenuButton } from '../../accessibility/context_menu/ContextMenuButton';
import ContextMenu, { ChevronFace, useContextMenu } from './ContextMenu';
import ContextMenu, { ChevronFace, MenuItemRadio, useContextMenu } from './ContextMenu';
import RoomContext, { TimelineRenderingType } from '../../contexts/RoomContext';
import TimelinePanel from './TimelinePanel';
import { Layout } from '../../settings/enums/Layout';
import { useEventEmitter } from '../../hooks/useEventEmitter';
import AccessibleButton from '../views/elements/AccessibleButton';
import { TileShape } from '../views/rooms/EventTile';
import { RoomPermalinkCreator } from '../../utils/permalinks/Permalinks';
@@ -98,14 +97,14 @@ export const ThreadPanelHeaderFilterOptionItem = ({
onClick: () => void;
isSelected: boolean;
}) => {
return <AccessibleButton
aria-selected={isSelected}
return <MenuItemRadio
active={isSelected}
className="mx_ThreadPanel_Header_FilterOptionItem"
onClick={onClick}
>
<span>{ label }</span>
<span>{ description }</span>
</AccessibleButton>;
</MenuItemRadio>;
};
export const ThreadPanelHeader = ({ filterOption, setFilterOption }: {
@@ -141,8 +140,8 @@ export const ThreadPanelHeader = ({ filterOption, setFilterOption }: {
top={0}
right={25}
onFinished={closeMenu}
managed={false}
chevronFace={ChevronFace.Top}
mountAsChild={true}
>
{ contextMenuOptions }
</ContextMenu> : null;