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

Commit 9bab356

Browse files
Kerryrichvdh
Kerry
andauthored
Use semantic headings in user settings Labs (#10773)
* allow testids in settings sections * use semantic headings in LabsUserSettingsTab * put back margin var * explicit cast to boolean * Update src/components/views/settings/shared/SettingsSubsection.tsx Co-authored-by: Richard van der Hoff <[email protected]> --------- Co-authored-by: Richard van der Hoff <[email protected]>
1 parent 38c1350 commit 9bab356

File tree

10 files changed

+164
-156
lines changed

10 files changed

+164
-156
lines changed

Diff for: res/css/_components.pcss

-1
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,6 @@
344344
@import "./views/settings/tabs/user/_GeneralUserSettingsTab.pcss";
345345
@import "./views/settings/tabs/user/_HelpUserSettingsTab.pcss";
346346
@import "./views/settings/tabs/user/_KeyboardUserSettingsTab.pcss";
347-
@import "./views/settings/tabs/user/_LabsUserSettingsTab.pcss";
348347
@import "./views/settings/tabs/user/_MjolnirUserSettingsTab.pcss";
349348
@import "./views/settings/tabs/user/_PreferencesUserSettingsTab.pcss";
350349
@import "./views/settings/tabs/user/_SecurityUserSettingsTab.pcss";

Diff for: res/css/components/views/settings/shared/_SettingsSubsection.pcss

+4
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,8 @@ limitations under the License.
4646
margin-bottom: $spacing-8;
4747
}
4848
}
49+
50+
&.mx_SettingsSubsection_contentStretch {
51+
justify-items: stretch;
52+
}
4953
}

Diff for: res/css/views/beta/_BetaCard.pcss

-5
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ limitations under the License.
1515
*/
1616

1717
.mx_BetaCard {
18-
margin-bottom: $spacing-20;
1918
padding: $spacing-24;
2019
background-color: $system;
2120
border-radius: 8px;
@@ -114,10 +113,6 @@ limitations under the License.
114113
}
115114
}
116115
}
117-
118-
&:last-child {
119-
margin-bottom: 0;
120-
}
121116
}
122117

