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

Commit f7a078d

Browse files
authored
Update right panel base card styling to match Compound (#12768)
* Update base card styling to match Compound Signed-off-by: Michael Telatynski <[email protected]> * Update screenshot Signed-off-by: Michael Telatynski <[email protected]> --------- Signed-off-by: Michael Telatynski <[email protected]>
1 parent 5f10ccb commit f7a078d

File tree

24 files changed

+118
-130
lines changed

24 files changed

+118
-130
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@
8181
"@sentry/browser": "^8.0.0",
8282
"@testing-library/react-hooks": "^8.0.1",
8383
"@vector-im/compound-design-tokens": "^1.2.0",
84-
"@vector-im/compound-web": "^5.2.3",
84+
"@vector-im/compound-web": "^5.4.0",
8585
"@zxcvbn-ts/core": "^3.0.4",
8686
"@zxcvbn-ts/language-common": "^3.0.4",
8787
"@zxcvbn-ts/language-en": "^3.0.2",

playwright/e2e/crypto/crypto.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ test.describe("Cryptography", function () {
227227
await verify(page, bob);
228228

229229
// Assert that verified icon is rendered
230-
await page.getByRole("button", { name: "Room members" }).click();
230+
await page.getByTestId("base-card-back-button").click();
231231
await page.locator(".mx_RightPanelTabs").getByText("Info").click();
232232
await expect(page.locator('.mx_RoomSummaryCard_badges [data-kind="success"]')).toContainText("Encrypted");
233233

playwright/e2e/crypto/event-shields.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ test.describe("Cryptography", function () {
132132
// wait for the logout to propagate. Workaround for https://github.com/vector-im/element-web/issues/26263 by repeatedly closing and reopening Bob's user info.
133133
async function awaitOneDevice(iterations = 1) {
134134
const rightPanel = page.locator(".mx_RightPanel");
135-
await rightPanel.getByRole("button", { name: "Room members" }).click();
135+
await rightPanel.getByTestId("base-card-back-button").click();
136136
await rightPanel.getByText("Bob").click();
137137
const sessionCountText = await rightPanel
138138
.locator(".mx_UserInfo_devices")

playwright/e2e/read-receipts/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -538,7 +538,7 @@ class Helpers {
538538
const threadPanel = this.page.locator(".mx_ThreadPanel");
539539
await expect(threadPanel).toBeVisible();
540540
await threadPanel.evaluate(($panel) => {
541-
const $button = $panel.querySelector<HTMLElement>('.mx_BaseCard_back[aria-label="Threads"]');
541+
const $button = $panel.querySelector<HTMLElement>('[data-testid="base-card-back-button"]');
542542
// If the Threads back button is present then click it - the
543543
// threads button can open either threads list or thread panel
544544
if ($button) {

playwright/e2e/right-panel/right-panel.spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ test.describe("RightPanel", () => {
106106
await expect(page.locator(".mx_FilePanel")).toBeVisible();
107107
await expect(page.locator(".mx_FilePanel_empty")).toBeVisible();
108108

109-
await page.getByRole("button", { name: "Room information" }).click();
109+
await page.getByTestId("base-card-back-button").click();
110110
await checkRoomSummaryCard(page, ROOM_NAME);
111111
});
112112

@@ -120,7 +120,7 @@ test.describe("RightPanel", () => {
120120
await expect(page.locator(".mx_UserInfo")).toBeVisible();
121121
await expect(page.locator(".mx_UserInfo_profile").getByText(NAME)).toBeVisible();
122122

123-
await page.getByRole("button", { name: "Room members" }).click();
123+
await page.getByTestId("base-card-back-button").click();
124124
await expect(page.locator(".mx_MemberList")).toBeVisible();
125125

126126
await page.locator(".mx_RightPanelTabs").getByText("Info").click();
@@ -145,7 +145,7 @@ test.describe("RightPanel", () => {
145145
await expect(page.locator(".mx_UserInfo_profile").getByText(NAME)).toBeVisible();
146146
await expect(page.locator(".mx_SpaceScopeHeader").getByText(SPACE_NAME)).toBeVisible();
147147

148-
await page.getByRole("button", { name: "Back" }).click();
148+
await page.getByTestId("base-card-back-button").click();
149149
await expect(page.locator(".mx_MemberList")).toBeVisible();
150150
});
151151
});

playwright/e2e/threads/threads.spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -433,7 +433,7 @@ test.describe("Threads", () => {
433433
await textbox.press("Enter");
434434
await expect(locator.locator(".mx_EventTile_last").getByText("Hello Mr. User")).toBeAttached();
435435
// Close thread
436-
await locator.getByRole("button", { name: "Close" }).click();
436+
await locator.getByTestId("base-card-close-button").click();
437437

438438
// Open existing thread
439439
locator = page
@@ -486,7 +486,7 @@ test.describe("Threads", () => {
486486
await textbox.press("Enter");
487487
await expect(threadPanel.locator(".mx_EventTile_last").getByText(threadMessage)).toBeVisible();
488488
// Close thread
489-
await threadPanel.getByRole("button", { name: "Close" }).click();
489+
await threadPanel.getByTestId("base-card-close-button").click();
490490
};
491491

492492
await sendMessage("Hello Mr. Bot");
@@ -502,7 +502,7 @@ test.describe("Threads", () => {
502502
).toBeVisible();
503503

504504
// Open threads list
505-
await page.locator(".mx_BaseCard_back").click();
505+
await page.getByTestId("base-card-back-button").click();
506506
const rightPanel = page.locator(".mx_RightPanel");
507507
// Check that the threads are listed
508508
await expect(rightPanel.locator(".mx_EventTile").getByText("Hello Mr. User in a thread")).toBeVisible();
Loading
Loading
Loading
Loading
Loading
Loading

res/css/views/right_panel/_BaseCard.pcss

Lines changed: 7 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ limitations under the License.
2727

2828
.mx_BaseCard_header {
2929
height: 64px;
30-
padding: var(--cpd-space-3x);
30+
padding: var(--cpd-space-4x);
3131
box-sizing: border-box;
3232
/* changing the color from $separator to transparent as it is
3333
the best visual output during the transition period. This will be
@@ -36,8 +36,13 @@ limitations under the License.
3636
display: flex;
3737
align-items: center;
3838
justify-content: space-between;
39-
gap: var(--cpd-space-2x);
39+
gap: var(--cpd-space-3x);
4040
flex-shrink: 0;
41+
border-block-end: var(--cpd-border-width-1) solid $separator;
42+
43+
.mx_BaseCard_header_spacer {
44+
flex: 1;
45+
}
4146

4247
> h2 {
4348
margin: 0 44px;
@@ -155,52 +160,6 @@ limitations under the License.
155160
}
156161
}
157162

158-
.mx_BaseCard_back,
159-
.mx_BaseCard_close {
160-
flex-shrink: 0;
161-
position: relative;
162-
/* @TODO(kerrya) background colours here are not semantic
163-
these buttons to be replaced with IconButton after secondary variant is added
164-
https://github.com/vector-im/compound/issues/279 */
165-
background-color: var(--cpd-color-bg-subtle-secondary);
166-
width: var(--BaseCard_header-button-size);
167-
height: var(--BaseCard_header-button-size);
168-
border-radius: 50%;
169-
170-
&:hover {
171-
background-color: var(--cpd-color-bg-subtle-primary);
172-
}
173-
174-
&::before {
175-
content: "";
176-
position: absolute;
177-
height: inherit;
178-
width: inherit;
179-
top: 0;
180-
left: 0;
181-
mask-repeat: no-repeat;
182-
mask-position: center;
183-
mask-size: 20px;
184-
background-color: var(--cpd-color-icon-secondary);
185-
}
186-
}
187-
188-
.mx_BaseCard_back {
189-
order: 0; /* always first! */
190-
&::before {
191-
transform: rotate(90deg);
192-
mask-size: 22px;
193-
mask-image: url("$(res)/img/feather-customised/chevron-down.svg");
194-
}
195-
}
196-
197-
.mx_BaseCard_close {
198-
order: 999; /* always last */
199-
&::before {
200-
mask-image: url("@vector-im/compound-design-tokens/icons/close.svg");
201-
}
202-
}
203-
204163
.mx_ContextualMenu_wrapper.mx_BaseCard_header_title {
205164
.mx_ContextualMenu {
206165
position: initial;
@@ -235,7 +194,3 @@ limitations under the License.
235194
}
236195
}
237196
}
238-
239-
.mx_BaseCard_headerProp {
240-
flex: 1 1 100%;
241-
}

res/themes/dark/css/_dark.pcss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ $overlay-background: var(--cpd-color-alpha-gray-1300);
1414
$panels: var(--cpd-color-bg-subtle-secondary);
1515
$panel-actions: var(--cpd-color-alpha-gray-300);
1616

17-
$separator: var(--cpd-color-alpha-gray-400);
17+
$separator: var(--cpd-color-gray-400);
1818

1919
/* ******************** */
2020

res/themes/legacy-dark/css/_legacy-dark.pcss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ $overlay-background: rgba($background, 0.85);
105105
$panels: rgba($system, 0.9);
106106
$panel-actions: $roomtile-selected-bg-color;
107107

108-
$separator: var(--cpd-color-alpha-gray-400);
108+
$separator: var(--cpd-color-gray-400);
109109

110110
/**
111111
* Creating a `semantic` color scale. This will not be needed with the new

res/themes/legacy-light/css/_legacy-light.pcss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ $overlay-background: rgba($background, 0.85);
163163
$panels: rgba($system, 0.9);
164164
$panel-actions: $roomtile-selected-bg-color;
165165

166-
$separator: var(--cpd-color-alpha-gray-400);
166+
$separator: var(--cpd-color-gray-400);
167167

168168
/* Legacy theme backports */
169169

res/themes/light/css/_light.pcss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ $overlay-background: var(--cpd-color-alpha-gray-1300);
3232
$panels: var(--cpd-color-bg-subtle-secondary);
3333
$panel-actions: var(--cpd-color-alpha-gray-300);
3434

35-
$separator: var(--cpd-color-alpha-gray-400);
35+
$separator: var(--cpd-color-gray-400);
3636

3737
$accent: var(--cpd-color-text-action-accent);
3838
$alert: var(--cpd-color-text-critical-primary);

src/components/structures/ThreadPanel.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ const ThreadPanel: React.FC<IProps> = ({ roomId, onClose, permalinkCreator }) =>
229229
const roomContext = useContext(RoomContext);
230230
const timelinePanel = useRef<TimelinePanel | null>(null);
231231
const card = useRef<HTMLDivElement | null>(null);
232-
const closeButonRef = useRef<HTMLDivElement | null>(null);
232+
const closeButonRef = useRef<HTMLButtonElement | null>(null);
233233

234234
const [filterOption, setFilterOption] = useState<ThreadFilterType>(ThreadFilterType.All);
235235
const [room, setRoom] = useState<Room | null>(null);

src/components/views/right_panel/BaseCard.tsx

Lines changed: 37 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,14 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
1616

17-
import React, { forwardRef, ReactNode, KeyboardEvent, Ref } from "react";
17+
import React, { forwardRef, ReactNode, KeyboardEvent, Ref, MouseEvent } from "react";
1818
import classNames from "classnames";
19+
import { IconButton, Text } from "@vector-im/compound-web";
20+
import { Icon as CloseIcon } from "@vector-im/compound-design-tokens/icons/close.svg";
21+
import { Icon as ChevronLeftIcon } from "@vector-im/compound-design-tokens/icons/chevron-left.svg";
1922

2023
import AutoHideScrollbar from "../../structures/AutoHideScrollbar";
2124
import { _t } from "../../../languageHandler";
22-
import AccessibleButton, { ButtonEvent } from "../elements/AccessibleButton";
2325
import RightPanelStore from "../../../stores/right-panel/RightPanelStore";
2426
import { backLabelForPhase } from "../../../stores/right-panel/RightPanelStorePhases";
2527
import { CardContext } from "./context";
@@ -34,13 +36,13 @@ interface IProps {
3436
ariaLabelledBy?: string;
3537
withoutScrollContainer?: boolean;
3638
closeLabel?: string;
37-
onClose?(ev: ButtonEvent): void;
38-
onBack?(ev: ButtonEvent): void;
39+
onClose?(ev: MouseEvent<HTMLButtonElement>): void;
40+
onBack?(ev: MouseEvent<HTMLButtonElement>): void;
3941
onKeyDown?(ev: KeyboardEvent): void;
4042
cardState?: any;
4143
ref?: Ref<HTMLDivElement>;
4244
// Ref for the 'close' button the the card
43-
closeButtonRef?: Ref<HTMLDivElement>;
45+
closeButtonRef?: Ref<HTMLButtonElement>;
4446
children: ReactNode;
4547
}
4648

@@ -81,43 +83,46 @@ const BaseCard: React.FC<IProps> = forwardRef<HTMLDivElement, IProps>(
8183
) => {
8284
let backButton;
8385
const cardHistory = RightPanelStore.instance.roomPhaseHistory;
84-
if (cardHistory.length > 1) {
86+
if (cardHistory.length > 1 && !hideHeaderButtons) {
8587
const prevCard = cardHistory[cardHistory.length - 2];
86-
const onBackClick = (ev: ButtonEvent): void => {
88+
const onBackClick = (ev: MouseEvent<HTMLButtonElement>): void => {
8789
onBack?.(ev);
8890
RightPanelStore.instance.popCard();
8991
};
9092
const label = backLabelForPhase(prevCard.phase) ?? _t("action|back");
91-
backButton = <AccessibleButton className="mx_BaseCard_back" onClick={onBackClick} title={label} />;
93+
backButton = (
94+
<IconButton
95+
size="28px"
96+
data-testid="base-card-back-button"
97+
onClick={onBackClick}
98+
tooltip={label}
99+
subtleBackground
100+
>
101+
<ChevronLeftIcon />
102+
</IconButton>
103+
);
92104
}
93105

94106
let closeButton;
95-
if (onClose) {
107+
if (onClose && !hideHeaderButtons) {
96108
closeButton = (
97-
<AccessibleButton
109+
<IconButton
110+
size="28px"
98111
data-testid="base-card-close-button"
99-
className="mx_BaseCard_close"
100112
onClick={onClose}
101-
title={closeLabel || _t("action|close")}
102113
ref={closeButtonRef}
103-
/>
114+
tooltip={closeLabel ?? _t("action|close")}
115+
subtleBackground
116+
>
117+
<CloseIcon />
118+
</IconButton>
104119
);
105120
}
106121

107122
if (!withoutScrollContainer) {
108123
children = <AutoHideScrollbar>{children}</AutoHideScrollbar>;
109124
}
110125

111-
let headerButtons: React.ReactElement | undefined;
112-
if (!hideHeaderButtons) {
113-
headerButtons = (
114-
<>
115-
{backButton}
116-
{closeButton}
117-
</>
118-
);
119-
}
120-
121126
const shouldRenderHeader = header || !hideHeaderButtons;
122127

123128
return (
@@ -132,8 +137,15 @@ const BaseCard: React.FC<IProps> = forwardRef<HTMLDivElement, IProps>(
132137
>
133138
{shouldRenderHeader && (
134139
<div className="mx_BaseCard_header">
135-
{headerButtons}
136-
<div className="mx_BaseCard_headerProp">{header}</div>
140+
{backButton}
141+
{typeof header === "string" ? (
142+
<Text size="md" weight="medium" className="mx_BaseCard_header_title">
143+
{header}
144+
</Text>
145+
) : (
146+
header ?? <div className="mx_BaseCard_header_spacer" />
147+
)}
148+
{closeButton}
137149
</div>
138150
)}
139151
{children}

src/components/views/right_panel/UserInfo.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1778,7 +1778,7 @@ const UserInfo: React.FC<IProps> = ({ user, room, onClose, phase = RightPanelPha
17781778
return (
17791779
<BaseCard
17801780
className={classes.join(" ")}
1781-
header={createSpaceScopeHeader(room)}
1781+
header={createSpaceScopeHeader(room) ?? _t("common|profile")}
17821782
onClose={onClose}
17831783
closeLabel={closeLabel}
17841784
cardState={cardState}

0 commit comments

Comments
 (0)