1
0
mirror of https://github.com/matrix-org/matrix-react-sdk.git synced 2025-11-17 17:42:41 +03:00

Implement roving tab index context based magic thing and demo on LeftPanel

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
Michael Telatynski
2020-01-15 02:44:22 +00:00
parent 23633abc10
commit 5252cf4c45
7 changed files with 242 additions and 25 deletions

View File

@@ -129,9 +129,6 @@ const LeftPanel = createReactClass({
if (!this.focusedElement) return;
switch (ev.key) {
case Key.TAB:
this._onMoveFocus(ev, ev.shiftKey);
break;
case Key.ARROW_UP:
this._onMoveFocus(ev, true, true);
break;

View File

@@ -31,6 +31,7 @@ import PropTypes from 'prop-types';
import RoomTile from "../views/rooms/RoomTile";
import LazyRenderList from "../views/elements/LazyRenderList";
import {_t} from "../../languageHandler";
import {RovingTabIndex, RovingTabIndexGroup} from "../../contexts/RovingTabIndexContext";
// turn this on for drop & drag console debugging galore
const debug = false;
@@ -272,20 +273,32 @@ export default class RoomSubList extends React.PureComponent {
// Wrap the contents in a div and apply styles to the child div so that the browser default outline works
if (subListNotifCount > 0) {
badge = (
<AccessibleButton className={badgeClasses} onClick={this._onNotifBadgeClick} aria-label={_t("Jump to first unread room.")}>
<RovingTabIndex
component={AccessibleButton}
useInputRef
className={badgeClasses}
onClick={this._onNotifBadgeClick}
aria-label={_t("Jump to first unread room.")}
>
<div>
{ FormattingUtils.formatCount(subListNotifCount) }
</div>
</AccessibleButton>
</RovingTabIndex>
);
} else if (this.props.isInvite && this.props.list.length) {
// no notifications but highlight anyway because this is an invite badge
badge = (
<AccessibleButton className={badgeClasses} onClick={this._onInviteBadgeClick} aria-label={_t("Jump to first invite.")}>
<RovingTabIndex
component={AccessibleButton}
useInputRef
className={badgeClasses}
onClick={this._onInviteBadgeClick}
aria-label={_t("Jump to first invite.")}
>
<div>
{ this.props.list.length }
</div>
</AccessibleButton>
</RovingTabIndex>
);
}
}
@@ -308,7 +321,9 @@ export default class RoomSubList extends React.PureComponent {
let addRoomButton;
if (this.props.onAddRoom) {
addRoomButton = (
<AccessibleTooltipButton
<RovingTabIndex
component={AccessibleTooltipButton}
useInputRef
onClick={this.onAddRoom}
className="mx_RoomSubList_addRoom"
title={this.props.addRoomLabel || _t("Add room")}
@@ -327,12 +342,13 @@ export default class RoomSubList extends React.PureComponent {
chevron = (<div className={chevronClasses} />);
}
return (
return <RovingTabIndexGroup>
<div className="mx_RoomSubList_labelContainer" title={title} ref={this._header} onKeyDown={this.onHeaderKeyDown}>
<AccessibleButton
<RovingTabIndex
component={AccessibleButton}
useInputRef
onClick={this.onClick}
className="mx_RoomSubList_label"
tabIndex={0}
aria-expanded={!isCollapsed}
inputRef={this._headerButton}
role="treeitem"
@@ -341,11 +357,11 @@ export default class RoomSubList extends React.PureComponent {
{ chevron }
<span>{this.props.label}</span>
{ incomingCall }
</AccessibleButton>
</RovingTabIndex>
{ badge }
{ addRoomButton }
</div>
);
</RovingTabIndexGroup>;
}
checkOverflow = () => {

View File

@@ -26,6 +26,7 @@ import classNames from 'classnames';
import MatrixClientPeg from "../../../MatrixClientPeg";
import {ContextMenu, ContextMenuButton, toRightOf} from "../../structures/ContextMenu";
import MatrixClientContext from "../../../contexts/MatrixClientContext";
import {RovingTabIndex, RovingTabIndexGroup} from "../../../contexts/RovingTabIndexContext";
// XXX this class copies a lot from RoomTile.js
export default createReactClass({
@@ -138,14 +139,16 @@ export default createReactClass({
const badgeContent = badgeEllipsis ? '\u00B7\u00B7\u00B7' : '!';
const badge = (
<ContextMenuButton
<RovingTabIndex
component={ContextMenuButton}
useInputRef
className={badgeClasses}
onClick={this.onContextMenuButtonClick}
label={_t("Options")}
isExpanded={isMenuDisplayed}
>
{ badgeContent }
</ContextMenuButton>
</RovingTabIndex>
);
let tooltip;
@@ -170,8 +173,10 @@ export default createReactClass({
);
}
return <React.Fragment>
<AccessibleButton
return <RovingTabIndexGroup>
<RovingTabIndex
component={AccessibleButton}
useInputRef
className={classes}
onClick={this.onClick}
onMouseEnter={this.onMouseEnter}
@@ -186,9 +191,9 @@ export default createReactClass({
{ badge }
</div>
{ tooltip }
</AccessibleButton>
</RovingTabIndex>
{ contextMenu }
</React.Fragment>;
</RovingTabIndexGroup>;
},
});

View File

@@ -41,6 +41,7 @@ import ResizeHandle from '../elements/ResizeHandle';
import {Resizer} from '../../../resizer';
import {Layout, Distributor} from '../../../resizer/distributors/roomsublist2';
import {RovingTabIndexContextWrapper} from "../../../contexts/RovingTabIndexContext";
const HIDE_CONFERENCE_CHANS = true;
const STANDARD_TAGS_REGEX = /^(m\.(favourite|lowpriority|server_notice)|im\.vector\.fake\.(invite|recent|direct|archived))$/;
const HOVER_MOVE_TIMEOUT = 1000;
@@ -788,7 +789,9 @@ module.exports = createReactClass({
onMouseMove={this.onMouseMove}
onMouseLeave={this.onMouseLeave}
>
{ subListComponents }
<RovingTabIndexContextWrapper>
{ subListComponents }
</RovingTabIndexContextWrapper>
</div>
);
},

View File

@@ -32,6 +32,7 @@ import ActiveRoomObserver from '../../../ActiveRoomObserver';
import RoomViewStore from '../../../stores/RoomViewStore';
import SettingsStore from "../../../settings/SettingsStore";
import {_t} from "../../../languageHandler";
import {RovingTabIndex} from "../../../contexts/RovingTabIndexContext";
module.exports = createReactClass({
displayName: 'RoomTile',
@@ -432,8 +433,9 @@ module.exports = createReactClass({
}
return <React.Fragment>
<AccessibleButton
tabIndex="0"
<RovingTabIndex
component={AccessibleButton}
useInputRef
className={classes}
onClick={this.onClick}
onMouseEnter={this.onMouseEnter}
@@ -461,7 +463,7 @@ module.exports = createReactClass({
</div>
{ /* { incomingCallBox } */ }
{ tooltip }
</AccessibleButton>
</RovingTabIndex>
{ contextMenu }
</React.Fragment>;