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:
@@ -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;
|
||||
|
||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
BIN
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
@@ -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
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
*/
|
||||
|
||||
.content svg[data-state="supported"] {
|
||||
color: inherit;
|
||||
color: var(--cpd-color-icon-primary);
|
||||
}
|
||||
|
||||
.content svg[data-state="unsupported"] {
|
||||
|
||||
+1
-1
@@ -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}
|
||||
|
||||
+4
-4
@@ -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"
|
||||
|
||||
+1
-1
@@ -7,6 +7,6 @@
|
||||
|
||||
.content {
|
||||
svg {
|
||||
color: var(--cpd-color-text-primary);
|
||||
color: var(--cpd-color-icon-primary);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user