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

Space panel accessibility improvements #6744

Merged
merged 3 commits into from
Sep 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/components/views/spaces/SpacePanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -195,12 +195,10 @@ const InnerSpacePanel = React.memo<IInnerSpacePanelProps>(({ children, isPanelCo
{ (provided, snapshot) => (
<SpaceItem
{...provided.draggableProps}
{...provided.dragHandleProps}
dragHandleProps={provided.dragHandleProps}
key={s.roomId}
innerRef={provided.innerRef}
className={snapshot.isDragging
? "mx_SpaceItem_dragging"
: undefined}
className={snapshot.isDragging ? "mx_SpaceItem_dragging" : undefined}
space={s}
activeSpaces={activeSpaces}
isPanelCollapsed={isPanelCollapsed}
Expand All @@ -223,6 +221,8 @@ const SpacePanel = () => {
}, []);

const onKeyDown = (ev: React.KeyboardEvent) => {
if (ev.defaultPrevented) return;

let handled = true;

switch (ev.key) {
Expand Down
36 changes: 28 additions & 8 deletions src/components/views/spaces/SpaceTreeLevel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import RoomAvatar from "../avatars/RoomAvatar";
import SpaceStore from "../../../stores/SpaceStore";
import SpaceTreeLevelLayoutStore from "../../../stores/SpaceTreeLevelLayoutStore";
import NotificationBadge from "../rooms/NotificationBadge";
import { RovingAccessibleTooltipButton } from "../../../accessibility/roving/RovingAccessibleTooltipButton";
import { _t } from "../../../languageHandler";
import { ContextMenuTooltipButton } from "../../../accessibility/context_menu/ContextMenuTooltipButton";
import { toRightOf, useContextMenu } from "../../structures/ContextMenu";
Expand All @@ -40,8 +39,11 @@ import { NotificationColor } from "../../../stores/notifications/NotificationCol
import { getKeyBindingsManager, RoomListAction } from "../../../KeyBindingsManager";
import { NotificationState } from "../../../stores/notifications/NotificationState";
import SpaceContextMenu from "../context_menus/SpaceContextMenu";
import AccessibleTooltipButton from "../elements/AccessibleTooltipButton";
import { DraggableProvidedDragHandleProps } from "react-beautiful-dnd";
import { useRovingTabIndex } from "../../../accessibility/RovingTabIndex";

interface IButtonProps extends Omit<ComponentProps<typeof RovingAccessibleTooltipButton>, "title"> {
interface IButtonProps extends Omit<ComponentProps<typeof AccessibleTooltipButton>, "title"> {
space?: Room;
className?: string;
selected?: boolean;
Expand All @@ -68,7 +70,9 @@ export const SpaceButton: React.FC<IButtonProps> = ({
ContextMenuComponent,
...props
}) => {
const [menuDisplayed, handle, openMenu, closeMenu] = useContextMenu<HTMLElement>();
const [menuDisplayed, ref, openMenu, closeMenu] = useContextMenu<HTMLElement>();
const [onFocus, isActive, handle] = useRovingTabIndex(ref);
const tabIndex = isActive ? 0 : -1;

let avatar = <div className="mx_SpaceButton_avatarPlaceholder"><div className="mx_SpaceButton_icon" /></div>;
if (space) {
Expand All @@ -88,6 +92,7 @@ export const SpaceButton: React.FC<IButtonProps> = ({
forceCount={false}
notification={notificationState}
aria-label={ariaLabel}
tabIndex={tabIndex}
/>
</div>;
}
Expand All @@ -102,7 +107,7 @@ export const SpaceButton: React.FC<IButtonProps> = ({
}

return (
<RovingAccessibleTooltipButton
<AccessibleTooltipButton
{...props}
className={classNames("mx_SpaceButton", className, {
mx_SpaceButton_active: selected,
Expand All @@ -114,6 +119,8 @@ export const SpaceButton: React.FC<IButtonProps> = ({
onContextMenu={openMenu}
forceHide={!isNarrow || menuDisplayed}
inputRef={handle}
tabIndex={tabIndex}
onFocus={onFocus}
>
{ children }
<div className="mx_SpaceButton_selectionWrapper">
Expand All @@ -130,7 +137,7 @@ export const SpaceButton: React.FC<IButtonProps> = ({

{ contextMenu }
</div>
</RovingAccessibleTooltipButton>
</AccessibleTooltipButton>
);
};

Expand All @@ -142,6 +149,7 @@ interface IItemProps extends InputHTMLAttributes<HTMLLIElement> {
onExpand?: Function;
parents?: Set<string>;
innerRef?: LegacyRef<HTMLLIElement>;
dragHandleProps?: DraggableProvidedDragHandleProps;
}

interface IItemState {
Expand Down Expand Up @@ -270,8 +278,10 @@ export class SpaceItem extends React.PureComponent<IItemProps, IItemState> {
? StaticNotificationState.forSymbol("!", NotificationColor.Red)
: SpaceStore.instance.getNotificationState(space.roomId);

const hasChildren = this.state.childSpaces?.length;

let childItems;
if (this.state.childSpaces?.length && !collapsed) {
if (hasChildren && !collapsed) {
childItems = <SpaceTreeLevel
spaces={this.state.childSpaces}
activeSpaces={activeSpaces}
Expand All @@ -280,17 +290,27 @@ export class SpaceItem extends React.PureComponent<IItemProps, IItemState> {
/>;
}

const toggleCollapseButton = this.state.childSpaces?.length ?
const toggleCollapseButton = hasChildren ?
<AccessibleButton
className="mx_SpaceButton_toggleCollapse"
onClick={this.toggleCollapse}
tabIndex={-1}
aria-label={collapsed ? _t("Expand") : _t("Collapse")}
/> : null;

// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { tabIndex, ...dragHandleProps } = this.props.dragHandleProps || {};

return (
<li {...otherProps} className={itemClasses} ref={innerRef} aria-expanded={!collapsed} role="treeitem">
<li
{...otherProps}
className={itemClasses}
ref={innerRef}
aria-expanded={hasChildren ? !collapsed : undefined}
role="treeitem"
>
<SpaceButton
{...dragHandleProps}
space={space}
className={isInvite ? "mx_SpaceButton_invite" : undefined}
selected={activeSpaces.includes(space)}
Expand Down