Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Commit

Permalink
Allow filtering room list during treeview navigation (#7219)
Browse files Browse the repository at this point in the history
  • Loading branch information
t3chguy authored Nov 29, 2021
1 parent 768e270 commit 9727a82
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 3 deletions.
11 changes: 8 additions & 3 deletions src/accessibility/RovingTabIndex.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -123,9 +123,14 @@ export const reducer = (state: IState, action: IAction) => {

if (state.refs.splice(oldIndex, 1)[0] === state.activeRef) {
// we just removed the active ref, need to replace it
// pick the ref which is now in the index the old ref was in
const len = state.refs.length;
state.activeRef = oldIndex >= len ? state.refs[len - 1] : state.refs[oldIndex];
// pick the ref closest to the index the old ref was in
if (oldIndex >= state.refs.length) {
state.activeRef = findSiblingElement(state.refs, state.refs.length - 1, true);
} else {
state.activeRef = findSiblingElement(state.refs, oldIndex)
|| findSiblingElement(state.refs, oldIndex, true);
}
state.activeRef?.current?.focus();
}

// update the refs list
Expand Down
15 changes: 15 additions & 0 deletions src/components/structures/LeftPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import { getKeyBindingsManager, RoomListAction } from "../../KeyBindingsManager"
import UIStore from "../../stores/UIStore";
import { findSiblingElement, IState as IRovingTabIndexState } from "../../accessibility/RovingTabIndex";
import MatrixClientContext from "../../contexts/MatrixClientContext";
import { Key } from "../../Keyboard";

interface IProps {
isMinimized: boolean;
Expand Down Expand Up @@ -304,6 +305,19 @@ export default class LeftPanel extends React.Component<IProps, IState> {
}
};

private onRoomListKeydown = (ev: React.KeyboardEvent) => {
// we cannot handle Space as that is an activation key for all focusable elements in this widget
if (ev.key.length === 1) {
ev.preventDefault();
ev.stopPropagation();
this.roomSearchRef.current?.appendChar(ev.key);
} else if (ev.key === Key.BACKSPACE) {
ev.preventDefault();
ev.stopPropagation();
this.roomSearchRef.current?.backspace();
}
};

private selectRoom = () => {
const firstRoom = this.listContainerRef.current.querySelector<HTMLDivElement>(".mx_RoomTile");
if (firstRoom) {
Expand Down Expand Up @@ -411,6 +425,7 @@ export default class LeftPanel extends React.Component<IProps, IState> {
// Firefox sometimes makes this element focusable due to
// overflow:scroll;, so force it out of tab order.
tabIndex={-1}
onKeyDown={this.onRoomListKeydown}
>
{ roomList }
</div>
Expand Down
12 changes: 12 additions & 0 deletions src/components/structures/RoomSearch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -214,4 +214,16 @@ export default class RoomSearch extends React.PureComponent<IProps, IState> {
</div>
);
}

public appendChar(char: string): void {
this.setState({
query: this.state.query + char,
});
}

public backspace(): void {
this.setState({
query: this.state.query.substring(0, this.state.query.length - 1),
});
}
}
5 changes: 5 additions & 0 deletions test/accessibility/RovingTabIndex-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ const button2 = <Button key={2}>b</Button>;
const button3 = <Button key={3}>c</Button>;
const button4 = <Button key={4}>d</Button>;

// mock offsetParent
Object.defineProperty(HTMLElement.prototype, "offsetParent", {
get() { return this.parentNode; },
});

describe("RovingTabIndex", () => {
it("RovingTabIndexProvider renders children as expected", () => {
const wrapper = mount(<RovingTabIndexProvider>
Expand Down

0 comments on commit 9727a82

Please sign in to comment.