Make shared-components tiles render identically outside Element Web - # 3 (#33529)

* Clean up unused app/web styling for ReactionsRow

* Align shared Storybook theme root with app/web

* Move PlayPauseButton styling into shared component

* Use closest compound icon color for all crypto events in both app/web and Storybook

* Updated snapshot

* Experimental strict color matching threshold for playwright

* Experimental color matching threshold for playwright

* Revert color matching threshold for playwright to the default value

* Updated screenshots after matching icon size in audio player with other media body components

* Changed icon color for crypto events accroding to recommendation from the design team

* Use --cpd-color-icon-primary for all crypto events

* Updated snapshots and screenshots after icon color changes

* Updated app/web snapshots and screenshots
This commit is contained in:
rbondesson
2026-05-22 18:00:38 +02:00
committed by GitHub
parent 375fc140a6
commit 7285293b7b
32 changed files with 77 additions and 105 deletions
Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

-2
View File
@@ -93,7 +93,6 @@
@import "./structures/auth/_Registration.pcss";
@import "./structures/auth/_SessionLockStolenView.pcss";
@import "./structures/auth/_SetupEncryptionBody.pcss";
@import "./views/audio_messages/_PlayPauseButton.pcss";
@import "./views/audio_messages/_PlaybackContainer.pcss";
@import "./views/audio_messages/_SeekBar.pcss";
@import "./views/audio_messages/_Waveform.pcss";
@@ -228,7 +227,6 @@
@import "./views/messages/_MPollBody.pcss";
@import "./views/messages/_MStickerBody.pcss";
@import "./views/messages/_MessageActionBar.pcss";
@import "./views/messages/_ReactionsRow.pcss";
@import "./views/messages/_TextualEvent.pcss";
@import "./views/messages/_ThreadActionBar.pcss";
@import "./views/messages/_common_CryptoEvent.pcss";
@@ -1,29 +0,0 @@
/*
Copyright 2024 New Vector Ltd.
Copyright 2021 The Matrix.org Foundation C.I.C.
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE files in the repository root for full details.
*/
.mx_PlayPauseButton {
position: relative;
width: 32px;
height: 32px;
min-width: 32px; /* for when the button is used in a flexbox */
min-height: 32px; /* for when the button is used in a flexbox */
border-radius: 32px;
background-color: $system;
/* !important override compound icon button */
padding: var(--cpd-space-1-5x) !important;
box-sizing: border-box;
svg {
width: 20px;
height: 20px;
}
&[disabled] svg {
opacity: 0.5;
}
}
@@ -1,57 +0,0 @@
/*
Copyright 2019-2024 New Vector Ltd.
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE files in the repository root for full details.
*/
.mx_ReactionsRow {
color: var(--cpd-color-text-primary);
.mx_ReactionsRow_addReactionButton {
display: inline-block;
visibility: hidden; /* show on hover of the .mx_EventTile */
width: 16px;
height: 16px;
padding: var(--cpd-space-1x);
vertical-align: middle;
margin-left: 4px;
margin-right: 4px;
svg {
height: inherit;
width: inherit;
color: $tertiary-content;
}
&.mx_ReactionsRow_addReactionButton_active {
visibility: visible; /* keep showing whilst the context menu is shown */
}
&:hover,
&.mx_ReactionsRow_addReactionButton_active {
svg {
color: $primary-content;
}
}
}
}
.mx_EventTile:hover .mx_ReactionsRow_addReactionButton {
visibility: visible;
}
.mx_ReactionsRow_showAll {
color: $tertiary-content;
&.mx_AccessibleButton_kind_link_inline {
font-size: $font-12px;
line-height: $font-20px;
margin-inline-start: $spacing-4;
vertical-align: middle;
&:hover {
color: $primary-content;
}
}
}
@@ -8,8 +8,4 @@ Please see LICENSE files in the repository root for full details.
.mx_EventTileBubble.mx_cryptoEvent {
margin: var(--EventTileBubble_margin-block) auto;
svg[data-state="supported"] {
color: $header-panel-text-primary-color;
}
}
@@ -750,7 +750,7 @@ exports[`RoomView for a local room in state NEW that is encrypted should match t
style="height: 400px;"
>
<div
class="_container_sq5fu_8 mx_EventTileBubble mx_cryptoEvent _content_m88ar_8"
class="_container_sq5fu_8 mx_EventTileBubble mx_cryptoEvent _content_ufv8a_8"
>
<svg
data-state="supported"
@@ -113,11 +113,11 @@ const ThemeSwitcher: React.FC<{
theme: string;
}> = ({ theme }) => {
useLayoutEffect(() => {
document.documentElement.classList.remove(...allThemesClasses);
document.body.classList.remove(...allThemesClasses);
if (theme !== "system") {
document.documentElement.classList.add(`cpd-theme-${theme}`);
document.body.classList.add(`cpd-theme-${theme}`);
}
return () => document.documentElement.classList.remove(...allThemesClasses);
return () => document.body.classList.remove(...allThemesClasses);
}, [theme]);
return null;
Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 17 KiB

@@ -6,6 +6,22 @@
*/
.button {
position: relative;
width: 32px;
height: 32px;
min-width: 32px;
min-height: 32px;
border-radius: 32px;
background-color: var(--cpd-color-bg-subtle-primary);
padding: var(--cpd-space-1-5x);
box-sizing: border-box;
}
.button svg {
width: 20px;
height: 20px;
}
.button[disabled] svg {
opacity: 0.5;
}
@@ -24,3 +24,4 @@ type Story = StoryObj<typeof meta>;
export const Default: Story = {};
export const Playing: Story = { args: { playing: true } };
export const Disabled: Story = { args: { disabled: true } };
@@ -14,7 +14,7 @@ import { describe, it, expect } from "vitest";
import * as stories from "./PlayPauseButton.stories.tsx";
const { Default, Playing } = composeStories(stories);
const { Default, Playing, Disabled } = composeStories(stories);
describe("PlayPauseButton", () => {
it("renders the button in default state", () => {
@@ -27,6 +27,11 @@ describe("PlayPauseButton", () => {
expect(container).toMatchSnapshot();
});
it("renders the button in disabled state", () => {
const { container } = render(<Disabled />);
expect(container).toMatchSnapshot();
});
it("calls togglePlay when clicked", async () => {
const user = userEvent.setup();
const togglePlay = fn();
@@ -35,4 +40,12 @@ describe("PlayPauseButton", () => {
await user.click(getByRole("button"));
expect(togglePlay).toHaveBeenCalled();
});
it("preserves consumer class names alongside shared styles", () => {
const { getByRole } = render(<Default className="custom-play-pause-button" />);
const button = getByRole("button");
expect(button).toHaveClass("custom-play-pause-button");
expect(button.className).toContain("PlayPauseButton-module_button");
});
});
@@ -6,6 +6,7 @@
*/
import React, { type HTMLAttributes, type JSX, type MouseEventHandler } from "react";
import classNames from "classnames";
import { IconButton } from "@vector-im/compound-web";
import Play from "@vector-im/compound-design-tokens/assets/web/icons/play-solid";
import Pause from "@vector-im/compound-design-tokens/assets/web/icons/pause-solid";
@@ -44,6 +45,7 @@ export function PlayPauseButton({
disabled = false,
playing = false,
togglePlay,
className,
...rest
}: Readonly<PlayPauseButtonProps>): JSX.Element {
const { translate: _t } = useI18n();
@@ -56,7 +58,7 @@ export function PlayPauseButton({
aria-label={label}
tooltip={label}
onClick={togglePlay}
className={styles.button}
className={classNames(styles.button, className)}
disabled={disabled}
{...rest}
>
@@ -32,6 +32,38 @@ exports[`PlayPauseButton > renders the button in default state 1`] = `
</div>
`;
exports[`PlayPauseButton > renders the button in disabled state 1`] = `
<div>
<button
aria-disabled="true"
aria-label="Play"
aria-labelledby="react-use-id-1"
class="_icon-button_1215g_8 PlayPauseButton-module_button"
data-kind="primary"
role="button"
style="--cpd-icon-button-size: 32px;"
tabindex="0"
>
<div
class="_indicator-icon_147l5_17"
style="--cpd-icon-button-size: 100%; --cpd-color-icon-tertiary: var(--cpd-color-icon-disabled);"
>
<svg
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="m8.98 4.677 9.921 5.58c1.36.764 1.36 2.722 0 3.486l-9.92 5.58C7.647 20.073 6 19.11 6 17.58V6.42c0-1.53 1.647-2.493 2.98-1.743"
/>
</svg>
</div>
</button>
</div>
`;
exports[`PlayPauseButton > renders the button in playing state 1`] = `
<div>
<button
@@ -6,7 +6,7 @@
*/
.content svg[data-state="supported"] {
color: inherit;
color: var(--cpd-color-icon-primary);
}
.content svg[data-state="unsupported"] {
@@ -61,7 +61,7 @@ export function MJitsiWidgetEventView({
return (
<EventTileBubble
icon={<VideoCallSolidIcon color="var(--cpd-color-text-primary)" />}
icon={<VideoCallSolidIcon color="var(--cpd-color-icon-primary)" />}
className={className}
title={title}
subtitle={subtitle || undefined}
@@ -6,7 +6,7 @@ exports[`MJitsiWidgetEventView > renders a timestamp 1`] = `
class="EventTileBubble-module_container"
>
<svg
color="var(--cpd-color-text-primary)"
color="var(--cpd-color-icon-primary)"
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
@@ -42,7 +42,7 @@ exports[`MJitsiWidgetEventView > renders the Ended story without a subtitle 1`]
class="EventTileBubble-module_container"
>
<svg
color="var(--cpd-color-text-primary)"
color="var(--cpd-color-icon-primary)"
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
@@ -68,7 +68,7 @@ exports[`MJitsiWidgetEventView > renders the Started story 1`] = `
class="EventTileBubble-module_container"
>
<svg
color="var(--cpd-color-text-primary)"
color="var(--cpd-color-icon-primary)"
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
@@ -99,7 +99,7 @@ exports[`MJitsiWidgetEventView > renders the Updated story 1`] = `
class="EventTileBubble-module_container"
>
<svg
color="var(--cpd-color-text-primary)"
color="var(--cpd-color-icon-primary)"
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
@@ -7,6 +7,6 @@
.content {
svg {
color: var(--cpd-color-text-primary);
color: var(--cpd-color-icon-primary);
}
}