Add more menu stories and update tests

This commit is contained in:
David Langley 2026-01-30 15:54:06 +00:00
parent de02b11c65
commit 628f708ab5
5 changed files with 882 additions and 166 deletions

View File

@ -0,0 +1,154 @@
/*
* Copyright 2026 Element Creations 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.
*/
import React, { type JSX } from "react";
import { fn } from "storybook/test";
import { userEvent, within } from "storybook/test";
import type { Meta, StoryObj } from "@storybook/react-vite";
import { RoomListItemMoreOptionsMenu } from "./RoomListItemMoreOptionsMenu";
import { type RoomListItemSnapshot, type RoomListItemActions } from "./RoomListItem";
import { useMockedViewModel } from "../../viewmodel";
import { defaultSnapshot } from "./default-snapshot";
type MoreOptionsMenuProps = RoomListItemSnapshot & RoomListItemActions;
// Wrapper component that creates a mocked ViewModel
const MoreOptionsMenuWrapper = ({
onOpenRoom,
onMarkAsRead,
onMarkAsUnread,
onToggleFavorite,
onToggleLowPriority,
onInvite,
onCopyRoomLink,
onLeaveRoom,
onSetRoomNotifState,
...rest
}: MoreOptionsMenuProps): JSX.Element => {
const vm = useMockedViewModel(rest, {
onOpenRoom,
onMarkAsRead,
onMarkAsUnread,
onToggleFavorite,
onToggleLowPriority,
onInvite,
onCopyRoomLink,
onLeaveRoom,
onSetRoomNotifState,
});
return <RoomListItemMoreOptionsMenu vm={vm} />;
};
const meta = {
title: "Room List/RoomListItem/MoreOptionsMenu",
component: MoreOptionsMenuWrapper,
tags: ["autodocs"],
decorators: [
(Story) => (
<div style={{ padding: "16px" }}>
<Story />
</div>
),
],
args: {
...defaultSnapshot,
showMoreOptionsMenu: true,
onOpenRoom: fn(),
onMarkAsRead: fn(),
onMarkAsUnread: fn(),
onToggleFavorite: fn(),
onToggleLowPriority: fn(),
onInvite: fn(),
onCopyRoomLink: fn(),
onLeaveRoom: fn(),
onSetRoomNotifState: fn(),
},
} satisfies Meta<typeof MoreOptionsMenuWrapper>;
export default meta;
type Story = StoryObj<typeof meta>;
// Closed state
export const Default: Story = {
args: {
canMarkAsRead: false,
canMarkAsUnread: true,
isFavourite: false,
isLowPriority: false,
},
};
// Open state - default (can mark as unread, favourite off, low priority off)
export const Open: Story = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const trigger = canvas.getByRole("button", { name: "More Options" });
await userEvent.click(trigger);
},
};
// Open state - can mark as read (has unread messages)
export const OpenCanMarkAsRead: Story = {
args: {
canMarkAsRead: true,
canMarkAsUnread: false,
},
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const trigger = canvas.getByRole("button", { name: "More Options" });
await userEvent.click(trigger);
},
};
// Open state - favourite enabled
export const OpenFavouriteOn: Story = {
args: {
isFavourite: true,
},
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const trigger = canvas.getByRole("button", { name: "More Options" });
await userEvent.click(trigger);
},
};
// Open state - low priority enabled
export const OpenLowPriorityOn: Story = {
args: {
isLowPriority: true,
},
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const trigger = canvas.getByRole("button", { name: "More Options" });
await userEvent.click(trigger);
},
};
// Open state - without invite option (DM or no permission)
export const OpenWithoutInvite: Story = {
args: {
canInvite: false,
},
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const trigger = canvas.getByRole("button", { name: "More Options" });
await userEvent.click(trigger);
},
};
// Open state - without copy room link (DM room)
export const OpenWithoutCopyLink: Story = {
args: {
canCopyRoomLink: false,
},
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const trigger = canvas.getByRole("button", { name: "More Options" });
await userEvent.click(trigger);
},
};

View File

