From 57092375c4d688d237c27c1041c3493c2c461c50 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Thu, 21 Apr 2022 10:31:36 +0100 Subject: [PATCH 1/5] Align NetworkDropdown component with new design --- res/css/structures/_RoomDirectory.scss | 19 ++++-- res/css/views/directory/_NetworkDropdown.scss | 59 ++++++++---------- res/img/feather-customised/chevron-down.svg | 2 +- .../context_menu/ContextMenuButton.tsx | 7 ++- .../views/directory/NetworkDropdown.tsx | 61 +++++++++---------- .../views/elements/AccessibleButton.tsx | 19 +++--- src/utils/DirectoryUtils.ts | 7 ++- 7 files changed, 91 insertions(+), 83 deletions(-) diff --git a/res/css/structures/_RoomDirectory.scss b/res/css/structures/_RoomDirectory.scss index 0137db7ebf2..cb94a736b03 100644 --- a/res/css/structures/_RoomDirectory.scss +++ b/res/css/structures/_RoomDirectory.scss @@ -15,7 +15,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -.mx_RoomDirectory_dialogWrapper > .mx_Dialog { +.mx_RoomDirectory_dialogWrapper>.mx_Dialog { max-width: 960px; height: 100%; } @@ -48,6 +48,15 @@ limitations under the License. .mx_RoomDirectory_listheader { display: block; margin-top: 13px; + + .mx_DirectorySearchBox { + margin-left: 0; + margin-right: 0; + } + + .mx_NetworkDropdown { + float: right; + } } .mx_RoomDirectory_searchbox { @@ -66,7 +75,7 @@ limitations under the License. margin-top: 24px; text-align: center; - > h5 { + >h5 { margin: 0; font-weight: $font-semi-bold; font-size: $font-15px; @@ -74,7 +83,7 @@ limitations under the License. color: $primary-content; } - > p { + >p { margin: 40px auto 60px; font-size: $font-14px; line-height: $font-20px; @@ -82,7 +91,7 @@ limitations under the License. max-width: 464px; // easier reading } - > hr { + >hr { margin: 0; border: none; height: 1px; @@ -176,7 +185,7 @@ limitations under the License. padding: 0; } -.mx_RoomDirectory > span { +.mx_RoomDirectory>span { font-size: $font-15px; margin-top: 0; diff --git a/res/css/views/directory/_NetworkDropdown.scss b/res/css/views/directory/_NetworkDropdown.scss index eadca7326bf..1b6a6834644 100644 --- a/res/css/views/directory/_NetworkDropdown.scss +++ b/res/css/views/directory/_NetworkDropdown.scss @@ -15,16 +15,23 @@ limitations under the License. */ .mx_NetworkDropdown { - height: 32px; - position: relative; - width: max-content; - padding-right: 32px; - margin-left: auto; - margin-right: 9px; - margin-top: 12px; - - .mx_AccessibleButton { - width: max-content; + + --gutterSize: 8px; + + border-radius: 8px; + display: inline-flex; + gap: var(--gutterSize); + padding: calc(var(--gutterSize) / 2) var(--gutterSize); + align-items: center; + + border: 1px solid currentColor; + color: $secondary-content; + font-size: $font-12px; + + &:hover, + &.mx_NetworkDropdown--open { + background-color: $system; + border-color: $system; } } @@ -49,7 +56,6 @@ limitations under the License. .mx_NetworkDropdown_server_title { padding: 0 10px; - font-size: $font-15px; font-weight: 600; line-height: $font-20px; margin-bottom: 4px; @@ -139,29 +145,16 @@ limitations under the License. } } -.mx_NetworkDropdown_handle { - position: relative; - - &::after { - content: ""; - position: absolute; - width: 26px; - height: 26px; - right: -27.5px; // - (width: 26 + spacing to align with X above: 1.5) - top: -3px; - mask-repeat: no-repeat; - mask-position: center; - mask-size: contain; - mask-image: url('$(res)/img/feather-customised/chevron-down-thin.svg'); - background-color: $primary-content; - } +.mx_NetworkDropdown_dialog .mx_Dialog { + width: 45vw; +} - .mx_NetworkDropdown_handle_server { - color: $muted-fg-color; - font-size: $font-12px; - } +.mx_NetworkDropdown_chevron { + width: 1em; } -.mx_NetworkDropdown_dialog .mx_Dialog { - width: 45vw; +.mx_NetworkDropdown--open { + .mx_NetworkDropdown_chevron { + transform: rotate(180deg); + } } diff --git a/res/img/feather-customised/chevron-down.svg b/res/img/feather-customised/chevron-down.svg index a091913b42e..c7264474391 100644 --- a/res/img/feather-customised/chevron-down.svg +++ b/res/img/feather-customised/chevron-down.svg @@ -1,3 +1,3 @@ - + diff --git a/src/accessibility/context_menu/ContextMenuButton.tsx b/src/accessibility/context_menu/ContextMenuButton.tsx index e211a4c9333..f69620fabf1 100644 --- a/src/accessibility/context_menu/ContextMenuButton.tsx +++ b/src/accessibility/context_menu/ContextMenuButton.tsx @@ -27,14 +27,14 @@ interface IProps extends React.ComponentProps { } // Semantic component for representing the AccessibleButton which launches a -export const ContextMenuButton: React.FC = ({ +export const ContextMenuButton: React.FC = React.forwardRef(({ label, isExpanded, children, onClick, onContextMenu, ...props -}) => { +}, ref) => { return ( = ({ aria-label={label} aria-haspopup={true} aria-expanded={isExpanded} + ref={ref} > { children } ); -}; +}); diff --git a/src/components/views/directory/NetworkDropdown.tsx b/src/components/views/directory/NetworkDropdown.tsx index cc7a559db0f..afe0de44f85 100644 --- a/src/components/views/directory/NetworkDropdown.tsx +++ b/src/components/views/directory/NetworkDropdown.tsx @@ -17,7 +17,7 @@ limitations under the License. import React, { useEffect, useState } from "react"; import { MatrixError } from "matrix-js-sdk/src/http-api"; -import { IProtocol } from "matrix-js-sdk/src/client"; +import classnames from "classnames"; import { MatrixClientPeg } from '../../../MatrixClientPeg'; import { instanceForInstanceId } from '../../../utils/DirectoryUtils'; @@ -42,15 +42,14 @@ import UIStore from "../../../stores/UIStore"; import { compare } from "../../../utils/strings"; import { SnakedObject } from "../../../utils/SnakedObject"; import { IConfigOptions } from "../../../IConfigOptions"; - -// XXX: We would ideally use a symbol here but we can't since we save this value to localStorage -export const ALL_ROOMS = "ALL_ROOMS"; +import { ALL_ROOMS, Protocols } from "../../../utils/DirectoryUtils"; +import { Icon as ChevronDownIcon } from "../../../../res/img/feather-customised/chevron-down.svg"; const SETTING_NAME = "room_directory_servers"; -const inPlaceOf = (elementRect: Pick) => ({ - right: UIStore.instance.windowWidth - elementRect.right, - top: elementRect.top, +const inPlaceOf = (elementRect: Pick) => ({ + right: UIStore.instance.windowWidth - elementRect.right - 16, + top: elementRect.top + elementRect.height, chevronOffset: 0, chevronFace: ChevronFace.None, }); @@ -85,8 +84,6 @@ const validServer = withValidation({ ], }); -export type Protocols = Record; - interface IProps { protocols: Protocols; selectedServerName: string; @@ -277,35 +274,35 @@ const NetworkDropdown = ({ onOptionChange, protocols = {}, selectedServerName, s ; + } + + let currentValue; + if (selectedInstanceId === ALL_ROOMS) { + currentValue = _t("All rooms"); + } else if (selectedInstanceId) { + const instance = instanceForInstanceId(protocols, selectedInstanceId); + currentValue = _t("%(networkName)s rooms", { + networkName: instance.desc, + }); } else { - let currentValue; - if (selectedInstanceId === ALL_ROOMS) { - currentValue = _t("All rooms"); - } else if (selectedInstanceId) { - const instance = instanceForInstanceId(protocols, selectedInstanceId); - currentValue = _t("%(networkName)s rooms", { - networkName: instance.desc, - }); - } else { - currentValue = _t("Matrix rooms"); - } + currentValue = _t("Matrix rooms"); + } - content = + - - { currentValue } - - ({ selectedServerName }) - - ; - } - - return
+ { currentValue } ({ selectedServerName }) + + { content } -
; + ; }; export default NetworkDropdown; diff --git a/src/components/views/elements/AccessibleButton.tsx b/src/components/views/elements/AccessibleButton.tsx index 3db6d0dfb05..0cdd45cf441 100644 --- a/src/components/views/elements/AccessibleButton.tsx +++ b/src/components/views/elements/AccessibleButton.tsx @@ -69,7 +69,7 @@ interface IAccessibleButtonProps extends React.InputHTMLAttributes { * @param {Object} props react element properties * @returns {Object} rendered react */ -export default function AccessibleButton({ +const AccessibleButton = React.forwardRef(({ element, onClick, children, @@ -81,7 +81,7 @@ export default function AccessibleButton({ onKeyUp, triggerOnMouseDown, ...restProps -}: IProps) { +}: IProps, ref) => { const newProps: IAccessibleButtonProps = restProps; if (disabled) { newProps["aria-disabled"] = true; @@ -133,9 +133,6 @@ export default function AccessibleButton({ }; } - // Pass through the ref - used for keyboard shortcut access to some buttons - newProps.ref = inputRef; - newProps.className = classnames( "mx_AccessibleButton", className, @@ -146,9 +143,17 @@ export default function AccessibleButton({ }, ); + const passedRef = ref ?? inputRef; + // React.createElement expects InputHTMLAttributes - return React.createElement(element, newProps, children); -} + return React.createElement( + element, + { ...newProps, ref: passedRef }, + children, + ); +}); + +export default AccessibleButton; AccessibleButton.defaultProps = { element: 'div' as keyof ReactHTML, diff --git a/src/utils/DirectoryUtils.ts b/src/utils/DirectoryUtils.ts index 89e719f320b..21878035d6f 100644 --- a/src/utils/DirectoryUtils.ts +++ b/src/utils/DirectoryUtils.ts @@ -14,9 +14,12 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { IInstance } from "matrix-js-sdk/src/client"; +import { IInstance, IProtocol } from "matrix-js-sdk/src/client"; -import { Protocols } from "../components/views/directory/NetworkDropdown"; +// XXX: We would ideally use a symbol here but we can't since we save this value to localStorage +export const ALL_ROOMS = "ALL_ROOMS"; + +export type Protocols = Record; // Find a protocol 'instance' with a given instance_id // in the supplied protocols dict From 730b884bc3da6d3988d00c28620dc6902f609ee5 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Thu, 21 Apr 2022 10:55:21 +0100 Subject: [PATCH 2/5] fix lint --- res/css/structures/_RoomDirectory.scss | 8 ++----- res/css/views/directory/_NetworkDropdown.scss | 1 - .../context_menu/ContextMenuButton.tsx | 2 +- src/components/structures/RoomDirectory.tsx | 4 ++-- .../views/directory/NetworkDropdown.tsx | 2 +- .../views/elements/AccessibleButton.tsx | 22 ++++++++----------- 6 files changed, 15 insertions(+), 24 deletions(-) diff --git a/res/css/structures/_RoomDirectory.scss b/res/css/structures/_RoomDirectory.scss index cb94a736b03..56744cf54e0 100644 --- a/res/css/structures/_RoomDirectory.scss +++ b/res/css/structures/_RoomDirectory.scss @@ -15,7 +15,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -.mx_RoomDirectory_dialogWrapper>.mx_Dialog { +.mx_RoomDirectory_dialogWrapper > .mx_Dialog { max-width: 960px; height: 100%; } @@ -63,10 +63,6 @@ limitations under the License. flex: 1 !important; } -.mx_RoomDirectory_listheader .mx_NetworkDropdown { - flex: 0 0 200px; -} - .mx_RoomDirectory_tableWrapper { overflow-y: auto; flex: 1 1 0; @@ -185,7 +181,7 @@ limitations under the License. padding: 0; } -.mx_RoomDirectory>span { +.mx_RoomDirectory > span { font-size: $font-15px; margin-top: 0; diff --git a/res/css/views/directory/_NetworkDropdown.scss b/res/css/views/directory/_NetworkDropdown.scss index 1b6a6834644..d8baaa8f397 100644 --- a/res/css/views/directory/_NetworkDropdown.scss +++ b/res/css/views/directory/_NetworkDropdown.scss @@ -15,7 +15,6 @@ limitations under the License. */ .mx_NetworkDropdown { - --gutterSize: 8px; border-radius: 8px; diff --git a/src/accessibility/context_menu/ContextMenuButton.tsx b/src/accessibility/context_menu/ContextMenuButton.tsx index f69620fabf1..62371ddf0e3 100644 --- a/src/accessibility/context_menu/ContextMenuButton.tsx +++ b/src/accessibility/context_menu/ContextMenuButton.tsx @@ -44,7 +44,7 @@ export const ContextMenuButton: React.FC = React.forwardRef(({ aria-label={label} aria-haspopup={true} aria-expanded={isExpanded} - ref={ref} + inputRef={ref} > { children } diff --git a/src/components/structures/RoomDirectory.tsx b/src/components/structures/RoomDirectory.tsx index 5577bc29e70..9f5ec4fa721 100644 --- a/src/components/structures/RoomDirectory.tsx +++ b/src/components/structures/RoomDirectory.tsx @@ -26,9 +26,9 @@ import dis from "../../dispatcher/dispatcher"; import Modal from "../../Modal"; import { _t } from '../../languageHandler'; import SdkConfig from '../../SdkConfig'; -import { instanceForInstanceId, protocolNameForInstanceId } from '../../utils/DirectoryUtils'; +import { ALL_ROOMS, instanceForInstanceId, protocolNameForInstanceId, Protocols } from '../../utils/DirectoryUtils'; import Analytics from '../../Analytics'; -import NetworkDropdown, { ALL_ROOMS, Protocols } from "../views/directory/NetworkDropdown"; +import NetworkDropdown from "../views/directory/NetworkDropdown"; import SettingsStore from "../../settings/SettingsStore"; import { IDialogProps } from "../views/dialogs/IDialogProps"; import AccessibleButton, { ButtonEvent } from "../views/elements/AccessibleButton"; diff --git a/src/components/views/directory/NetworkDropdown.tsx b/src/components/views/directory/NetworkDropdown.tsx index afe0de44f85..98a8ee6ab03 100644 --- a/src/components/views/directory/NetworkDropdown.tsx +++ b/src/components/views/directory/NetworkDropdown.tsx @@ -296,7 +296,7 @@ const NetworkDropdown = ({ onOptionChange, protocols = {}, selectedServerName, s "mx_NetworkDropdown": true, "mx_NetworkDropdown--open": menuDisplayed, })} - ref={handle} + inputRef={handle} > { currentValue } ({ selectedServerName }) diff --git a/src/components/views/elements/AccessibleButton.tsx b/src/components/views/elements/AccessibleButton.tsx index 0cdd45cf441..0bc82f2f812 100644 --- a/src/components/views/elements/AccessibleButton.tsx +++ b/src/components/views/elements/AccessibleButton.tsx @@ -42,7 +42,7 @@ type AccessibleButtonKind = | 'primary' * implemented exactly like a normal onClick handler. */ interface IProps extends React.InputHTMLAttributes { - inputRef?: React.Ref; + inputRef?: React.RefObject | React.ForwardedRef | React.LegacyRef; element?: keyof ReactHTML; // The kind of button, similar to how Bootstrap works. // See available classes for AccessibleButton for options. @@ -58,7 +58,7 @@ interface IProps extends React.InputHTMLAttributes { } interface IAccessibleButtonProps extends React.InputHTMLAttributes { - ref?: React.Ref; + ref?: React.RefObject | React.ForwardedRef | React.LegacyRef; } /** @@ -69,7 +69,7 @@ interface IAccessibleButtonProps extends React.InputHTMLAttributes { * @param {Object} props react element properties * @returns {Object} rendered react */ -const AccessibleButton = React.forwardRef(({ +export default function AccessibleButton({ element, onClick, children, @@ -81,7 +81,7 @@ const AccessibleButton = React.forwardRef(({ onKeyUp, triggerOnMouseDown, ...restProps -}: IProps, ref) => { +}: IProps) { const newProps: IAccessibleButtonProps = restProps; if (disabled) { newProps["aria-disabled"] = true; @@ -143,17 +143,13 @@ const AccessibleButton = React.forwardRef(({ }, ); - const passedRef = ref ?? inputRef; + if (inputRef) { + newProps.ref = inputRef; + } // React.createElement expects InputHTMLAttributes - return React.createElement( - element, - { ...newProps, ref: passedRef }, - children, - ); -}); - -export default AccessibleButton; + return React.createElement(element, newProps, children); +} AccessibleButton.defaultProps = { element: 'div' as keyof ReactHTML, From 5ac0fe15b2c93aad28007342a72387eb73b0a27c Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Thu, 21 Apr 2022 11:01:22 +0100 Subject: [PATCH 3/5] fix duplicated import --- src/components/structures/RoomDirectory.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/structures/RoomDirectory.tsx b/src/components/structures/RoomDirectory.tsx index 7bda013f92c..77714629fe4 100644 --- a/src/components/structures/RoomDirectory.tsx +++ b/src/components/structures/RoomDirectory.tsx @@ -43,7 +43,6 @@ import PosthogTrackers from "../../PosthogTrackers"; import { PublicRoomTile } from "../views/rooms/PublicRoomTile"; import { getFieldsForThirdPartyLocation, joinRoomByAlias, showRoom } from "../../utils/rooms"; import { GenericError } from "../../utils/error"; -import { ALL_ROOMS, Protocols } from "../../utils/DirectoryUtils"; const LAST_SERVER_KEY = "mx_last_room_directory_server"; const LAST_INSTANCE_KEY = "mx_last_room_directory_instance"; From 532e2ccc5cb75336119f82a3af3923b3bda8f166 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Thu, 21 Apr 2022 12:03:14 +0100 Subject: [PATCH 4/5] Update snapshots --- .../structures/__snapshots__/ThreadPanel-test.tsx.snap | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/components/structures/__snapshots__/ThreadPanel-test.tsx.snap b/test/components/structures/__snapshots__/ThreadPanel-test.tsx.snap index 6c3d1db26d0..12c4dcd32aa 100644 --- a/test/components/structures/__snapshots__/ThreadPanel-test.tsx.snap +++ b/test/components/structures/__snapshots__/ThreadPanel-test.tsx.snap @@ -7,7 +7,7 @@ exports[`ThreadPanel Header expect that All filter for ThreadPanelHeader properl Threads - Show: All threads - + `; @@ -29,7 +29,7 @@ exports[`ThreadPanel Header expect that My filter for ThreadPanelHeader properly Threads - Show: My threads - + `; From b46ba615a2bce030f29435f4b23471f288e475d6 Mon Sep 17 00:00:00 2001 From: Germain Souquet Date: Thu, 21 Apr 2022 13:44:54 +0100 Subject: [PATCH 5/5] fix prop name --- src/accessibility/context_menu/ContextMenuButton.tsx | 1 + src/components/views/directory/NetworkDropdown.tsx | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/accessibility/context_menu/ContextMenuButton.tsx b/src/accessibility/context_menu/ContextMenuButton.tsx index 62371ddf0e3..456ccaa317a 100644 --- a/src/accessibility/context_menu/ContextMenuButton.tsx +++ b/src/accessibility/context_menu/ContextMenuButton.tsx @@ -24,6 +24,7 @@ interface IProps extends React.ComponentProps { label?: string; // whether or not the context menu is currently open isExpanded: boolean; + ref?: React.Ref | React.LegacyRef | React.ForwardedRef; } // Semantic component for representing the AccessibleButton which launches a diff --git a/src/components/views/directory/NetworkDropdown.tsx b/src/components/views/directory/NetworkDropdown.tsx index 98a8ee6ab03..afe0de44f85 100644 --- a/src/components/views/directory/NetworkDropdown.tsx +++ b/src/components/views/directory/NetworkDropdown.tsx @@ -296,7 +296,7 @@ const NetworkDropdown = ({ onOptionChange, protocols = {}, selectedServerName, s "mx_NetworkDropdown": true, "mx_NetworkDropdown--open": menuDisplayed, })} - inputRef={handle} + ref={handle} > { currentValue } ({ selectedServerName })