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
|
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 5.8 KiB |
|
Before Width: | Height: | Size: 8.4 KiB After Width: | Height: | Size: 8.4 KiB |
|
Before Width: | Height: | Size: 7.6 KiB After Width: | Height: | Size: 7.5 KiB |
|
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 5.7 KiB |
|
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 5.5 KiB |
|
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
|
Before Width: | Height: | Size: 9.4 KiB After Width: | Height: | Size: 9.4 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
@@ -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;
|
||||
|
||||
|
After Width: | Height: | Size: 17 KiB |
|
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);
|
||||
}
|
||||
}
|
||||
|
||||