@ -5,223 +5,161 @@
* Please see LICENSE files in the repository root for full details.
*/
import React, { type JSX } from "react";
import React from "react";
import { render, screen } from "@test-utils";
import userEvent from "@testing-library/user-event";
import { describe, it, expect, vi } from "vitest";
import { composeStories } from "@storybook/react-vite";
import { describe, it, expect } from "vitest";
import { RoomListItemMoreOptionsMenu } from "./RoomListItemMoreOptionsMenu";
import { useMockedViewModel } from "../../viewmodel";
import type { RoomListItemSnapshot } from "./RoomListItem";
import { defaultSnapshot } from "./default-snapshot";
import * as stories from "./RoomListItemMoreOptionsMenu.stories";
describe("<RoomListItemMoreOptionsMenu />", () => {
const mockCallbacks = {
onOpenRoom: vi.fn(),
onMarkAsRead: vi.fn(),
onMarkAsUnread: vi.fn(),
onToggleFavorite: vi.fn(),
onToggleLowPriority: vi.fn(),
onInvite: vi.fn(),
onCopyRoomLink: vi.fn(),
onLeaveRoom: vi.fn(),
onSetRoomNotifState: vi.fn(),
};
const { Default, Open, OpenCanMarkAsRead, OpenFavouriteOn, OpenLowPriorityOn, OpenWithoutInvite, OpenWithoutCopyLink } =
composeStories(stories);
const renderMenu = (overrides: Partial<RoomListItemSnapshot> = {}): ReturnType<typeof render> => {
const TestComponent = (): JSX.Element => {
const vm = useMockedViewModel(
{
...defaultSnapshot,
showMoreOptionsMenu: true,
showNotificationMenu: false,
...overrides,
} as RoomListItemSnapshot,
mockCallbacks,
);
return <RoomListItemMoreOptionsMenu vm={vm} />;
};
return render(<TestComponent />);
};
it("should render the more options button", () => {
renderMenu();
expect(screen.getByRole("button", { name: "More Options" })).toBeInTheDocument();
describe("<RoomListItemMoreOptionsMenu /> stories", () => {
it("renders Default story (closed)", () => {
const { container } = render(<Default />);
expect(container).toMatchSnapshot();
});
it("should open menu when clicked", async () => {
const user = userEvent.setup();
renderMenu();
const button = screen.getByRole("button", { name: "More Options" });
await user.click(button);
expect(screen.getByRole("menu")).toBeInTheDocument();
it("renders Open story", async () => {
const { container } = render(<Open />);
await Open.play?.({ canvasElement: container });
expect(container).toMatchSnapshot();
});
it("should show mark as read option when canMarkAsRead is true", async () => {
const user = userEvent.setup();
renderMenu({ canMarkAsRead: true });
const button = screen.getByRole("button", { name: "More Options" });
await user.click(button);
expect(screen.getByRole("menuitem", { name: "Mark as read" })).toBeInTheDocument();
it("renders OpenCanMarkAsRead story", async () => {
const { container } = render(<OpenCanMarkAsRead />);
await OpenCanMarkAsRead.play?.({ canvasElement: container });
expect(container).toMatchSnapshot();
});
it("should not show mark as read option when canMarkAsRead is false", async () => {
const user = userEvent.setup();
renderMenu({ canMarkAsRead: false });
it("renders OpenFavouriteOn story", async () => {
const { container } = render(<OpenFavouriteOn />);
await OpenFavouriteOn.play?.({ canvasElement: container });
expect(container).toMatchSnapshot();
});
const button = screen.getByRole("button", { name: "More Options" });
await user.click(button);
it("renders OpenLowPriorityOn story", async () => {
const { container } = render(<OpenLowPriorityOn />);
await OpenLowPriorityOn.play?.({ canvasElement: container });
expect(container).toMatchSnapshot();
});
it("renders OpenWithoutInvite story", async () => {
const { container } = render(<OpenWithoutInvite />);
await OpenWithoutInvite.play?.({ canvasElement: container });
expect(container).toMatchSnapshot();
});
it("renders OpenWithoutCopyLink story", async () => {
const { container } = render(<OpenWithoutCopyLink />);
await OpenWithoutCopyLink.play?.({ canvasElement: container });
expect(container).toMatchSnapshot();
});
it("should show mark as unread by default", async () => {
const { container } = render(<Open />);
await Open.play?.({ canvasElement: container });
expect(screen.getByRole("menuitem", { name: "Mark as unread" })).toBeInTheDocument();
expect(screen.queryByRole("menuitem", { name: "Mark as read" })).not.toBeInTheDocument();
});
it("should call onMarkAsRead when mark as read clicked", async () => {
const user = userEvent.setup();
renderMenu({ canMarkAsRead: true });
it("should show mark as read when canMarkAsRead is true", async () => {
const { container } = render(<OpenCanMarkAsRead />);
await OpenCanMarkAsRead.play?.({ canvasElement: container });
const button = screen.getByRole("button", { name: "More Options" });
await user.click(button);
const markAsReadOption = screen.getByRole("menuitem", { name: "Mark as read" });
await user.click(markAsReadOption);
expect(mockCallbacks.onMarkAsRead).toHaveBeenCalled();
expect(screen.getByRole("menuitem", { name: "Mark as read" })).toBeInTheDocument();
expect(screen.queryByRole("menuitem", { name: "Mark as unread" })).not.toBeInTheDocument();
});
it("should show mark as unread option when canMarkAsUnread is true", async () => {
const user = userEvent.setup();
renderMenu({ canMarkAsUnread: true });
it("should show favourite as checked when isFavourite is true", async () => {
const { container } = render(<OpenFavouriteOn />);
await OpenFavouriteOn.play?.({ canvasElement: container });
const button = screen.getByRole("button", { name: "More Options" });
await user.click(button);
expect(screen.getByRole("menuitem", { name: "Mark as unread" })).toBeInTheDocument();
const favouriteOption = screen.getByRole("menuitemcheckbox", { name: "Favourited" });
expect(favouriteOption).toHaveAttribute("aria-checked", "true");
});
it("should call onMarkAsUnread when mark as unread clicked", async () => {
const user = userEvent.setup();
renderMenu({ canMarkAsUnread: true });
it("should show favourite as unchecked by default", async () => {
const { container } = render(<Open />);
await Open.play?.({ canvasElement: container });
const button = screen.getByRole("button", { name: "More Options" });
await user.click(button);
const markAsUnreadOption = screen.getByRole("menuitem", { name: "Mark as unread" });
await user.click(markAsUnreadOption);
expect(mockCallbacks.onMarkAsUnread).toHaveBeenCalled();
const favouriteOption = screen.getByRole("menuitemcheckbox", { name: "Favourited" });
expect(favouriteOption).toHaveAttribute("aria-checked", "false");
});
it("should show favorite option and call onToggleFavorite", async () => {
const user = userEvent.setup();
renderMenu({ isFavourite: false });
const button = screen.getByRole("button", { name: "More Options" });
await user.click(button);
const favoriteOption = screen.getByRole("menuitemcheckbox", { name: "Favourited" });
expect(favoriteOption).toBeInTheDocument();
expect(favoriteOption).toHaveAttribute("aria-checked", "false");
await user.click(favoriteOption);
expect(mockCallbacks.onToggleFavorite).toHaveBeenCalled();
});
it("should show favorite as checked when isFavourite is true", async () => {
const user = userEvent.setup();
renderMenu({ isFavourite: true });
const button = screen.getByRole("button", { name: "More Options" });
await user.click(button);
const favoriteOption = screen.getByRole("menuitemcheckbox", { name: "Favourited" });
expect(favoriteOption).toHaveAttribute("aria-checked", "true");
});
it("should show low priority option and call onToggleLowPriority", async () => {
const user = userEvent.setup();
renderMenu({ isLowPriority: false });
const button = screen.getByRole("button", { name: "More Options" });
await user.click(button);
it("should show low priority as checked when isLowPriority is true", async () => {
const { container } = render(<OpenLowPriorityOn />);
await OpenLowPriorityOn.play?.({ canvasElement: container });
const lowPriorityOption = screen.getByRole("menuitemcheckbox", { name: "Low priority" });
expect(lowPriorityOption).toBeInTheDocument();
expect(lowPriorityOption).toHaveAttribute("aria-checked", "false");
await user.click(lowPriorityOption);
expect(mockCallbacks.onToggleLowPriority).toHaveBeenCalled();
expect(lowPriorityOption).toHaveAttribute("aria-checked", "true");
});
it("should show invite option when canInvite is true", async () => {
const user = userEvent.setup();
renderMenu({ canInvite: true });
it("should show low priority as unchecked by default", async () => {
const { container } = render(<Open />);
await Open.play?.({ canvasElement: container });
const button = screen.getByRole("button", { name: "More Options" });
await user.click(button);
const lowPriorityOption = screen.getByRole("menuitemcheckbox", { name: "Low priority" });
expect(lowPriorityOption).toHaveAttribute("aria-checked", "false");
});
it("should show invite option by default", async () => {
const { container } = render(<Open />);
await Open.play?.({ canvasElement: container });
expect(screen.getByRole("menuitem", { name: "Invite" })).toBeInTheDocument();
});
it("should call onInvite when invite clicked", async () => {
const user = userEvent.setup();
renderMenu({ canInvite: true });
it("should hide invite option when canInvite is false", async () => {
const { container } = render(<OpenWithoutInvite />);
await OpenWithoutInvite.play?.({ canvasElement: container });
const button = screen.getByRole("button", { name: "More Options" });
await user.click(button);
const inviteOption = screen.getByRole("menuitem", { name: "Invite" });
await user.click(inviteOption);
expect(mockCallbacks.onInvite).toHaveBeenCalled();
expect(screen.queryByRole("menuitem", { name: "Invite" })).not.toBeInTheDocument();
});
it("should show copy link option when canCopyRoomLink is true", async () => {
const user = userEvent.setup();
renderMenu({ canCopyRoomLink: true });
const button = screen.getByRole("button", { name: "More Options" });
await user.click(button);
it("should show copy room link by default", async () => {
const { container } = render(<Open />);
await Open.play?.({ canvasElement: container });
expect(screen.getByRole("menuitem", { name: "Copy room link" })).toBeInTheDocument();
});
it("should call onCopyRoomLink when copy link clicked", async () => {
const user = userEvent.setup();
renderMenu({ canCopyRoomLink: true });
it("should hide copy room link when canCopyRoomLink is false", async () => {
const { container } = render(<OpenWithoutCopyLink />);
await OpenWithoutCopyLink.play?.({ canvasElement: container });
const button = screen.getByRole("button", { name: "More Options" });
await user.click(button);
const copyLinkOption = screen.getByRole("menuitem", { name: "Copy room link" });
await user.click(copyLinkOption);
expect(mockCallbacks.onCopyRoomLink).toHaveBeenCalled();
expect(screen.queryByRole("menuitem", { name: "Copy room link" })).not.toBeInTheDocument();
});
it("should show leave room option", async () => {
const user = userEvent.setup();
renderMenu();
const button = screen.getByRole("button", { name: "More Options" });
await user.click(button);
it("should always show leave room option", async () => {
const { container } = render(<Open />);
await Open.play?.({ canvasElement: container });
expect(screen.getByRole("menuitem", { name: "Leave room" })).toBeInTheDocument();
});
it("should call onLeaveRoom when leave room clicked", async () => {
it("should call onToggleFavorite when favourite is clicked", async () => {
const user = userEvent.setup();
renderMenu();
const { container } = render(<Open />);
await Open.play?.({ canvasElement: container });
const button = screen.getByRole("button", { name: "More Options" });
await user.click(button);
const favouriteOption = screen.getByRole("menuitemcheckbox", { name: "Favourited" });
await user.click(favouriteOption);
const leaveRoomOption = screen.getByRole("menuitem", { name: "Leave room" });
await user.click(leaveRoomOption);
expect(Open.args.onToggleFavorite).toHaveBeenCalled();
});
expect(mockCallbacks.onLeaveRoom).toHaveBeenCalled();
it("should call onToggleLowPriority when low priority is clicked", async () => {
const user = userEvent.setup();
const { container } = render(<Open />);
await Open.play?.({ canvasElement: container });
const lowPriorityOption = screen.getByRole("menuitemcheckbox", { name: "Low priority" });
await user.click(lowPriorityOption);
expect(Open.args.onToggleLowPriority).toHaveBeenCalled();
});
});

View File

@ -0,0 +1,312 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`<RoomListItemMoreOptionsMenu /> stories > renders Default story (closed) 1`] = `
<div>
<div
style="padding: 16px;"
>
<button
aria-disabled="false"
aria-expanded="false"
aria-haspopup="menu"
aria-label="More Options"
aria-labelledby="_r_2_"
class="_icon-button_1215g_8"
data-kind="primary"
data-state="closed"
id="radix-_r_0_"
role="button"
style="--cpd-icon-button-size: 24px;"
tabindex="0"
type="button"
>
<div
class="_indicator-icon_147l5_17"
style="--cpd-icon-button-size: 100%;"
>
<svg
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M6 14q-.824 0-1.412-.588A1.93 1.93 0 0 1 4 12q0-.825.588-1.412A1.93 1.93 0 0 1 6 10q.824 0 1.412.588Q8 11.175 8 12t-.588 1.412A1.93 1.93 0 0 1 6 14m6 0q-.825 0-1.412-.588A1.93 1.93 0 0 1 10 12q0-.825.588-1.412A1.93 1.93 0 0 1 12 10q.825 0 1.412.588Q14 11.175 14 12t-.588 1.412A1.93 1.93 0 0 1 12 14m6 0q-.824 0-1.413-.588A1.93 1.93 0 0 1 16 12q0-.825.587-1.412A1.93 1.93 0 0 1 18 10q.824 0 1.413.588Q20 11.175 20 12t-.587 1.412A1.93 1.93 0 0 1 18 14"
/>
</svg>
</div>
</button>
</div>
</div>
`;
exports[`<RoomListItemMoreOptionsMenu /> stories > renders Open story 1`] = `
<div
aria-hidden="true"
data-aria-hidden="true"
>
<div
style="padding: 16px;"
>
<button
aria-controls="radix-_r_9_"
aria-disabled="false"
aria-expanded="true"
aria-haspopup="menu"
aria-label="More Options"
aria-labelledby="_r_a_"
class="_icon-button_1215g_8"
data-kind="primary"
data-state="open"
id="radix-_r_8_"
role="button"
style="--cpd-icon-button-size: 24px;"
tabindex="0"
type="button"
>
<div
class="_indicator-icon_147l5_17"
style="--cpd-icon-button-size: 100%;"
>
<svg
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M6 14q-.824 0-1.412-.588A1.93 1.93 0 0 1 4 12q0-.825.588-1.412A1.93 1.93 0 0 1 6 10q.824 0 1.412.588Q8 11.175 8 12t-.588 1.412A1.93 1.93 0 0 1 6 14m6 0q-.825 0-1.412-.588A1.93 1.93 0 0 1 10 12q0-.825.588-1.412A1.93 1.93 0 0 1 12 10q.825 0 1.412.588Q14 11.175 14 12t-.588 1.412A1.93 1.93 0 0 1 12 14m6 0q-.824 0-1.413-.588A1.93 1.93 0 0 1 16 12q0-.825.587-1.412A1.93 1.93 0 0 1 18 10q.824 0 1.413.588Q20 11.175 20 12t-.587 1.412A1.93 1.93 0 0 1 18 14"
/>
</svg>
</div>
</button>
</div>
</div>
`;
exports[`<RoomListItemMoreOptionsMenu /> stories > renders OpenCanMarkAsRead story 1`] = `
<div
aria-hidden="true"
data-aria-hidden="true"
>
<div
style="padding: 16px;"
>
<button
aria-controls="radix-_r_q_"
aria-disabled="false"
aria-expanded="true"
aria-haspopup="menu"
aria-label="More Options"
aria-labelledby="_r_r_"
class="_icon-button_1215g_8"
data-kind="primary"
data-state="open"
id="radix-_r_p_"
role="button"
style="--cpd-icon-button-size: 24px;"
tabindex="0"
type="button"
>
<div
class="_indicator-icon_147l5_17"
style="--cpd-icon-button-size: 100%;"
>
<svg
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M6 14q-.824 0-1.412-.588A1.93 1.93 0 0 1 4 12q0-.825.588-1.412A1.93 1.93 0 0 1 6 10q.824 0 1.412.588Q8 11.175 8 12t-.588 1.412A1.93 1.93 0 0 1 6 14m6 0q-.825 0-1.412-.588A1.93 1.93 0 0 1 10 12q0-.825.588-1.412A1.93 1.93 0 0 1 12 10q.825 0 1.412.588Q14 11.175 14 12t-.588 1.412A1.93 1.93 0 0 1 12 14m6 0q-.824 0-1.413-.588A1.93 1.93 0 0 1 16 12q0-.825.587-1.412A1.93 1.93 0 0 1 18 10q.824 0 1.413.588Q20 11.175 20 12t-.587 1.412A1.93 1.93 0 0 1 18 14"
/>
</svg>
</div>
</button>
</div>
</div>
`;
exports[`<RoomListItemMoreOptionsMenu /> stories > renders OpenFavouriteOn story 1`] = `
<div
aria-hidden="true"
data-aria-hidden="true"
>
<div
style="padding: 16px;"
>
<button
aria-controls="radix-_r_1b_"
aria-disabled="false"
aria-expanded="true"
aria-haspopup="menu"
aria-label="More Options"
aria-labelledby="_r_1c_"
class="_icon-button_1215g_8"
data-kind="primary"
data-state="open"
id="radix-_r_1a_"
role="button"
style="--cpd-icon-button-size: 24px;"
tabindex="0"
type="button"
>
<div
class="_indicator-icon_147l5_17"
style="--cpd-icon-button-size: 100%;"
>
<svg
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M6 14q-.824 0-1.412-.588A1.93 1.93 0 0 1 4 12q0-.825.588-1.412A1.93 1.93 0 0 1 6 10q.824 0 1.412.588Q8 11.175 8 12t-.588 1.412A1.93 1.93 0 0 1 6 14m6 0q-.825 0-1.412-.588A1.93 1.93 0 0 1 10 12q0-.825.588-1.412A1.93 1.93 0 0 1 12 10q.825 0 1.412.588Q14 11.175 14 12t-.588 1.412A1.93 1.93 0 0 1 12 14m6 0q-.824 0-1.413-.588A1.93 1.93 0 0 1 16 12q0-.825.587-1.412A1.93 1.93 0 0 1 18 10q.824 0 1.413.588Q20 11.175 20 12t-.587 1.412A1.93 1.93 0 0 1 18 14"
/>
</svg>
</div>
</button>
</div>
</div>
`;
exports[`<RoomListItemMoreOptionsMenu /> stories > renders OpenLowPriorityOn story 1`] = `
<div
aria-hidden="true"
data-aria-hidden="true"
>
<div
style="padding: 16px;"
>
<button
aria-controls="radix-_r_1s_"
aria-disabled="false"
aria-expanded="true"
aria-haspopup="menu"
aria-label="More Options"
aria-labelledby="_r_1t_"
class="_icon-button_1215g_8"
data-kind="primary"
data-state="open"
id="radix-_r_1r_"
role="button"
style="--cpd-icon-button-size: 24px;"
tabindex="0"
type="button"
>
<div
class="_indicator-icon_147l5_17"
style="--cpd-icon-button-size: 100%;"
>
<svg
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M6 14q-.824 0-1.412-.588A1.93 1.93 0 0 1 4 12q0-.825.588-1.412A1.93 1.93 0 0 1 6 10q.824 0 1.412.588Q8 11.175 8 12t-.588 1.412A1.93 1.93 0 0 1 6 14m6 0q-.825 0-1.412-.588A1.93 1.93 0 0 1 10 12q0-.825.588-1.412A1.93 1.93 0 0 1 12 10q.825 0 1.412.588Q14 11.175 14 12t-.588 1.412A1.93 1.93 0 0 1 12 14m6 0q-.824 0-1.413-.588A1.93 1.93 0 0 1 16 12q0-.825.587-1.412A1.93 1.93 0 0 1 18 10q.824 0 1.413.588Q20 11.175 20 12t-.587 1.412A1.93 1.93 0 0 1 18 14"
/>
</svg>
</div>
</button>
</div>
</div>
`;
exports[`<RoomListItemMoreOptionsMenu /> stories > renders OpenWithoutCopyLink story 1`] = `
<div
aria-hidden="true"
data-aria-hidden="true"
>
<div
style="padding: 16px;"
>
<button
aria-controls="radix-_r_2t_"
aria-disabled="false"
aria-expanded="true"
aria-haspopup="menu"
aria-label="More Options"
aria-labelledby="_r_2u_"
class="_icon-button_1215g_8"
data-kind="primary"
data-state="open"
id="radix-_r_2s_"
role="button"
style="--cpd-icon-button-size: 24px;"
tabindex="0"
type="button"
>
<div
class="_indicator-icon_147l5_17"
style="--cpd-icon-button-size: 100%;"
>
<svg
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M6 14q-.824 0-1.412-.588A1.93 1.93 0 0 1 4 12q0-.825.588-1.412A1.93 1.93 0 0 1 6 10q.824 0 1.412.588Q8 11.175 8 12t-.588 1.412A1.93 1.93 0 0 1 6 14m6 0q-.825 0-1.412-.588A1.93 1.93 0 0 1 10 12q0-.825.588-1.412A1.93 1.93 0 0 1 12 10q.825 0 1.412.588Q14 11.175 14 12t-.588 1.412A1.93 1.93 0 0 1 12 14m6 0q-.824 0-1.413-.588A1.93 1.93 0 0 1 16 12q0-.825.587-1.412A1.93 1.93 0 0 1 18 10q.824 0 1.413.588Q20 11.175 20 12t-.587 1.412A1.93 1.93 0 0 1 18 14"
/>
</svg>
</div>
</button>
</div>
</div>
`;
exports[`<RoomListItemMoreOptionsMenu /> stories > renders OpenWithoutInvite story 1`] = `
<div
aria-hidden="true"
data-aria-hidden="true"
>
<div
style="padding: 16px;"
>
<button
aria-controls="radix-_r_2d_"
aria-disabled="false"
aria-expanded="true"
aria-haspopup="menu"
aria-label="More Options"
aria-labelledby="_r_2e_"
class="_icon-button_1215g_8"
data-kind="primary"
data-state="open"
id="radix-_r_2c_"
role="button"
style="--cpd-icon-button-size: 24px;"
tabindex="0"
type="button"
>
<div
class="_indicator-icon_147l5_17"
style="--cpd-icon-button-size: 100%;"
>
<svg
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M6 14q-.824 0-1.412-.588A1.93 1.93 0 0 1 4 12q0-.825.588-1.412A1.93 1.93 0 0 1 6 10q.824 0 1.412.588Q8 11.175 8 12t-.588 1.412A1.93 1.93 0 0 1 6 14m6 0q-.825 0-1.412-.588A1.93 1.93 0 0 1 10 12q0-.825.588-1.412A1.93 1.93 0 0 1 12 10q.825 0 1.412.588Q14 11.175 14 12t-.588 1.412A1.93 1.93 0 0 1 12 14m6 0q-.824 0-1.413-.588A1.93 1.93 0 0 1 16 12q0-.825.587-1.412A1.93 1.93 0 0 1 18 10q.824 0 1.413.588Q20 11.175 20 12t-.587 1.412A1.93 1.93 0 0 1 18 14"
/>
</svg>
</div>
</button>
</div>
</div>
`;

View File

@ -0,0 +1,312 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`<RoomListItemMoreOptionsMenu /> stories > renders Default story (closed) 1`] = `
<div>
<div
style="padding: 16px;"
>
<button
aria-disabled="false"
aria-expanded="false"
aria-haspopup="menu"
aria-label="More Options"
aria-labelledby="_r_2_"
class="_icon-button_1215g_8"
data-kind="primary"
data-state="closed"
id="radix-_r_0_"
role="button"
style="--cpd-icon-button-size: 24px;"
tabindex="0"
type="button"
>
<div
class="_indicator-icon_147l5_17"
style="--cpd-icon-button-size: 100%;"
>
<svg
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M6 14q-.824 0-1.412-.588A1.93 1.93 0 0 1 4 12q0-.825.588-1.412A1.93 1.93 0 0 1 6 10q.824 0 1.412.588Q8 11.175 8 12t-.588 1.412A1.93 1.93 0 0 1 6 14m6 0q-.825 0-1.412-.588A1.93 1.93 0 0 1 10 12q0-.825.588-1.412A1.93 1.93 0 0 1 12 10q.825 0 1.412.588Q14 11.175 14 12t-.588 1.412A1.93 1.93 0 0 1 12 14m6 0q-.824 0-1.413-.588A1.93 1.93 0 0 1 16 12q0-.825.587-1.412A1.93 1.93 0 0 1 18 10q.824 0 1.413.588Q20 11.175 20 12t-.587 1.412A1.93 1.93 0 0 1 18 14"
/>
</svg>
</div>
</button>
</div>
</div>
`;
exports[`<RoomListItemMoreOptionsMenu /> stories > renders Open story 1`] = `
<div
aria-hidden="true"
data-aria-hidden="true"
>
<div
style="padding: 16px;"
>
<button
aria-controls="radix-_r_9_"
aria-disabled="false"
aria-expanded="true"
aria-haspopup="menu"
aria-label="More Options"
aria-labelledby="_r_a_"
class="_icon-button_1215g_8"
data-kind="primary"
data-state="open"
id="radix-_r_8_"
role="button"
style="--cpd-icon-button-size: 24px;"
tabindex="0"
type="button"
>
<div
class="_indicator-icon_147l5_17"
style="--cpd-icon-button-size: 100%;"
>
<svg
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M6 14q-.824 0-1.412-.588A1.93 1.93 0 0 1 4 12q0-.825.588-1.412A1.93 1.93 0 0 1 6 10q.824 0 1.412.588Q8 11.175 8 12t-.588 1.412A1.93 1.93 0 0 1 6 14m6 0q-.825 0-1.412-.588A1.93 1.93 0 0 1 10 12q0-.825.588-1.412A1.93 1.93 0 0 1 12 10q.825 0 1.412.588Q14 11.175 14 12t-.588 1.412A1.93 1.93 0 0 1 12 14m6 0q-.824 0-1.413-.588A1.93 1.93 0 0 1 16 12q0-.825.587-1.412A1.93 1.93 0 0 1 18 10q.824 0 1.413.588Q20 11.175 20 12t-.587 1.412A1.93 1.93 0 0 1 18 14"
/>
</svg>
</div>
</button>
</div>
</div>
`;
exports[`<RoomListItemMoreOptionsMenu /> stories > renders OpenCanMarkAsRead story 1`] = `
<div
aria-hidden="true"
data-aria-hidden="true"
>
<div
style="padding: 16px;"
>
<button
aria-controls="radix-_r_q_"
aria-disabled="false"
aria-expanded="true"
aria-haspopup="menu"
aria-label="More Options"
aria-labelledby="_r_r_"
class="_icon-button_1215g_8"
data-kind="primary"
data-state="open"
id="radix-_r_p_"
role="button"
style="--cpd-icon-button-size: 24px;"
tabindex="0"
type="button"
>
<div
class="_indicator-icon_147l5_17"
style="--cpd-icon-button-size: 100%;"
>
<svg
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M6 14q-.824 0-1.412-.588A1.93 1.93 0 0 1 4 12q0-.825.588-1.412A1.93 1.93 0 0 1 6 10q.824 0 1.412.588Q8 11.175 8 12t-.588 1.412A1.93 1.93 0 0 1 6 14m6 0q-.825 0-1.412-.588A1.93 1.93 0 0 1 10 12q0-.825.588-1.412A1.93 1.93 0 0 1 12 10q.825 0 1.412.588Q14 11.175 14 12t-.588 1.412A1.93 1.93 0 0 1 12 14m6 0q-.824 0-1.413-.588A1.93 1.93 0 0 1 16 12q0-.825.587-1.412A1.93 1.93 0 0 1 18 10q.824 0 1.413.588Q20 11.175 20 12t-.587 1.412A1.93 1.93 0 0 1 18 14"
/>
</svg>
</div>
</button>
</div>
</div>
`;
exports[`<RoomListItemMoreOptionsMenu /> stories > renders OpenFavouriteOn story 1`] = `
<div
aria-hidden="true"
data-aria-hidden="true"
>
<div
style="padding: 16px;"
>
<button
aria-controls="radix-_r_1b_"
aria-disabled="false"
aria-expanded="true"
aria-haspopup="menu"
aria-label="More Options"
aria-labelledby="_r_1c_"
class="_icon-button_1215g_8"
data-kind="primary"
data-state="open"
id="radix-_r_1a_"
role="button"
style="--cpd-icon-button-size: 24px;"
tabindex="0"
type="button"
>
<div
class="_indicator-icon_147l5_17"
style="--cpd-icon-button-size: 100%;"
>
<svg
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M6 14q-.824 0-1.412-.588A1.93 1.93 0 0 1 4 12q0-.825.588-1.412A1.93 1.93 0 0 1 6 10q.824 0 1.412.588Q8 11.175 8 12t-.588 1.412A1.93 1.93 0 0 1 6 14m6 0q-.825 0-1.412-.588A1.93 1.93 0 0 1 10 12q0-.825.588-1.412A1.93 1.93 0 0 1 12 10q.825 0 1.412.588Q14 11.175 14 12t-.588 1.412A1.93 1.93 0 0 1 12 14m6 0q-.824 0-1.413-.588A1.93 1.93 0 0 1 16 12q0-.825.587-1.412A1.93 1.93 0 0 1 18 10q.824 0 1.413.588Q20 11.175 20 12t-.587 1.412A1.93 1.93 0 0 1 18 14"
/>
</svg>
</div>
</button>
</div>
</div>
`;
exports[`<RoomListItemMoreOptionsMenu /> stories > renders OpenLowPriorityOn story 1`] = `
<div
aria-hidden="true"
data-aria-hidden="true"
>
<div
style="padding: 16px;"
>
<button
aria-controls="radix-_r_1s_"
aria-disabled="false"
aria-expanded="true"
aria-haspopup="menu"
aria-label="More Options"
aria-labelledby="_r_1t_"
class="_icon-button_1215g_8"
data-kind="primary"
data-state="open"
id="radix-_r_1r_"
role="button"
style="--cpd-icon-button-size: 24px;"
tabindex="0"
type="button"
>
<div
class="_indicator-icon_147l5_17"
style="--cpd-icon-button-size: 100%;"
>
<svg
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M6 14q-.824 0-1.412-.588A1.93 1.93 0 0 1 4 12q0-.825.588-1.412A1.93 1.93 0 0 1 6 10q.824 0 1.412.588Q8 11.175 8 12t-.588 1.412A1.93 1.93 0 0 1 6 14m6 0q-.825 0-1.412-.588A1.93 1.93 0 0 1 10 12q0-.825.588-1.412A1.93 1.93 0 0 1 12 10q.825 0 1.412.588Q14 11.175 14 12t-.588 1.412A1.93 1.93 0 0 1 12 14m6 0q-.824 0-1.413-.588A1.93 1.93 0 0 1 16 12q0-.825.587-1.412A1.93 1.93 0 0 1 18 10q.824 0 1.413.588Q20 11.175 20 12t-.587 1.412A1.93 1.93 0 0 1 18 14"
/>
</svg>
</div>
</button>
</div>
</div>
`;
exports[`<RoomListItemMoreOptionsMenu /> stories > renders OpenWithoutCopyLink story 1`] = `
<div
aria-hidden="true"
data-aria-hidden="true"
>
<div
style="padding: 16px;"
>
<button
aria-controls="radix-_r_2t_"
aria-disabled="false"
aria-expanded="true"
aria-haspopup="menu"
aria-label="More Options"
aria-labelledby="_r_2u_"
class="_icon-button_1215g_8"
data-kind="primary"
data-state="open"
id="radix-_r_2s_"
role="button"
style="--cpd-icon-button-size: 24px;"
tabindex="0"
type="button"
>
<div
class="_indicator-icon_147l5_17"
style="--cpd-icon-button-size: 100%;"
>
<svg
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M6 14q-.824 0-1.412-.588A1.93 1.93 0 0 1 4 12q0-.825.588-1.412A1.93 1.93 0 0 1 6 10q.824 0 1.412.588Q8 11.175 8 12t-.588 1.412A1.93 1.93 0 0 1 6 14m6 0q-.825 0-1.412-.588A1.93 1.93 0 0 1 10 12q0-.825.588-1.412A1.93 1.93 0 0 1 12 10q.825 0 1.412.588Q14 11.175 14 12t-.588 1.412A1.93 1.93 0 0 1 12 14m6 0q-.824 0-1.413-.588A1.93 1.93 0 0 1 16 12q0-.825.587-1.412A1.93 1.93 0 0 1 18 10q.824 0 1.413.588Q20 11.175 20 12t-.587 1.412A1.93 1.93 0 0 1 18 14"
/>
</svg>
</div>
</button>
</div>
</div>
`;
exports[`<RoomListItemMoreOptionsMenu /> stories > renders OpenWithoutInvite story 1`] = `
<div
aria-hidden="true"
data-aria-hidden="true"
>
<div
style="padding: 16px;"
>
<button
aria-controls="radix-_r_2d_"
aria-disabled="false"
aria-expanded="true"
aria-haspopup="menu"
aria-label="More Options"
aria-labelledby="_r_2e_"
class="_icon-button_1215g_8"
data-kind="primary"
data-state="open"
id="radix-_r_2c_"
role="button"
style="--cpd-icon-button-size: 24px;"
tabindex="0"
type="button"
>
<div
class="_indicator-icon_147l5_17"
style="--cpd-icon-button-size: 100%;"
>
<svg
fill="currentColor"
height="1em"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M6 14q-.824 0-1.412-.588A1.93 1.93 0 0 1 4 12q0-.825.588-1.412A1.93 1.93 0 0 1 6 10q.824 0 1.412.588Q8 11.175 8 12t-.588 1.412A1.93 1.93 0 0 1 6 14m6 0q-.825 0-1.412-.588A1.93 1.93 0 0 1 10 12q0-.825.588-1.412A1.93 1.93 0 0 1 12 10q.825 0 1.412.588Q14 11.175 14 12t-.588 1.412A1.93 1.93 0 0 1 12 14m6 0q-.824 0-1.413-.588A1.93 1.93 0 0 1 16 12q0-.825.587-1.412A1.93 1.93 0 0 1 18 10q.824 0 1.413.588Q20 11.175 20 12t-.587 1.412A1.93 1.93 0 0 1 18 14"
/>
</svg>
</div>
</button>
</div>
</div>
`;