Accessibility improvements in settings (#32968)
* Add more playwright axe tests to settings dialogs * Fix axe issue heading-order * Fix heading order * Iterate * Update snapshots * Iterate * Update snapshots * Iterate * Update screenshot * Iterate * Iterate * Update snapshot
@@ -24,7 +24,7 @@ test.describe("Account user settings tab", () => {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
test("should be rendered properly", { tag: "@screenshot" }, async ({ uut, user }) => {
|
test("should be rendered properly", { tag: "@screenshot" }, async ({ uut, user, axe }) => {
|
||||||
await expect(uut).toMatchScreenshot("account.png");
|
await expect(uut).toMatchScreenshot("account.png");
|
||||||
|
|
||||||
// Assert that the top heading is rendered
|
// Assert that the top heading is rendered
|
||||||
@@ -70,6 +70,8 @@ test.describe("Account user settings tab", () => {
|
|||||||
await expect(accountManagementSection.getByRole("button", { name: "Deactivate Account" })).toHaveClass(
|
await expect(accountManagementSection.getByRole("button", { name: "Deactivate Account" })).toHaveClass(
|
||||||
/mx_AccessibleButton_kind_danger/,
|
/mx_AccessibleButton_kind_danger/,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
await expect(axe).toHaveNoViolations();
|
||||||
});
|
});
|
||||||
|
|
||||||
test("should respond to small screen sizes", { tag: "@screenshot" }, async ({ page, uut }) => {
|
test("should respond to small screen sizes", { tag: "@screenshot" }, async ({ page, uut }) => {
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ test.describe("Appearance user settings tab", () => {
|
|||||||
displayName: "Hanako",
|
displayName: "Hanako",
|
||||||
});
|
});
|
||||||
|
|
||||||
test("should be rendered properly", { tag: "@screenshot" }, async ({ page, user, app }) => {
|
test("should be rendered properly", { tag: "@screenshot" }, async ({ page, user, app, axe }) => {
|
||||||
const tab = await app.settings.openUserSettings("Appearance");
|
const tab = await app.settings.openUserSettings("Appearance");
|
||||||
|
|
||||||
// Click "Show advanced" link button
|
// Click "Show advanced" link button
|
||||||
@@ -23,6 +23,8 @@ test.describe("Appearance user settings tab", () => {
|
|||||||
await expect(tab.getByRole("button", { name: "Hide advanced" })).toBeVisible();
|
await expect(tab.getByRole("button", { name: "Hide advanced" })).toBeVisible();
|
||||||
|
|
||||||
await expect(tab).toMatchScreenshot("appearance-tab.png");
|
await expect(tab).toMatchScreenshot("appearance-tab.png");
|
||||||
|
|
||||||
|
await expect(axe).toHaveNoViolations();
|
||||||
});
|
});
|
||||||
|
|
||||||
test(
|
test(
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ test.describe("Appearance user settings tab", () => {
|
|||||||
test(
|
test(
|
||||||
"should be rendered with the light theme selected",
|
"should be rendered with the light theme selected",
|
||||||
{ tag: "@screenshot" },
|
{ tag: "@screenshot" },
|
||||||
async ({ page, app, util }) => {
|
async ({ page, app, util, axe }) => {
|
||||||
// Assert that 'Match system theme' is not checked
|
// Assert that 'Match system theme' is not checked
|
||||||
await expect(util.getMatchSystemThemeSwitch()).not.toBeChecked();
|
await expect(util.getMatchSystemThemeSwitch()).not.toBeChecked();
|
||||||
|
|
||||||
@@ -34,6 +34,8 @@ test.describe("Appearance user settings tab", () => {
|
|||||||
await expect(util.getHighContrastTheme()).not.toBeChecked();
|
await expect(util.getHighContrastTheme()).not.toBeChecked();
|
||||||
|
|
||||||
await expect(util.getThemePanel()).toMatchScreenshot("theme-panel-light.png");
|
await expect(util.getThemePanel()).toMatchScreenshot("theme-panel-light.png");
|
||||||
|
|
||||||
|
await expect(axe).toHaveNoViolations();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ test.describe("Device manager", () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test("should display sessions", async ({ page, app }) => {
|
test("should display sessions", async ({ page, app, axe }) => {
|
||||||
await app.settings.openUserSettings("Sessions");
|
await app.settings.openUserSettings("Sessions");
|
||||||
const tab = page.locator(".mx_SettingsTab");
|
const tab = page.locator(".mx_SettingsTab");
|
||||||
|
|
||||||
@@ -85,7 +85,7 @@ test.describe("Device manager", () => {
|
|||||||
// session name updated in details
|
// session name updated in details
|
||||||
await expect(firstSession.locator(".mx_DeviceDetailHeading h4").getByText(sessionName)).toBeVisible();
|
await expect(firstSession.locator(".mx_DeviceDetailHeading h4").getByText(sessionName)).toBeVisible();
|
||||||
// and main list item
|
// and main list item
|
||||||
await expect(firstSession.locator(".mx_DeviceTile h4").getByText(sessionName)).toBeVisible();
|
await expect(firstSession.locator(".mx_DeviceTile h3").getByText(sessionName)).toBeVisible();
|
||||||
|
|
||||||
// sign out using the device details sign out
|
// sign out using the device details sign out
|
||||||
await firstSession.getByRole("button", { name: "Remove this session" }).click();
|
await firstSession.getByRole("button", { name: "Remove this session" }).click();
|
||||||
@@ -96,5 +96,7 @@ test.describe("Device manager", () => {
|
|||||||
// no other sessions or security recommendations sections when only one session
|
// no other sessions or security recommendations sections when only one session
|
||||||
await expect(tab.getByText("Other sessions")).not.toBeVisible();
|
await expect(tab.getByText("Other sessions")).not.toBeVisible();
|
||||||
await expect(tab.getByTestId("security-recommendations-section")).not.toBeVisible();
|
await expect(tab.getByTestId("security-recommendations-section")).not.toBeVisible();
|
||||||
|
|
||||||
|
await expect(axe).toHaveNoViolations();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ test.describe("Advanced section in Encryption tab", () => {
|
|||||||
await bootstrapCrossSigningForClient(clientHandle, credentials, true);
|
await bootstrapCrossSigningForClient(clientHandle, credentials, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("should show the encryption details", { tag: "@screenshot" }, async ({ page, app, util }) => {
|
test("should show the encryption details", { tag: "@screenshot" }, async ({ page, app, util, axe }) => {
|
||||||
await util.openEncryptionTab();
|
await util.openEncryptionTab();
|
||||||
const section = util.getEncryptionDetailsSection();
|
const section = util.getEncryptionDetailsSection();
|
||||||
|
|
||||||
@@ -26,6 +26,8 @@ test.describe("Advanced section in Encryption tab", () => {
|
|||||||
await expect(section).toMatchScreenshot("encryption-details.png", {
|
await expect(section).toMatchScreenshot("encryption-details.png", {
|
||||||
mask: [section.getByTestId("deviceId"), section.getByTestId("sessionKey")],
|
mask: [section.getByTestId("deviceId"), section.getByTestId("sessionKey")],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await expect(axe).toHaveNoViolations();
|
||||||
});
|
});
|
||||||
|
|
||||||
test("should show the import room keys dialog", async ({ page, app, util }) => {
|
test("should show the import room keys dialog", async ({ page, app, util }) => {
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ test.describe("General room settings tab", () => {
|
|||||||
await app.viewRoomByName(roomName);
|
await app.viewRoomByName(roomName);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("should be rendered properly", { tag: "@screenshot" }, async ({ page, app }) => {
|
test("should be rendered properly", { tag: "@screenshot" }, async ({ page, app, axe }) => {
|
||||||
const settings = await app.settings.openRoomSettings("General");
|
const settings = await app.settings.openRoomSettings("General");
|
||||||
|
|
||||||
// Assert that "Show less" details element is rendered
|
// Assert that "Show less" details element is rendered
|
||||||
@@ -34,6 +34,9 @@ test.describe("General room settings tab", () => {
|
|||||||
// Assert that "Show more" details element is rendered instead of "Show more"
|
// Assert that "Show more" details element is rendered instead of "Show more"
|
||||||
await expect(settings.getByText("Show less")).not.toBeVisible();
|
await expect(settings.getByText("Show less")).not.toBeVisible();
|
||||||
await expect(settings.getByText("Show more")).toBeVisible();
|
await expect(settings.getByText("Show more")).toBeVisible();
|
||||||
|
|
||||||
|
axe.disableRules("color-contrast"); // XXX: We have some known contrast issues here
|
||||||
|
await expect(axe).toHaveNoViolations();
|
||||||
});
|
});
|
||||||
|
|
||||||
test("long address should not cause dialog to overflow", { tag: "@no-webkit" }, async ({ page, app, user }) => {
|
test("long address should not cause dialog to overflow", { tag: "@no-webkit" }, async ({ page, app, user }) => {
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ test.describe("Preferences user settings tab", () => {
|
|||||||
labsFlags: ["feature_new_room_list"],
|
labsFlags: ["feature_new_room_list"],
|
||||||
});
|
});
|
||||||
|
|
||||||
test("should be rendered properly", { tag: "@screenshot" }, async ({ app, page, user }) => {
|
test("should be rendered properly", { tag: "@screenshot" }, async ({ app, page, user, axe }) => {
|
||||||
await page.setViewportSize({ width: 1024, height: 4000 });
|
await page.setViewportSize({ width: 1024, height: 4000 });
|
||||||
const tab = await app.settings.openUserSettings("Preferences");
|
const tab = await app.settings.openUserSettings("Preferences");
|
||||||
// Assert that the top heading is rendered
|
// Assert that the top heading is rendered
|
||||||
@@ -39,6 +39,8 @@ test.describe("Preferences user settings tab", () => {
|
|||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await expect(axe).toHaveNoViolations();
|
||||||
});
|
});
|
||||||
|
|
||||||
test("should be able to change the app language", { tag: ["@no-firefox", "@no-webkit"] }, async ({ uut, user }) => {
|
test("should be able to change the app language", { tag: ["@no-firefox", "@no-webkit"] }, async ({ uut, user }) => {
|
||||||
|
|||||||
@@ -8,11 +8,13 @@ Please see LICENSE files in the repository root for full details.
|
|||||||
import { test, expect } from "../../element-web-test";
|
import { test, expect } from "../../element-web-test";
|
||||||
|
|
||||||
test.describe("Quick settings menu", () => {
|
test.describe("Quick settings menu", () => {
|
||||||
test("should be rendered properly", { tag: "@screenshot" }, async ({ app, page, user }) => {
|
test("should be rendered properly", { tag: "@screenshot" }, async ({ app, page, user, axe }) => {
|
||||||
await page.getByRole("button", { name: "Quick settings" }).click();
|
await page.getByRole("button", { name: "Quick settings" }).click();
|
||||||
// Assert that the top heading is renderedc
|
// Assert that the top heading is renderedc
|
||||||
const settings = page.getByTestId("quick-settings-menu");
|
const settings = page.getByTestId("quick-settings-menu");
|
||||||
await expect(settings).toBeVisible();
|
await expect(settings).toBeVisible();
|
||||||
await expect(settings).toMatchScreenshot("quick-settings.png");
|
await expect(settings).toMatchScreenshot("quick-settings.png");
|
||||||
|
|
||||||
|
await expect(axe).toHaveNoViolations();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ test.describe("Roles & Permissions room settings tab", () => {
|
|||||||
settings = await app.settings.openRoomSettings("Roles & Permissions");
|
settings = await app.settings.openRoomSettings("Roles & Permissions");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("should be able to change the role of a user", async ({ page, app, user }) => {
|
test("should be able to change the role of a user", async ({ page, app, user, axe }) => {
|
||||||
const privilegedUserSection = settings.locator(".mx_SettingsFieldset").first();
|
const privilegedUserSection = settings.locator(".mx_SettingsFieldset").first();
|
||||||
const applyButton = privilegedUserSection.getByRole("button", { name: "Apply" });
|
const applyButton = privilegedUserSection.getByRole("button", { name: "Apply" });
|
||||||
|
|
||||||
@@ -55,5 +55,7 @@ test.describe("Roles & Permissions room settings tab", () => {
|
|||||||
settings = await app.settings.openRoomSettings("Roles & Permissions");
|
settings = await app.settings.openRoomSettings("Roles & Permissions");
|
||||||
combobox = privilegedUserSection.getByRole("combobox", { name: user.userId });
|
combobox = privilegedUserSection.getByRole("combobox", { name: user.userId });
|
||||||
await expect(combobox).toHaveValue("50");
|
await expect(combobox).toHaveValue("50");
|
||||||
|
|
||||||
|
await expect(axe).toHaveNoViolations();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -32,12 +32,14 @@ test.describe("Security user settings tab", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test.describe("AnalyticsLearnMoreDialog", () => {
|
test.describe("AnalyticsLearnMoreDialog", () => {
|
||||||
test("should be rendered properly", { tag: "@screenshot" }, async ({ app, page, user }) => {
|
test("should be rendered properly", { tag: "@screenshot" }, async ({ app, page, user, axe }) => {
|
||||||
const tab = await app.settings.openUserSettings("Security");
|
const tab = await app.settings.openUserSettings("Security");
|
||||||
await tab.getByRole("button", { name: "Learn more" }).click();
|
await tab.getByRole("button", { name: "Learn more" }).click();
|
||||||
await expect(page.locator(".mx_AnalyticsLearnMoreDialog_wrapper .mx_Dialog")).toMatchScreenshot(
|
await expect(page.locator(".mx_AnalyticsLearnMoreDialog_wrapper .mx_Dialog")).toMatchScreenshot(
|
||||||
"Security-user-settings-tab-with-posthog-enable-b5d89-csLearnMoreDialog-should-be-rendered-properly-1.png",
|
"Security-user-settings-tab-with-posthog-enable-b5d89-csLearnMoreDialog-should-be-rendered-properly-1.png",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
await expect(axe).toHaveNoViolations();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 63 KiB |
|
Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 78 KiB |
|
Before Width: | Height: | Size: 87 KiB After Width: | Height: | Size: 87 KiB |
@@ -36,5 +36,5 @@ Please see LICENSE files in the repository root for full details.
|
|||||||
grid-template-columns: minmax(0, 1fr);
|
grid-template-columns: minmax(0, 1fr);
|
||||||
gap: $spacing-32;
|
gap: $spacing-32;
|
||||||
|
|
||||||
padding: $spacing-16 0;
|
margin: $spacing-16 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,15 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
|
|||||||
Please see LICENSE files in the repository root for full details.
|
Please see LICENSE files in the repository root for full details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { type JSX, type CSSProperties, type RefObject, type SyntheticEvent, useRef, useState } from "react";
|
import React, {
|
||||||
|
type JSX,
|
||||||
|
type CSSProperties,
|
||||||
|
type RefObject,
|
||||||
|
type SyntheticEvent,
|
||||||
|
useRef,
|
||||||
|
useState,
|
||||||
|
type AriaRole,
|
||||||
|
} from "react";
|
||||||
import ReactDOM from "react-dom";
|
import ReactDOM from "react-dom";
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
import FocusLock from "react-focus-lock";
|
import FocusLock from "react-focus-lock";
|
||||||
@@ -74,27 +82,31 @@ export interface MenuProps extends IPosition {
|
|||||||
|
|
||||||
export interface IProps extends MenuProps {
|
export interface IProps extends MenuProps {
|
||||||
// If true, insert an invisible screen-sized element behind the menu that when clicked will close it.
|
// If true, insert an invisible screen-sized element behind the menu that when clicked will close it.
|
||||||
hasBackground?: boolean;
|
"hasBackground"?: boolean;
|
||||||
// whether this context menu should be focus managed. If false it must handle itself
|
// whether this context menu should be focus managed. If false it must handle itself
|
||||||
managed?: boolean;
|
"managed"?: boolean;
|
||||||
wrapperClassName?: string;
|
"wrapperClassName"?: string;
|
||||||
menuClassName?: string;
|
"menuClassName"?: string;
|
||||||
|
|
||||||
// If true, this context menu will be mounted as a child to the parent container. Otherwise
|
// If true, this context menu will be mounted as a child to the parent container. Otherwise
|
||||||
// it will be mounted to a container at the root of the DOM.
|
// it will be mounted to a container at the root of the DOM.
|
||||||
mountAsChild?: boolean;
|
"mountAsChild"?: boolean;
|
||||||
|
|
||||||
// If specified, contents will be wrapped in a FocusLock, this is only needed if the context menu is being rendered
|
// If specified, contents will be wrapped in a FocusLock, this is only needed if the context menu is being rendered
|
||||||
// within an existing FocusLock e.g inside a modal.
|
// within an existing FocusLock e.g inside a modal.
|
||||||
focusLock?: boolean;
|
"focusLock"?: boolean;
|
||||||
|
|
||||||
// call onFinished on any interaction with the menu
|
// call onFinished on any interaction with the menu
|
||||||
closeOnInteraction?: boolean;
|
"closeOnInteraction"?: boolean;
|
||||||
|
|
||||||
// Function to be called on menu close
|
// Function to be called on menu close
|
||||||
onFinished(this: void): void;
|
onFinished(this: void): void;
|
||||||
// on resize callback
|
// on resize callback
|
||||||
windowResize?(this: void): void;
|
windowResize?(this: void): void;
|
||||||
|
|
||||||
|
// Role & label for accessibility
|
||||||
|
"role"?: AriaRole;
|
||||||
|
"aria-label"?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IState {
|
interface IState {
|
||||||
@@ -257,9 +269,11 @@ export default class ContextMenu extends React.PureComponent<React.PropsWithChil
|
|||||||
focusLock,
|
focusLock,
|
||||||
managed,
|
managed,
|
||||||
wrapperClassName,
|
wrapperClassName,
|
||||||
chevronFace: propsChevronFace,
|
"chevronFace": propsChevronFace,
|
||||||
chevronOffset: propsChevronOffset,
|
"chevronOffset": propsChevronOffset,
|
||||||
mountAsChild,
|
mountAsChild,
|
||||||
|
role,
|
||||||
|
"aria-label": ariaLabel,
|
||||||
...props
|
...props
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
@@ -424,6 +438,8 @@ export default class ContextMenu extends React.PureComponent<React.PropsWithChil
|
|||||||
onClick={this.onClick}
|
onClick={this.onClick}
|
||||||
onKeyDown={onKeyDownHandler}
|
onKeyDown={onKeyDownHandler}
|
||||||
onContextMenu={this.onContextMenuPreventBubbling}
|
onContextMenu={this.onContextMenuPreventBubbling}
|
||||||
|
role={role}
|
||||||
|
aria-label={ariaLabel}
|
||||||
>
|
>
|
||||||
{background}
|
{background}
|
||||||
<TooltipProvider>
|
<TooltipProvider>
|
||||||
|
|||||||
@@ -76,8 +76,10 @@ export default class SetIntegrationManager extends React.Component<EmptyObject,
|
|||||||
>
|
>
|
||||||
<div className="mx_SettingsFlag">
|
<div className="mx_SettingsFlag">
|
||||||
<div className="mx_SetIntegrationManager_heading_manager">
|
<div className="mx_SetIntegrationManager_heading_manager">
|
||||||
<Heading size="3">{_t("integration_manager|manage_title")}</Heading>
|
<Heading as="h2" size="3">
|
||||||
<Heading id="mx_SetIntegrationManager_ManagerName" size="4">
|
{_t("integration_manager|manage_title")}
|
||||||
|
</Heading>
|
||||||
|
<Heading id="mx_SetIntegrationManager_ManagerName" as="h3" size="4">
|
||||||
{managerName}
|
{managerName}
|
||||||
</Heading>
|
</Heading>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -13,6 +13,10 @@ import { Heading } from "@vector-im/compound-web";
|
|||||||
* The heading for a settings section.
|
* The heading for a settings section.
|
||||||
*/
|
*/
|
||||||
interface SettingsHeaderProps {
|
interface SettingsHeaderProps {
|
||||||
|
/**
|
||||||
|
* The component to render the heading as, defaults to h2
|
||||||
|
*/
|
||||||
|
as?: React.ComponentProps<typeof Heading>["as"];
|
||||||
/**
|
/**
|
||||||
* Whether the user has a recommended tag.
|
* Whether the user has a recommended tag.
|
||||||
*/
|
*/
|
||||||
@@ -23,12 +27,12 @@ interface SettingsHeaderProps {
|
|||||||
label: string;
|
label: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function SettingsHeader({ hasRecommendedTag = false, label }: SettingsHeaderProps): JSX.Element {
|
export function SettingsHeader({ hasRecommendedTag = false, label, as = "h2" }: SettingsHeaderProps): JSX.Element {
|
||||||
const classes = classNames("mx_SettingsHeader", {
|
const classes = classNames("mx_SettingsHeader", {
|
||||||
mx_SettingsHeader_recommended: hasRecommendedTag,
|
mx_SettingsHeader_recommended: hasRecommendedTag,
|
||||||
});
|
});
|
||||||
return (
|
return (
|
||||||
<Heading className={classes} as="h2" size="sm" weight="semibold">
|
<Heading className={classes} as={as} size="sm" weight="semibold">
|
||||||
{label}
|
{label}
|
||||||
</Heading>
|
</Heading>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import { type ThirdPartyIdentifier } from "../../../AddThreepid";
|
|||||||
import SettingsStore from "../../../settings/SettingsStore";
|
import SettingsStore from "../../../settings/SettingsStore";
|
||||||
import { UIFeature } from "../../../settings/UIFeature";
|
import { UIFeature } from "../../../settings/UIFeature";
|
||||||
import { AddRemoveThreepids } from "./AddRemoveThreepids";
|
import { AddRemoveThreepids } from "./AddRemoveThreepids";
|
||||||
import Heading from "../typography/Heading.tsx";
|
import { SettingsSection } from "./shared/SettingsSection.tsx";
|
||||||
|
|
||||||
type LoadingState = "loading" | "loaded" | "error";
|
type LoadingState = "loading" | "loaded" | "error";
|
||||||
|
|
||||||
@@ -82,8 +82,7 @@ export const UserPersonalInfoSettings: React.FC<UserPersonalInfoSettingsProps> =
|
|||||||
if (!SettingsStore.getValue(UIFeature.ThirdPartyID)) return null;
|
if (!SettingsStore.getValue(UIFeature.ThirdPartyID)) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx_UserPersonalInfoSettings">
|
<SettingsSection heading={_t("settings|general|personal_info")} className="mx_UserPersonalInfoSettings">
|
||||||
<Heading size="2">{_t("settings|general|personal_info")}</Heading>
|
|
||||||
<SettingsSubsection
|
<SettingsSubsection
|
||||||
heading={_t("settings|general|emails_heading")}
|
heading={_t("settings|general|emails_heading")}
|
||||||
stretchContent
|
stretchContent
|
||||||
@@ -123,6 +122,6 @@ export const UserPersonalInfoSettings: React.FC<UserPersonalInfoSettingsProps> =
|
|||||||
/>
|
/>
|
||||||
</ThreepidSectionWrapper>
|
</ThreepidSectionWrapper>
|
||||||
</SettingsSubsection>
|
</SettingsSubsection>
|
||||||
</div>
|
</SettingsSection>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ import AccessibleButton from "../elements/AccessibleButton";
|
|||||||
import LogoutDialog, { shouldShowLogoutDialog } from "../dialogs/LogoutDialog";
|
import LogoutDialog, { shouldShowLogoutDialog } from "../dialogs/LogoutDialog";
|
||||||
import Modal from "../../../Modal";
|
import Modal from "../../../Modal";
|
||||||
import defaultDispatcher from "../../../dispatcher/dispatcher";
|
import defaultDispatcher from "../../../dispatcher/dispatcher";
|
||||||
import Heading from "../typography/Heading.tsx";
|
import { SettingsSection } from "./shared/SettingsSection.tsx";
|
||||||
|
|
||||||
const SpinnerToast: React.FC<{ children?: ReactNode }> = ({ children }) => (
|
const SpinnerToast: React.FC<{ children?: ReactNode }> = ({ children }) => (
|
||||||
<>
|
<>
|
||||||
@@ -194,54 +194,55 @@ const UserProfileSettings: React.FC<UserProfileSettingsProps> = ({
|
|||||||
const someFieldsDisabled = !canSetDisplayName || !canSetAvatar;
|
const someFieldsDisabled = !canSetDisplayName || !canSetAvatar;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx_UserProfileSettings">
|
<SettingsSection heading={_t("common|profile")}>
|
||||||
<Heading size="2">{_t("common|profile")}</Heading>
|
<div className="mx_UserProfileSettings">
|
||||||
<div>
|
<div>
|
||||||
{someFieldsDisabled
|
{someFieldsDisabled
|
||||||
? _t("settings|general|profile_subtitle_oidc")
|
? _t("settings|general|profile_subtitle_oidc")
|
||||||
: _t("settings|general|profile_subtitle")}
|
: _t("settings|general|profile_subtitle")}
|
||||||
</div>
|
</div>
|
||||||
<div className="mx_UserProfileSettings_profile">
|
<div className="mx_UserProfileSettings_profile">
|
||||||
<AvatarSetting
|
<AvatarSetting
|
||||||
avatar={avatarURL ?? undefined}
|
avatar={avatarURL ?? undefined}
|
||||||
avatarAccessibleName={_t("common|user_avatar")}
|
avatarAccessibleName={_t("common|user_avatar")}
|
||||||
onChange={onAvatarChange}
|
onChange={onAvatarChange}
|
||||||
removeAvatar={avatarURL ? onAvatarRemove : undefined}
|
removeAvatar={avatarURL ? onAvatarRemove : undefined}
|
||||||
placeholderName={displayName}
|
placeholderName={displayName}
|
||||||
placeholderId={client.getUserId() ?? ""}
|
placeholderId={client.getUserId() ?? ""}
|
||||||
disabled={!canSetAvatar}
|
disabled={!canSetAvatar}
|
||||||
/>
|
/>
|
||||||
<EditInPlace
|
<EditInPlace
|
||||||
className="mx_UserProfileSettings_profile_displayName"
|
className="mx_UserProfileSettings_profile_displayName"
|
||||||
label={_t("settings|general|display_name")}
|
label={_t("settings|general|display_name")}
|
||||||
value={displayName}
|
value={displayName}
|
||||||
saveButtonLabel={_t("common|save")}
|
saveButtonLabel={_t("common|save")}
|
||||||
cancelButtonLabel={_t("common|cancel")}
|
cancelButtonLabel={_t("common|cancel")}
|
||||||
savedLabel={_t("common|saved")}
|
savedLabel={_t("common|saved")}
|
||||||
savingLabel={_t("common|updating")}
|
savingLabel={_t("common|updating")}
|
||||||
onChange={onDisplayNameChanged}
|
onChange={onDisplayNameChanged}
|
||||||
onCancel={onDisplayNameCancel}
|
onCancel={onDisplayNameCancel}
|
||||||
onSave={onDisplayNameSave}
|
onSave={onDisplayNameSave}
|
||||||
disabled={!canSetDisplayName}
|
disabled={!canSetDisplayName}
|
||||||
>
|
>
|
||||||
{displayNameError && <ErrorMessage>{_t("settings|general|display_name_error")}</ErrorMessage>}
|
{displayNameError && <ErrorMessage>{_t("settings|general|display_name_error")}</ErrorMessage>}
|
||||||
</EditInPlace>
|
</EditInPlace>
|
||||||
</div>
|
</div>
|
||||||
{avatarError && (
|
{avatarError && (
|
||||||
<Alert title={_t("settings|general|avatar_upload_error_title")} type="critical">
|
<Alert title={_t("settings|general|avatar_upload_error_title")} type="critical">
|
||||||
{maxUploadSize === undefined
|
{maxUploadSize === undefined
|
||||||
? _t("settings|general|avatar_upload_error_text_generic")
|
? _t("settings|general|avatar_upload_error_text_generic")
|
||||||
: _t("settings|general|avatar_upload_error_text", { size: formatBytes(maxUploadSize) })}
|
: _t("settings|general|avatar_upload_error_text", { size: formatBytes(maxUploadSize) })}
|
||||||
</Alert>
|
</Alert>
|
||||||
)}
|
|
||||||
{userIdentifier && <UsernameBox username={userIdentifier} />}
|
|
||||||
<Flex gap="var(--cpd-space-4x)" className="mx_UserProfileSettings_profile_buttons">
|
|
||||||
{externalAccountManagementUrl && (
|
|
||||||
<ManageAccountButton externalAccountManagementUrl={externalAccountManagementUrl} />
|
|
||||||
)}
|
)}
|
||||||
<SignOutButton />
|
{userIdentifier && <UsernameBox username={userIdentifier} />}
|
||||||
</Flex>
|
<Flex gap="var(--cpd-space-4x)" className="mx_UserProfileSettings_profile_buttons">
|
||||||
</div>
|
{externalAccountManagementUrl && (
|
||||||
|
<ManageAccountButton externalAccountManagementUrl={externalAccountManagementUrl} />
|
||||||
|
)}
|
||||||
|
<SignOutButton />
|
||||||
|
</Flex>
|
||||||
|
</div>
|
||||||
|
</SettingsSection>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -22,7 +22,11 @@ export interface DeviceTileProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const DeviceTileName: React.FC<{ device: ExtendedDevice }> = ({ device }) => {
|
const DeviceTileName: React.FC<{ device: ExtendedDevice }> = ({ device }) => {
|
||||||
return <Heading size="4">{device.display_name || device.device_id}</Heading>;
|
return (
|
||||||
|
<Heading as="h3" size="4">
|
||||||
|
{device.display_name || device.device_id}
|
||||||
|
</Heading>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const DeviceTile: React.FC<DeviceTileProps> = ({ device, children, isSelected, onClick }) => {
|
const DeviceTile: React.FC<DeviceTileProps> = ({ device, children, isSelected, onClick }) => {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { useCallback } from "react";
|
import React, { useCallback } from "react";
|
||||||
import { InlineField, InlineSpinner, Label, Root, ToggleControl } from "@vector-im/compound-web";
|
import { InlineField, InlineSpinner, Label, Link, Root, ToggleControl } from "@vector-im/compound-web";
|
||||||
|
|
||||||
import type { FormEvent } from "react";
|
import type { FormEvent } from "react";
|
||||||
import { SettingsSection } from "../shared/SettingsSection";
|
import { SettingsSection } from "../shared/SettingsSection";
|
||||||
@@ -56,9 +56,9 @@ export const KeyStoragePanel: React.FC<Props> = ({ onKeyStorageDisableClick }) =
|
|||||||
}
|
}
|
||||||
subHeading={_t("settings|encryption|key_storage|description", undefined, {
|
subHeading={_t("settings|encryption|key_storage|description", undefined, {
|
||||||
a: (sub) => (
|
a: (sub) => (
|
||||||
<a href={SdkConfig.get("help_key_storage_url")} target="_blank" rel="noreferrer noopener">
|
<Link href={SdkConfig.get("help_key_storage_url")} target="_blank">
|
||||||
{sub}
|
{sub}
|
||||||
</a>
|
</Link>
|
||||||
),
|
),
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ Please see LICENSE files in the repository root for full details.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import classnames from "classnames";
|
import classnames from "classnames";
|
||||||
import React, { type HTMLAttributes } from "react";
|
import React, { type ComponentProps, createContext, type HTMLAttributes, useContext } from "react";
|
||||||
|
|
||||||
import Heading from "../../typography/Heading";
|
import Heading from "../../typography/Heading";
|
||||||
import { SettingsHeader } from "../SettingsHeader";
|
import { SettingsHeader } from "../SettingsHeader";
|
||||||
@@ -19,15 +19,30 @@ export interface SettingsSectionProps extends HTMLAttributes<HTMLDivElement> {
|
|||||||
legacy?: boolean;
|
legacy?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderHeading(heading: string | React.ReactNode | undefined, legacy: boolean): React.ReactNode | undefined {
|
type HeadingLevel = 2 | 3 | 4 | 5 | 6;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* React context to correctly set heading levels in nested settings sections dynamically
|
||||||
|
*/
|
||||||
|
export const HeadingLevelContext = createContext<HeadingLevel>(2);
|
||||||
|
|
||||||
|
function SectionHeading({
|
||||||
|
heading,
|
||||||
|
legacy,
|
||||||
|
level,
|
||||||
|
}: {
|
||||||
|
heading: string | React.ReactNode | undefined;
|
||||||
|
legacy: boolean;
|
||||||
|
level: HeadingLevel;
|
||||||
|
}): React.ReactNode | undefined {
|
||||||
switch (typeof heading) {
|
switch (typeof heading) {
|
||||||
case "string":
|
case "string":
|
||||||
return legacy ? (
|
return legacy ? (
|
||||||
<Heading as="h2" size="3">
|
<Heading as={`h${level}`} size={(level + 1).toString() as ComponentProps<typeof Heading>["size"]}>
|
||||||
{heading}
|
{heading}
|
||||||
</Heading>
|
</Heading>
|
||||||
) : (
|
) : (
|
||||||
<SettingsHeader label={heading} />
|
<SettingsHeader as={`h${level}`} label={heading} />
|
||||||
);
|
);
|
||||||
case "undefined":
|
case "undefined":
|
||||||
return undefined;
|
return undefined;
|
||||||
@@ -60,22 +75,28 @@ export const SettingsSection: React.FC<SettingsSectionProps> = ({
|
|||||||
legacy = true,
|
legacy = true,
|
||||||
children,
|
children,
|
||||||
...rest
|
...rest
|
||||||
}) => (
|
}) => {
|
||||||
<div
|
const level = useContext(HeadingLevelContext);
|
||||||
{...rest}
|
|
||||||
className={classnames("mx_SettingsSection", className, {
|
return (
|
||||||
mx_SettingsSection_newUi: !legacy,
|
<div
|
||||||
})}
|
{...rest}
|
||||||
>
|
className={classnames("mx_SettingsSection", className, {
|
||||||
{heading &&
|
mx_SettingsSection_newUi: !legacy,
|
||||||
(subHeading ? (
|
})}
|
||||||
<div className="mx_SettingsSection_header">
|
>
|
||||||
{renderHeading(heading, legacy)}
|
{heading &&
|
||||||
{subHeading}
|
(subHeading ? (
|
||||||
</div>
|
<div className="mx_SettingsSection_header">
|
||||||
) : (
|
<SectionHeading heading={heading} legacy={legacy} level={level} />
|
||||||
renderHeading(heading, legacy)
|
{subHeading}
|
||||||
))}
|
</div>
|
||||||
{legacy ? <div className="mx_SettingsSection_subSections">{children}</div> : children}
|
) : (
|
||||||
</div>
|
<SectionHeading heading={heading} legacy={legacy} level={level} />
|
||||||
);
|
))}
|
||||||
|
<HeadingLevelContext.Provider value={heading ? ((level + 1) as HeadingLevel) : level}>
|
||||||
|
{legacy ? <div className="mx_SettingsSection_subSections">{children}</div> : children}
|
||||||
|
</HeadingLevelContext.Provider>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|||||||
@@ -7,10 +7,11 @@ Please see LICENSE files in the repository root for full details.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
import React, { type HTMLAttributes } from "react";
|
import React, { type HTMLAttributes, useContext } from "react";
|
||||||
import { Form, Separator } from "@vector-im/compound-web";
|
import { Form, Separator } from "@vector-im/compound-web";
|
||||||
|
|
||||||
import { SettingsSubsectionHeading } from "./SettingsSubsectionHeading";
|
import { SettingsSubsectionHeading } from "./SettingsSubsectionHeading";
|
||||||
|
import { HeadingLevelContext } from "./SettingsSection.tsx";
|
||||||
|
|
||||||
export interface SettingsSubsectionProps extends HTMLAttributes<HTMLDivElement> {
|
export interface SettingsSubsectionProps extends HTMLAttributes<HTMLDivElement> {
|
||||||
heading?: string | React.ReactNode;
|
heading?: string | React.ReactNode;
|
||||||
@@ -45,6 +46,8 @@ export const SettingsSubsection: React.FC<SettingsSubsectionProps> = ({
|
|||||||
formWrap,
|
formWrap,
|
||||||
...rest
|
...rest
|
||||||
}) => {
|
}) => {
|
||||||
|
const level = useContext(HeadingLevelContext);
|
||||||
|
|
||||||
const content = (
|
const content = (
|
||||||
<div
|
<div
|
||||||
{...rest}
|
{...rest}
|
||||||
@@ -52,7 +55,11 @@ export const SettingsSubsection: React.FC<SettingsSubsectionProps> = ({
|
|||||||
mx_SettingsSubsection_newUi: !legacy,
|
mx_SettingsSubsection_newUi: !legacy,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
{typeof heading === "string" ? <SettingsSubsectionHeading heading={heading} /> : <>{heading}</>}
|
{typeof heading === "string" ? (
|
||||||
|
<SettingsSubsectionHeading heading={heading} as={`h${level}`} />
|
||||||
|
) : (
|
||||||
|
<>{heading}</>
|
||||||
|
)}
|
||||||
{!!description && (
|
{!!description && (
|
||||||
<div className="mx_SettingsSubsection_description">
|
<div className="mx_SettingsSubsection_description">
|
||||||
<SettingsSubsectionText>{description}</SettingsSubsectionText>
|
<SettingsSubsectionText>{description}</SettingsSubsectionText>
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ export interface SettingsSubsectionHeadingProps extends HTMLAttributes<HTMLDivEl
|
|||||||
|
|
||||||
export const SettingsSubsectionHeading: React.FC<SettingsSubsectionHeadingProps> = ({
|
export const SettingsSubsectionHeading: React.FC<SettingsSubsectionHeadingProps> = ({
|
||||||
heading,
|
heading,
|
||||||
as = "h3",
|
as = "h2",
|
||||||
children,
|
children,
|
||||||
...rest
|
...rest
|
||||||
}) => {
|
}) => {
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ const AccountSection: React.FC<AccountSectionProps> = ({
|
|||||||
if (!canChangePassword) return <></>;
|
if (!canChangePassword) return <></>;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<SettingsSection>
|
||||||
<SettingsSubsection
|
<SettingsSubsection
|
||||||
heading={_t("settings|general|account_section")}
|
heading={_t("settings|general|account_section")}
|
||||||
stretchContent
|
stretchContent
|
||||||
@@ -59,7 +59,7 @@ const AccountSection: React.FC<AccountSectionProps> = ({
|
|||||||
onFinished={onPasswordChanged}
|
onFinished={onPasswordChanged}
|
||||||
/>
|
/>
|
||||||
</SettingsSubsection>
|
</SettingsSubsection>
|
||||||
</>
|
</SettingsSection>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -179,21 +179,19 @@ const AccountUserSettingsTab: React.FC<IProps> = ({ closeSettingsFn }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<SettingsTab data-testid="mx_AccountUserSettingsTab">
|
<SettingsTab data-testid="mx_AccountUserSettingsTab">
|
||||||
<SettingsSection>
|
<UserProfileSettings
|
||||||
<UserProfileSettings
|
externalAccountManagementUrl={externalAccountManagementUrl}
|
||||||
externalAccountManagementUrl={externalAccountManagementUrl}
|
canSetDisplayName={canSetDisplayName}
|
||||||
canSetDisplayName={canSetDisplayName}
|
canSetAvatar={canSetAvatar}
|
||||||
canSetAvatar={canSetAvatar}
|
/>
|
||||||
/>
|
{(!isAccountManagedExternally || canMake3pidChanges) && (
|
||||||
{(!isAccountManagedExternally || canMake3pidChanges) && (
|
<UserPersonalInfoSettings canMake3pidChanges={canMake3pidChanges} />
|
||||||
<UserPersonalInfoSettings canMake3pidChanges={canMake3pidChanges} />
|
)}
|
||||||
)}
|
<AccountSection
|
||||||
<AccountSection
|
canChangePassword={canChangePassword}
|
||||||
canChangePassword={canChangePassword}
|
onPasswordChanged={onPasswordChanged}
|
||||||
onPasswordChanged={onPasswordChanged}
|
onPasswordChangeError={onPasswordChangeError}
|
||||||
onPasswordChangeError={onPasswordChangeError}
|
/>
|
||||||
/>
|
|
||||||
</SettingsSection>
|
|
||||||
{accountManagementSection}
|
{accountManagementSection}
|
||||||
</SettingsTab>
|
</SettingsTab>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -58,6 +58,8 @@ const QuickSettingsButton: React.FC<{
|
|||||||
onFinished={closeMenu}
|
onFinished={closeMenu}
|
||||||
managed={false}
|
managed={false}
|
||||||
focusLock={true}
|
focusLock={true}
|
||||||
|
role="region"
|
||||||
|
aria-label={_t("quick_settings|title")}
|
||||||
>
|
>
|
||||||
<h2>{_t("quick_settings|title")}</h2>
|
<h2>{_t("quick_settings|title")}</h2>
|
||||||
|
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ const QuickThemeSwitcher: React.FC<Props> = ({ requestClose }) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx_QuickThemeSwitcher">
|
<div className="mx_QuickThemeSwitcher">
|
||||||
<h4 className="mx_QuickThemeSwitcher_heading">{_t("common|theme")}</h4>
|
<h3 className="mx_QuickThemeSwitcher_heading">{_t("common|theme")}</h3>
|
||||||
<Dropdown
|
<Dropdown
|
||||||
id="mx_QuickSettingsButton_themePickerDropdown"
|
id="mx_QuickSettingsButton_themePickerDropdown"
|
||||||
onOptionChange={onOptionChange}
|
onOptionChange={onOptionChange}
|
||||||
|
|||||||
@@ -9,11 +9,11 @@ exports[`FontScalingPanel renders the font scaling UI 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
Font size
|
Font size
|
||||||
</h3>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsection_content mx_SettingsSubsection_contentStretch"
|
class="mx_SettingsSubsection_content mx_SettingsSubsection_contentStretch"
|
||||||
|
|||||||
@@ -9,11 +9,11 @@ exports[`<LayoutSwitcher /> should render 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
Message layout
|
Message layout
|
||||||
</h3>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsection_content mx_SettingsSubsection_content_newUi"
|
class="mx_SettingsSubsection_content mx_SettingsSubsection_content_newUi"
|
||||||
|
|||||||
@@ -11,17 +11,17 @@ exports[`SetIntegrationManager should render manage integrations sections 1`] =
|
|||||||
<div
|
<div
|
||||||
class="mx_SetIntegrationManager_heading_manager"
|
class="mx_SetIntegrationManager_heading_manager"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h3"
|
class="mx_Heading_h3"
|
||||||
>
|
>
|
||||||
Manage integrations
|
Manage integrations
|
||||||
</h3>
|
</h2>
|
||||||
<h4
|
<h3
|
||||||
class="mx_Heading_h4"
|
class="mx_Heading_h4"
|
||||||
id="mx_SetIntegrationManager_ManagerName"
|
id="mx_SetIntegrationManager_ManagerName"
|
||||||
>
|
>
|
||||||
(scalar.vector.im)
|
(scalar.vector.im)
|
||||||
</h4>
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -9,11 +9,11 @@ exports[`<ThemeChoicePanel /> custom theme should display custom theme 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
Theme
|
Theme
|
||||||
</h3>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsection_content mx_SettingsSubsection_content_newUi"
|
class="mx_SettingsSubsection_content mx_SettingsSubsection_content_newUi"
|
||||||
@@ -288,11 +288,11 @@ exports[`<ThemeChoicePanel /> custom theme should render the custom theme sectio
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
Theme
|
Theme
|
||||||
</h3>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsection_content mx_SettingsSubsection_content_newUi"
|
class="mx_SettingsSubsection_content mx_SettingsSubsection_content_newUi"
|
||||||
@@ -567,11 +567,11 @@ exports[`<ThemeChoicePanel /> renders the theme choice UI 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
Theme
|
Theme
|
||||||
</h3>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsection_content mx_SettingsSubsection_content_newUi"
|
class="mx_SettingsSubsection_content mx_SettingsSubsection_content_newUi"
|
||||||
|
|||||||
@@ -137,11 +137,11 @@ exports[`<CurrentDeviceSection /> handles when device is falsy 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
Current session
|
Current session
|
||||||
</h3>
|
</h2>
|
||||||
<div
|
<div
|
||||||
aria-disabled="true"
|
aria-disabled="true"
|
||||||
aria-expanded="false"
|
aria-expanded="false"
|
||||||
@@ -183,11 +183,11 @@ exports[`<CurrentDeviceSection /> renders device and correct security card when
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
Current session
|
Current session
|
||||||
</h3>
|
</h2>
|
||||||
<div
|
<div
|
||||||
aria-expanded="false"
|
aria-expanded="false"
|
||||||
aria-haspopup="true"
|
aria-haspopup="true"
|
||||||
@@ -257,11 +257,11 @@ exports[`<CurrentDeviceSection /> renders device and correct security card when
|
|||||||
<div
|
<div
|
||||||
class="mx_DeviceTile_info"
|
class="mx_DeviceTile_info"
|
||||||
>
|
>
|
||||||
<h4
|
<h3
|
||||||
class="mx_Heading_h4"
|
class="mx_Heading_h4"
|
||||||
>
|
>
|
||||||
alices_device
|
alices_device
|
||||||
</h4>
|
</h3>
|
||||||
<div
|
<div
|
||||||
class="mx_DeviceTile_metadata"
|
class="mx_DeviceTile_metadata"
|
||||||
>
|
>
|
||||||
@@ -370,11 +370,11 @@ exports[`<CurrentDeviceSection /> renders device and correct security card when
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
Current session
|
Current session
|
||||||
</h3>
|
</h2>
|
||||||
<div
|
<div
|
||||||
aria-expanded="false"
|
aria-expanded="false"
|
||||||
aria-haspopup="true"
|
aria-haspopup="true"
|
||||||
@@ -444,11 +444,11 @@ exports[`<CurrentDeviceSection /> renders device and correct security card when
|
|||||||
<div
|
<div
|
||||||
class="mx_DeviceTile_info"
|
class="mx_DeviceTile_info"
|
||||||
>
|
>
|
||||||
<h4
|
<h3
|
||||||
class="mx_Heading_h4"
|
class="mx_Heading_h4"
|
||||||
>
|
>
|
||||||
alices_device
|
alices_device
|
||||||
</h4>
|
</h3>
|
||||||
<div
|
<div
|
||||||
class="mx_DeviceTile_metadata"
|
class="mx_DeviceTile_metadata"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -45,11 +45,11 @@ exports[`<DeviceTile /> renders a device with no metadata 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="mx_DeviceTile_info"
|
class="mx_DeviceTile_info"
|
||||||
>
|
>
|
||||||
<h4
|
<h3
|
||||||
class="mx_Heading_h4"
|
class="mx_Heading_h4"
|
||||||
>
|
>
|
||||||
123
|
123
|
||||||
</h4>
|
</h3>
|
||||||
<div
|
<div
|
||||||
class="mx_DeviceTile_metadata"
|
class="mx_DeviceTile_metadata"
|
||||||
>
|
>
|
||||||
@@ -118,11 +118,11 @@ exports[`<DeviceTile /> renders a verified device with no metadata 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="mx_DeviceTile_info"
|
class="mx_DeviceTile_info"
|
||||||
>
|
>
|
||||||
<h4
|
<h3
|
||||||
class="mx_Heading_h4"
|
class="mx_Heading_h4"
|
||||||
>
|
>
|
||||||
123
|
123
|
||||||
</h4>
|
</h3>
|
||||||
<div
|
<div
|
||||||
class="mx_DeviceTile_metadata"
|
class="mx_DeviceTile_metadata"
|
||||||
>
|
>
|
||||||
@@ -191,11 +191,11 @@ exports[`<DeviceTile /> renders display name with a tooltip 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="mx_DeviceTile_info"
|
class="mx_DeviceTile_info"
|
||||||
>
|
>
|
||||||
<h4
|
<h3
|
||||||
class="mx_Heading_h4"
|
class="mx_Heading_h4"
|
||||||
>
|
>
|
||||||
My device
|
My device
|
||||||
</h4>
|
</h3>
|
||||||
<div
|
<div
|
||||||
class="mx_DeviceTile_metadata"
|
class="mx_DeviceTile_metadata"
|
||||||
>
|
>
|
||||||
@@ -264,11 +264,11 @@ exports[`<DeviceTile /> separates metadata with a dot 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="mx_DeviceTile_info"
|
class="mx_DeviceTile_info"
|
||||||
>
|
>
|
||||||
<h4
|
<h3
|
||||||
class="mx_Heading_h4"
|
class="mx_Heading_h4"
|
||||||
>
|
>
|
||||||
123
|
123
|
||||||
</h4>
|
</h3>
|
||||||
<div
|
<div
|
||||||
class="mx_DeviceTile_metadata"
|
class="mx_DeviceTile_metadata"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -9,11 +9,11 @@ exports[`<SecurityRecommendations /> renders both cards when user has both unver
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
Security recommendations
|
Security recommendations
|
||||||
</h3>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsection_description"
|
class="mx_SettingsSubsection_description"
|
||||||
@@ -141,11 +141,11 @@ exports[`<SecurityRecommendations /> renders inactive devices section when user
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
Security recommendations
|
Security recommendations
|
||||||
</h3>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsection_description"
|
class="mx_SettingsSubsection_description"
|
||||||
@@ -273,11 +273,11 @@ exports[`<SecurityRecommendations /> renders unverified devices section when use
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
Security recommendations
|
Security recommendations
|
||||||
</h3>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsection_description"
|
class="mx_SettingsSubsection_description"
|
||||||
|
|||||||
@@ -101,11 +101,11 @@ exports[`<SelectableDeviceTile /> renders unselected device tile with checkbox 1
|
|||||||
<div
|
<div
|
||||||
class="mx_DeviceTile_info"
|
class="mx_DeviceTile_info"
|
||||||
>
|
>
|
||||||
<h4
|
<h3
|
||||||
class="mx_Heading_h4"
|
class="mx_Heading_h4"
|
||||||
>
|
>
|
||||||
My Device
|
My Device
|
||||||
</h4>
|
</h3>
|
||||||
<div
|
<div
|
||||||
class="mx_DeviceTile_metadata"
|
class="mx_DeviceTile_metadata"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -948,11 +948,11 @@ exports[`<Notifications /> correctly handles the loading/disabled state 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
Email summary
|
Email summary
|
||||||
</h3>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsection_content mx_SettingsSubsection_content_newUi"
|
class="mx_SettingsSubsection_content mx_SettingsSubsection_content_newUi"
|
||||||
@@ -998,11 +998,11 @@ exports[`<Notifications /> correctly handles the loading/disabled state 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
Quick Actions
|
Quick Actions
|
||||||
</h3>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsection_content"
|
class="mx_SettingsSubsection_content"
|
||||||
@@ -2174,11 +2174,11 @@ exports[`<Notifications /> matches the snapshot 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
Email summary
|
Email summary
|
||||||
</h3>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsection_content mx_SettingsSubsection_content_newUi"
|
class="mx_SettingsSubsection_content mx_SettingsSubsection_content_newUi"
|
||||||
@@ -2280,11 +2280,11 @@ exports[`<Notifications /> matches the snapshot 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
Notification targets
|
Notification targets
|
||||||
</h3>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsection_content mx_SettingsSubsection_content_newUi"
|
class="mx_SettingsSubsection_content mx_SettingsSubsection_content_newUi"
|
||||||
@@ -2308,11 +2308,11 @@ exports[`<Notifications /> matches the snapshot 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
Quick Actions
|
Quick Actions
|
||||||
</h3>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsection_content"
|
class="mx_SettingsSubsection_content"
|
||||||
|
|||||||
@@ -8,11 +8,11 @@ exports[`<SettingsSubsection /> renders with plain text description 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
Test
|
Test
|
||||||
</h3>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsection_description"
|
class="mx_SettingsSubsection_description"
|
||||||
@@ -42,11 +42,11 @@ exports[`<SettingsSubsection /> renders with plain text heading 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
Test
|
Test
|
||||||
</h3>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsection_content"
|
class="mx_SettingsSubsection_content"
|
||||||
@@ -67,11 +67,11 @@ exports[`<SettingsSubsection /> renders with react element description 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
Test
|
Test
|
||||||
</h3>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsection_description"
|
class="mx_SettingsSubsection_description"
|
||||||
@@ -127,11 +127,11 @@ exports[`<SettingsSubsection /> renders without description 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
Test
|
Test
|
||||||
</h3>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsection_content"
|
class="mx_SettingsSubsection_content"
|
||||||
|
|||||||
@@ -6,11 +6,11 @@ exports[`<SettingsSubsectionHeading /> renders with children 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
test
|
test
|
||||||
</h3>
|
</h2>
|
||||||
<a
|
<a
|
||||||
href="/#"
|
href="/#"
|
||||||
>
|
>
|
||||||
@@ -27,11 +27,11 @@ exports[`<SettingsSubsectionHeading /> renders without children 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
test
|
test
|
||||||
</h3>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
</div>,
|
</div>,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,11 +22,11 @@ exports[`AppearanceUserSettingsTab should render 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
Theme
|
Theme
|
||||||
</h3>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsection_content mx_SettingsSubsection_content_newUi"
|
class="mx_SettingsSubsection_content mx_SettingsSubsection_content_newUi"
|
||||||
@@ -152,11 +152,11 @@ exports[`AppearanceUserSettingsTab should render 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
Message layout
|
Message layout
|
||||||
</h3>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsection_content mx_SettingsSubsection_content_newUi"
|
class="mx_SettingsSubsection_content mx_SettingsSubsection_content_newUi"
|
||||||
@@ -510,11 +510,11 @@ exports[`AppearanceUserSettingsTab should render 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
Font size
|
Font size
|
||||||
</h3>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsection_content mx_SettingsSubsection_contentStretch"
|
class="mx_SettingsSubsection_content mx_SettingsSubsection_contentStretch"
|
||||||
@@ -692,11 +692,11 @@ exports[`AppearanceUserSettingsTab should render 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
Image size in the timeline
|
Image size in the timeline
|
||||||
</h3>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsection_content"
|
class="mx_SettingsSubsection_content"
|
||||||
|
|||||||
@@ -20,11 +20,11 @@ exports[`KeyboardUserSettingsTab renders list of keyboard shortcuts 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
Composer
|
Composer
|
||||||
</h3>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsection_content"
|
class="mx_SettingsSubsection_content"
|
||||||
@@ -381,11 +381,11 @@ exports[`KeyboardUserSettingsTab renders list of keyboard shortcuts 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
Calls
|
Calls
|
||||||
</h3>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsection_content"
|
class="mx_SettingsSubsection_content"
|
||||||
@@ -442,11 +442,11 @@ exports[`KeyboardUserSettingsTab renders list of keyboard shortcuts 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
Room
|
Room
|
||||||
</h3>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsection_content"
|
class="mx_SettingsSubsection_content"
|
||||||
@@ -611,11 +611,11 @@ exports[`KeyboardUserSettingsTab renders list of keyboard shortcuts 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
Room List
|
Room List
|
||||||
</h3>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsection_content"
|
class="mx_SettingsSubsection_content"
|
||||||
@@ -702,11 +702,11 @@ exports[`KeyboardUserSettingsTab renders list of keyboard shortcuts 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
Accessibility
|
Accessibility
|
||||||
</h3>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsection_content"
|
class="mx_SettingsSubsection_content"
|
||||||
@@ -771,11 +771,11 @@ exports[`KeyboardUserSettingsTab renders list of keyboard shortcuts 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
Navigation
|
Navigation
|
||||||
</h3>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsection_content"
|
class="mx_SettingsSubsection_content"
|
||||||
@@ -1062,11 +1062,11 @@ exports[`KeyboardUserSettingsTab renders list of keyboard shortcuts 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
Autocomplete
|
Autocomplete
|
||||||
</h3>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsection_content"
|
class="mx_SettingsSubsection_content"
|
||||||
|
|||||||
@@ -41,11 +41,11 @@ exports[`<MjolnirUserSettingsTab /> renders correctly when user has no ignored u
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
Personal ban list
|
Personal ban list
|
||||||
</h3>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsection_description"
|
class="mx_SettingsSubsection_description"
|
||||||
@@ -97,11 +97,11 @@ exports[`<MjolnirUserSettingsTab /> renders correctly when user has no ignored u
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
Subscribed lists
|
Subscribed lists
|
||||||
</h3>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsection_description"
|
class="mx_SettingsSubsection_description"
|
||||||
|
|||||||
@@ -24,11 +24,11 @@ exports[`PreferencesUserSettingsTab should render 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
Language
|
Language
|
||||||
</h3>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsection_content"
|
class="mx_SettingsSubsection_content"
|
||||||
@@ -77,11 +77,11 @@ exports[`PreferencesUserSettingsTab should render 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
Room list
|
Room list
|
||||||
</h3>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsection_content"
|
class="mx_SettingsSubsection_content"
|
||||||
@@ -129,11 +129,11 @@ exports[`PreferencesUserSettingsTab should render 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
Spaces
|
Spaces
|
||||||
</h3>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsection_content"
|
class="mx_SettingsSubsection_content"
|
||||||
@@ -188,11 +188,11 @@ exports[`PreferencesUserSettingsTab should render 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
Keyboard shortcuts
|
Keyboard shortcuts
|
||||||
</h3>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsection_description"
|
class="mx_SettingsSubsection_description"
|
||||||
@@ -260,11 +260,11 @@ exports[`PreferencesUserSettingsTab should render 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
Displaying time
|
Displaying time
|
||||||
</h3>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsection_content"
|
class="mx_SettingsSubsection_content"
|
||||||
@@ -421,11 +421,11 @@ exports[`PreferencesUserSettingsTab should render 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
Presence
|
Presence
|
||||||
</h3>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsection_description"
|
class="mx_SettingsSubsection_description"
|
||||||
@@ -523,11 +523,11 @@ exports[`PreferencesUserSettingsTab should render 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
Composer
|
Composer
|
||||||
</h3>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsection_content"
|
class="mx_SettingsSubsection_content"
|
||||||
@@ -784,11 +784,11 @@ exports[`PreferencesUserSettingsTab should render 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
Code blocks
|
Code blocks
|
||||||
</h3>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsection_content"
|
class="mx_SettingsSubsection_content"
|
||||||
@@ -902,11 +902,11 @@ exports[`PreferencesUserSettingsTab should render 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
Images, GIFs and videos
|
Images, GIFs and videos
|
||||||
</h3>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsection_content"
|
class="mx_SettingsSubsection_content"
|
||||||
@@ -1020,11 +1020,11 @@ exports[`PreferencesUserSettingsTab should render 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
Timeline
|
Timeline
|
||||||
</h3>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsection_content"
|
class="mx_SettingsSubsection_content"
|
||||||
@@ -1401,11 +1401,11 @@ exports[`PreferencesUserSettingsTab should render 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
Moderation and safety
|
Moderation and safety
|
||||||
</h3>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsection_content mx_SettingsSubsection_content_newUi"
|
class="mx_SettingsSubsection_content mx_SettingsSubsection_content_newUi"
|
||||||
@@ -1615,11 +1615,11 @@ exports[`PreferencesUserSettingsTab should render 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
Room directory
|
Room directory
|
||||||
</h3>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsection_content"
|
class="mx_SettingsSubsection_content"
|
||||||
@@ -1668,11 +1668,11 @@ exports[`PreferencesUserSettingsTab should render 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
General
|
General
|
||||||
</h3>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsection_content mx_SettingsSubsection_contentStretch"
|
class="mx_SettingsSubsection_content mx_SettingsSubsection_contentStretch"
|
||||||
|
|||||||
@@ -44,17 +44,17 @@ exports[`<SecurityUserSettingsTab /> renders security section 1`] = `
|
|||||||
<div
|
<div
|
||||||
class="mx_SetIntegrationManager_heading_manager"
|
class="mx_SetIntegrationManager_heading_manager"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h3"
|
class="mx_Heading_h3"
|
||||||
>
|
>
|
||||||
Manage integrations
|
Manage integrations
|
||||||
</h3>
|
</h2>
|
||||||
<h4
|
<h3
|
||||||
class="mx_Heading_h4"
|
class="mx_Heading_h4"
|
||||||
id="mx_SetIntegrationManager_ManagerName"
|
id="mx_SetIntegrationManager_ManagerName"
|
||||||
>
|
>
|
||||||
(scalar.vector.im)
|
(scalar.vector.im)
|
||||||
</h4>
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -83,11 +83,11 @@ exports[`<SessionManagerTab /> current session section renders current session s
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
Current session
|
Current session
|
||||||
</h3>
|
</h2>
|
||||||
<div
|
<div
|
||||||
aria-expanded="false"
|
aria-expanded="false"
|
||||||
aria-haspopup="true"
|
aria-haspopup="true"
|
||||||
@@ -159,11 +159,11 @@ exports[`<SessionManagerTab /> current session section renders current session s
|
|||||||
<div
|
<div
|
||||||
class="mx_DeviceTile_info"
|
class="mx_DeviceTile_info"
|
||||||
>
|
>
|
||||||
<h4
|
<h3
|
||||||
class="mx_Heading_h4"
|
class="mx_Heading_h4"
|
||||||
>
|
>
|
||||||
Alices device
|
Alices device
|
||||||
</h4>
|
</h3>
|
||||||
<div
|
<div
|
||||||
class="mx_DeviceTile_metadata"
|
class="mx_DeviceTile_metadata"
|
||||||
>
|
>
|
||||||
@@ -260,11 +260,11 @@ exports[`<SessionManagerTab /> current session section renders current session s
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
Current session
|
Current session
|
||||||
</h3>
|
</h2>
|
||||||
<div
|
<div
|
||||||
aria-expanded="false"
|
aria-expanded="false"
|
||||||
aria-haspopup="true"
|
aria-haspopup="true"
|
||||||
@@ -334,11 +334,11 @@ exports[`<SessionManagerTab /> current session section renders current session s
|
|||||||
<div
|
<div
|
||||||
class="mx_DeviceTile_info"
|
class="mx_DeviceTile_info"
|
||||||
>
|
>
|
||||||
<h4
|
<h3
|
||||||
class="mx_Heading_h4"
|
class="mx_Heading_h4"
|
||||||
>
|
>
|
||||||
Alices device
|
Alices device
|
||||||
</h4>
|
</h3>
|
||||||
<div
|
<div
|
||||||
class="mx_DeviceTile_metadata"
|
class="mx_DeviceTile_metadata"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -20,11 +20,11 @@ exports[`<SidebarUserSettingsTab /> renders sidebar settings with guest spa url
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
Spaces to show
|
Spaces to show
|
||||||
</h3>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsection_description"
|
class="mx_SettingsSubsection_description"
|
||||||
@@ -310,11 +310,11 @@ exports[`<SidebarUserSettingsTab /> renders sidebar settings without guest spa u
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsectionHeading"
|
class="mx_SettingsSubsectionHeading"
|
||||||
>
|
>
|
||||||
<h3
|
<h2
|
||||||
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
class="mx_Heading_h4 mx_SettingsSubsectionHeading_heading"
|
||||||
>
|
>
|
||||||
Spaces to show
|
Spaces to show
|
||||||
</h3>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="mx_SettingsSubsection_description"
|
class="mx_SettingsSubsection_description"
|
||||||
|
|||||||
@@ -173,11 +173,11 @@ exports[`<SpaceSettingsVisibilityTab /> for a public space renders addresses sec
|
|||||||
<div
|
<div
|
||||||
class="mx_SettingsSection"
|
class="mx_SettingsSection"
|
||||||
>
|
>
|
||||||
<h2
|
<h3
|
||||||
class="mx_Heading_h3"
|
class="mx_Heading_h4"
|
||||||
>
|
>
|
||||||
Address
|
Address
|
||||||
</h2>
|
</h3>
|
||||||
<div
|
<div
|
||||||
class="mx_SettingsSection_subSections"
|
class="mx_SettingsSection_subSections"
|
||||||
>
|
>
|
||||||
|
|||||||