Skip to content

feat(useMouseInElement): add support for tracking inline-level elements - #5049

Merged
43081j merged 8 commits into
vueuse:mainfrom
siavava:inline-use-mouse-in-element
Nov 19, 2025
Merged

43081j merged 8 commits into
vueuse:mainfrom
siavava:inline-use-mouse-in-element

Conversation

@siavava

@siavava siavava commented Sep 19, 2025 •

Copy link
Copy Markdown
Contributor

Before submitting the PR, please make sure you do the following

  • Read the Contributing Guidelines.
  • Read the Pull Request Guidelines.
  • Check that there isn't already a PR that solves the problem the same way to avoid creating a duplicate.
  • Provide a description in this PR that addresses what the PR is solving, or reference the issue that it solves (e.g. fixes #123).
  • Ideally, include relevant tests that fail without this PR but pass with it.
⚠️ Slowing down new functions

Warning: Slowing down new functions

As the VueUse audience continues to grow, we have been inundated with an overwhelming number of feature requests and pull requests. As a result, maintaining the project has become increasingly challenging and has stretched our capacity to its limits. As such, in the near future, we may need to slow down our acceptance of new features and prioritize the stability and quality of existing functions. Please note that new features for VueUse may not be accepted at this time. If you have any new ideas, we suggest that you first incorporate them into your own codebase, iterate on them to suit your needs, and assess their generalizability. If you strongly believe that your ideas are beneficial to the community, you may submit a pull request along with your use cases, and we would be happy to review and discuss them. Thank you for your understanding.


Description

Current Behavior

useMouseInElement works perfectly for block elements, but does not work correctly for inline elements. This is because it uses el.getBoundingClientRect(), which returns a single rect that wraps the entire element. For inline elements, this means that this rect will potentially include parts that are not in the element itself.

For example, the regions marked with x below would be detected as being in the inline element when hovered.

--------------------------------------
| xxxxxxxxxxxxxxx here is the inline |
| element which wraps onto this line |
| and ends here. xxxxxxxxxxxxxxxxxxx | 
--------------------------------------

Proposed Behavior

Instead of using el.getBoundingClientRect(), we can use el.getClientRects() to get more precise bounding.

Per the docs:

The getClientRects() method of the Element interface returns a collection of DOMRect objects that indicate the bounding rectangles for each CSS border box in a client.

Most elements only have one border box each, but a multiline inline-level element (such as a multiline element, by default) has a border box around each line.

For example, in the above scenario, we'll get three rects returned, the first one containing "here is the inline", the second rect containing "element which wraps onto this line", and the third element containing "and ends here."
And hovering on the x regions will no longer be detected as being still within the inline element.

                ----------------------
 xxxxxxxxxxxxxx | here is the inline |
                ----------------------
--------------------------------------
| element which wraps onto this line |
--------------------------------------
------------------
| and ends here. | xxxxxxxxxxxxxxxxx
------------------

Note

Since getClientRects returns a single DOMRect for block elements (see second paragraph in the quoted text above, or check the documentation source), there should be no regression in performance for block elements.

@dosubot dosubot Bot added size:M This PR changes 30-99 lines, ignoring generated files. enhancement New feature or request labels Sep 19, 2025
Comment thread packages/core/useMouseInElement/demo.vue Outdated
Comment thread packages/core/useMouseInElement/demo.vue Outdated
@siavava

siavava commented Sep 19, 2025

Copy link
Copy Markdown
Contributor Author

Added an inline-element demo

(or if link is dead, go to the latest deploy-preview and search for useMouseInElement or paste /core/useMouseInElement/#usemouseinelement after the base URL.

@siavava siavava changed the title feat(useMouseInElement): add support for tracking inline elements such as spans feat(useMouseInElement): add support for tracking inline-level elements Sep 19, 2025
Comment on lines +98 to +99
if (!isOutside.value)
break

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

For inline elements, if we're inside the current rect,
there's no need to check the others coming after it.

This also avoids the state of the other rects from overwriting
the fact that we're hovering on the current rect.

@pkg-pr-new

pkg-pr-new Bot commented Sep 23, 2025 •

Copy link
Copy Markdown

Open in StackBlitz

@vueuse/components

npm i https://pkg.pr.new/@vueuse/components@5049

@vueuse/core

npm i https://pkg.pr.new/@vueuse/core@5049

@vueuse/electron

npm i https://pkg.pr.new/@vueuse/electron@5049

@vueuse/firebase

npm i https://pkg.pr.new/@vueuse/firebase@5049

@vueuse/integrations

npm i https://pkg.pr.new/@vueuse/integrations@5049

@vueuse/math

npm i https://pkg.pr.new/@vueuse/math@5049

@vueuse/metadata

npm i https://pkg.pr.new/@vueuse/metadata@5049

@vueuse/nuxt

npm i https://pkg.pr.new/@vueuse/nuxt@5049

@vueuse/router

npm i https://pkg.pr.new/@vueuse/router@5049

@vueuse/rxjs

npm i https://pkg.pr.new/@vueuse/rxjs@5049

@vueuse/shared

npm i https://pkg.pr.new/@vueuse/shared@5049

commit: a15aa04

@siavava

siavava commented Sep 30, 2025

Copy link
Copy Markdown
Contributor Author

...not sure who is the right person to reach out to for approval or feedback on if this change is desirable.

9romise
9romise previously approved these changes Sep 30, 2025
@dosubot dosubot Bot added the lgtm This PR has been approved by a maintainer label Sep 30, 2025
@9romise

9romise commented Sep 30, 2025

Copy link
Copy Markdown
Member

Updated the demo. For preview:
image

@siavava

siavava commented Oct 16, 2025

Copy link
Copy Markdown
Contributor Author

@9romise could you merge this if it looks good to you?
I don't have the right permissions to run two of the workflows needed to merge (rerun needed because of rebase)

@codecov

codecov Bot commented Oct 16, 2025 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 63.97%. Comparing base (375d1f9) to head (a15aa04).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #5049      +/-   ##
==========================================
+ Coverage   63.95%   63.97%   +0.01%     
==========================================
  Files         343      343              
  Lines        7838     7841       +3     
  Branches     2424     2413      -11     
==========================================
+ Hits         5013     5016       +3     
  Misses       2286     2286              
  Partials      539      539              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 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.

@9romise

9romise commented Oct 16, 2025

Copy link
Copy Markdown
Member

To prevent regressions, I think it would be best to add some test cases to this PR after #5101 has been merged. Once other members also approve this request, we can proceed with merging.

@dosubot dosubot Bot added size:L This PR changes 100-499 lines, ignoring generated files. and removed size:M This PR changes 30-99 lines, ignoring generated files. labels Oct 17, 2025
@siavava

siavava commented Oct 17, 2025

Copy link
Copy Markdown
Contributor Author

@9romise thanks for adding the tests! 🎉

@siavava

siavava commented Nov 18, 2025

Copy link
Copy Markdown
Contributor Author

To prevent regressions, I think it would be best to add some test cases to this PR after #5101 has been merged. Once other members also approve this request, we can proceed with merging.

cc @9romise —— any chance we could get someone to review/merge this? since it's been stalled for over a month now and we already added the tests.

@9romise
9romise requested review from 43081j and OrbisK November 19, 2025 07:09
This was referenced Mar 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request lgtm This PR has been approved by a maintainer size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants