Space panel accessibility improvements (#9157)

* Move the UserMenu out of the SpacePanel ul list

* Apply aria-selected to the spacepanel treeview

* Fix typing
This commit is contained in:
Michael Telatynski 2022-08-10 13:14:54 +01:00 committed by GitHub
parent 350341d13d
commit 3d0982e9a6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 44 additions and 39 deletions

View file

@ -15,18 +15,28 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React, { HTMLAttributes, WheelEvent } from "react";
import classNames from "classnames";
import React, { HTMLAttributes, ReactHTML, WheelEvent } from "react";
interface IProps extends Omit<HTMLAttributes<HTMLDivElement>, "onScroll"> {
type DynamicHtmlElementProps<T extends keyof JSX.IntrinsicElements> =
JSX.IntrinsicElements[T] extends HTMLAttributes<{}> ? DynamicElementProps<T> : DynamicElementProps<"div">;
type DynamicElementProps<T extends keyof JSX.IntrinsicElements> = Partial<Omit<JSX.IntrinsicElements[T], 'ref'>>;
export type IProps<T extends keyof JSX.IntrinsicElements> = DynamicHtmlElementProps<T> & {
element?: T;
className?: string;
onScroll?: (event: Event) => void;
onWheel?: (event: WheelEvent) => void;
style?: React.CSSProperties;
tabIndex?: number;
wrappedRef?: (ref: HTMLDivElement) => void;
}
};
export default class AutoHideScrollbar<T extends keyof JSX.IntrinsicElements> extends React.Component<IProps<T>> {
static defaultProps = {
element: 'div' as keyof ReactHTML,
};
export default class AutoHideScrollbar extends React.Component<IProps> {
public readonly containerRef: React.RefObject<HTMLDivElement> = React.createRef();
public componentDidMount() {
@ -36,9 +46,7 @@ export default class AutoHideScrollbar extends React.Component<IProps> {
this.containerRef.current.addEventListener("scroll", this.props.onScroll, { passive: true });
}
if (this.props.wrappedRef) {
this.props.wrappedRef(this.containerRef.current);
}
this.props.wrappedRef?.(this.containerRef.current);
}
public componentWillUnmount() {
@ -49,19 +57,15 @@ export default class AutoHideScrollbar extends React.Component<IProps> {
public render() {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { className, onScroll, onWheel, style, tabIndex, wrappedRef, children, ...otherProps } = this.props;
const { element, className, onScroll, tabIndex, wrappedRef, children, ...otherProps } = this.props;
return (<div
{...otherProps}
ref={this.containerRef}
style={style}
className={["mx_AutoHideScrollbar", className].join(" ")}
onWheel={onWheel}
return React.createElement(element, {
...otherProps,
ref: this.containerRef,
className: classNames("mx_AutoHideScrollbar", className),
// Firefox sometimes makes this element focusable due to
// overflow:scroll;, so force it out of tab order by default.
tabIndex={tabIndex ?? -1}
>
{ children }
</div>);
tabIndex: tabIndex ?? -1,
}, children);
}
}

View file

@ -14,12 +14,12 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React, { ComponentProps, createRef } from "react";
import React, { createRef } from "react";
import AutoHideScrollbar from "./AutoHideScrollbar";
import AutoHideScrollbar, { IProps as AutoHideScrollbarProps } from "./AutoHideScrollbar";
import UIStore, { UI_EVENTS } from "../../stores/UIStore";
interface IProps extends Omit<ComponentProps<typeof AutoHideScrollbar>, "onWheel"> {
export type IProps<T extends keyof JSX.IntrinsicElements> = Omit<AutoHideScrollbarProps<T>, "onWheel"> & {
// If true, the scrollbar will append mx_IndicatorScrollbar_leftOverflowIndicator
// and mx_IndicatorScrollbar_rightOverflowIndicator elements to the list for positioning
// by the parent element.
@ -31,21 +31,22 @@ interface IProps extends Omit<ComponentProps<typeof AutoHideScrollbar>, "onWheel
verticalScrollsHorizontally?: boolean;
children: React.ReactNode;
className: string;
}
};
interface IState {
leftIndicatorOffset: string;
rightIndicatorOffset: string;
}
export default class IndicatorScrollbar extends React.Component<IProps, IState> {
private autoHideScrollbar = createRef<AutoHideScrollbar>();
export default class IndicatorScrollbar<
T extends keyof JSX.IntrinsicElements,
> extends React.Component<IProps<T>, IState> {
private autoHideScrollbar = createRef<AutoHideScrollbar<any>>();
private scrollElement: HTMLDivElement;
private likelyTrackpadUser: boolean = null;
private checkAgainForTrackpad = 0; // ts in milliseconds to recheck this._likelyTrackpadUser
constructor(props: IProps) {
constructor(props: IProps<T>) {
super(props);
this.state = {
@ -65,7 +66,7 @@ export default class IndicatorScrollbar extends React.Component<IProps, IState>
}
};
public componentDidUpdate(prevProps: IProps): void {
public componentDidUpdate(prevProps: IProps<T>): void {
const prevLen = React.Children.count(prevProps.children);
const curLen = React.Children.count(this.props.children);
// check overflow only if amount of children changes.