iterate spaces treeview stuff

This commit is contained in:
Michael Telatynski 2021-08-09 14:01:34 +01:00
parent 09f20bcda7
commit 0f49fe92c6
5 changed files with 57 additions and 46 deletions

View file

@ -278,6 +278,10 @@ limitations under the License.
} }
} }
li.mx_SpaceRoomDirectory_roomTileWrapper {
list-style: none;
}
.mx_SpaceRoomDirectory_roomTile, .mx_SpaceRoomDirectory_roomTile,
.mx_SpaceRoomDirectory_subspace_children { .mx_SpaceRoomDirectory_subspace_children {
&::before { &::before {

View file

@ -196,7 +196,7 @@ export const RovingTabIndexProvider: React.FC<IProps> = ({ children, handleHomeE
handled = true; handled = true;
if (context.state.refs.length > 0) { if (context.state.refs.length > 0) {
const idx = context.state.refs.indexOf(context.state.activeRef); const idx = context.state.refs.indexOf(context.state.activeRef);
if (idx > 1) { if (idx > 0) {
context.state.refs[idx - 1].current.focus(); context.state.refs[idx - 1].current.focus();
} }
} }

View file

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
import React, { ReactNode, KeyboardEvent, useMemo, useState } from "react"; import React, { ReactNode, KeyboardEvent, useMemo, useState, KeyboardEventHandler } from "react";
import { Room } from "matrix-js-sdk/src/models/room"; import { Room } from "matrix-js-sdk/src/models/room";
import { EventType, RoomType } from "matrix-js-sdk/src/@types/event"; import { EventType, RoomType } from "matrix-js-sdk/src/@types/event";
import { ISpaceSummaryRoom, ISpaceSummaryEvent } from "matrix-js-sdk/src/@types/spaces"; import { ISpaceSummaryRoom, ISpaceSummaryEvent } from "matrix-js-sdk/src/@types/spaces";
@ -185,8 +185,9 @@ const Tile: React.FC<ITileProps> = ({
</div> </div>
</React.Fragment>; </React.Fragment>;
let childToggle; let childToggle: JSX.Element;
let childSection; let childSection: JSX.Element;
let onKeyDown: KeyboardEventHandler;
if (children) { if (children) {
// the chevron is purposefully a div rather than a button as it should be ignored for a11y // the chevron is purposefully a div rather than a button as it should be ignored for a11y
childToggle = <div childToggle = <div
@ -216,36 +217,41 @@ const Tile: React.FC<ITileProps> = ({
{ children } { children }
</div>; </div>;
} }
onKeyDown = (e) => {
let handled = false;
switch (e.key) {
case Key.ARROW_LEFT:
if (showChildren) {
handled = true;
toggleShowChildren();
}
break;
case Key.ARROW_RIGHT:
handled = true;
if (showChildren) {
const childSection = ref.current?.nextElementSibling;
childSection?.querySelector<HTMLDivElement>(".mx_SpaceRoomDirectory_roomTile")?.focus();
} else {
toggleShowChildren();
}
break;
}
if (handled) {
e.preventDefault();
e.stopPropagation();
}
};
} }
const onKeyDown = children ? (e) => { return <li
let handled = false; className="mx_SpaceRoomDirectory_roomTileWrapper"
role="treeitem"
switch (e.key) { aria-expanded={children ? showChildren : undefined}
case Key.ARROW_LEFT: >
if (showChildren) {
handled = true;
toggleShowChildren();
}
break;
case Key.ARROW_RIGHT:
handled = true;
if (showChildren) {
(ref.current?.nextElementSibling?.firstElementChild as HTMLElement)?.focus();
} else {
toggleShowChildren();
}
break;
}
if (handled) {
e.preventDefault();
e.stopPropagation();
}
} : undefined;
return <>
<AccessibleButton <AccessibleButton
className={classNames("mx_SpaceRoomDirectory_roomTile", { className={classNames("mx_SpaceRoomDirectory_roomTile", {
mx_SpaceRoomDirectory_subspace: room.room_type === RoomType.Space, mx_SpaceRoomDirectory_subspace: room.room_type === RoomType.Space,
@ -255,14 +261,12 @@ const Tile: React.FC<ITileProps> = ({
inputRef={ref} inputRef={ref}
onFocus={onFocus} onFocus={onFocus}
tabIndex={isActive ? 0 : -1} tabIndex={isActive ? 0 : -1}
aria-expanded={children ? showChildren : undefined}
role="treeitem"
> >
{ content } { content }
{ childToggle } { childToggle }
</AccessibleButton> </AccessibleButton>
{ childSection } { childSection }
</>; </li>;
}; };
export const showRoom = (room: ISpaceSummaryRoom, viaServers?: string[], autoJoin = false) => { export const showRoom = (room: ISpaceSummaryRoom, viaServers?: string[], autoJoin = false) => {

View file

@ -100,9 +100,12 @@ const HomeButton = ({ selected, isPanelCollapsed }: IHomeButtonProps) => {
return SpaceStore.instance.allRoomsInHome; return SpaceStore.instance.allRoomsInHome;
}); });
return <li className={classNames("mx_SpaceItem", { return <li
"collapsed": isPanelCollapsed, className={classNames("mx_SpaceItem", {
})}> "collapsed": isPanelCollapsed,
})}
role="treeitem"
>
<SpaceButton <SpaceButton
className="mx_SpaceButton_home" className="mx_SpaceButton_home"
onClick={() => SpaceStore.instance.setActiveSpace(null)} onClick={() => SpaceStore.instance.setActiveSpace(null)}
@ -142,9 +145,12 @@ const CreateSpaceButton = ({
openMenu(); openMenu();
}; };
return <li className={classNames("mx_SpaceItem", { return <li
"collapsed": isPanelCollapsed, className={classNames("mx_SpaceItem", {
})}> "collapsed": isPanelCollapsed,
})}
role="treeitem"
>
<SpaceButton <SpaceButton
className={classNames("mx_SpaceButton_new", { className={classNames("mx_SpaceButton_new", {
mx_SpaceButton_newCancel: menuDisplayed, mx_SpaceButton_newCancel: menuDisplayed,

View file

@ -113,7 +113,6 @@ export const SpaceButton: React.FC<IButtonProps> = ({
onClick={onClick} onClick={onClick}
onContextMenu={openMenu} onContextMenu={openMenu}
forceHide={!isNarrow || menuDisplayed} forceHide={!isNarrow || menuDisplayed}
role="treeitem"
inputRef={handle} inputRef={handle}
> >
{ children } { children }
@ -290,7 +289,7 @@ export class SpaceItem extends React.PureComponent<IItemProps, IItemState> {
/> : null; /> : null;
return ( return (
<li {...otherProps} className={itemClasses} ref={innerRef}> <li {...otherProps} className={itemClasses} ref={innerRef} aria-expanded={!collapsed} role="treeitem">
<SpaceButton <SpaceButton
space={space} space={space}
className={isInvite ? "mx_SpaceButton_invite" : undefined} className={isInvite ? "mx_SpaceButton_invite" : undefined}
@ -302,9 +301,7 @@ export class SpaceItem extends React.PureComponent<IItemProps, IItemState> {
avatarSize={isNested ? 24 : 32} avatarSize={isNested ? 24 : 32}
onClick={this.onClick} onClick={this.onClick}
onKeyDown={this.onKeyDown} onKeyDown={this.onKeyDown}
aria-expanded={!collapsed} ContextMenuComponent={this.props.space.getMyMembership() === "join" ? SpaceContextMenu : undefined}
ContextMenuComponent={this.props.space.getMyMembership() === "join"
? SpaceContextMenu : undefined}
> >
{ toggleCollapseButton } { toggleCollapseButton }
</SpaceButton> </SpaceButton>