Replace LayoutToggle with compound-web Switch component

This commit is contained in:
Half-Shot
2026-04-24 11:47:24 +01:00
parent d6f6542945
commit 44b6db6ff1
6 changed files with 22 additions and 173 deletions

View File

@@ -8,6 +8,12 @@ Please see LICENSE in the repository root for full details.
import { type FC, type JSX, type Ref, useMemo } from "react";
import classNames from "classnames";
import { BehaviorSubject } from "rxjs";
import { Switch } from "@vector-im/compound-web";
import { t } from "i18next";
import {
SpotlightIcon,
GridIcon,
} from "@vector-im/compound-design-tokens/assets/web/icons";
import LogoMark from "../icons/LogoMark.svg?react";
import LogoType from "../icons/LogoType.svg?react";
@@ -23,7 +29,6 @@ import {
type ReactionData,
} from "../button";
import styles from "./CallFooter.module.css";
import { LayoutToggle } from "../room/LayoutToggle";
import { type GridMode } from "../state/CallViewModel/CallViewModel";
export interface AudioOutputSwitcher {
@@ -232,10 +237,16 @@ export const CallFooter: FC<FooterProps> = ({
</div>
{!hideControls && <div className={styles.buttons}>{buttons}</div>}
{setLayoutMode && layoutMode && showLayoutSwitcher && (
<LayoutToggle
<Switch
leftLabel={t("layout_spotlight_label")}
leftValue="spotlight"
leftIcon={SpotlightIcon}
rightLabel={t("layout_grid_label")}
rightValue="grid"
rightIcon={GridIcon}
className={styles.layout}
layout={layoutMode}
setLayout={setLayoutMode}
value={layoutMode}
onChange={setLayoutMode}
/>
)}
</div>

View File

@@ -1,79 +0,0 @@
/*
Copyright 2023, 2024 New Vector Ltd.
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE in the repository root for full details.
*/
.toggle {
padding: 2px;
border: 1px solid var(--cpd-color-border-interactive-secondary);
border-radius: var(--cpd-radius-pill-effect);
background: var(--cpd-color-bg-canvas-default);
display: flex;
position: relative;
}
.toggle input {
appearance: none;
/* Safari puts a margin on these, which is not removed via appearance: none */
margin: 0;
block-size: var(--cpd-space-11x);
inline-size: var(--cpd-space-11x);
cursor: pointer;
border-radius: var(--cpd-radius-pill-effect);
background: var(--cpd-color-bg-action-secondary-rest);
box-shadow: var(--small-drop-shadow);
transition: background-color 0.1s;
}
.toggle svg {
display: block;
position: absolute;
padding: calc(2.5 * var(--cpd-space-1x));
pointer-events: none;
color: var(--cpd-color-icon-primary);
transition: color 0.1s;
}
.toggle svg:nth-child(2) {
inset-inline-start: 2px;
}
.toggle svg:nth-child(4) {
inset-inline-end: 2px;
}
@media (hover: hover) {
.toggle input:hover {
background: var(--cpd-color-bg-action-secondary-hovered);
box-shadow: none;
}
}
.toggle input:active {
background: var(--cpd-color-bg-action-secondary-pressed);
box-shadow: none;
}
.toggle input:checked {
background: var(--cpd-color-bg-action-primary-rest);
}
.toggle input:checked + svg {
color: var(--cpd-color-icon-on-solid-primary);
}
@media (hover: hover) {
.toggle input:checked:hover {
background: var(--cpd-color-bg-action-primary-hovered);
}
}
.toggle input:checked:active {
background: var(--cpd-color-bg-action-primary-pressed);
}
.toggle input:first-child {
margin-inline-end: 5px;
}

View File

@@ -1,25 +0,0 @@
/*
Copyright 2026 Element Creations Ltd.
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE in the repository root for full details.
*/
import { fn } from "storybook/test";
import type { Meta, StoryObj } from "@storybook/react-vite";
import { LayoutToggle } from "./LayoutToggle";
const meta = {
component: LayoutToggle,
} satisfies Meta<typeof LayoutToggle>;
export default meta;
type Story = StoryObj<typeof meta>;
export const Default: Story = {
args: {
layout: "grid",
setLayout: fn(),
},
};

View File

@@ -1,59 +0,0 @@
/*
Copyright 2023, 2024 New Vector Ltd.
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE in the repository root for full details.
*/
import { type ChangeEvent, type FC, useCallback } from "react";
import { useTranslation } from "react-i18next";
import { Tooltip } from "@vector-im/compound-web";
import {
SpotlightIcon,
GridIcon,
} from "@vector-im/compound-design-tokens/assets/web/icons";
import classNames from "classnames";
import styles from "./LayoutToggle.module.css";
export type Layout = "spotlight" | "grid";
type Props = {
layout: Layout;
setLayout: (layout: Layout) => void;
className?: string;
};
export const LayoutToggle: FC<Props> = ({ layout, setLayout, className }) => {
const { t } = useTranslation();
const onChange = useCallback(
(e: ChangeEvent<HTMLInputElement>) => setLayout(e.target.value as Layout),
[setLayout],
);
return (
<form className={classNames(styles.toggle, className)}>
<Tooltip label={t("layout_spotlight_label")}>
<input
type="radio"
name="layout"
value="spotlight"
checked={layout === "spotlight"}
onChange={onChange}
/>
</Tooltip>
<SpotlightIcon aria-hidden width={24} height={24} />
<Tooltip label={t("layout_grid_label")}>
<input
type="radio"
name="layout"
value="grid"
checked={layout === "grid"}
onChange={onChange}
/>
</Tooltip>
<GridIcon aria-hidden width={24} height={24} />
</form>
);
};