Skip to content

feat: migrate options, selects, menus and member lists to Item - #42818

Merged
ggazzo merged 30 commits into
developfrom
feat/item-options-menu
Oct 16, 2026
Merged

ggazzo merged 30 commits into
developfrom
feat/item-options-menu

Conversation

@juliajforesti

@juliajforesti juliajforesti commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Proposed changes (including videos or screenshots)

ARCH-2496
Migrates Option, Options, Select and Menu to the Item components, and applies the result across Rocket.Chat in the same PR, so every list built on them changes together.

Fuselage

Renders Option, Options, Select and Menu with the Item family from RocketChat/fuselage#2281. Rows share one layout and one set of states, and the public rcx-option classes stay in place.

Item

  • Menu-item rows (role="menuitem*") are named by their ItemTitle and described by a labelled ItemIcon, as an ItemLink is.
  • New focusVisible prop shows the focus ring for focus moved by a script, such as a menu's. The browser's :focus-visible also matches on hover there.

Menu

  • MenuItem, submenu triggers and MenuSection render as Item, ItemGroupHeader and ItemGroup.

Option, Options and Select

  • Option renders as an Item row. The Option* parts, and their MenuItem* aliases, render as the matching Item part: ItemMedia, ItemIcon, ItemContent, ItemTitle, ItemDescription and ItemActions.
  • OptionHeader and OptionTitle render as ItemGroupHeader. Options dividers render as ItemDivider, and Select sections as ItemGroupHeader and ItemGroup.
  • New iconLabel prop on Option names what its icon conveys. Without it, the icon stays decorative.

Fixes

  • Options scrolls to the keyboard cursor when renderItem renders an Item.
  • The CheckOption checkbox is hidden from assistive technology and made inert, so selection is announced once, through aria-selected.
  • OptionSkeleton placeholder rows are hidden from assistive technology.
  • The Options empty state is a disabled option, so the listbox only contains options.

Rocket.Chat

  • Autocompletes (rooms, users, teams, departments, agents, contacts, peers) and the UiKit user and channel selects use Item parts. Avatars use ITEM_MEDIA_SIZE, and status or room-type icons are named with iconLabel.
  • Room members, banned users and team channels render as Item rows. Member groups use an ItemGroupHeader instead of MembersListDivider, and row menus mount through useDeferredMenuMount.
  • Call members, participants and the chat access modal render as Item rows. The members panel groups "In call" and "Not in the call" as named lists.
  • The category menu's "Create new" item uses GenericMenuItem.

Issue(s)

Replaces RocketChat/fuselage#2310, and takes over the options, selects, menus and member-list parts of #42520.

Steps to test or reproduce

  • yarn workspace @rocket.chat/fuselage storybook: the Menu, Option, Options and Select stories.
  • In the app: room/user/team autocompletes, a UiKit modal with user and channel selects, the room members, banned users and team channels contextual bars, the user menu, and a video conference's members panel. Check with a keyboard and a screen reader.

Further comments

Part of the Item migration, split by area (fuselage change + its application together, so each area looks finished when it merges):

Bottom commits from other PRs, dropped on rebase once they land: #42829 (hidden-actions gap fix), #42831 (useDeferredMenuMount in ui-client), #42830 (ITEM_MEDIA_SIZE).

Commit order: fuselage commits first (replayed from the Fuselage PR), then test: adapt app tests… with the adaptations the fuselage change forces on its own (the CheckOption checkbox is hidden from assistive technology; MenuItemContent wraps its text in an ItemTitle), then the app commits.

Why Options and Menu are in one PR: the public MenuItem* parts re-export the Option* parts, so migrating one without the other breaks every menu.

Jest snapshots and the visual-regression baselines (arm64 image) were regenerated here. fuselage.api.md isn't part of this repository, so those commits were dropped.

🤖 Generated with Claude Code

@dionisio-bot

