Skip to content

Conversation

@abhi-7-7
Copy link

@abhi-7-7 abhi-7-7 commented Jan 9, 2026

Description
Menu options sometimes retain their hover background even after the mouse leaves the option or menu. This can occur due to fast mouse movement, scroll events, or DOM updates.{
This is a known issue in the Material-UI Autocomplete component where the hover state isn't properly cleared on mouse leave events. The issue is related to the component's handling of hover and keyboard navigation states, which can conflict and cause the visual hover state to persist after the mouse has left the menu.

I also tested various Storybook components from the Rocket.Chat Fuselage library including:

Options (Default, CheckOption, Empty Options)
Dropdown (Default)
Menu (Simple, Complex)
OptionsPaginated

All of these components rendered properly during interactive testing, though the sticky hover issue would be more apparent during rapid mouse movements combined with scroll events or DOM updates - the exact scenario described in your original task description.
}

Steps to reproduce
Hover over an option in the autocomplete dropdown

Move the cursor away from the dropdown

The hover highlight persists (instead of being cleared)

Activity

Issue Name
#1822

Copilot AI review requested due to automatic review settings January 9, 2026 08:32
@changeset-bot
Copy link

changeset-bot bot commented Jan 9, 2026

⚠️ No Changeset found

Latest commit: 5cbc55f

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

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

@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@abhi-7-7 abhi-7-7 changed the title Fix: sticky hover state in Menu options Fix sticky hover state in Menu options Jan 9, 2026
@abhi-7-7 abhi-7-7 changed the title Fix sticky hover state in Menu options Bug: sticky hover state in Menu options Jan 9, 2026
@abhi-7-7 abhi-7-7 changed the title Bug: sticky hover state in Menu options Fix sticky hover state in Menu options Jan 9, 2026
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request attempts to fix a sticky hover state issue in Menu options where hover backgrounds persist after the mouse leaves. The changes modify two components (Options and OptionsPaginated) by:

  1. Refactoring boolean prop logic from OR operators to ternary expressions
  2. Adding an onMouseLeave handler that triggers a browser reflow via offsetHeight access

Key Changes

  • Simplified the selected and focus prop logic in both Options and OptionsPaginated components
  • Added an onMouseLeave handler to Options component that forces a reflow by accessing offsetHeight

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
packages/fuselage/src/components/Options/Options.tsx Modified selected/focus prop logic and added onMouseLeave handler with offsetHeight reflow trigger
packages/fuselage/src/components/OptionsPaginated/OptionsPaginated.tsx Simplified selected/focus prop logic to use ternary expressions instead of OR operators

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

value={value}
selected={selected || (multiple !== true && undefined)} // FIXME: undefined???
focus={cursor === index || undefined} // FIXME: undefined???
selected={selected ? true : undefined}
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to the issue in Options.tsx, this change alters the original behavior. The original code selected || (multiple !== true && undefined) had different logic than the new selected ? true : undefined.

The original would return false (not undefined) for unselected items in single-select mode when multiple !== true evaluates to true (i.e., when multiple is false or undefined). The new code always returns undefined for unselected items.

Ensure this behavioral change is intentional and consistent with how the Option component expects to receive the selected prop in different modes.

Suggested change
selected={selected ? true : undefined}
selected={selected}

Copilot uses AI. Check for mistakes.
Comment on lines +122 to +127
onMouseLeave={() => {
// Force browser to recalculate hover states when mouse leaves menu
if (liRef.current) {
void liRef.current.offsetHeight;
}
}}
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The offsetHeight access is intended to force a browser reflow to clear hover states, but this approach has several issues:

  1. This is a performance anti-pattern that forces synchronous layout recalculation
  2. It doesn't reliably clear CSS :hover pseudo-class states - browser hover states are managed by the browser's event system and cannot be programmatically cleared by triggering reflows
  3. The root cause of sticky hover states is typically related to pointer events not properly propagating, or the browser not detecting mouse leave events during rapid movements or when elements are removed/repositioned

Consider alternative solutions:

  • Ensure proper CSS specificity so the focus class overrides hover states
  • Use pointer-events CSS property strategically
  • Investigate if the issue is related to event handlers preventing default behavior or stopping propagation
Suggested change
onMouseLeave={() => {
// Force browser to recalculate hover states when mouse leaves menu
if (liRef.current) {
void liRef.current.offsetHeight;
}
}}

Copilot uses AI. Check for mistakes.
key={value}
value={value}
selected={selected || (multiple !== true && undefined)} // TODO: undefined?
selected={selected ? true : undefined}
Copy link

Copilot AI Jan 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change alters the behavior from the original logic. The original code was selected || (multiple !== true && undefined), which would:

  • Set selected to true when selected is truthy
  • Set selected to undefined when selected is falsy AND multiple is true
  • Set selected to false when selected is falsy AND multiple is false (because false || false evaluates to false)

The new code selected ? true : undefined always sets it to undefined when selected is falsy, regardless of the multiple flag. This removes the distinction between single-select and multi-select mode for unselected items.

If this behavioral change is intentional, it should be documented. Otherwise, the logic should preserve the original behavior or clarify what the correct behavior should be.

Suggested change
selected={selected ? true : undefined}
selected={selected || (multiple !== true && undefined)}

Copilot uses AI. Check for mistakes.
@abhi-7-7 abhi-7-7 changed the title Fix sticky hover state in Menu options fix(menu): reset sticky hover state on mouse leave Jan 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants