Skip to content

Commit

Permalink
Put room settings form elements in fieldsets (#7311)
Browse files Browse the repository at this point in the history
* override default fieldset styles

Signed-off-by: Kerry Archibald <kerrya@element.io>

* SettingsFieldset component

Signed-off-by: Kerry Archibald <kerrya@element.io>

* test settings fieldset

Signed-off-by: Kerry Archibald <kerrya@element.io>

* refactor SettingsFlag styles

* use SettingsFieldset in room > securit settings

* use fieldset in urlpreviewsettings

Signed-off-by: Kerry Archibald <kerrya@element.io>

* use SettingsFieldset in AliasSettings

Signed-off-by: Kerry Archibald <kerrya@element.io>

* fieldset in room > roles settings

Signed-off-by: Kerry Archibald <kerrya@element.io>

* css lint

Signed-off-by: Kerry Archibald <kerrya@element.io>

* run i18n

Signed-off-by: Kerry Archibald <kerrya@element.io>

* fussy order

Signed-off-by: Kerry Archibald <kerrya@element.io>

* default export

Signed-off-by: Kerry Archibald <kerrya@element.io>

* fix copyright headers

Signed-off-by: Kerry Archibald <kerrya@element.io>
  • Loading branch information
Kerry committed Dec 9, 2021
1 parent cba92c0 commit 2e3f225
Show file tree
Hide file tree
Showing 16 changed files with 385 additions and 147 deletions.
15 changes: 15 additions & 0 deletions res/css/_common.scss
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,21 @@ input[type=text]:focus, input[type=password]:focus, textarea:focus {
outline: none;
}

// override defaults
fieldset {
display: inline-block;
margin-inline: unset;
padding-block: unset;
padding-inline: unset;
min-inline-size: unset;
border: none;
}

legend {
padding-inline: unset;
border: none;
}

// .mx_textinput is a container for a text input
// + some other controls like buttons, ...
// it has the appearance of a text box so the controls
Expand Down
2 changes: 2 additions & 0 deletions res/css/_components.scss
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@
@import "./views/elements/_RoomAliasField.scss";
@import "./views/elements/_SSOButtons.scss";
@import "./views/elements/_ServerPicker.scss";
@import "./views/elements/_SettingsFlag.scss";
@import "./views/elements/_Slider.scss";
@import "./views/elements/_Spinner.scss";
@import "./views/elements/_StyledCheckbox.scss";
Expand Down Expand Up @@ -269,6 +270,7 @@
@import "./views/settings/_SecureBackupPanel.scss";
@import "./views/settings/_SetIdServer.scss";
@import "./views/settings/_SetIntegrationManager.scss";
@import "./views/settings/_SettingsFieldset.scss";
@import "./views/settings/_SpellCheckLanguages.scss";
@import "./views/settings/_ThemeChoicePanel.scss";
@import "./views/settings/_UpdateCheckButton.scss";
Expand Down
2 changes: 2 additions & 0 deletions res/css/views/dialogs/_SettingsDialog.scss
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ limitations under the License.
box-sizing: border-box;
min-width: 580px;
padding-right: 100px;
display: flex;
flex-direction: column;

// Put some padding on the bottom to avoid the settings tab from
// colliding harshly with the dialog when scrolled down.
Expand Down
43 changes: 43 additions & 0 deletions res/css/views/elements/_SettingsFlag.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
Copyright 2021 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

.mx_SettingsFlag {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
margin-bottom: 4px;

.mx_ToggleSwitch {
flex: 0 0 auto;
}
}

.mx_SettingsFlag_label {
flex: 1;
display: flex;
flex-direction: column;
font-size: $font-14px;
color: $primary-content;
padding-right: 10px;
}

.mx_SettingsFlag_microcopy {
margin-top: 4px;
font-size: $font-12px;
line-height: $font-15px;
color: $secondary-content;
}
46 changes: 46 additions & 0 deletions res/css/views/settings/_SettingsFieldset.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
Copyright 2021 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

.mx_SettingsFieldset {
margin: 10px 80px 10px 0;
box-sizing: content-box;
}

.mx_SettingsFieldset_legend {
font-size: $font-16px;
display: block;
font-weight: $font-semi-bold;
color: $primary-content;
margin-bottom: 10px;
margin-top: 12px;
}

.mx_SettingsFieldset_description {
color: $settings-subsection-fg-color;
font-size: $font-14px;
display: block;
margin-top: 0;
margin-bottom: 10px;

p {
margin-top: 10px;
margin-bottom: 0;

&:first-child {
margin: 0;
}
}
}
10 changes: 6 additions & 4 deletions src/components/views/elements/SettingsFlag.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,16 +93,18 @@ export default class SettingsFlag extends React.Component<IProps, IState> {
} else {
return (
<div className="mx_SettingsFlag">
<span className="mx_SettingsFlag_label">{ label }</span>
<label className="mx_SettingsFlag_label">
<span className="mx_SettingsFlag_labelText">{ label }</span>
{ description && <span className="mx_SettingsFlag_microcopy">
{ description }
</span> }
</label>
<ToggleSwitch
checked={this.state.value}
onChange={this.onChange}
disabled={this.props.disabled || !canChange}
aria-label={label}
/>
{ description && <div className="mx_SettingsFlag_microcopy">
{ description }
</div> }
</div>
);
}
Expand Down
87 changes: 49 additions & 38 deletions src/components/views/room_settings/AliasSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import Modal from "../../../Modal";
import RoomPublishSetting from "./RoomPublishSetting";
import { replaceableComponent } from "../../../utils/replaceableComponent";
import RoomAliasField from "../elements/RoomAliasField";
import SettingsFieldset from "../settings/SettingsFieldset";

import { logger } from "matrix-js-sdk/src/logger";

Expand Down Expand Up @@ -380,54 +381,64 @@ export default class AliasSettings extends React.Component<IProps, IState> {

return (
<div className='mx_AliasSettings'>
<SettingsFieldset
legend={_t("Published Addresses")}
description={<>
{ isSpaceRoom
? _t("Published addresses can be used by anyone on any server to join your space.")
: _t("Published addresses can be used by anyone on any server to join your room.") }
&nbsp;
{ _t("To publish an address, it needs to be set as a local address first.") }
</>}
>
{ /*
<span className='mx_SettingsTab_subheading'>{ _t("Published Addresses") }</span>
<p>
{ isSpaceRoom
? _t("Published addresses can be used by anyone on any server to join your space.")
: _t("Published addresses can be used by anyone on any server to join your room.") }
&nbsp;
{ _t("To publish an address, it needs to be set as a local address first.") }
</p>
{ canonicalAliasSection }
{ this.props.hidePublishSetting
? null
: <RoomPublishSetting
roomId={this.props.roomId}
canSetCanonicalAlias={this.props.canSetCanonicalAlias}
/> }
<datalist id="mx_AliasSettings_altRecommendations">
{ this.getLocalNonAltAliases().map(alias => {
return <option value={alias} key={alias} />;
}) };
</datalist>
<EditableAliasesList
id="roomAltAliases"
items={this.state.altAliases}
newItem={this.state.newAltAlias}
onNewItemChanged={this.onNewAltAliasChanged}
canRemove={this.props.canSetCanonicalAlias}
canEdit={this.props.canSetCanonicalAlias}
onItemAdded={this.onAltAliasAdded}
onItemRemoved={this.onAltAliasDeleted}
suggestionsListId="mx_AliasSettings_altRecommendations"
itemsLabel={_t('Other published addresses:')}
noItemsLabel={_t('No other published addresses yet, add one below')}
placeholder={_t('New published address (e.g. #alias:server)')}
/>
<span className='mx_SettingsTab_subheading mx_AliasSettings_localAliasHeader'>
{ _t("Local Addresses") }
</span>
<p>
{ isSpaceRoom
</p> */ }
{ canonicalAliasSection }
{ this.props.hidePublishSetting
? null
: <RoomPublishSetting
roomId={this.props.roomId}
canSetCanonicalAlias={this.props.canSetCanonicalAlias}
/> }
<datalist id="mx_AliasSettings_altRecommendations">
{ this.getLocalNonAltAliases().map(alias => {
return <option value={alias} key={alias} />;
}) };
</datalist>
<EditableAliasesList
id="roomAltAliases"
items={this.state.altAliases}
newItem={this.state.newAltAlias}
onNewItemChanged={this.onNewAltAliasChanged}
canRemove={this.props.canSetCanonicalAlias}
canEdit={this.props.canSetCanonicalAlias}
onItemAdded={this.onAltAliasAdded}
onItemRemoved={this.onAltAliasDeleted}
suggestionsListId="mx_AliasSettings_altRecommendations"
itemsLabel={_t('Other published addresses:')}
noItemsLabel={_t('No other published addresses yet, add one below')}
placeholder={_t('New published address (e.g. #alias:server)')}
/>
</SettingsFieldset>
<SettingsFieldset legend={_t("Local Addresses")}
description={isSpaceRoom
? _t("Set addresses for this space so users can find this space " +
"through your homeserver (%(localDomain)s)", { localDomain })
: _t("Set addresses for this room so users can find this room " +
"through your homeserver (%(localDomain)s)", { localDomain }) }
</p>
<details onToggle={this.onLocalAliasesToggled} open={this.state.detailsOpen}>
<summary>{ this.state.detailsOpen ? _t('Show less') : _t("Show more") }</summary>
{ localAliasesList }
</details>
"through your homeserver (%(localDomain)s)", { localDomain })}>
<details onToggle={this.onLocalAliasesToggled} open={this.state.detailsOpen}>
<summary>{ this.state.detailsOpen ? _t('Show less') : _t("Show more") }</summary>
{ localAliasesList }
</details>
</SettingsFieldset>

</div>
);
}
Expand Down
20 changes: 11 additions & 9 deletions src/components/views/room_settings/UrlPreviewSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import { SettingLevel } from "../../../settings/SettingLevel";
import { replaceableComponent } from "../../../utils/replaceableComponent";
import { Room } from "matrix-js-sdk/src/models/room";
import SettingsFlag from "../elements/SettingsFlag";
import SettingsFieldset from '../settings/SettingsFieldset';

interface IProps {
room: Room;
Expand Down Expand Up @@ -96,18 +97,19 @@ export default class UrlPreviewSettings extends React.Component<IProps> {
roomId={roomId} />
);

return (
<div>
<div className='mx_SettingsTab_subsectionText'>
{ _t('When someone puts a URL in their message, a URL preview can be shown to give more ' +
const description = <>
<p>
{ _t('When someone puts a URL in their message, a URL preview can be shown to give more ' +
'information about that link such as the title, description, and an image from the website.') }
</div>
<div className='mx_SettingsTab_subsectionText'>
{ previewsForAccount }
</div>
</p>
<p>{ previewsForAccount }</p>
</>;

return (
<SettingsFieldset legend={_t("URL Previews")} description={description}>
{ previewsForRoom }
<label>{ previewsForRoomAccount }</label>
</div>
</SettingsFieldset>
);
}
}
31 changes: 31 additions & 0 deletions src/components/views/settings/SettingsFieldset.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
Copyright 2021 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

import React, { ReactNode, HTMLAttributes } from 'react';
import classNames from 'classnames';

interface Props extends HTMLAttributes<HTMLFieldSetElement> {
// section title
legend: string | ReactNode;
description?: string | ReactNode;
}

const SettingsFieldset: React.FC<Props> = ({ legend, className, children, description, ...rest }) =>
<fieldset {...rest} className={classNames('mx_SettingsFieldset', className)}>
<legend className='mx_SettingsFieldset_legend'>{ legend }</legend>
{ description && <div className='mx_SettingsFieldset_description'>{ description }</div> }
{ children }
</fieldset>;

export default SettingsFieldset;
26 changes: 9 additions & 17 deletions src/components/views/settings/tabs/room/GeneralRoomSettingsTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,15 +66,9 @@ export default class GeneralRoomSettingsTab extends React.Component<IProps, ISta
const canChangeGroups = room.currentState.mayClientSendStateEvent("m.room.related_groups", client);
const groupsEvent = room.currentState.getStateEvents("m.room.related_groups", "");

let urlPreviewSettings = <>
<span className='mx_SettingsTab_subheading'>{ _t("URL Previews") }</span>
<div className='mx_SettingsTab_section'>
<UrlPreviewSettings room={room} />
</div>
</>;
if (!SettingsStore.getValue(UIFeature.URLPreviews)) {
urlPreviewSettings = null;
}
const urlPreviewSettings = SettingsStore.getValue(UIFeature.URLPreviews) ?
<UrlPreviewSettings room={room} /> :
null;

let flairSection;
if (SettingsStore.getValue(UIFeature.Flair)) {
Expand Down Expand Up @@ -110,14 +104,12 @@ export default class GeneralRoomSettingsTab extends React.Component<IProps, ISta
</div>

<div className="mx_SettingsTab_heading">{ _t("Room Addresses") }</div>
<div className='mx_SettingsTab_section mx_SettingsTab_subsectionText'>
<AliasSettings
roomId={this.props.roomId}
canSetCanonicalAlias={canSetCanonical}
canSetAliases={canSetAliases}
canonicalAliasEvent={canonicalAliasEv}
/>
</div>
<AliasSettings
roomId={this.props.roomId}
canSetCanonicalAlias={canSetCanonical}
canSetAliases={canSetAliases}
canonicalAliasEvent={canonicalAliasEv}
/>
<div className="mx_SettingsTab_heading">{ _t("Other") }</div>
{ flairSection }
{ urlPreviewSettings }
Expand Down

0 comments on commit 2e3f225

Please sign in to comment.