Fix usages of ARIA tabpanel (#10628)
* RovingTabIndex handle looping around start/end * Make TabbedView expose aria tabpanel/tablist/tab roles * Fix right panel being wrongly specified as aria tabs Not all right panels map to the top right header buttons so we cannot describe it as a tabpanel relation * tsc strict * Update snapshots * Fix ARIA AXE violation * Update tests
This commit is contained in:
parent
961b843662
commit
a1a087f755
9 changed files with 153 additions and 66 deletions
|
@ -59,7 +59,7 @@ const INTEGRATION_MANAGER_HTML = `
|
||||||
`;
|
`;
|
||||||
|
|
||||||
function openIntegrationManager() {
|
function openIntegrationManager() {
|
||||||
cy.findByRole("tab", { name: "Room info" }).click();
|
cy.findByRole("button", { name: "Room info" }).click();
|
||||||
cy.findByRole("button", { name: "Add widgets, bridges & bots" }).click();
|
cy.findByRole("button", { name: "Add widgets, bridges & bots" }).click();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,7 @@ const INTEGRATION_MANAGER_HTML = `
|
||||||
`;
|
`;
|
||||||
|
|
||||||
function openIntegrationManager() {
|
function openIntegrationManager() {
|
||||||
cy.findByRole("tab", { name: "Room info" }).click();
|
cy.findByRole("button", { name: "Room info" }).click();
|
||||||
cy.findByRole("button", { name: "Add widgets, bridges & bots" }).click();
|
cy.findByRole("button", { name: "Add widgets, bridges & bots" }).click();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -156,6 +156,7 @@ export const reducer: Reducer<IState, IAction> = (state: IState, action: IAction
|
||||||
};
|
};
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
|
handleLoop?: boolean;
|
||||||
handleHomeEnd?: boolean;
|
handleHomeEnd?: boolean;
|
||||||
handleUpDown?: boolean;
|
handleUpDown?: boolean;
|
||||||
handleLeftRight?: boolean;
|
handleLeftRight?: boolean;
|
||||||
|
@ -167,6 +168,7 @@ export const findSiblingElement = (
|
||||||
refs: RefObject<HTMLElement>[],
|
refs: RefObject<HTMLElement>[],
|
||||||
startIndex: number,
|
startIndex: number,
|
||||||
backwards = false,
|
backwards = false,
|
||||||
|
loop = false,
|
||||||
): RefObject<HTMLElement> | undefined => {
|
): RefObject<HTMLElement> | undefined => {
|
||||||
if (backwards) {
|
if (backwards) {
|
||||||
for (let i = startIndex; i < refs.length && i >= 0; i--) {
|
for (let i = startIndex; i < refs.length && i >= 0; i--) {
|
||||||
|
@ -174,12 +176,18 @@ export const findSiblingElement = (
|
||||||
return refs[i];
|
return refs[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (loop) {
|
||||||
|
return findSiblingElement(refs.slice(startIndex + 1), refs.length - 1, true, false);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
for (let i = startIndex; i < refs.length && i >= 0; i++) {
|
for (let i = startIndex; i < refs.length && i >= 0; i++) {
|
||||||
if (refs[i].current?.offsetParent !== null) {
|
if (refs[i].current?.offsetParent !== null) {
|
||||||
return refs[i];
|
return refs[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (loop) {
|
||||||
|
return findSiblingElement(refs.slice(0, startIndex), 0, false, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -188,6 +196,7 @@ export const RovingTabIndexProvider: React.FC<IProps> = ({
|
||||||
handleHomeEnd,
|
handleHomeEnd,
|
||||||
handleUpDown,
|
handleUpDown,
|
||||||
handleLeftRight,
|
handleLeftRight,
|
||||||
|
handleLoop,
|
||||||
onKeyDown,
|
onKeyDown,
|
||||||
}) => {
|
}) => {
|
||||||
const [state, dispatch] = useReducer<Reducer<IState, IAction>>(reducer, {
|
const [state, dispatch] = useReducer<Reducer<IState, IAction>>(reducer, {
|
||||||
|
@ -252,7 +261,7 @@ export const RovingTabIndexProvider: React.FC<IProps> = ({
|
||||||
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!);
|
||||||
focusRef = findSiblingElement(context.state.refs, idx + 1);
|
focusRef = findSiblingElement(context.state.refs, idx + 1, false, handleLoop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -266,7 +275,7 @@ export const RovingTabIndexProvider: React.FC<IProps> = ({
|
||||||
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!);
|
||||||
focusRef = findSiblingElement(context.state.refs, idx - 1, true);
|
focusRef = findSiblingElement(context.state.refs, idx - 1, true, handleLoop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -289,7 +298,7 @@ export const RovingTabIndexProvider: React.FC<IProps> = ({
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[context, onKeyDown, handleHomeEnd, handleUpDown, handleLeftRight],
|
[context, onKeyDown, handleHomeEnd, handleUpDown, handleLeftRight, handleLoop],
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -22,9 +22,9 @@ import { logger } from "matrix-js-sdk/src/logger";
|
||||||
|
|
||||||
import { _t } from "../../languageHandler";
|
import { _t } from "../../languageHandler";
|
||||||
import AutoHideScrollbar from "./AutoHideScrollbar";
|
import AutoHideScrollbar from "./AutoHideScrollbar";
|
||||||
import AccessibleButton from "../views/elements/AccessibleButton";
|
|
||||||
import { PosthogScreenTracker, ScreenName } from "../../PosthogTrackers";
|
import { PosthogScreenTracker, ScreenName } from "../../PosthogTrackers";
|
||||||
import { NonEmptyArray } from "../../@types/common";
|
import { NonEmptyArray } from "../../@types/common";
|
||||||
|
import { RovingAccessibleButton, RovingTabIndexProvider } from "../../accessibility/RovingTabIndex";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a tab for the TabbedView.
|
* Represents a tab for the TabbedView.
|
||||||
|
@ -98,9 +98,10 @@ export default class TabbedView extends React.Component<IProps, IState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private renderTabLabel(tab: Tab): JSX.Element {
|
private renderTabLabel(tab: Tab): JSX.Element {
|
||||||
let classes = "mx_TabbedView_tabLabel ";
|
const isActive = this.state.activeTabId === tab.id;
|
||||||
|
const classes = classNames("mx_TabbedView_tabLabel", {
|
||||||
if (this.state.activeTabId === tab.id) classes += "mx_TabbedView_tabLabel_active";
|
mx_TabbedView_tabLabel_active: isActive,
|
||||||
|
});
|
||||||
|
|
||||||
let tabIcon: JSX.Element | undefined;
|
let tabIcon: JSX.Element | undefined;
|
||||||
if (tab.icon) {
|
if (tab.icon) {
|
||||||
|
@ -108,24 +109,35 @@ export default class TabbedView extends React.Component<IProps, IState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
const onClickHandler = (): void => this.setActiveTab(tab);
|
const onClickHandler = (): void => this.setActiveTab(tab);
|
||||||
|
const id = this.getTabId(tab);
|
||||||
|
|
||||||
const label = _t(tab.label);
|
const label = _t(tab.label);
|
||||||
return (
|
return (
|
||||||
<AccessibleButton
|
<RovingAccessibleButton
|
||||||
className={classes}
|
className={classes}
|
||||||
key={"tab_label_" + tab.label}
|
key={"tab_label_" + tab.label}
|
||||||
onClick={onClickHandler}
|
onClick={onClickHandler}
|
||||||
data-testid={`settings-tab-${tab.id}`}
|
data-testid={`settings-tab-${tab.id}`}
|
||||||
|
role="tab"
|
||||||
|
aria-selected={isActive}
|
||||||
|
aria-controls={id}
|
||||||
>
|
>
|
||||||
{tabIcon}
|
{tabIcon}
|
||||||
<span className="mx_TabbedView_tabLabel_text">{label}</span>
|
<span className="mx_TabbedView_tabLabel_text" id={`${id}_label`}>
|
||||||
</AccessibleButton>
|
{label}
|
||||||
|
</span>
|
||||||
|
</RovingAccessibleButton>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private getTabId(tab: Tab): string {
|
||||||
|
return `mx_tabpanel_${tab.id}`;
|
||||||
|
}
|
||||||
|
|
||||||
private renderTabPanel(tab: Tab): React.ReactNode {
|
private renderTabPanel(tab: Tab): React.ReactNode {
|
||||||
|
const id = this.getTabId(tab);
|
||||||
return (
|
return (
|
||||||
<div className="mx_TabbedView_tabPanel" key={"mx_tabpanel_" + tab.label}>
|
<div className="mx_TabbedView_tabPanel" key={id} id={id} aria-labelledby={`${id}_label`}>
|
||||||
<AutoHideScrollbar className="mx_TabbedView_tabPanelContent">{tab.body}</AutoHideScrollbar>
|
<AutoHideScrollbar className="mx_TabbedView_tabPanelContent">{tab.body}</AutoHideScrollbar>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -147,7 +159,23 @@ export default class TabbedView extends React.Component<IProps, IState> {
|
||||||
return (
|
return (
|
||||||
<div className={tabbedViewClasses}>
|
<div className={tabbedViewClasses}>
|
||||||
{screenName && <PosthogScreenTracker screenName={screenName} />}
|
{screenName && <PosthogScreenTracker screenName={screenName} />}
|
||||||
<div className="mx_TabbedView_tabLabels">{labels}</div>
|
<RovingTabIndexProvider
|
||||||
|
handleLoop
|
||||||
|
handleHomeEnd
|
||||||
|
handleLeftRight={this.props.tabLocation == TabLocation.TOP}
|
||||||
|
handleUpDown={this.props.tabLocation == TabLocation.LEFT}
|
||||||
|
>
|
||||||
|
{({ onKeyDownHandler }) => (
|
||||||
|
<div
|
||||||
|
className="mx_TabbedView_tabLabels"
|
||||||
|
role="tablist"
|
||||||
|
aria-orientation={this.props.tabLocation == TabLocation.LEFT ? "vertical" : "horizontal"}
|
||||||
|
onKeyDown={onKeyDownHandler}
|
||||||
|
>
|
||||||
|
{labels}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</RovingTabIndexProvider>
|
||||||
{panel}
|
{panel}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -54,8 +54,7 @@ export default class HeaderButton extends React.Component<IProps> {
|
||||||
return (
|
return (
|
||||||
<AccessibleTooltipButton
|
<AccessibleTooltipButton
|
||||||
{...props}
|
{...props}
|
||||||
aria-selected={isHighlighted}
|
aria-current={isHighlighted ? "true" : "false"}
|
||||||
role="tab"
|
|
||||||
title={title}
|
title={title}
|
||||||
alignment={Alignment.Bottom}
|
alignment={Alignment.Bottom}
|
||||||
className={classes}
|
className={classes}
|
||||||
|
|
|
@ -98,10 +98,6 @@ export default abstract class HeaderButtons<P = {}> extends React.Component<IPro
|
||||||
public abstract renderButtons(): JSX.Element;
|
public abstract renderButtons(): JSX.Element;
|
||||||
|
|
||||||
public render(): React.ReactNode {
|
public render(): React.ReactNode {
|
||||||
return (
|
return <div className="mx_HeaderButtons">{this.renderButtons()}</div>;
|
||||||
<div className="mx_HeaderButtons" role="tablist">
|
|
||||||
{this.renderButtons()}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,12 +6,16 @@ exports[`<TabbedView /> renders tabs 1`] = `
|
||||||
class="mx_TabbedView mx_TabbedView_tabsOnLeft"
|
class="mx_TabbedView mx_TabbedView_tabsOnLeft"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
aria-orientation="vertical"
|
||||||
class="mx_TabbedView_tabLabels"
|
class="mx_TabbedView_tabLabels"
|
||||||
|
role="tablist"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
aria-controls="mx_tabpanel_GENERAL"
|
||||||
|
aria-selected="true"
|
||||||
class="mx_AccessibleButton mx_TabbedView_tabLabel mx_TabbedView_tabLabel_active"
|
class="mx_AccessibleButton mx_TabbedView_tabLabel mx_TabbedView_tabLabel_active"
|
||||||
data-testid="settings-tab-GENERAL"
|
data-testid="settings-tab-GENERAL"
|
||||||
role="button"
|
role="tab"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
|
@ -19,43 +23,52 @@ exports[`<TabbedView /> renders tabs 1`] = `
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
class="mx_TabbedView_tabLabel_text"
|
class="mx_TabbedView_tabLabel_text"
|
||||||
|
id="mx_tabpanel_GENERAL_label"
|
||||||
>
|
>
|
||||||
General
|
General
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="mx_AccessibleButton mx_TabbedView_tabLabel "
|
aria-controls="mx_tabpanel_LABS"
|
||||||
|
aria-selected="false"
|
||||||
|
class="mx_AccessibleButton mx_TabbedView_tabLabel"
|
||||||
data-testid="settings-tab-LABS"
|
data-testid="settings-tab-LABS"
|
||||||
role="button"
|
role="tab"
|
||||||
tabindex="0"
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
class="mx_TabbedView_maskedIcon labs"
|
class="mx_TabbedView_maskedIcon labs"
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
class="mx_TabbedView_tabLabel_text"
|
class="mx_TabbedView_tabLabel_text"
|
||||||
|
id="mx_tabpanel_LABS_label"
|
||||||
>
|
>
|
||||||
Labs
|
Labs
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="mx_AccessibleButton mx_TabbedView_tabLabel "
|
aria-controls="mx_tabpanel_SECURITY"
|
||||||
|
aria-selected="false"
|
||||||
|
class="mx_AccessibleButton mx_TabbedView_tabLabel"
|
||||||
data-testid="settings-tab-SECURITY"
|
data-testid="settings-tab-SECURITY"
|
||||||
role="button"
|
role="tab"
|
||||||
tabindex="0"
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
class="mx_TabbedView_maskedIcon security"
|
class="mx_TabbedView_maskedIcon security"
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
class="mx_TabbedView_tabLabel_text"
|
class="mx_TabbedView_tabLabel_text"
|
||||||
|
id="mx_tabpanel_SECURITY_label"
|
||||||
>
|
>
|
||||||
Security
|
Security
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
aria-labelledby="mx_tabpanel_GENERAL_label"
|
||||||
class="mx_TabbedView_tabPanel"
|
class="mx_TabbedView_tabPanel"
|
||||||
|
id="mx_tabpanel_GENERAL"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="mx_AutoHideScrollbar mx_TabbedView_tabPanelContent"
|
class="mx_AutoHideScrollbar mx_TabbedView_tabPanelContent"
|
||||||
|
|
|
@ -3,9 +3,11 @@
|
||||||
exports[`<RoomSettingsDialog /> Settings tabs renders default tabs correctly 1`] = `
|
exports[`<RoomSettingsDialog /> Settings tabs renders default tabs correctly 1`] = `
|
||||||
NodeList [
|
NodeList [
|
||||||
<div
|
<div
|
||||||
|
aria-controls="mx_tabpanel_ROOM_GENERAL_TAB"
|
||||||
|
aria-selected="true"
|
||||||
class="mx_AccessibleButton mx_TabbedView_tabLabel mx_TabbedView_tabLabel_active"
|
class="mx_AccessibleButton mx_TabbedView_tabLabel mx_TabbedView_tabLabel_active"
|
||||||
data-testid="settings-tab-ROOM_GENERAL_TAB"
|
data-testid="settings-tab-ROOM_GENERAL_TAB"
|
||||||
role="button"
|
role="tab"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
|
@ -13,66 +15,79 @@ NodeList [
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
class="mx_TabbedView_tabLabel_text"
|
class="mx_TabbedView_tabLabel_text"
|
||||||
|
id="mx_tabpanel_ROOM_GENERAL_TAB_label"
|
||||||
>
|
>
|
||||||
General
|
General
|
||||||
</span>
|
</span>
|
||||||
</div>,
|
</div>,
|
||||||
<div
|
<div
|
||||||
class="mx_AccessibleButton mx_TabbedView_tabLabel "
|
aria-controls="mx_tabpanel_ROOM_SECURITY_TAB"
|
||||||
|
aria-selected="false"
|
||||||
|
class="mx_AccessibleButton mx_TabbedView_tabLabel"
|
||||||
data-testid="settings-tab-ROOM_SECURITY_TAB"
|
data-testid="settings-tab-ROOM_SECURITY_TAB"
|
||||||
role="button"
|
role="tab"
|
||||||
tabindex="0"
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
class="mx_TabbedView_maskedIcon mx_RoomSettingsDialog_securityIcon"
|
class="mx_TabbedView_maskedIcon mx_RoomSettingsDialog_securityIcon"
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
class="mx_TabbedView_tabLabel_text"
|
class="mx_TabbedView_tabLabel_text"
|
||||||
|
id="mx_tabpanel_ROOM_SECURITY_TAB_label"
|
||||||
>
|
>
|
||||||
Security & Privacy
|
Security & Privacy
|
||||||
</span>
|
</span>
|
||||||
</div>,
|
</div>,
|
||||||
<div
|
<div
|
||||||
class="mx_AccessibleButton mx_TabbedView_tabLabel "
|
aria-controls="mx_tabpanel_ROOM_ROLES_TAB"
|
||||||
|
aria-selected="false"
|
||||||
|
class="mx_AccessibleButton mx_TabbedView_tabLabel"
|
||||||
data-testid="settings-tab-ROOM_ROLES_TAB"
|
data-testid="settings-tab-ROOM_ROLES_TAB"
|
||||||
role="button"
|
role="tab"
|
||||||
tabindex="0"
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
class="mx_TabbedView_maskedIcon mx_RoomSettingsDialog_rolesIcon"
|
class="mx_TabbedView_maskedIcon mx_RoomSettingsDialog_rolesIcon"
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
class="mx_TabbedView_tabLabel_text"
|
class="mx_TabbedView_tabLabel_text"
|
||||||
|
id="mx_tabpanel_ROOM_ROLES_TAB_label"
|
||||||
>
|
>
|
||||||
Roles & Permissions
|
Roles & Permissions
|
||||||
</span>
|
</span>
|
||||||
</div>,
|
</div>,
|
||||||
<div
|
<div
|
||||||
class="mx_AccessibleButton mx_TabbedView_tabLabel "
|
aria-controls="mx_tabpanel_ROOM_NOTIFICATIONS_TAB"
|
||||||
|
aria-selected="false"
|
||||||
|
class="mx_AccessibleButton mx_TabbedView_tabLabel"
|
||||||
data-testid="settings-tab-ROOM_NOTIFICATIONS_TAB"
|
data-testid="settings-tab-ROOM_NOTIFICATIONS_TAB"
|
||||||
role="button"
|
role="tab"
|
||||||
tabindex="0"
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
class="mx_TabbedView_maskedIcon mx_RoomSettingsDialog_notificationsIcon"
|
class="mx_TabbedView_maskedIcon mx_RoomSettingsDialog_notificationsIcon"
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
class="mx_TabbedView_tabLabel_text"
|
class="mx_TabbedView_tabLabel_text"
|
||||||
|
id="mx_tabpanel_ROOM_NOTIFICATIONS_TAB_label"
|
||||||
>
|
>
|
||||||
Notifications
|
Notifications
|
||||||
</span>
|
</span>
|
||||||
</div>,
|
</div>,
|
||||||
<div
|
<div
|
||||||
class="mx_AccessibleButton mx_TabbedView_tabLabel "
|
aria-controls="mx_tabpanel_ROOM_POLL_HISTORY_TAB"
|
||||||
|
aria-selected="false"
|
||||||
|
class="mx_AccessibleButton mx_TabbedView_tabLabel"
|
||||||
data-testid="settings-tab-ROOM_POLL_HISTORY_TAB"
|
data-testid="settings-tab-ROOM_POLL_HISTORY_TAB"
|
||||||
role="button"
|
role="tab"
|
||||||
tabindex="0"
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
class="mx_TabbedView_maskedIcon mx_RoomSettingsDialog_pollsIcon"
|
class="mx_TabbedView_maskedIcon mx_RoomSettingsDialog_pollsIcon"
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
class="mx_TabbedView_tabLabel_text"
|
class="mx_TabbedView_tabLabel_text"
|
||||||
|
id="mx_tabpanel_ROOM_POLL_HISTORY_TAB_label"
|
||||||
>
|
>
|
||||||
Poll history
|
Poll history
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -3,9 +3,11 @@
|
||||||
exports[`<UserSettingsDialog /> renders tabs correctly 1`] = `
|
exports[`<UserSettingsDialog /> renders tabs correctly 1`] = `
|
||||||
NodeList [
|
NodeList [
|
||||||
<div
|
<div
|
||||||
|
aria-controls="mx_tabpanel_USER_GENERAL_TAB"
|
||||||
|
aria-selected="true"
|
||||||
class="mx_AccessibleButton mx_TabbedView_tabLabel mx_TabbedView_tabLabel_active"
|
class="mx_AccessibleButton mx_TabbedView_tabLabel mx_TabbedView_tabLabel_active"
|
||||||
data-testid="settings-tab-USER_GENERAL_TAB"
|
data-testid="settings-tab-USER_GENERAL_TAB"
|
||||||
role="button"
|
role="tab"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
|
@ -13,126 +15,151 @@ NodeList [
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
class="mx_TabbedView_tabLabel_text"
|
class="mx_TabbedView_tabLabel_text"
|
||||||
|
id="mx_tabpanel_USER_GENERAL_TAB_label"
|
||||||
>
|
>
|
||||||
General
|
General
|
||||||
</span>
|
</span>
|
||||||
</div>,
|
</div>,
|
||||||
<div
|
<div
|
||||||
class="mx_AccessibleButton mx_TabbedView_tabLabel "
|
aria-controls="mx_tabpanel_USER_APPEARANCE_TAB"
|
||||||
|
aria-selected="false"
|
||||||
|
class="mx_AccessibleButton mx_TabbedView_tabLabel"
|
||||||
data-testid="settings-tab-USER_APPEARANCE_TAB"
|
data-testid="settings-tab-USER_APPEARANCE_TAB"
|
||||||
role="button"
|
role="tab"
|
||||||
tabindex="0"
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
class="mx_TabbedView_maskedIcon mx_UserSettingsDialog_appearanceIcon"
|
class="mx_TabbedView_maskedIcon mx_UserSettingsDialog_appearanceIcon"
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
class="mx_TabbedView_tabLabel_text"
|
class="mx_TabbedView_tabLabel_text"
|
||||||
|
id="mx_tabpanel_USER_APPEARANCE_TAB_label"
|
||||||
>
|
>
|
||||||
Appearance
|
Appearance
|
||||||
</span>
|
</span>
|
||||||
</div>,
|
</div>,
|
||||||
<div
|
<div
|
||||||
class="mx_AccessibleButton mx_TabbedView_tabLabel "
|
aria-controls="mx_tabpanel_USER_NOTIFICATIONS_TAB"
|
||||||
|
aria-selected="false"
|
||||||
|
class="mx_AccessibleButton mx_TabbedView_tabLabel"
|
||||||
data-testid="settings-tab-USER_NOTIFICATIONS_TAB"
|
data-testid="settings-tab-USER_NOTIFICATIONS_TAB"
|
||||||
role="button"
|
role="tab"
|
||||||
tabindex="0"
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
class="mx_TabbedView_maskedIcon mx_UserSettingsDialog_bellIcon"
|
class="mx_TabbedView_maskedIcon mx_UserSettingsDialog_bellIcon"
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
class="mx_TabbedView_tabLabel_text"
|
class="mx_TabbedView_tabLabel_text"
|
||||||
|
id="mx_tabpanel_USER_NOTIFICATIONS_TAB_label"
|
||||||
>
|
>
|
||||||
Notifications
|
Notifications
|
||||||
</span>
|
</span>
|
||||||
</div>,
|
</div>,
|
||||||
<div
|
<div
|
||||||
class="mx_AccessibleButton mx_TabbedView_tabLabel "
|
aria-controls="mx_tabpanel_USER_PREFERENCES_TAB"
|
||||||
|
aria-selected="false"
|
||||||
|
class="mx_AccessibleButton mx_TabbedView_tabLabel"
|
||||||
data-testid="settings-tab-USER_PREFERENCES_TAB"
|
data-testid="settings-tab-USER_PREFERENCES_TAB"
|
||||||
role="button"
|
role="tab"
|
||||||
tabindex="0"
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
class="mx_TabbedView_maskedIcon mx_UserSettingsDialog_preferencesIcon"
|
class="mx_TabbedView_maskedIcon mx_UserSettingsDialog_preferencesIcon"
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
class="mx_TabbedView_tabLabel_text"
|
class="mx_TabbedView_tabLabel_text"
|
||||||
|
id="mx_tabpanel_USER_PREFERENCES_TAB_label"
|
||||||
>
|
>
|
||||||
Preferences
|
Preferences
|
||||||
</span>
|
</span>
|
||||||
</div>,
|
</div>,
|
||||||
<div
|
<div
|
||||||
class="mx_AccessibleButton mx_TabbedView_tabLabel "
|
aria-controls="mx_tabpanel_USER_KEYBOARD_TAB"
|
||||||
|
aria-selected="false"
|
||||||
|
class="mx_AccessibleButton mx_TabbedView_tabLabel"
|
||||||
data-testid="settings-tab-USER_KEYBOARD_TAB"
|
data-testid="settings-tab-USER_KEYBOARD_TAB"
|
||||||
role="button"
|
role="tab"
|
||||||
tabindex="0"
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
class="mx_TabbedView_maskedIcon mx_UserSettingsDialog_keyboardIcon"
|
class="mx_TabbedView_maskedIcon mx_UserSettingsDialog_keyboardIcon"
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
class="mx_TabbedView_tabLabel_text"
|
class="mx_TabbedView_tabLabel_text"
|
||||||
|
id="mx_tabpanel_USER_KEYBOARD_TAB_label"
|
||||||
>
|
>
|
||||||
Keyboard
|
Keyboard
|
||||||
</span>
|
</span>
|
||||||
</div>,
|
</div>,
|
||||||
<div
|
<div
|
||||||
class="mx_AccessibleButton mx_TabbedView_tabLabel "
|
aria-controls="mx_tabpanel_USER_SIDEBAR_TAB"
|
||||||
|
aria-selected="false"
|
||||||
|
class="mx_AccessibleButton mx_TabbedView_tabLabel"
|
||||||
data-testid="settings-tab-USER_SIDEBAR_TAB"
|
data-testid="settings-tab-USER_SIDEBAR_TAB"
|
||||||
role="button"
|
role="tab"
|
||||||
tabindex="0"
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
class="mx_TabbedView_maskedIcon mx_UserSettingsDialog_sidebarIcon"
|
class="mx_TabbedView_maskedIcon mx_UserSettingsDialog_sidebarIcon"
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
class="mx_TabbedView_tabLabel_text"
|
class="mx_TabbedView_tabLabel_text"
|
||||||
|
id="mx_tabpanel_USER_SIDEBAR_TAB_label"
|
||||||
>
|
>
|
||||||
Sidebar
|
Sidebar
|
||||||
</span>
|
</span>
|
||||||
</div>,
|
</div>,
|
||||||
<div
|
<div
|
||||||
class="mx_AccessibleButton mx_TabbedView_tabLabel "
|
aria-controls="mx_tabpanel_USER_SECURITY_TAB"
|
||||||
|
aria-selected="false"
|
||||||
|
class="mx_AccessibleButton mx_TabbedView_tabLabel"
|
||||||
data-testid="settings-tab-USER_SECURITY_TAB"
|
data-testid="settings-tab-USER_SECURITY_TAB"
|
||||||
role="button"
|
role="tab"
|
||||||
tabindex="0"
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
class="mx_TabbedView_maskedIcon mx_UserSettingsDialog_securityIcon"
|
class="mx_TabbedView_maskedIcon mx_UserSettingsDialog_securityIcon"
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
class="mx_TabbedView_tabLabel_text"
|
class="mx_TabbedView_tabLabel_text"
|
||||||
|
id="mx_tabpanel_USER_SECURITY_TAB_label"
|
||||||
>
|
>
|
||||||
Security & Privacy
|
Security & Privacy
|
||||||
</span>
|
</span>
|
||||||
</div>,
|
</div>,
|
||||||
<div
|
<div
|
||||||
class="mx_AccessibleButton mx_TabbedView_tabLabel "
|
aria-controls="mx_tabpanel_USER_LABS_TAB"
|
||||||
|
aria-selected="false"
|
||||||
|
class="mx_AccessibleButton mx_TabbedView_tabLabel"
|
||||||
data-testid="settings-tab-USER_LABS_TAB"
|
data-testid="settings-tab-USER_LABS_TAB"
|
||||||
role="button"
|
role="tab"
|
||||||
tabindex="0"
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
class="mx_TabbedView_maskedIcon mx_UserSettingsDialog_labsIcon"
|
class="mx_TabbedView_maskedIcon mx_UserSettingsDialog_labsIcon"
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
class="mx_TabbedView_tabLabel_text"
|
class="mx_TabbedView_tabLabel_text"
|
||||||
|
id="mx_tabpanel_USER_LABS_TAB_label"
|
||||||
>
|
>
|
||||||
Labs
|
Labs
|
||||||
</span>
|
</span>
|
||||||
</div>,
|
</div>,
|
||||||
<div
|
<div
|
||||||
class="mx_AccessibleButton mx_TabbedView_tabLabel "
|
aria-controls="mx_tabpanel_USER_HELP_TAB"
|
||||||
|
aria-selected="false"
|
||||||
|
class="mx_AccessibleButton mx_TabbedView_tabLabel"
|
||||||
data-testid="settings-tab-USER_HELP_TAB"
|
data-testid="settings-tab-USER_HELP_TAB"
|
||||||
role="button"
|
role="tab"
|
||||||
tabindex="0"
|
tabindex="-1"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
class="mx_TabbedView_maskedIcon mx_UserSettingsDialog_helpIcon"
|
class="mx_TabbedView_maskedIcon mx_UserSettingsDialog_helpIcon"
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
class="mx_TabbedView_tabLabel_text"
|
class="mx_TabbedView_tabLabel_text"
|
||||||
|
id="mx_tabpanel_USER_HELP_TAB_label"
|
||||||
>
|
>
|
||||||
Help & About
|
Help & About
|
||||||
</span>
|
</span>
|
||||||
|
|
Loading…
Reference in a new issue