A11y: move focus to right panel when opened (#30553)

* fix: move focus to right panel when opened

* test: update snapshot

* test(e2e): update screenshot
This commit is contained in:
Florian Duros
2025-08-14 10:59:42 +02:00
committed by GitHub
parent 64dfbc5aa5
commit 0c498a66b1
5 changed files with 23 additions and 2 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 19 KiB

View File

@@ -34,6 +34,7 @@ import { Action } from "../../dispatcher/actions";
import { type XOR } from "../../@types/common";
import ExtensionsCard from "../views/right_panel/ExtensionsCard";
import MemberListView from "../views/rooms/MemberList/MemberListView";
import { _t } from "../../languageHandler";
interface BaseProps {
overwriteCard?: IRightPanelCard; // used to display a custom card and ignoring the RightPanelStore (used for UserView)
@@ -64,6 +65,7 @@ interface IState {
export default class RightPanel extends React.Component<Props, IState> {
public static contextType = MatrixClientContext;
declare public context: React.ContextType<typeof MatrixClientContext>;
private ref = React.createRef<HTMLDivElement>();
public constructor(props: Props) {
super(props);
@@ -82,6 +84,7 @@ export default class RightPanel extends React.Component<Props, IState> {
public componentDidMount(): void {
this.context.on(RoomStateEvent.Members, this.onRoomStateMember);
RightPanelStore.instance.on(UPDATE_EVENT, this.onRightPanelStoreUpdate);
this.ref.current?.focus();
}
public componentWillUnmount(): void {
@@ -119,7 +122,13 @@ export default class RightPanel extends React.Component<Props, IState> {
};
private onRightPanelStoreUpdate = (): void => {
this.setState({ ...(RightPanel.getDerivedStateFromProps(this.props) as IState) });
const oldPhase = this.state.phase;
const newState = RightPanel.getDerivedStateFromProps(this.props) as IState;
this.setState({ ...newState });
if (oldPhase !== newState.phase) {
this.ref.current?.focus();
}
};
private onClose = (): void => {
@@ -282,7 +291,14 @@ export default class RightPanel extends React.Component<Props, IState> {
}
return (
<aside className="mx_RightPanel" id="mx_RightPanel" data-testid="right-panel">
<aside
aria-label={_t("right_panel|title")}
ref={this.ref}
className="mx_RightPanel"
id="mx_RightPanel"
data-testid="right-panel"
tabIndex={-1}
>
{card}
</aside>
);

View File

@@ -1917,6 +1917,7 @@
"thread_list": {
"context_menu_label": "Thread options"
},
"title": "Right panel",
"video_room_chat": {
"title": "Chat"
}

View File

@@ -2189,9 +2189,11 @@ exports[`RoomView video rooms should render joined video room view 1`] = `
style="position: relative; user-select: auto; width: 420px; height: 100%; max-width: 50%; min-width: 320px; box-sizing: border-box; flex-shrink: 0;"
>
<aside
aria-label="Right panel"
class="mx_RightPanel"
data-testid="right-panel"
id="mx_RightPanel"
tabindex="-1"
>
<div
class="mx_BaseCard mx_ThreadPanel mx_TimelineCard"

View File

@@ -3,9 +3,11 @@
exports[`AppTile destroys non-persisted right panel widget on room change 1`] = `
<DocumentFragment>
<aside
aria-label="Right panel"
class="mx_RightPanel"
data-testid="right-panel"
id="mx_RightPanel"
tabindex="-1"
>
<div
class="mx_BaseCard mx_WidgetCard"