diff --git a/apps/web/playwright/snapshots/left-panel/room-list-panel/room-list.spec.ts/room-list-item-open-more-options-linux.png b/apps/web/playwright/snapshots/left-panel/room-list-panel/room-list.spec.ts/room-list-item-open-more-options-linux.png index d651340ace..77345fe6fe 100644 Binary files a/apps/web/playwright/snapshots/left-panel/room-list-panel/room-list.spec.ts/room-list-item-open-more-options-linux.png and b/apps/web/playwright/snapshots/left-panel/room-list-panel/room-list.spec.ts/room-list-item-open-more-options-linux.png differ diff --git a/apps/web/src/viewmodels/room-list/RoomListHeaderViewModel.ts b/apps/web/src/viewmodels/room-list/RoomListHeaderViewModel.ts index 8a5547e6e9..fa7697d084 100644 --- a/apps/web/src/viewmodels/room-list/RoomListHeaderViewModel.ts +++ b/apps/web/src/viewmodels/room-list/RoomListHeaderViewModel.ts @@ -199,8 +199,11 @@ export class RoomListHeaderViewModel SettingsStore.setValue("RoomList.showMessagePreview", null, SettingLevel.DEVICE, isMessagePreviewEnabled); this.snapshot.merge({ isMessagePreviewEnabled }); }; -} + public createSection = (): void => { + // To be implemented when custom section creation is added in vms + }; +} /** * Get the initial snapshot for the RoomListHeaderViewModel. * @param spaceStore - The space store instance. @@ -280,5 +283,8 @@ function computeHeaderSpaceState( displaySpaceMenu, canInviteInSpace, canAccessSpaceSettings, + // To be implemented when custom section creation is added in vms + canCreateSection: false, + useComposeIcon: true, }; } diff --git a/apps/web/src/viewmodels/room-list/RoomListItemViewModel.ts b/apps/web/src/viewmodels/room-list/RoomListItemViewModel.ts index b2f24da66d..ac3f32ad61 100644 --- a/apps/web/src/viewmodels/room-list/RoomListItemViewModel.ts +++ b/apps/web/src/viewmodels/room-list/RoomListItemViewModel.ts @@ -303,6 +303,8 @@ export class RoomListItemViewModel canMarkAsRead, canMarkAsUnread, roomNotifState, + // To be implemented when custom section creation is added in vms + canMoveToSection: false, }; } @@ -381,4 +383,8 @@ export class RoomListItemViewModel const echoChamber = EchoChamber.forRoom(this.props.room); echoChamber.notificationVolume = elementNotifState; }; + + public onCreateSection = (): void => { + // To be implemented when custom section creation is added in vms + }; } diff --git a/apps/web/src/viewmodels/room-list/RoomListViewModel.ts b/apps/web/src/viewmodels/room-list/RoomListViewModel.ts index d2ff465db9..a3e516ea2d 100644 --- a/apps/web/src/viewmodels/room-list/RoomListViewModel.ts +++ b/apps/web/src/viewmodels/room-list/RoomListViewModel.ts @@ -572,6 +572,12 @@ export class RoomListViewModel }); } }; + + public closeToast: () => void = () => { + this.snapshot.merge({ + toast: undefined, + }); + }; } /** diff --git a/packages/shared-components/__vis__/linux/__baselines__/room-list/RoomListHeaderView/RoomListHeaderView.stories.tsx/plus-icon-auto.png b/packages/shared-components/__vis__/linux/__baselines__/room-list/RoomListHeaderView/RoomListHeaderView.stories.tsx/plus-icon-auto.png new file mode 100644 index 0000000000..58f146e165 Binary files /dev/null and b/packages/shared-components/__vis__/linux/__baselines__/room-list/RoomListHeaderView/RoomListHeaderView.stories.tsx/plus-icon-auto.png differ diff --git a/packages/shared-components/__vis__/linux/__baselines__/room-list/RoomListView/RoomListToast/RoomListToast.stories.tsx/section-created-auto.png b/packages/shared-components/__vis__/linux/__baselines__/room-list/RoomListView/RoomListToast/RoomListToast.stories.tsx/section-created-auto.png new file mode 100644 index 0000000000..977772886a Binary files /dev/null and b/packages/shared-components/__vis__/linux/__baselines__/room-list/RoomListView/RoomListToast/RoomListToast.stories.tsx/section-created-auto.png differ diff --git a/packages/shared-components/__vis__/linux/__baselines__/room-list/RoomListView/RoomListView.stories.tsx/toast-auto.png b/packages/shared-components/__vis__/linux/__baselines__/room-list/RoomListView/RoomListView.stories.tsx/toast-auto.png new file mode 100644 index 0000000000..722398dc96 Binary files /dev/null and b/packages/shared-components/__vis__/linux/__baselines__/room-list/RoomListView/RoomListView.stories.tsx/toast-auto.png differ diff --git a/packages/shared-components/src/i18n/strings/en_EN.json b/packages/shared-components/src/i18n/strings/en_EN.json index 0ab6da3a94..31475607c7 100644 --- a/packages/shared-components/src/i18n/strings/en_EN.json +++ b/packages/shared-components/src/i18n/strings/en_EN.json @@ -5,6 +5,7 @@ "action": { "back": "Back", "click": "Click", + "close": "Close", "collapse": "Collapse", "delete": "Delete", "dismiss": "Dismiss", @@ -16,6 +17,7 @@ "invite": "Invite", "new_conversation": "New conversation", "new_room": "New room", + "new_section": "New section", "new_video_room": "New video room", "open_menu": "Open menu", "pause": "Pause", @@ -132,7 +134,8 @@ "leave_room": "Leave room", "low_priority": "Low priority", "mark_read": "Mark as read", - "mark_unread": "Mark as unread" + "mark_unread": "Mark as unread", + "move_to_section": "Move to" }, "notification_options": "Notification options", "open_space_menu": "Open space menu", @@ -141,6 +144,7 @@ "more_options": "More Options" }, "room_options": "Room Options", + "section_created": "Section created", "section_header": { "toggle": "Toggle %(section)s section", "toggle_unread": "Toggle %(section)s section with unread room(s)" diff --git a/packages/shared-components/src/room-list/RoomListHeaderView/RoomListHeaderView.stories.tsx b/packages/shared-components/src/room-list/RoomListHeaderView/RoomListHeaderView.stories.tsx index 35b5fd201b..83551bc21b 100644 --- a/packages/shared-components/src/room-list/RoomListHeaderView/RoomListHeaderView.stories.tsx +++ b/packages/shared-components/src/room-list/RoomListHeaderView/RoomListHeaderView.stories.tsx @@ -30,6 +30,7 @@ const RoomListHeaderViewWrapperImpl = ({ openSpacePreferences, sort, toggleMessagePreview, + createSection, ...rest }: RoomListHeaderProps): JSX.Element => { const vm = useMockedViewModel(rest, { @@ -42,6 +43,7 @@ const RoomListHeaderViewWrapperImpl = ({ sort, openSpacePreferences, toggleMessagePreview, + createSection, }); return ; }; @@ -62,6 +64,7 @@ const meta = { sort: fn(), openSpacePreferences: fn(), toggleMessagePreview: fn(), + createSection: fn(), }, parameters: { design: { @@ -100,3 +103,9 @@ export const LongTitle: Story = { title: "Loooooooooooooooooooooooooooooooooooooong title", }, }; + +export const PlusIcon: Story = { + args: { + useComposeIcon: false, + }, +}; diff --git a/packages/shared-components/src/room-list/RoomListHeaderView/RoomListHeaderView.tsx b/packages/shared-components/src/room-list/RoomListHeaderView/RoomListHeaderView.tsx index 2125ea9af2..05254899ea 100644 --- a/packages/shared-components/src/room-list/RoomListHeaderView/RoomListHeaderView.tsx +++ b/packages/shared-components/src/room-list/RoomListHeaderView/RoomListHeaderView.tsx @@ -8,6 +8,7 @@ import React, { type JSX } from "react"; import { IconButton, H1 } from "@vector-im/compound-web"; import ComposeIcon from "@vector-im/compound-design-tokens/assets/web/icons/compose"; +import PlusIcon from "@vector-im/compound-design-tokens/assets/web/icons/plus"; import { type ViewModel, useViewModel } from "../../core/viewmodel"; import { Flex } from "../../core/utils/Flex"; @@ -59,6 +60,14 @@ export interface RoomListHeaderViewSnapshot { * Whether message previews are enabled in the room list. */ isMessagePreviewEnabled: boolean; + /** + * Whether the user can create sections in the room list. + */ + canCreateSection: boolean; + /** + * Whether to use the compose icon instead of the create icon. + */ + useComposeIcon: boolean; } export interface RoomListHeaderViewActions { @@ -98,6 +107,10 @@ export interface RoomListHeaderViewActions { * Toggle message preview display in the room list. */ toggleMessagePreview: () => void; + /** + * Create a new section in the room list. + */ + createSection: () => void; } /** @@ -123,7 +136,7 @@ interface RoomListHeaderViewProps { */ export function RoomListHeaderView({ vm }: Readonly): JSX.Element { const { translate: _t } = useI18n(); - const { title, displaySpaceMenu, displayComposeMenu } = useViewModel(vm); + const { title, displaySpaceMenu, displayComposeMenu, useComposeIcon } = useViewModel(vm); return ( ): J onClick={(e) => vm.createChatRoom(e.nativeEvent)} tooltip={_t("action|new_conversation")} > - + {useComposeIcon ? ( + + ) : ( + + )} )} diff --git a/packages/shared-components/src/room-list/RoomListHeaderView/__snapshots__/RoomListHeaderView.test.tsx.snap b/packages/shared-components/src/room-list/RoomListHeaderView/__snapshots__/RoomListHeaderView.test.tsx.snap index 01c5914797..6608b5b3f3 100644 --- a/packages/shared-components/src/room-list/RoomListHeaderView/__snapshots__/RoomListHeaderView.test.tsx.snap +++ b/packages/shared-components/src/room-list/RoomListHeaderView/__snapshots__/RoomListHeaderView.test.tsx.snap @@ -110,6 +110,7 @@ exports[`RoomListHeaderView > renders the default state 1`] = ` > renders without space menu 1`] = ` > ", () => { expect(vm.createVideoRoom).toHaveBeenCalledTimes(1); }); + + it("should create a new section", async () => { + const user = userEvent.setup(); + + const vm = new MockedViewModel({ ...defaultSnapshot, isMessagePreviewEnabled: true }); + render(); + + await user.click(screen.getByRole("button", { name: "New conversation" })); + await user.click(screen.getByRole("menuitem", { name: "New section" })); + expect(vm.createSection).toHaveBeenCalled(); + }); }); diff --git a/packages/shared-components/src/room-list/RoomListHeaderView/menu/ComposeMenuView.tsx b/packages/shared-components/src/room-list/RoomListHeaderView/menu/ComposeMenuView.tsx index 0e4a2f2b73..3803c23fcf 100644 --- a/packages/shared-components/src/room-list/RoomListHeaderView/menu/ComposeMenuView.tsx +++ b/packages/shared-components/src/room-list/RoomListHeaderView/menu/ComposeMenuView.tsx @@ -11,6 +11,8 @@ import ComposeIcon from "@vector-im/compound-design-tokens/assets/web/icons/comp import VideoCallIcon from "@vector-im/compound-design-tokens/assets/web/icons/video-call"; import ChatIcon from "@vector-im/compound-design-tokens/assets/web/icons/chat"; import RoomIcon from "@vector-im/compound-design-tokens/assets/web/icons/room"; +import SectionIcon from "@vector-im/compound-design-tokens/assets/web/icons/section"; +import PlusIcon from "@vector-im/compound-design-tokens/assets/web/icons/plus"; import { type RoomListHeaderViewModel } from "../RoomListHeaderView"; import { useI18n } from "../../../core/i18n/i18nContext"; @@ -35,7 +37,7 @@ interface ComposeMenuViewProps { export function ComposeMenuView({ vm }: ComposeMenuViewProps): JSX.Element { const { translate: _t } = useI18n(); const [open, setOpen] = useState(false); - const { canCreateRoom, canCreateVideoRoom } = useViewModel(vm); + const { canCreateRoom, canCreateVideoRoom, canCreateSection, useComposeIcon } = useViewModel(vm); return ( - + {useComposeIcon ? ( + + ) : ( + + )} } > @@ -63,6 +69,9 @@ export function ComposeMenuView({ vm }: ComposeMenuViewProps): JSX.Element { hideChevron /> )} + {canCreateSection && ( + + )} ); } diff --git a/packages/shared-components/src/room-list/RoomListHeaderView/menu/__snapshots__/ComposeMenuView.test.tsx.snap b/packages/shared-components/src/room-list/RoomListHeaderView/menu/__snapshots__/ComposeMenuView.test.tsx.snap index d269845351..2f43a667bc 100644 --- a/packages/shared-components/src/room-list/RoomListHeaderView/menu/__snapshots__/ComposeMenuView.test.tsx.snap +++ b/packages/shared-components/src/room-list/RoomListHeaderView/menu/__snapshots__/ComposeMenuView.test.tsx.snap @@ -22,6 +22,7 @@ exports[` > should match snapshot 1`] = ` > i public sort = vi.fn<() => void>(); public openSpacePreferences = vi.fn<() => void>(); public toggleMessagePreview = vi.fn<() => void>(); + public createSection = vi.fn<() => void>(); } export { defaultSnapshot } from "./default-snapshot"; diff --git a/packages/shared-components/src/room-list/RoomListView/RoomListToast/RoomListToast.module.css b/packages/shared-components/src/room-list/RoomListView/RoomListToast/RoomListToast.module.css new file mode 100644 index 0000000000..288ec1000e --- /dev/null +++ b/packages/shared-components/src/room-list/RoomListView/RoomListToast/RoomListToast.module.css @@ -0,0 +1,15 @@ +/* + * 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. + */ + +.toast { + position: absolute; + bottom: var(--cpd-space-4x); + left: var(--cpd-space-3x); + right: var(--cpd-space-3x); + width: fit-content; + margin: 0 auto; +} diff --git a/packages/shared-components/src/room-list/RoomListView/RoomListToast/RoomListToast.stories.tsx b/packages/shared-components/src/room-list/RoomListView/RoomListToast/RoomListToast.stories.tsx new file mode 100644 index 0000000000..15a89a2e47 --- /dev/null +++ b/packages/shared-components/src/room-list/RoomListView/RoomListToast/RoomListToast.stories.tsx @@ -0,0 +1,40 @@ +/* + * 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 from "react"; +import { fn } from "storybook/test"; + +import type { Meta, StoryObj } from "@storybook/react-vite"; +import { RoomListToast } from "./RoomListToast"; + +const meta = { + title: "Room List/RoomListView/RoomListToast", + component: RoomListToast, + tags: ["autodocs"], + args: { + type: "section_created", + onClose: fn(), + }, + argTypes: { + type: { + control: "select", + options: ["section_created"], + }, + }, + decorators: [ + (Story) => ( + + + + ), + ], +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const SectionCreated: Story = {}; diff --git a/packages/shared-components/src/room-list/RoomListView/RoomListToast/RoomListToast.test.tsx b/packages/shared-components/src/room-list/RoomListView/RoomListToast/RoomListToast.test.tsx new file mode 100644 index 0000000000..e64d17ffb6 --- /dev/null +++ b/packages/shared-components/src/room-list/RoomListView/RoomListToast/RoomListToast.test.tsx @@ -0,0 +1,31 @@ +/* + * 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 from "react"; +import { render, screen } from "@test-utils"; +import { composeStories } from "@storybook/react-vite"; +import { describe, it, expect } from "vitest"; +import userEvent from "@testing-library/user-event"; + +import * as stories from "./RoomListToast.stories"; + +const { SectionCreated } = composeStories(stories); + +describe("", () => { + it("renders SectionCreated story", () => { + const { container } = render(); + expect(container).toMatchSnapshot(); + }); + + it("calls onClose when the close button is clicked", async () => { + const user = userEvent.setup(); + render(); + const closeButton = screen.getByRole("button", { name: "Close" }); + await user.click(closeButton); + expect(SectionCreated.args.onClose).toHaveBeenCalled(); + }); +}); diff --git a/packages/shared-components/src/room-list/RoomListView/RoomListToast/RoomListToast.tsx b/packages/shared-components/src/room-list/RoomListView/RoomListToast/RoomListToast.tsx new file mode 100644 index 0000000000..9388cd93f5 --- /dev/null +++ b/packages/shared-components/src/room-list/RoomListView/RoomListToast/RoomListToast.tsx @@ -0,0 +1,47 @@ +/* + * 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 ComponentType, type JSX, type MouseEventHandler } from "react"; +import { Toast } from "@vector-im/compound-web"; +import CheckIcon from "@vector-im/compound-design-tokens/assets/web/icons/check"; + +import styles from "./RoomListToast.module.css"; +import { useI18n } from "../../../core/i18n/i18nContext"; + +export type ToastType = "section_created"; + +interface RoomListToastProps { + /** The type of toast to display */ + type: ToastType; + /** Callback when the close button is clicked */ + onClose: MouseEventHandler; +} + +/** + * A toast component used for displaying temporary messages in the room list view. + * + * @example + * ```tsx + * + * ``` + */ +export function RoomListToast({ type, onClose }: Readonly): JSX.Element { + const { translate: _t } = useI18n(); + + let content: { text: string; icon: ComponentType> }; + switch (type) { + case "section_created": + content = { text: _t("room_list|section_created"), icon: CheckIcon }; + break; + } + + return ( + + {content.text} + + ); +} diff --git a/packages/shared-components/src/room-list/RoomListView/RoomListToast/__snapshots__/RoomListToast.test.tsx.snap b/packages/shared-components/src/room-list/RoomListView/RoomListToast/__snapshots__/RoomListToast.test.tsx.snap new file mode 100644 index 0000000000..b0e8906e3b --- /dev/null +++ b/packages/shared-components/src/room-list/RoomListView/RoomListToast/__snapshots__/RoomListToast.test.tsx.snap @@ -0,0 +1,57 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[` > renders SectionCreated story 1`] = ` + + + + + + + + Section created + + + + + + + + + + + +`; diff --git a/packages/shared-components/src/room-list/RoomListView/RoomListToast/index.ts b/packages/shared-components/src/room-list/RoomListView/RoomListToast/index.ts new file mode 100644 index 0000000000..3a6b6a5cf5 --- /dev/null +++ b/packages/shared-components/src/room-list/RoomListView/RoomListToast/index.ts @@ -0,0 +1,9 @@ +/* + * 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. + */ + +export type { ToastType } from "./RoomListToast"; +export { RoomListToast } from "./RoomListToast"; diff --git a/packages/shared-components/src/room-list/RoomListView/RoomListView.module.css b/packages/shared-components/src/room-list/RoomListView/RoomListView.module.css new file mode 100644 index 0000000000..c20d3006bf --- /dev/null +++ b/packages/shared-components/src/room-list/RoomListView/RoomListView.module.css @@ -0,0 +1,11 @@ +/* + * 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. + */ + +.list { + position: relative; + flex: 1; +} diff --git a/packages/shared-components/src/room-list/RoomListView/RoomListView.stories.tsx b/packages/shared-components/src/room-list/RoomListView/RoomListView.stories.tsx index 6f683225d0..dfdab19c92 100644 --- a/packages/shared-components/src/room-list/RoomListView/RoomListView.stories.tsx +++ b/packages/shared-components/src/room-list/RoomListView/RoomListView.stories.tsx @@ -39,6 +39,7 @@ const RoomListViewWrapperImpl = ({ getSectionHeaderViewModel, updateVisibleRooms, renderAvatar: renderAvatarProp, + closeToast, ...rest }: RoomListViewProps): JSX.Element => { const vm = useMockedViewModel(rest, { @@ -48,6 +49,7 @@ const RoomListViewWrapperImpl = ({ getRoomItemViewModel, getSectionHeaderViewModel, updateVisibleRooms, + closeToast, }); return ; }; @@ -98,6 +100,8 @@ const meta = { updateVisibleRooms: fn(), renderAvatar, isFlatList: true, + toast: undefined, + closeToast: fn(), }, parameters: { design: { @@ -245,3 +249,9 @@ export const LargeSectionList: Story = { getSectionHeaderViewModel: createGetSectionHeaderViewModel(mockLargeListSections.map((section) => section.id)), }, }; + +export const Toast: Story = { + args: { + toast: "section_created", + }, +}; diff --git a/packages/shared-components/src/room-list/RoomListView/RoomListView.test.tsx b/packages/shared-components/src/room-list/RoomListView/RoomListView.test.tsx index 380600541a..5d84e05d05 100644 --- a/packages/shared-components/src/room-list/RoomListView/RoomListView.test.tsx +++ b/packages/shared-components/src/room-list/RoomListView/RoomListView.test.tsx @@ -31,6 +31,7 @@ const { EmptyInvitesFilter, EmptyMentionsFilter, EmptyLowPriorityFilter, + Toast, } = composeStories(stories); const renderWithMockContext = (component: React.ReactElement): ReturnType => { @@ -124,6 +125,11 @@ describe("", () => { expect(container).toMatchSnapshot(); }); + it("renders Toast story", () => { + const { container } = renderWithMockContext(); + expect(container).toMatchSnapshot(); + }); + it("should call onToggleFilter when filter is clicked", async () => { const user = userEvent.setup(); renderWithMockContext(); @@ -186,4 +192,13 @@ describe("", () => { expect(EmptyLowPriorityFilter.args.onToggleFilter).toHaveBeenCalled(); }); + + it("should call closeToast when close button is clicked on toast", async () => { + const user = userEvent.setup(); + renderWithMockContext(); + + await user.click(screen.getByRole("button", { name: "Close" })); + + expect(EmptyLowPriorityFilter.args.closeToast).toHaveBeenCalled(); + }); }); diff --git a/packages/shared-components/src/room-list/RoomListView/RoomListView.tsx b/packages/shared-components/src/room-list/RoomListView/RoomListView.tsx index 132b9dfda3..3cace4b400 100644 --- a/packages/shared-components/src/room-list/RoomListView/RoomListView.tsx +++ b/packages/shared-components/src/room-list/RoomListView/RoomListView.tsx @@ -17,6 +17,9 @@ import { type RoomListItemViewModel, } from "../VirtualizedRoomListView/RoomListItemAccessibilityWrapper/RoomListItemView"; import { type RoomListSectionHeaderViewModel } from "../VirtualizedRoomListView/RoomListSectionHeaderView"; +import { type ToastType, RoomListToast } from "./RoomListToast"; +import styles from "./RoomListView.module.css"; +import { Flex } from "../../core/utils/Flex"; export type RoomListSection = { /** Unique identifier for the section */ @@ -49,6 +52,8 @@ export type RoomListViewSnapshot = { canCreateRoom?: boolean; /** Whether the room list is displayed as a flat list */ isFlatList: boolean; + /** Optional toast to display */ + toast?: ToastType; }; /** @@ -70,6 +75,8 @@ export interface RoomListViewActions { updateVisibleRooms: (startIndex: number, endIndex: number) => void; /** Get view model for a specific section header (virtualization API) */ getSectionHeaderViewModel: (sectionId: string) => RoomListSectionHeaderViewModel; + /** Called to close the toast message */ + closeToast: () => void; } /** @@ -113,7 +120,10 @@ export const RoomListView: React.FC = ({ vm, renderAvatar, on onToggleFilter={vm.onToggleFilter} /> - {listBody} + + {listBody} + {snapshot.toast && } + > ); }; diff --git a/packages/shared-components/src/room-list/RoomListView/__snapshots__/RoomListView.test.tsx.snap b/packages/shared-components/src/room-list/RoomListView/__snapshots__/RoomListView.test.tsx.snap index 388c0878ff..2cab617342 100644 --- a/packages/shared-components/src/room-list/RoomListView/__snapshots__/RoomListView.test.tsx.snap +++ b/packages/shared-components/src/room-list/RoomListView/__snapshots__/RoomListView.test.tsx.snap @@ -58,2610 +58,2616 @@ exports[` > renders Default story 1`] = ` - - - GE - - - - General - - - Last message in General - + GE - + General + + + Last message in General + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - + - - - - - + + - - RA - - + RA + + - Random + + Random + - - - - - - - - - - - + + + + + - - - - - + + + + + + + - - - - - - + + - - EN - - - - Engineering - - - Last message in Engineering - + EN - - - - + Engineering - - - - - + Last message in Engineering - + + + + + + + + + + + + + + + + + + - - - - - - + + - - DE - - + DE + + - Design + + Design + - - - - - - - - - - - + + + + + - - - - - + + + + + + + - - - - - - + + - - PR - - - - Product - - - Last message in Product - + PR - - - - + Product - - - - - + Last message in Product - + + + + + + + + + + + + + + + + + + - - - - - - + + - - MA - - - - Marketing - + MA - + Marketing + + + + + + + + + + + + + + + + + + + + - - - - - - - + 5 + - - - - - - - - - 5 - - - - - - + + - - SA - - - - Sales - - - Last message in Sales - + SA - - - - + Sales - - - - - + Last message in Sales - + + + + + + + + + + + + + + + + + + - - - - - - + + - - SU - - + SU + + - Support + + Support + - - - - - - - - - - - + + + + + - - - - - + + + + + + + - - - - - - + + - - AN - - - - Announcements - - - Last message in Announcements - + AN - - - - + Announcements - - - - - + Last message in Announcements - + + + + + + + + + + + + + + + + + + - - - - - - + + - - OF - - + OF + + - Off-topic + + Off-topic + - - - - - - - - - - - + + + + + - - - - - + + + + + + + - - - - - - + + - - TE - - - - Team Alpha - - - Last message in Team Alpha - + TE - + Team Alpha + + + Last message in Team Alpha + + + + + + + + + + + + + + + + + + + + - - - - - - - + 10 + - - - - - - - - - 10 - - - - - - + + - - TE - - + TE + + - Team Beta + + Team Beta + - - - - - - - - - - - + + + + + - - - - - + + + + + + + - - - - - - + + - - PR - - - - Project X - - - Last message in Project X - + PR - - - - + Project X - - - - - + Last message in Project X - + + + + + + + + + + + + + + + + + + - - - - - - + + - - PR - - + PR + + - Project Y + + Project Y + - - - - - - - - - - - + + + + + - - - - - + + + + + + + - - - - - - + + - - WA - - - - Water Cooler - - - Last message in Water Cooler - + WA - - - - + Water Cooler - - - - - + Last message in Water Cooler - + + + + + + + + + + + + + + + + + + - - - - - - + + - - FE - - - - Feedback - + FE - + Feedback + + + + + + + + + + + + + + + + + + + + - - - - - - - + 15 + - - - - - - - - - 15 - - - - - - + + - - ID - - - - Ideas - - - Last message in Ideas - + ID - - - - + Ideas - - - - - + Last message in Ideas - + + + + + + + + + + + + + + + + + + - - - - - - + + - - BU - - + BU + + - Bugs + + Bugs + - - - - - - - - - - - + + + + + - - - - - + + + + + + + - - - - - - + + - - FE - - - - Features - - - Last message in Features - + FE - - - - + Features - - - - - + Last message in Features - + + + + + + + + + + + + + + + + + + - - - - - - + + - - RE - - + RE + + - Releases + + Releases + - - - - - - - - - - - + + + + + - - - - - + + + + + + + - - - + + @@ -2728,66 +2734,71 @@ exports[` > renders Empty story 1`] = ` - - No chats yet - - - Get started by messaging someone or by creating a room - - - - - - Start chat - - + - + + - - - New room - + + + + Start chat + + + + + + New room + + @@ -2834,20 +2845,25 @@ exports[` > renders EmptyFavouriteFilter story 1`] = ` - - You don't have favourite chats yet - - - You can add a chat to your favourites in the chat settings - + + You don't have favourite chats yet + + + You can add a chat to your favourites in the chat settings + + @@ -2893,24 +2909,29 @@ exports[` > renders EmptyInvitesFilter story 1`] = ` - - You don't have any unread invites - - - See all activity - + + You don't have any unread invites + + + See all activity + + @@ -2956,24 +2977,29 @@ exports[` > renders EmptyLowPriorityFilter story 1`] = ` - - You don't have any low priority rooms - - - See all activity - + + You don't have any low priority rooms + + + See all activity + + @@ -3019,24 +3045,29 @@ exports[` > renders EmptyMentionsFilter story 1`] = ` - - You don't have any unread mentions - - - See all activity - + + You don't have any unread mentions + + + See all activity + + @@ -3082,20 +3113,25 @@ exports[` > renders EmptyPeopleFilter story 1`] = ` - - You don’t have direct chats with anyone yet - - - You can deselect filters in order to see your other chats - + + You don’t have direct chats with anyone yet + + + You can deselect filters in order to see your other chats + + @@ -3141,20 +3177,25 @@ exports[` > renders EmptyRoomsFilter story 1`] = ` - - You’re not in any room yet - - - You can deselect filters in order to see your other chats - + + You’re not in any room yet + + + You can deselect filters in order to see your other chats + + @@ -3200,24 +3241,29 @@ exports[` > renders EmptyUnreadFilter story 1`] = ` - - Congrats! You don’t have any unread messages - - - Show all chats - + + Congrats! You don’t have any unread messages + + + Show all chats + + @@ -3281,45 +3327,50 @@ exports[` > renders EmptyWithoutCreatePermission story 1`] = ` - - No chats yet - - - Get started by messaging someone - - - + + Get started by messaging someone + + + - - - Start chat - + + + + Start chat + + @@ -3384,4830 +3435,4836 @@ exports[` > renders LargeFlatList story 1`] = ` - - - GE - - - - General - - - Last message in General - + GE - + General + + + Last message in General + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - + - - - - - + + - - RA - - + RA + + - Random + + Random + - - - - - - - - - - - + + + + + - - - - - + + + + + + + - - - - - - + + - - EN - - - - Engineering - - - Last message in Engineering - + EN - - - - + Engineering - - - - - + Last message in Engineering - + + + + + + + + + + + + + + + + + + - - - - - - + + - - DE - - + DE + + - Design + + Design + - - - - - - - - - - - + + + + + - - - - - + + + + + + + - - - - - - + + - - PR - - - - Product - - - Last message in Product - + PR - - - - + Product - - - - - + Last message in Product - + + + + + + + + + + + + + + + + + + - - - - - - + + - - MA - - - - Marketing - + MA - + Marketing + + + + + + + + + + + + + + + + + + + + - - - - - - - + 5 + - - - - - - - - - 5 - - - - - - + + - - SA - - - - Sales - - - Last message in Sales - + SA - - - - + Sales - - - - - + Last message in Sales - + + + + + + + + + + + + + + + + + + - - - - - - + + - - SU - - + SU + + - Support + + Support + - - - - - - - - - - - + + + + + - - - - - + + + + + + + - - - - - - + + - - AN - - - - Announcements - - - Last message in Announcements - + AN - - - - + Announcements - - - - - + Last message in Announcements - + + + + + + + + + + + + + + + + + + - - - - - - + + - - OF - - + OF + + - Off-topic + + Off-topic + - - - - - - - - - - - + + + + + - - - - - + + + + + + + - - - - - - + + - - TE - - - - Team Alpha - - - Last message in Team Alpha - + TE - + Team Alpha + + + Last message in Team Alpha + + + + + + + + + + + + + + + + + + + + - - - - - - - + 10 + - - - - - - - - - 10 - - - - - - + + - - TE - - + TE + + - Team Beta + + Team Beta + - - - - - - - - - - - + + + + + - - - - - + + + + + + + - - - - - - + + - - PR - - - - Project X - - - Last message in Project X - + PR - - - - + Project X - - - - - + Last message in Project X - + + + + + + + + + + + + + + + + + + - - - - - - + + - - PR - - + PR + + - Project Y + + Project Y + - - - - - - - - - - - + + + + + - - - - - + + + + + + + - - - - - - + + - - WA - - - - Water Cooler - - - Last message in Water Cooler - + WA - - - - + Water Cooler - - - - - + Last message in Water Cooler - + + + + + + + + + + + + + + + + + + - - - - - - + + - - FE - - - - Feedback - + FE - + Feedback + + + + + + + + + + + + + + + + + + + + - - - - - - - + 15 + - - - - - - - - - 15 - - - - - - + + - - ID - - - - Ideas - - - Last message in Ideas - + ID - - - - + Ideas - - - - - + Last message in Ideas - + + + + + + + + + + + + + + + + + + - - - - - - + + - - BU - - + BU + + - Bugs + + Bugs + - - - - - - - - - - - + + + + + - - - - - + + + + + + + - - - - - - + + - - FE - - - - Features - - - Last message in Features - + FE - - - - + Features - - - - - + Last message in Features - + + + + + + + + + + + + + + + + + + - - - - - - + + - - RE - - + RE + + - Releases + + Releases + - - - - - - - - - - - + + + + + - - - - - + + + + + + + - - - - - - + + - - GE - - - - General - - - Last message in General - + GE - + General + + + Last message in General + + + + + + + + + + + + + + + + + + + + - - - - - - - + 20 + - - - - - - - - - 20 - - - - - - + + - - RA - - + RA + + - Random + + Random + - - - - - - - - - - - + + + + + - - - - - + + + + + + + - - - - - - + + - - EN - - - - Engineering - - - Last message in Engineering - + EN - - - - + Engineering - - - - - + Last message in Engineering - + + + + + + + + + + + + + + + + + + - - - - - - + + - - DE - - + DE + + - Design + + Design + - - - - - - - - - - - + + + + + - - - - - + + + + + + + - - - - - - + + - - PR - - - - Product - - - Last message in Product - + PR - - - - + Product - - - - - + Last message in Product - + + + + + + + + + + + + + + + + + + - - - - - - + + - - MA - - - - Marketing - + MA - + Marketing + + + + + + + + + + + + + + + + + + + + - - - - - - - + 25 + - - - - - - - - - 25 - - - - - - + + - - SA - - - - Sales - - - Last message in Sales - + SA - - - - + Sales - - - - - + Last message in Sales - + + + + + + + + + + + + + + + + + + - - - - - - + + - - SU - - + SU + + - Support + + Support + - - - - - - - - - - - + + + + + - - - - - + + + + + + + - - - - - - + + - - AN - - - - Announcements - - - Last message in Announcements - + AN - - - - + Announcements - - - - - + Last message in Announcements - + + + + + + + + + + + + + + + + + + - - - - - - + + - - OF - - + OF + + - Off-topic + + Off-topic + - - - - - - - - - - - + + + + + - - - - - + + + + + + + - - - - - - + + - - TE - - - - Team Alpha - - - Last message in Team Alpha - + TE - + Team Alpha + + + Last message in Team Alpha + + + + + + + + + + + + + + + + + + + + - - - - - - - + 30 + - - - - - - - - - 30 - - - - - - + + - - TE - - + TE + + - Team Beta + + Team Beta + - - - - - - - - - - - + + + + + - - - - - + + + + + + + - - - - - - + + - - PR - - - - Project X - - - Last message in Project X - + PR - - - - + Project X - - - - - + Last message in Project X - + + + + + + + + + + + + + + + + + + - - - - - - + + - - PR - - + PR + + - Project Y + + Project Y + - - - - - - - - - - - + + + + + - - - - - + + + + + + + - - - - - - + + - - WA - - - - Water Cooler - - - Last message in Water Cooler - + WA - - - - + Water Cooler - - - - - + Last message in Water Cooler - + + + + + + + + + + + + + + + + + + - - - - - - + + - - FE - - - - Feedback - + FE - + Feedback + + + + + + + + + + + + + + + + + + + + - - - - - - - + 35 + - - - - - - - - - 35 - - - - - - + + - - ID - - - - Ideas - - - Last message in Ideas - + ID - - - - + Ideas - - - - - + Last message in Ideas - + + + + + + + + + + + + + + + + + + - - - + + @@ -8274,4824 +8331,4830 @@ exports[` > renders LargeSectionList story 1`] = ` - - - - - - - Favourites - - - - - - - - - - GE + + + + + Favourites + + + + + + + - - General - - - Last message in General - + GE - + General + + + Last message in General + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - + - - + + - - - - - RA - - + RA + + - Random + + Random + - - - - - - - - - - - + + + + + - - - - - + + + + + + + - - - + + - - - - - EN - - - - Engineering - - - Last message in Engineering - + EN - - - - + Engineering - - - - - + Last message in Engineering - + + + + + + + + + + + + + + + + + + - - - + + - - - - - DE - - + DE + + - Design + + Design + - - - - - - - - - - - + + + + + - - - - - + + + + + + + - - - + + - - - - - PR - - - - Product - - - Last message in Product - + PR - - - - + Product - - - - - + Last message in Product - + + + + + + + + + + + + + + + + + + - - - + + - - - - - MA - - - - Marketing - + MA - + Marketing + + + + + + + + + + + + + + + + + + + + - - - - - - - + 5 + - - - - - - - - - 5 - - - + + - - - - - SA - - - - Sales - - - Last message in Sales - + SA - - - - + Sales - - - - - + Last message in Sales - + + + + + + + + + + + + + + + + + + - - - + + - - - - - SU - - + SU + + - Support + + Support + - - - - - - - - - - - + + + + + - - - - - + + + + + + + - - - + + - - - - - AN - - - - Announcements - - - Last message in Announcements - + AN - - - - + Announcements - - - - - + Last message in Announcements - + + + + + + + + + + + + + + + + + + - - - + + - - - - - OF - - + OF + + - Off-topic + + Off-topic + - - - - - - - - - - - + + + + + - - - - - + + + + + + + - - - + + - - - - - TE - - - - Team Alpha - - - Last message in Team Alpha - + TE - + Team Alpha + + + Last message in Team Alpha + + + + + + + + + + + + + + + + + + + + - - - - - - - + 10 + - - - - - - - - - 10 - - - + + - - - - - TE - - + TE + + - Team Beta + + Team Beta + - - - - - - - - - - - + + + + + - - - - - + + + + + + + - - - + + - - - - - PR - - - - Project X - - - Last message in Project X - + PR - - - - + Project X - - - - - + Last message in Project X - + + + + + + + + + + + + + + + + + + - - - + + - - - - - PR - - + PR + + - Project Y + + Project Y + - - - - - - - - - - - + + + + + - - - - - + + + + + + + - - - + + - - - - - WA - - - - Water Cooler - - - Last message in Water Cooler - + WA - - - - + Water Cooler - - - - - + Last message in Water Cooler - + + + + + + + + + + + + + + + + + + - - - + + - - - - - FE - - - - Feedback - + FE - + Feedback + + + + + + + + + + + + + + + + + + + + - - - - - - - + 15 + - - - - - - - - - 15 - - - + + - - - - - ID - - - - Ideas - - - Last message in Ideas - + ID - - - - + Ideas - - - - - + Last message in Ideas - + + + + + + + + + + + + + + + + + + - - - + + - - - - - BU - - + BU + + - Bugs + + Bugs + - - - - - - - - - - - + + + + + - - - - - + + + + + + + - - - + + - - - - - FE - - - - Features - - - Last message in Features - + FE - - - - + Features - - - - - + Last message in Features - + + + + + + + + + + + + + + + + + + - - - + + - - - - - RE - - + RE + + - Releases + + Releases + - - - - - - - - - - - + + + + + - - - - - + + + + + + + - - - + + - - - - - GE - - - - General - - - Last message in General - + GE - + General + + + Last message in General + + + + + + + + + + + + + + + + + + + + - - - - - - - + 20 + - - - - - - - - - 20 - - - + + - - - - - RA - - + RA + + - Random + + Random + - - - - - - - - - - - + + + + + - - - - - + + + + + + + - - - + + - - - - - EN - - - - Engineering - - - Last message in Engineering - + EN - - - - + Engineering - - - - - + Last message in Engineering - + + + + + + + + + + + + + + + + + + - - - + + - - - - - - - - - Chats - - - + + + + + Chats + + + + - - - - - DE - - + DE + + - Design + + Design + - - - - - - - - - - - + + + + + - - - - - + + + + + + + - - - + + - - - - - PR - - - - Product - - - Last message in Product - + PR - - - - + Product - - - - - + Last message in Product - + + + + + + + + + + + + + + + + + + - - - + + - - - - - MA - - - - Marketing - + MA - + Marketing + + + + + + + + + + + + + + + + + + + + - - - - - - - + 25 + - - - - - - - - - 25 - - - + + - - - - - SA - - - - Sales - - - Last message in Sales - + SA - - - - + Sales - - - - - + Last message in Sales - + + + + + + + + + + + + + + + + + + - - - + + - - - - - SU - - + SU + + - Support + + Support + - - - - - - - - - - - + + + + + - - - - - + + + + + + + - - - + + - - - - - AN - - - - Announcements - - - Last message in Announcements - + AN - - - - + Announcements - - - - - + Last message in Announcements - + + + + + + + + + + + + + + + + + + - - - + + - - - - - OF - - + OF + + - Off-topic + + Off-topic + - - - - - - - - - - - + + + + + - - - - - + + + + + + + - - - + + - - - - - TE - - - - Team Alpha - - - Last message in Team Alpha - + TE - + Team Alpha + + + Last message in Team Alpha + + + + + + + + + + + + + + + + + + + + - - - - - - - + 30 + - - - - - - - - - 30 - - - + + - - - - - TE - - + TE + + - Team Beta + + Team Beta + - - - - - - - - - - - + + + + + - - - - - + + + + + + + - - - + + - - - - - PR - - - - Project X - - - Last message in Project X - + PR - - - - + Project X - - - - - + Last message in Project X - + + + + + + + + + + + + + + + + + + - - - + + - - - - - PR - - + PR + + - Project Y + + Project Y + - - - - - - - - - - - + + + + + - - - - - + + + + + + + - - - + + - - - - - WA - - - - Water Cooler - - - Last message in Water Cooler - + WA - - - - + Water Cooler - - - - - + Last message in Water Cooler - + + + + + + + + + + + + + + + + + + - - - + + @@ -13159,8 +13222,13 @@ exports[` > renders Loading story 1`] = ` + class="Flex-module_flex RoomListView-module_list" + style="--mx-flex-display: flex; --mx-flex-direction: column; --mx-flex-align: start; --mx-flex-justify: start; --mx-flex-gap: 0; --mx-flex-wrap: nowrap;" + > + + `; @@ -13223,291 +13291,297 @@ exports[` > renders SmallFlatList story 1`] = ` - - - GE - - - - General - - - Last message in General - + GE - + General + + + Last message in General + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - + - - - - - + + - - RA - - + RA + + - Random + + Random + - - - - - - - - - - - + + + + + - - - - - + + + + + + + - - - + + @@ -13574,87 +13648,501 @@ exports[` > renders SmallSectionList story 1`] = ` - - - - - - + + + + Favourites + + + + + + + + + - Favourites - - - + + GE + + + + + General + + + Last message in General + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + RA + + + + + Random + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Chats + + + + + + + + + +`; + +exports[` > renders Toast story 1`] = ` + + + + + + + Unreads + + + People + + + Rooms + + + Favourites + + + + + + + > renders SmallSectionList story 1`] = ` aria-expanded="false" aria-haspopup="menu" aria-label="More Options" - aria-labelledby="_r_17q_" + aria-labelledby="_r_1qo_" class="_icon-button_1215g_8" data-kind="primary" data-state="closed" - id="radix-_r_17o_" + id="radix-_r_1qm_" role="button" style="--cpd-icon-button-size: 24px; padding: 2px;" tabindex="0" @@ -13732,11 +14220,11 @@ exports[` > renders SmallSectionList story 1`] = ` aria-expanded="false" aria-haspopup="menu" aria-label="Notification options" - aria-labelledby="_r_181_" + aria-labelledby="_r_1qv_" class="_icon-button_1215g_8" data-kind="primary" data-state="closed" - id="radix-_r_17v_" + id="radix-_r_1qt_" role="button" style="--cpd-icon-button-size: 24px; padding: 2px;" tabindex="0" @@ -13789,26 +14277,21 @@ exports[` > renders SmallSectionList story 1`] = ` - - > renders SmallSectionList story 1`] = ` aria-expanded="false" aria-haspopup="menu" aria-label="More Options" - aria-labelledby="_r_188_" + aria-labelledby="_r_1r6_" class="_icon-button_1215g_8" data-kind="primary" data-state="closed" - id="radix-_r_186_" + id="radix-_r_1r4_" role="button" style="--cpd-icon-button-size: 24px; padding: 2px;" tabindex="0" @@ -13880,11 +14363,2330 @@ exports[` > renders SmallSectionList story 1`] = ` aria-expanded="false" aria-haspopup="menu" aria-label="Notification options" - aria-labelledby="_r_18f_" + aria-labelledby="_r_1rd_" class="_icon-button_1215g_8" data-kind="primary" data-state="closed" - id="radix-_r_18d_" + id="radix-_r_1rb_" + role="button" + style="--cpd-icon-button-size: 24px; padding: 2px;" + tabindex="0" + type="button" + > + + + + + + + + + + + + + + + + + EN + + + + + Engineering + + + Last message in Engineering + + + + + + + + + + + + + + + + + + + + + + + + + + + + DE + + + + + Design + + + + + + + + + + + + + + + + + + + + + + + + + + + + PR + + + + + Product + + + Last message in Product + + + + + + + + + + + + + + + + + + + + + + + + + + + + MA + + + + + Marketing + + + + + + + + + + + + + + + + + + + + + + + + + 5 + + + + + + + + + + + + SA + + + + + Sales + + + Last message in Sales + + + + + + + + + + + + + + + + + + + + + + + + + + + + SU + + + + + Support + + + + + + + + + + + + + + + + + + + + + + + + + + + + AN + + + + + Announcements + + + Last message in Announcements + + + + + + + + + + + + + + + + + + + + + + + + + + + + OF + + + + + Off-topic + + + + + + + + + + + + + + + + + + + + + + + + + + + + TE + + + + + Team Alpha + + + Last message in Team Alpha + + + + + + + + + + + + + + + + + + + + + + + + + 10 + + + + + + + + + + + + TE + + + + + Team Beta + + + + + + + + + + + + + + + + + + + + + + + + + + + + PR + + + + + Project X + + + Last message in Project X + + + + + + + + + + + + + + + + + + + + + + + + + + + + PR + + + + + Project Y + + + + + + + + + + + + + + + + + + + + + + + + + + + + WA + + + + + Water Cooler + + + Last message in Water Cooler + + + + + + + + + + + + + + + + + + + + + + + + + + + + FE + + + + + Feedback + + + + + + + + + + + + + + + + + + + + + + + + + 15 + + + + + + + + + + + + ID + + + + + Ideas + + + Last message in Ideas + + + + + + + + + + + + + + + + + + + + + + + + + + + + BU + + + + + Bugs + + + + + + + + + + + + + + + + + + + + + + + + + + + + FE + + + + + Features + + + Last message in Features + + + + + + + + + + + + + + + + + + + + + + + + + + + + RE + + + + + Releases + + + + + + + + + + + > renders SmallSectionList story 1`] = ` - - - - - - - - - Chats - - - - - + + + + + + Section created + + + + + + + + + @@ -14028,2610 +16831,2616 @@ exports[` > renders WithActiveFilter story 1`] = ` - - - GE - - - - General - - - Last message in General - + GE - + General + + + Last message in General + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - + - - - - - + + - - RA - - + RA + + - Random + + Random + - - - - - - - - - - - + + + + + - - - - - + + + + + + + - - - - - - + + - - EN - - - - Engineering - - - Last message in Engineering - + EN - - - - + Engineering - - - - - + Last message in Engineering - + + + + + + + + + + + + + + + + + + - - - - - - + + - - DE - - + DE + + - Design + + Design + - - - - - - - - - - - + + + + + - - - - - + + + + + + + - - - - - - + + - - PR - - - - Product - - - Last message in Product - + PR - - - - + Product - - - - - + Last message in Product - + + + + + + + + + + + + + + + + + + - - - - - - + + - - MA - - - - Marketing - + MA - + Marketing + + + + + + + + + + + + + + + + + + + + - - - - - - - + 5 + - - - - - - - - - 5 - - - - - - + + - - SA - - - - Sales - - - Last message in Sales - + SA - - - - + Sales - - - - - + Last message in Sales - + + + + + + + + + + + + + + + + + + - - - - - - + + - - SU - - + SU + + - Support + + Support + - - - - - - - - - - - + + + + + - - - - - + + + + + + + - - - - - - + + - - AN - - - - Announcements - - - Last message in Announcements - + AN - - - - + Announcements - - - - - + Last message in Announcements - + + + + + + + + + + + + + + + + + + - - - - - - + + - - OF - - + OF + + - Off-topic + + Off-topic + - - - - - - - - - - - + + + + + - - - - - + + + + + + + - - - - - - + + - - TE - - - - Team Alpha - - - Last message in Team Alpha - + TE - + Team Alpha + + + Last message in Team Alpha + + + + + + + + + + + + + + + + + + + + - - - - - - - + 10 + - - - - - - - - - 10 - - - - - - + + - - TE - - + TE + + - Team Beta + + Team Beta + - - - - - - - - - - - + + + + + - - - - - + + + + + + + - - - - - - + + - - PR - - - - Project X - - - Last message in Project X - + PR - - - - + Project X - - - - - + Last message in Project X - + + + + + + + + + + + + + + + + + + - - - - - - + + - - PR - - + PR + + - Project Y + + Project Y + - - - - - - - - - - - + + + + + - - - - - + + + + + + + - - - - - - + + - - WA - - - - Water Cooler - - - Last message in Water Cooler - + WA - - - - + Water Cooler - - - - - + Last message in Water Cooler - + + + + + + + + + + + + + + + + + + - - - - - - + + - - FE - - - - Feedback - + FE - + Feedback + + + + + + + + + + + + + + + + + + + + - - - - - - - + 15 + - - - - - - - - - 15 - - - - - - + + - - ID - - - - Ideas - - - Last message in Ideas - + ID - - - - + Ideas - - - - - + Last message in Ideas - + + + + + + + + + + + + + + + + + + - - - - - - + + - - BU - - + BU + + - Bugs + + Bugs + - - - - - - - - - - - + + + + + - - - - - + + + + + + + - - - - - - + + - - FE - - - - Features - - - Last message in Features - + FE - - - - + Features - - - - - + Last message in Features - + + + + + + + + + + + + + + + + + + - - - - - - + + - - RE - - + RE + + - Releases + + Releases + - - - - - - - - - - - + + + + + - - - - - + + + + + + + - - - + + diff --git a/packages/shared-components/src/room-list/VirtualizedRoomListView/RoomListItemAccessibilityWrapper/RoomListItemView/RoomListItemMoreOptionsMenu.test.tsx b/packages/shared-components/src/room-list/VirtualizedRoomListView/RoomListItemAccessibilityWrapper/RoomListItemView/RoomListItemMoreOptionsMenu.test.tsx index ac13f7874e..bbf0fcc63a 100644 --- a/packages/shared-components/src/room-list/VirtualizedRoomListView/RoomListItemAccessibilityWrapper/RoomListItemView/RoomListItemMoreOptionsMenu.test.tsx +++ b/packages/shared-components/src/room-list/VirtualizedRoomListView/RoomListItemAccessibilityWrapper/RoomListItemView/RoomListItemMoreOptionsMenu.test.tsx @@ -10,7 +10,7 @@ import { render, screen } from "@test-utils"; import userEvent from "@testing-library/user-event"; import { describe, it, expect, vi } from "vitest"; -import { RoomListItemMoreOptionsMenu } from "./RoomListItemMoreOptionsMenu"; +import { RoomListItemMoreOptionsMenu, MoreOptionContent } from "./RoomListItemMoreOptionsMenu"; import { useMockedViewModel } from "../../../../core/viewmodel"; import type { RoomListItemViewSnapshot } from "./RoomListItemView"; import { defaultSnapshot } from "./default-snapshot"; @@ -26,6 +26,7 @@ describe("", () => { onCopyRoomLink: vi.fn(), onLeaveRoom: vi.fn(), onSetRoomNotifState: vi.fn(), + onCreateSection: vi.fn(), }; const renderMenu = (overrides: Partial = {}): ReturnType => { @@ -224,4 +225,19 @@ describe("", () => { expect(mockCallbacks.onLeaveRoom).toHaveBeenCalled(); }); + + it("should call onCreateSection when new section is clicked", async () => { + const user = userEvent.setup(); + // We need to render the MoreOptionContent directly here as radix is kind of messing in the test env + const TestComponent = (): JSX.Element => { + const vm = useMockedViewModel(defaultSnapshot, mockCallbacks); + return ; + }; + render(); + + const newSection = screen.getByRole("menuitem", { name: "New section" }); + await user.click(newSection); + + expect(mockCallbacks.onCreateSection).toHaveBeenCalled(); + }); }); diff --git a/packages/shared-components/src/room-list/VirtualizedRoomListView/RoomListItemAccessibilityWrapper/RoomListItemView/RoomListItemMoreOptionsMenu.tsx b/packages/shared-components/src/room-list/VirtualizedRoomListView/RoomListItemAccessibilityWrapper/RoomListItemView/RoomListItemMoreOptionsMenu.tsx index 8a6286e01c..e03504ad01 100644 --- a/packages/shared-components/src/room-list/VirtualizedRoomListView/RoomListItemAccessibilityWrapper/RoomListItemView/RoomListItemMoreOptionsMenu.tsx +++ b/packages/shared-components/src/room-list/VirtualizedRoomListView/RoomListItemAccessibilityWrapper/RoomListItemView/RoomListItemMoreOptionsMenu.tsx @@ -6,7 +6,7 @@ */ import React, { useState, type JSX } from "react"; -import { IconButton, Menu, MenuItem, Separator, ToggleMenuItem } from "@vector-im/compound-web"; +import { IconButton, Menu, MenuItem, Separator, SubMenu, ToggleMenuItem } from "@vector-im/compound-web"; import { MarkAsReadIcon, MarkAsUnreadIcon, @@ -16,6 +16,7 @@ import { LinkIcon, LeaveIcon, OverflowHorizontalIcon, + ArrowRightIcon, } from "@vector-im/compound-design-tokens/assets/web/icons"; import { _t } from "../../../../core/i18n/i18n"; @@ -106,6 +107,7 @@ export function MoreOptionContent({ vm }: MoreOptionContentProps): JSX.Element { onSelect={vm.onToggleLowPriority} onClick={(evt) => evt.stopPropagation()} /> + {snapshot.canInvite && ( )} + {snapshot.canMoveToSection && ( + + } + > + + + )} ", () => { onCopyRoomLink: vi.fn(), onLeaveRoom: vi.fn(), onSetRoomNotifState: vi.fn(), + onCreateSection: vi.fn(), }; const renderMenu = (roomNotifState: RoomNotifState = RoomNotifState.AllMessages): ReturnType => { diff --git a/packages/shared-components/src/room-list/VirtualizedRoomListView/RoomListItemAccessibilityWrapper/RoomListItemView/RoomListItemView.stories.tsx b/packages/shared-components/src/room-list/VirtualizedRoomListView/RoomListItemAccessibilityWrapper/RoomListItemView/RoomListItemView.stories.tsx index c6c7986ffb..165d38d267 100644 --- a/packages/shared-components/src/room-list/VirtualizedRoomListView/RoomListItemAccessibilityWrapper/RoomListItemView/RoomListItemView.stories.tsx +++ b/packages/shared-components/src/room-list/VirtualizedRoomListView/RoomListItemAccessibilityWrapper/RoomListItemView/RoomListItemView.stories.tsx @@ -38,6 +38,7 @@ const RoomListItemWrapperImpl = ({ onCopyRoomLink, onLeaveRoom, onSetRoomNotifState, + onCreateSection, isSelected, isFocused, onFocus, @@ -56,6 +57,7 @@ const RoomListItemWrapperImpl = ({ onCopyRoomLink, onLeaveRoom, onSetRoomNotifState, + onCreateSection, }); return ( void; /** Called when setting the room notification state */ onSetRoomNotifState: (state: RoomNotifState) => void; + /** Called when creating a new section */ + onCreateSection: () => void; } /** diff --git a/packages/shared-components/src/room-list/VirtualizedRoomListView/RoomListItemAccessibilityWrapper/RoomListItemView/default-snapshot.ts b/packages/shared-components/src/room-list/VirtualizedRoomListView/RoomListItemAccessibilityWrapper/RoomListItemView/default-snapshot.ts index 2ec961ff98..f01243eb09 100644 --- a/packages/shared-components/src/room-list/VirtualizedRoomListView/RoomListItemAccessibilityWrapper/RoomListItemView/default-snapshot.ts +++ b/packages/shared-components/src/room-list/VirtualizedRoomListView/RoomListItemAccessibilityWrapper/RoomListItemView/default-snapshot.ts @@ -36,4 +36,5 @@ export const defaultSnapshot: RoomListItemViewSnapshot = { canMarkAsRead: false, canMarkAsUnread: true, roomNotifState: RoomNotifState.AllMessages, + canMoveToSection: true, }; diff --git a/packages/shared-components/src/room-list/VirtualizedRoomListView/RoomListItemAccessibilityWrapper/RoomListItemView/mocked-actions.ts b/packages/shared-components/src/room-list/VirtualizedRoomListView/RoomListItemAccessibilityWrapper/RoomListItemView/mocked-actions.ts index bda12ac114..806e2e76ff 100644 --- a/packages/shared-components/src/room-list/VirtualizedRoomListView/RoomListItemAccessibilityWrapper/RoomListItemView/mocked-actions.ts +++ b/packages/shared-components/src/room-list/VirtualizedRoomListView/RoomListItemAccessibilityWrapper/RoomListItemView/mocked-actions.ts @@ -19,4 +19,5 @@ export const mockedActions: RoomListItemViewActions = { onCopyRoomLink: fn(), onLeaveRoom: fn(), onSetRoomNotifState: fn(), + onCreateSection: fn(), }; diff --git a/packages/shared-components/src/room-list/VirtualizedRoomListView/VirtualizedRoomListView.module.css b/packages/shared-components/src/room-list/VirtualizedRoomListView/VirtualizedRoomListView.module.css index c444c8c1cd..e42f1fbaca 100644 --- a/packages/shared-components/src/room-list/VirtualizedRoomListView/VirtualizedRoomListView.module.css +++ b/packages/shared-components/src/room-list/VirtualizedRoomListView/VirtualizedRoomListView.module.css @@ -9,6 +9,5 @@ * Room list container styles */ .roomList { - height: 100%; width: 100%; } diff --git a/packages/shared-components/src/room-list/VirtualizedRoomListView/VirtualizedRoomListView.stories.tsx b/packages/shared-components/src/room-list/VirtualizedRoomListView/VirtualizedRoomListView.stories.tsx index a5048b5c73..b1c312cee0 100644 --- a/packages/shared-components/src/room-list/VirtualizedRoomListView/VirtualizedRoomListView.stories.tsx +++ b/packages/shared-components/src/room-list/VirtualizedRoomListView/VirtualizedRoomListView.stories.tsx @@ -34,6 +34,7 @@ const RoomListWrapperImpl = ({ getRoomItemViewModel, getSectionHeaderViewModel, updateVisibleRooms, + closeToast, renderAvatar: renderAvatarProp, ...rest }: RoomListStoryProps): JSX.Element => { @@ -44,6 +45,7 @@ const RoomListWrapperImpl = ({ getRoomItemViewModel, getSectionHeaderViewModel, updateVisibleRooms, + closeToast, }); return ( @@ -82,6 +84,7 @@ const meta = { updateVisibleRooms: fn(), renderAvatar, isFlatList: true, + closeToast: fn(), }, parameters: { design: { diff --git a/packages/shared-components/src/room-list/VirtualizedRoomListView/VirtualizedRoomListView.tsx b/packages/shared-components/src/room-list/VirtualizedRoomListView/VirtualizedRoomListView.tsx index ad6b105e05..180723ba44 100644 --- a/packages/shared-components/src/room-list/VirtualizedRoomListView/VirtualizedRoomListView.tsx +++ b/packages/shared-components/src/room-list/VirtualizedRoomListView/VirtualizedRoomListView.tsx @@ -21,6 +21,7 @@ import type { RoomListViewSnapshot, RoomListViewModel } from "../RoomListView"; import { GroupedVirtualizedList } from "../../core/VirtualizedList"; import { RoomListSectionHeaderView } from "./RoomListSectionHeaderView"; import { RoomListItemAccessibilityWrapper } from "./RoomListItemAccessibilityWrapper"; +import styles from "./VirtualizedRoomListView.module.css"; /** * Filter key type - opaque string type for filter identifiers @@ -350,6 +351,7 @@ export function VirtualizedRoomListView({ vm, renderAvatar, onKeyDown }: Virtual rangeChanged, onKeyDown, increaseViewportBy, + className: styles.roomList, }; if (isFlatList) { diff --git a/packages/shared-components/src/room-list/VirtualizedRoomListView/__snapshots__/VirtualizedRoomListView.test.tsx.snap b/packages/shared-components/src/room-list/VirtualizedRoomListView/__snapshots__/VirtualizedRoomListView.test.tsx.snap index 6b64e96ad3..03e092feff 100644 --- a/packages/shared-components/src/room-list/VirtualizedRoomListView/__snapshots__/VirtualizedRoomListView.test.tsx.snap +++ b/packages/shared-components/src/room-list/VirtualizedRoomListView/__snapshots__/VirtualizedRoomListView.test.tsx.snap @@ -10,6 +10,7 @@ exports[` > renders Default story 1`] = ` >