dionisio-bot Bot commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Looks like this PR is not ready to merge, because of the following issues:

  • This PR is missing the 'stat: QA assured' label

Please fix the issues and try again

If you have any trouble, please check the PR guidelines

@coderabbitai

coderabbitai Bot commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 5ffd106b-d658-469e-8e82-f617dc17090f
📥 Commits

Reviewing files that changed from the base of the PR and between 6b86dff and dd25fc2.

⛔ Files ignored due to path filters: 29
  • apps/meteor/client/views/room/contextualBar/BannedUsers/__snapshots__/BannedUsers.spec.tsx.snap is excluded by !**/*.snap
  • apps/meteor/client/views/room/contextualBar/RoomMembers/__snapshots__/RoomMembers.spec.tsx.snap is excluded by !**/*.snap
  • packages/fuselage/src/components/Item/__snapshots__/Item.spec.tsx.snap is excluded by !**/*.snap
  • packages/fuselage/src/components/Menu/__snapshots__/Menu.spec.tsx.snap is excluded by !**/*.snap
  • packages/fuselage/src/components/Option/__snapshots__/Option.spec.tsx.snap is excluded by !**/*.snap
  • packages/fuselage/src/components/Options/__snapshots__/Options.spec.tsx.snap is excluded by !**/*.snap
  • packages/fuselage/test/snapshots/navigation-dropdown--default-desktop.png is excluded by !**/*.png
  • packages/fuselage/test/snapshots/navigation-item--hidden-actions-desktop.png is excluded by !**/*.png
  • packages/fuselage/test/snapshots/navigation-menu--with-item-aliases-desktop.png is excluded by !**/*.png
  • packages/fuselage/test/snapshots/navigation-menu--with-item-parts-desktop.png is excluded by !**/*.png
  • packages/fuselage/test/snapshots/navigation-option--as-user-item-desktop.png is excluded by !**/*.png
  • packages/fuselage/test/snapshots/navigation-option--default-desktop.png is excluded by !**/*.png
  • packages/fuselage/test/snapshots/navigation-option--disabled-desktop.png is excluded by !**/*.png
  • packages/fuselage/test/snapshots/navigation-option--with-and-without-icon-desktop.png is excluded by !**/*.png
  • packages/fuselage/test/snapshots/navigation-option--with-avatar-desktop.png is excluded by !**/*.png
  • packages/fuselage/test/snapshots/navigation-option--with-icon-desktop.png is excluded by !**/*.png
  • packages/fuselage/test/snapshots/navigation-option--with-menu-desktop.png is excluded by !**/*.png
  • packages/fuselage/test/snapshots/navigation-option--with-presence-desktop.png is excluded by !**/*.png
  • packages/fuselage/test/snapshots/navigation-options--check-option-story-desktop.png is excluded by !**/*.png
  • packages/fuselage/test/snapshots/navigation-options--custom-empty-desktop.png is excluded by !**/*.png
  • packages/fuselage/test/snapshots/navigation-options--default-desktop.png is excluded by !**/*.png
  • packages/fuselage/test/snapshots/navigation-options--empty-options-desktop.png is excluded by !**/*.png
  • packages/fuselage/test/snapshots/navigation-options--grouped-desktop.png is excluded by !**/*.png
  • packages/fuselage/test/snapshots/navigation-options--option-story-desktop.png is excluded by !**/*.png
  • packages/fuselage/test/snapshots/navigation-options-optionspaginated--check-option-story-desktop.png is excluded by !**/*.png
  • packages/fuselage/test/snapshots/navigation-options-optionspaginated--default-desktop.png is excluded by !**/*.png
  • packages/fuselage/test/snapshots/navigation-options-optionspaginated--option-story-desktop.png is excluded by !**/*.png
  • packages/ui-conference/src/call/__snapshots__/callStories.spec.tsx.snap is excluded by !**/*.snap
  • packages/ui-conference/src/preflight/__snapshots__/preflightStories.spec.tsx.snap is excluded by !**/*.snap
📒 Files selected for processing: 94
  • .changeset/check-option-hidden-checkbox.md
  • .changeset/check-option-inert-checkbox.md
  • .changeset/item-options-menu-app.md
  • .changeset/menu-item-rows.md
  • .changeset/option-groups-item.md
  • .changeset/option-icon-label.md
  • .changeset/option-item-rows.md
  • .changeset/option-parts-item.md
  • .changeset/option-skeleton-hidden.md
  • .changeset/options-empty-option.md
  • .changeset/options-item-focus-scroll.md
  • apps/meteor/client/components/RoomAutoComplete/RoomAutoComplete.tsx
  • apps/meteor/client/components/RoomAutoCompleteMultiple/RoomAutoCompleteMultiple.tsx
  • apps/meteor/client/components/UserAndRoomAutoCompleteMultiple/UserAndRoomAutoCompleteMultiple.tsx
  • apps/meteor/client/components/UserAutoCompleteMultiple/UserAutoCompleteMultipleOption.tsx
  • apps/meteor/client/components/UserStatusText/UserStatusText.tsx
  • apps/meteor/client/components/UserStatusText/index.ts
  • apps/meteor/client/sidebar/categories/CategoryMenu.tsx
  • apps/meteor/client/views/omnichannel/components/AutoCompleteDepartmentMultiple.spec.tsx
  • apps/meteor/client/views/omnichannel/components/outboundMessage/components/AutoCompleteDepartmentAgent.tsx
  • apps/meteor/client/views/omnichannel/components/outboundMessage/components/OutboundMessageWizard/forms/RecipientForm/components/ContactField.tsx
  • apps/meteor/client/views/room/contextualBar/BannedUsers/BannedUsers.tsx
  • apps/meteor/client/views/room/contextualBar/BannedUsers/BannedUsersItem.tsx
  • apps/meteor/client/views/room/contextualBar/RoomMembers/MembersListDivider.tsx
  • apps/meteor/client/views/room/contextualBar/RoomMembers/MembersListGroupHeader.tsx
  • apps/meteor/client/views/room/contextualBar/RoomMembers/RoomMembers.tsx
  • apps/meteor/client/views/room/contextualBar/RoomMembers/RoomMembersItem.spec.tsx
  • apps/meteor/client/views/room/contextualBar/RoomMembers/RoomMembersItem.tsx
  • apps/meteor/client/views/room/contextualBar/RoomMembers/RoomMembersRow.tsx
  • apps/meteor/client/views/room/contextualBar/RoomMembers/useMembersListNavigation.spec.ts
  • apps/meteor/client/views/room/contextualBar/RoomMembers/useMembersListNavigation.ts
  • apps/meteor/client/views/teams/contextualBar/TeamAutocomplete/TeamAutocomplete.tsx
  • apps/meteor/client/views/teams/contextualBar/channels/AddExistingModal/RoomsAvailableForTeamsAutoComplete.tsx
  • apps/meteor/client/views/teams/contextualBar/channels/TeamsChannelItem.tsx
  • apps/meteor/client/views/teams/contextualBar/channels/TeamsChannels.tsx
  • apps/meteor/tests/e2e/page-objects/conference-window.ts
  • apps/meteor/tests/e2e/page-objects/fragments/flextabs/channels-flextab.ts
  • apps/meteor/tests/e2e/page-objects/fragments/flextabs/members-flextab.ts
  • apps/meteor/tests/e2e/saml.spec.ts
  • apps/meteor/tests/e2e/video-conference-call-window.spec.ts
  • packages/fuselage-ui-kit/src/elements/ChannelsSelectElement/ChannelsSelectElement.tsx
  • packages/fuselage-ui-kit/src/elements/ChannelsSelectElement/MultiChannelsSelectElement.tsx
  • packages/fuselage-ui-kit/src/elements/UsersSelectElement/MultiUsersSelectElement.tsx
  • packages/fuselage-ui-kit/src/elements/UsersSelectElement/UsersSelectElement.tsx
  • packages/fuselage/src/components/Item/Item.stories.tsx
  • packages/fuselage/src/components/Item/Item.styles.scss
  • packages/fuselage/src/components/Item/Item.tsx
  • packages/fuselage/src/components/Item/ItemContext.ts
  • packages/fuselage/src/components/Item/ItemIcon.tsx
  • packages/fuselage/src/components/Item/ItemTitle.tsx
  • packages/fuselage/src/components/Menu/Menu.spec.tsx
  • packages/fuselage/src/components/Menu/Menu.stories.tsx
  • packages/fuselage/src/components/Menu/Menu.styles.scss
  • packages/fuselage/src/components/Menu/MenuItem.tsx
  • packages/fuselage/src/components/Menu/MenuSection.tsx
  • packages/fuselage/src/components/Menu/MenuSubmenu.tsx
  • packages/fuselage/src/components/MultiSelect/MultiSelect.spec.tsx
  • packages/fuselage/src/components/Option/CheckOption.tsx
  • packages/fuselage/src/components/Option/Option.spec.tsx
  • packages/fuselage/src/components/Option/Option.stories.tsx
  • packages/fuselage/src/components/Option/Option.styles.scss
  • packages/fuselage/src/components/Option/Option.tsx
  • packages/fuselage/src/components/Option/OptionAvatar.tsx
  • packages/fuselage/src/components/Option/OptionColumn.tsx
  • packages/fuselage/src/components/Option/OptionContent.tsx
  • packages/fuselage/src/components/Option/OptionDescription.tsx
  • packages/fuselage/src/components/Option/OptionHeader.tsx
  • packages/fuselage/src/components/Option/OptionIcon.tsx
  • packages/fuselage/src/components/Option/OptionInput.tsx
  • packages/fuselage/src/components/Option/OptionMenu.tsx
  • packages/fuselage/src/components/Option/OptionSkeleton.tsx
  • packages/fuselage/src/components/Option/OptionTitle.tsx
  • packages/fuselage/src/components/Options/Options.spec.tsx
  • packages/fuselage/src/components/Options/Options.stories.tsx
  • packages/fuselage/src/components/Options/Options.styles.scss
  • packages/fuselage/src/components/Options/Options.tsx
  • packages/fuselage/src/components/Options/OptionsEmpty.tsx
  • packages/fuselage/src/components/OptionsPaginated/OptionsPaginated.tsx
  • packages/fuselage/src/components/Select/Listbox.tsx
  • packages/fuselage/src/components/Select/Select.spec.tsx
  • packages/fuselage/src/components/index.scss
  • packages/ui-avatar/src/index.ts
  • packages/ui-avatar/src/itemMediaSize.ts
  • packages/ui-client/src/components/MembersListDivider/MembersListDivider.tsx
  • packages/ui-client/src/components/MembersListDivider/index.ts
  • packages/ui-client/src/components/MultiSelectCustom/MultiSelectCustomList.tsx
  • packages/ui-client/src/components/UserAutoComplete/UserAutoComplete.tsx
  • packages/ui-client/src/components/index.ts
  • packages/ui-conference/src/components/CallMemberItem/CallMemberItem.tsx
  • packages/ui-conference/src/components/CallMembersPanel/CallMembersPanel.stories.tsx
  • packages/ui-conference/src/components/CallMembersPanel/CallMembersPanel.tsx
  • packages/ui-conference/src/components/CallParticipantItem/CallParticipantItem.tsx
  • packages/ui-conference/src/components/ChatAccessModal/ChatAccessModal.tsx
  • packages/ui-voip/src/components/PeerAutocomplete.tsx
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Base automatically changed from chore/migrate-fuselage to develop October 15, 2026 20:34
@juliajforesti
juliajforesti force-pushed the feat/item-options-menu branch from 96f5ade to 24ca06a Compare October 15, 2026 21:22
@changeset-bot

changeset-bot Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: dd25fc2

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 22 packages
Name Type
@rocket.chat/fuselage Minor
@rocket.chat/meteor Minor
@rocket.chat/ui-client Minor
@rocket.chat/ui-conference Minor
@rocket.chat/ui-voip Minor
@rocket.chat/fuselage-ui-kit Minor
@rocket.chat/uikit-playground Patch
@rocket.chat/core-typings Minor
@rocket.chat/fuselage-forms Patch
@rocket.chat/fuselage-toastbar Patch
@rocket.chat/gazzodown Patch
@rocket.chat/layout Patch
@rocket.chat/onboarding-ui Patch
@rocket.chat/storybook-config Patch
@rocket.chat/ui-account Patch
@rocket.chat/ui-avatar Patch
@rocket.chat/ui-composer Patch
@rocket.chat/ui-media Patch
@rocket.chat/ui-video-conf Patch
@rocket.chat/web-ui-registration Patch
@rocket.chat/ui-livekit Patch
@rocket.chat/rest-typings Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@juliajforesti
juliajforesti force-pushed the feat/item-options-menu branch from 24ca06a to 505f830 Compare October 15, 2026 22:25
@juliajforesti juliajforesti changed the title feat: Migrate Option, Options, Select and Menu to Item components feat: migrate options, selects, menus and member lists to Item Oct 15, 2026
@codecov

codecov Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 67.03911% with 118 lines in your changes missing coverage. Please review.
✅ Project coverage is 70.52%. Comparing base (6b86dff) to head (dd25fc2).
⚠️ Report is 1 commits behind head on develop.

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##           develop   #42818      +/-   ##
===========================================
+ Coverage    70.51%   70.52%   +0.01%     
===========================================
  Files         5413     5414       +1     
  Lines       229634   229754     +120     
  Branches     41800    41860      +60     
===========================================
+ Hits        161934   162044     +110     
- Misses       62350    62371      +21     
+ Partials      5350     5339      -11     
Flag Coverage Δ
unit 71.00% <67.03%> (+0.02%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@ggazzo ggazzo added the preview Builds a UI preview that Rocket.Chat Desktop can load label Oct 16, 2026
@github-actions

github-actions Bot commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

🖥️ UI preview

Removed from ghcr.io/rocketchat/rocket.chat-web. Add the preview label again to publish a new one.

juliajforesti and others added 14 commits October 15, 2026 22:14
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…by labelled `ItemIcon`

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… `Item`

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…technology

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…` as `ItemMedia` and `ItemIcon`

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…emContent`, `ItemTitle` and `ItemDescription`

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
juliajforesti and others added 16 commits October 15, 2026 22:14
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…Header`

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…`Item` group parts

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…st-axe and snapshots

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… and group headers

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The `CheckOption` checkbox is hidden from assistive technology, and `MenuItemContent` wraps its text in an `ItemTitle`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Avatars use `ITEM_MEDIA_SIZE`, and option icons that convey a state are named with `iconLabel`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…he chat access modal

The members panel groups "In call" and "Not in the call" as named `ItemGroup` lists instead of dividers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Member groups use an `ItemGroupHeader` instead of `MembersListDivider`, and row menus mount through `useDeferredMenuMount`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ggazzo
ggazzo force-pushed the feat/item-options-menu branch from 505f830 to dd25fc2 Compare October 16, 2026 01:14
@ggazzo ggazzo added this to the 8.10.0 milestone Oct 16, 2026
@ggazzo
ggazzo marked this pull request as ready for review October 16, 2026 01:18
@ggazzo
ggazzo requested a review from a team as a code owner October 16, 2026 01:18
@ggazzo
ggazzo merged commit 80dceec into develop Oct 16, 2026
15 of 17 checks passed
@ggazzo
ggazzo deleted the feat/item-options-menu branch October 16, 2026 01:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

preview Builds a UI preview that Rocket.Chat Desktop can load

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants