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

Commit 09ffad9

Browse files
authored
Merge pull request #6569 from matrix-org/t3chguy/fix/spaces-a11y
2 parents 1321e2f + 857bb9d commit 09ffad9

File tree

11 files changed

+351
-211
lines changed

11 files changed

+351
-211
lines changed

res/css/structures/_SpaceRoomDirectory.scss

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ limitations under the License.
269269
}
270270
}
271271

272-
&:hover {
272+
&:hover, &:focus-within {
273273
background-color: $groupFilterPanel-bg-color;
274274

275275
.mx_AccessibleButton {
@@ -278,6 +278,10 @@ limitations under the License.
278278
}
279279
}
280280

281+
li.mx_SpaceRoomDirectory_roomTileWrapper {
282+
list-style: none;
283+
}
284+
281285
.mx_SpaceRoomDirectory_roomTile,
282286
.mx_SpaceRoomDirectory_subspace_children {
283287
&::before {

src/accessibility/RovingTabIndex.tsx

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -150,13 +150,14 @@ const reducer = (state: IState, action: IAction) => {
150150

151151
interface IProps {
152152
handleHomeEnd?: boolean;
153+
handleUpDown?: boolean;
153154
children(renderProps: {
154155
onKeyDownHandler(ev: React.KeyboardEvent);
155156
});
156157
onKeyDown?(ev: React.KeyboardEvent, state: IState);
157158
}
158159

159-
export const RovingTabIndexProvider: React.FC<IProps> = ({ children, handleHomeEnd, onKeyDown }) => {
160+
export const RovingTabIndexProvider: React.FC<IProps> = ({ children, handleHomeEnd, handleUpDown, onKeyDown }) => {
160161
const [state, dispatch] = useReducer<Reducer<IState, IAction>>(reducer, {
161162
activeRef: null,
162163
refs: [],
@@ -167,21 +168,50 @@ export const RovingTabIndexProvider: React.FC<IProps> = ({ children, handleHomeE
167168
const onKeyDownHandler = useCallback((ev) => {
168169
let handled = false;
169170
// Don't interfere with input default keydown behaviour
170-
if (handleHomeEnd && ev.target.tagName !== "INPUT" && ev.target.tagName !== "TEXTAREA") {
171+
if (ev.target.tagName !== "INPUT" && ev.target.tagName !== "TEXTAREA") {
171172
// check if we actually have any items
172173
switch (ev.key) {
173174
case Key.HOME:
174-
handled = true;
175-
// move focus to first item
176-
if (context.state.refs.length > 0) {
177-
context.state.refs[0].current.focus();
175+
if (handleHomeEnd) {
176+
handled = true;
177+
// move focus to first item
178+
if (context.state.refs.length > 0) {
179+
context.state.refs[0].current.focus();
180+
}
178181
}
179182
break;
183+
180184
case Key.END:
181-
handled = true;
182-
// move focus to last item
183-
if (context.state.refs.length > 0) {
184-
context.state.refs[context.state.refs.length - 1].current.focus();
185+
if (handleHomeEnd) {
186+
handled = true;
187+
// move focus to last item
188+
if (context.state.refs.length > 0) {
189+
context.state.refs[context.state.refs.length - 1].current.focus();
190+
}
191+
}
192+
break;
193+
194+
case Key.ARROW_UP:
195+
if (handleUpDown) {
196+
handled = true;
197+
if (context.state.refs.length > 0) {
198+
const idx = context.state.refs.indexOf(context.state.activeRef);
199+
if (idx > 0) {
200+
context.state.refs[idx - 1].current.focus();
201+
}
202+
}
203+
}
204+
break;
205+
206+
case Key.ARROW_DOWN:
207+
if (handleUpDown) {
208+
handled = true;
209+
if (context.state.refs.length > 0) {
210+
const idx = context.state.refs.indexOf(context.state.activeRef);
211+
if (idx < context.state.refs.length - 1) {
212+
context.state.refs[idx + 1].current.focus();
213+
}
214+
}
185215
}
186216
break;
187217
}
@@ -193,7 +223,7 @@ export const RovingTabIndexProvider: React.FC<IProps> = ({ children, handleHomeE
193223
} else if (onKeyDown) {
194224
return onKeyDown(ev, context.state);
195225
}
196-
}, [context.state, onKeyDown, handleHomeEnd]);
226+
}, [context.state, onKeyDown, handleHomeEnd, handleUpDown]);
197227

198228
return <RovingTabIndexContext.Provider value={context}>
199229
{ children({ onKeyDownHandler }) }

src/components/structures/AutoHideScrollbar.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,9 @@ export default class AutoHideScrollbar extends React.Component<IProps> {
6161
style={style}
6262
className={["mx_AutoHideScrollbar", className].join(" ")}
6363
onWheel={onWheel}
64-
tabIndex={tabIndex}
64+
// Firefox sometimes makes this element focusable due to
65+
// overflow:scroll;, so force it out of tab order by default.
66+
tabIndex={tabIndex ?? -1}
6567
>
6668
{ children }
6769
</div>);

src/components/structures/LeftPanel.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -392,9 +392,6 @@ export default class LeftPanel extends React.Component<IProps, IState> {
392392
<IndicatorScrollbar
393393
className="mx_LeftPanel_breadcrumbsContainer mx_AutoHideScrollbar"
394394
verticalScrollsHorizontally={true}
395-
// Firefox sometimes makes this element focusable due to
396-
// overflow:scroll;, so force it out of tab order.
397-
tabIndex={-1}
398395
>
399396
<RoomBreadcrumbs />
400397
</IndicatorScrollbar>

0 commit comments

Comments
 (0)