123118
.mx_BetaCard_betaPill {

Diff for: res/css/views/elements/_SettingsFlag.pcss

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ limitations under the License.
2020
align-items: flex-start;
2121
justify-content: space-between;
2222
margin-bottom: 4px;
23+
width: 100%;
2324

2425
.mx_ToggleSwitch {
2526
flex: 0 0 auto;

Diff for: res/css/views/settings/tabs/user/_LabsUserSettingsTab.pcss

-27
This file was deleted.

Diff for: src/components/views/settings/shared/SettingsSubsection.tsx

+17-2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
1616

17+
import classNames from "classnames";
1718
import React, { HTMLAttributes } from "react";
1819

1920
import { SettingsSubsectionHeading } from "./SettingsSubsectionHeading";
@@ -22,6 +23,8 @@ export interface SettingsSubsectionProps extends HTMLAttributes<HTMLDivElement>
2223
heading: string | React.ReactNode;
2324
description?: string | React.ReactNode;
2425
children?: React.ReactNode;
26+
// when true content will be justify-items: stretch, which will make items within the section stretch to full width.
27+
stretchContent?: boolean;
2528
}
2629

2730
export const SettingsSubsectionText: React.FC<HTMLAttributes<HTMLDivElement>> = ({ children, ...rest }) => (
@@ -30,15 +33,27 @@ export const SettingsSubsectionText: React.FC<HTMLAttributes<HTMLDivElement>> =
3033
</div>
3134
);
3235

33-
export const SettingsSubsection: React.FC<SettingsSubsectionProps> = ({ heading, description, children, ...rest }) => (
36+
export const SettingsSubsection: React.FC<SettingsSubsectionProps> = ({
37+
heading,
38+
description,
39+
children,
40+
stretchContent,
41+
...rest
42+
}) => (
3443
<div {...rest} className="mx_SettingsSubsection">
3544
{typeof heading === "string" ? <SettingsSubsectionHeading heading={heading} /> : <>{heading}</>}
3645
{!!description && (
3746
<div className="mx_SettingsSubsection_description">
3847
<SettingsSubsectionText>{description}</SettingsSubsectionText>
3948
</div>
4049
)}
41-
<div className="mx_SettingsSubsection_content">{children}</div>
50+
<div
51+
className={classNames("mx_SettingsSubsection_content", {
52+
mx_SettingsSubsection_contentStretch: !!stretchContent,
53+
})}
54+
>
55+
{children}
56+
</div>
4257
</div>
4358
);
4459

Diff for: src/components/views/settings/tabs/SettingsTab.tsx

+4-4
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1313
See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
16-
import React from "react";
16+
import React, { HTMLAttributes } from "react";
1717

18-
export interface SettingsTabProps {
18+
export interface SettingsTabProps extends Omit<HTMLAttributes<HTMLDivElement>, "className"> {
1919
children?: React.ReactNode;
2020
}
2121

@@ -37,8 +37,8 @@ export interface SettingsTabProps {
3737
* </SettingsTab>
3838
* ```
3939
*/
40-
const SettingsTab: React.FC<SettingsTabProps> = ({ children }) => (
41-
<div className="mx_SettingsTab">
40+
const SettingsTab: React.FC<SettingsTabProps> = ({ children, ...rest }) => (
41+
<div {...rest} className="mx_SettingsTab">
4242
<div className="mx_SettingsTab_sections">{children}</div>
4343
</div>
4444
);

Diff for: src/components/views/settings/tabs/user/LabsUserSettingsTab.tsx

+29-22
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ import BetaCard from "../../../beta/BetaCard";
2525
import SettingsFlag from "../../../elements/SettingsFlag";
2626
import { LabGroup, labGroupNames } from "../../../../../settings/Settings";
2727
import { EnhancedMap } from "../../../../../utils/maps";
28+
import { SettingsSection } from "../../shared/SettingsSection";
29+
import SettingsSubsection, { SettingsSubsectionText } from "../../shared/SettingsSubsection";
30+
import SettingsTab from "../SettingsTab";
2831

2932
export default class LabsUserSettingsTab extends React.Component<{}> {
3033
private readonly labs: string[];
@@ -54,11 +57,11 @@ export default class LabsUserSettingsTab extends React.Component<{}> {
5457
let betaSection: JSX.Element | undefined;
5558
if (this.betas.length) {
5659
betaSection = (
57-
<div data-testid="labs-beta-section" className="mx_SettingsTab_section">
60+
<>
5861
{this.betas.map((f) => (
5962
<BetaCard key={f} featureId={f} />
6063
))}
61-
</div>
64+
</>
6265
);
6366
}
6467

@@ -93,31 +96,35 @@ export default class LabsUserSettingsTab extends React.Component<{}> {
9396
labsSections = (
9497
<>
9598
{sortBy(Array.from(groups.entries()), "0").map(([group, flags]) => (
96-
<div className="mx_SettingsTab_section" key={group} data-testid={`labs-group-${group}`}>
97-
<span className="mx_SettingsTab_subheading">{_t(labGroupNames[group])}</span>
99+
<SettingsSubsection
100+
key={group}
101+
data-testid={`labs-group-${group}`}
102+
heading={_t(labGroupNames[group])}
103+
>
98104
{flags}
99-
</div>
105+
</SettingsSubsection>
100106
))}
101107
</>
102108
);
103109
}
104110

105111
return (
106-
<div className="mx_SettingsTab mx_LabsUserSettingsTab">
107-
<div className="mx_SettingsTab_heading">{_t("Upcoming features")}</div>
108-
<div className="mx_SettingsTab_subsectionText">
109-
{_t(
110-
"What's next for %(brand)s? " +
111-
"Labs are the best way to get things early, " +
112-
"test out new features and help shape them before they actually launch.",
113-
{ brand: SdkConfig.get("brand") },
114-
)}
115-
</div>
116-
{betaSection}
112+
<SettingsTab>
113+
<SettingsSection heading={_t("Upcoming features")}>
114+
<SettingsSubsectionText>
115+
{_t(
116+
"What's next for %(brand)s? " +
117+
"Labs are the best way to get things early, " +
118+
"test out new features and help shape them before they actually launch.",
119+
{ brand: SdkConfig.get("brand") },
120+
)}
121+
</SettingsSubsectionText>
122+
{betaSection}
123+
</SettingsSection>
124+
117125
{labsSections && (
118-
<>
119-
<div className="mx_SettingsTab_heading">{_t("Early previews")}</div>
120-
<div className="mx_SettingsTab_subsectionText">
126+
<SettingsSection heading={_t("Early previews")}>
127+
<SettingsSubsectionText>
121128
{_t(
122129
"Feeling experimental? " +
123130
"Try out our latest ideas in development. " +
@@ -139,11 +146,11 @@ export default class LabsUserSettingsTab extends React.Component<{}> {
139146
},
140147
},
141148
)}
142-
</div>
149+
</SettingsSubsectionText>
143150
{labsSections}
144-
</>
151+
</SettingsSection>
145152
)}
146-
</div>
153+
</SettingsTab>
147154
);
148155
}
149156
}

Diff for: test/components/views/settings/tabs/user/LabsUserSettingsTab-test.tsx

+9-8
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ limitations under the License.
1515
*/
1616

1717
import React from "react";
18-
import { render, waitFor } from "@testing-library/react";
18+
import { render, screen, waitFor } from "@testing-library/react";
1919
import { defer } from "matrix-js-sdk/src/utils";
2020

2121
import LabsUserSettingsTab from "../../../../../../src/components/views/settings/tabs/user/LabsUserSettingsTab";
@@ -51,26 +51,27 @@ describe("<LabsUserSettingsTab />", () => {
5151
});
5252

5353
it("renders settings marked as beta as beta cards", () => {
54-
const { getByTestId } = render(getComponent());
55-
expect(getByTestId("labs-beta-section")).toMatchSnapshot();
54+
render(getComponent());
55+
expect(screen.getByText("Upcoming features").parentElement!).toMatchSnapshot();
5656
});
5757

5858
it("does not render non-beta labs settings when disabled in config", () => {
59-
const { container } = render(getComponent());
59+
render(getComponent());
6060
expect(sdkConfigSpy).toHaveBeenCalledWith("show_labs_settings");
6161

62-
const labsSections = container.getElementsByClassName("mx_SettingsTab_section");
6362
// only section is beta section
64-
expect(labsSections.length).toEqual(1);
63+
expect(screen.queryByText("Early previews")).not.toBeInTheDocument();
6564
});
6665

6766
it("renders non-beta labs settings when enabled in config", () => {
6867
// enable labs
6968
sdkConfigSpy.mockImplementation((configName) => configName === "show_labs_settings");
7069
const { container } = render(getComponent());
7170

72-
const labsSections = container.getElementsByClassName("mx_SettingsTab_section");
73-
expect(labsSections).toHaveLength(11);
71+
// non-beta labs section
72+
expect(screen.getByText("Early previews")).toBeInTheDocument();
73+
const labsSections = container.getElementsByClassName("mx_SettingsSubsection");
74+
expect(labsSections).toHaveLength(10);
7475
});
7576

7677
it("allow setting a labs flag which requires unstable support once support is confirmed", async () => {

0 commit comments

Comments
 (0)