Allow filtering room list during treeview navigation (#7219)

This commit is contained in:
Michael Telatynski 2021-11-29 17:18:35 +00:00 committed by GitHub
parent 768e270f3f
commit 9727a82a12
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 40 additions and 3 deletions

View file

@ -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

View file

@ -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;
@ -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) {
@ -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>

View file

@ -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),
});
}
}

View file

@ -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>