Refine SettingsSection & SettingsTab

This commit is contained in:
Florian Duros 2024-12-04 14:35:24 +01:00
parent c659afa8db
commit 4958dad672
No known key found for this signature in database
GPG key ID: A5BBB4041B493F15
7 changed files with 112 additions and 9 deletions

View file

@ -346,6 +346,7 @@
@import "./views/settings/_SetIdServer.pcss";
@import "./views/settings/_SetIntegrationManager.pcss";
@import "./views/settings/_SettingsFieldset.pcss";
@import "./views/settings/_SettingsHeader.pcss";
@import "./views/settings/_SpellCheckLanguages.pcss";
@import "./views/settings/_ThemeChoicePanel.pcss";
@import "./views/settings/_UpdateCheckButton.pcss";

View file

@ -0,0 +1,19 @@
/*
* Copyright 2024 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
* Please see LICENSE files in the repository root for full details.
*/
.mx_SettingsHeader {
display: flex;
align-items: center;
gap: var(--cpd-space-2x);
/* Override margin from common.pcss */
margin: 0;
> span {
font: var(--cpd-font-body-sm-medium);
color: var(--cpd-color-text-action-accent);
}
}

View file

@ -15,6 +15,20 @@ Please see LICENSE files in the repository root for full details.
a {
color: $links;
}
&.mx_SettingsSection_newUi {
display: flex;
flex-direction: column;
gap: var(--cpd-space-6x);
align-items: start;
}
.mx_SettingsSection_header {
display: flex;
flex-direction: column;
gap: var(--cpd-space-3x);
color: var(--cpd-color-text-secondary);
}
}
.mx_SettingsSection_subSections {

View file

@ -0,0 +1,33 @@
/*
* Copyright 2024 New Vector Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
* Please see LICENSE files in the repository root for full details.
*/
import React, { JSX } from "react";
import { Heading } from "@vector-im/compound-web";
import { _t } from "../../../languageHandler";
/**
* The heading for a settings section.
*/
interface SettingsHeaderProps {
/**
* Whether the user has a recommended tag.
*/
hasRecommendedTag?: boolean;
/**
* The label for the header.
*/
label: string;
}
export function SettingsHeader({ hasRecommendedTag = false, label }: SettingsHeaderProps): JSX.Element {
return (
<Heading className="mx_SettingsHeader" as="h2" size="sm" weight="semibold">
{label} {hasRecommendedTag && <span>{_t("common|recommended")}</span>}
</Heading>
);
}

View file

@ -10,19 +10,24 @@ import classnames from "classnames";
import React, { HTMLAttributes } from "react";
import Heading from "../../typography/Heading";
import { SettingsHeader } from "../SettingsHeader";
export interface SettingsSectionProps extends HTMLAttributes<HTMLDivElement> {
heading?: string | React.ReactNode;
subHeading?: string | React.ReactNode;
children?: React.ReactNode;
legacy?: boolean;
}
function renderHeading(heading: string | React.ReactNode | undefined): React.ReactNode | undefined {
function renderHeading(heading: string | React.ReactNode | undefined, legacy: boolean): React.ReactNode | undefined {
switch (typeof heading) {
case "string":
return (
return legacy ? (
<Heading as="h2" size="3">
{heading}
</Heading>
) : (
<SettingsHeader label={heading} />
);
case "undefined":
return undefined;
@ -31,6 +36,15 @@ function renderHeading(heading: string | React.ReactNode | undefined): React.Rea
}
}
function renderSubHeading(subHeading: string | React.ReactNode | undefined): React.ReactNode | undefined {
switch (typeof subHeading) {
case "undefined":
return undefined;
default:
return subHeading;
}
}
/**
* A section of settings content
* A SettingsTab may contain one or more SettingsSections
@ -48,9 +62,29 @@ function renderHeading(heading: string | React.ReactNode | undefined): React.Rea
* </SettingsTab>
* ```
*/
export const SettingsSection: React.FC<SettingsSectionProps> = ({ className, heading, children, ...rest }) => (
<div {...rest} className={classnames("mx_SettingsSection", className)}>
{renderHeading(heading)}
<div className="mx_SettingsSection_subSections">{children}</div>
export const SettingsSection: React.FC<SettingsSectionProps> = ({
className,
heading,
subHeading,
legacy = true,
children,
...rest
}) => (
<div
{...rest}
className={classnames("mx_SettingsSection", className, {
mx_SettingsSection_newUi: !legacy,
})}
>
{heading &&
(subHeading ? (
<div className="mx_SettingsSection_header">
{renderHeading(heading, legacy)}
{renderSubHeading(subHeading)}
</div>
) : (
renderHeading(heading, legacy)
))}
{legacy ? <div className="mx_SettingsSection_subSections">{children}</div> : children}
</div>
);

View file

@ -6,8 +6,9 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
Please see LICENSE files in the repository root for full details.
*/
import React, { HTMLAttributes } from "react";
import classNames from "classnames";
export interface SettingsTabProps extends Omit<HTMLAttributes<HTMLDivElement>, "className"> {
export interface SettingsTabProps extends HTMLAttributes<HTMLDivElement> {
children?: React.ReactNode;
}
@ -29,8 +30,8 @@ export interface SettingsTabProps extends Omit<HTMLAttributes<HTMLDivElement>, "
* </SettingsTab>
* ```
*/
const SettingsTab: React.FC<SettingsTabProps> = ({ children, ...rest }) => (
<div {...rest} className="mx_SettingsTab">
const SettingsTab: React.FC<SettingsTabProps> = ({ children, className, ...rest }) => (
<div {...rest} className={classNames("mx_SettingsTab", className)}>
<div className="mx_SettingsTab_sections">{children}</div>
</div>
);

View file

@ -542,6 +542,7 @@
"qr_code": "QR Code",
"random": "Random",
"reactions": "Reactions",
"recommended": "Recommended",
"report_a_bug": "Report a bug",
"room": "Room",
"room_name": "Room name",