Skip to content

fix(Tabs): don't activate tabs on right or middle click - #3027

Merged
zernonia merged 3 commits into
unovue:v2from
b84330808:fix/tabs-non-left-click
Oct 26, 2026
Merged

zernonia merged 3 commits into
unovue:v2from
b84330808:fix/tabs-non-left-click

Conversation

@b84330808

@b84330808 b84330808 commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

🔗 Linked issue

Resolves #2258

❓ Type of change

  • 📖 Documentation (updates to the documentation, readme or JSdoc annotations)
  • 🐞 Bug fix (a non-breaking change that fixes an issue)
  • 👌 Enhancement (improving an existing functionality like performance)
  • ✨ New feature (a non-breaking change that adds functionality)
  • 🧹 Chore (updates to the build process or auxiliary tools and libraries)
  • ⚠️ Breaking change (fix or feature that would cause existing functionality to change)

📚 Description

TabsTrigger listened with @mousedown.left, so its handler never ran for the middle or right button. The else branch that prevents focus "to avoid accidental activation" was therefore never reached for those buttons: the tab got focus, and in the default automatic activation mode, @focus then selected it.

The listener now runs for every button, and only the left button (without Ctrl) activates the tab; other buttons prevent the default, so the tab doesn't take focus. This matches Radix's TabsTrigger, which this component follows.

The new tests dispatch a mousedown with button 1 and 2 and check that the tab isn't activated and the event's default is prevented. They fail without this change. The other Tabs tests pass, except "ssr hydration", which fails the same way on v2 in my environment.

The v3 branch's useTabs.ts has the same logic; I can open a follow-up there if this approach is fine.

I used Claude Code to write this change.

📝 Checklist

  • I have linked an issue or discussion.
  • I have updated the documentation accordingly.

Summary by CodeRabbit

  • Bug Fixes
    • Middle- and right-clicking a tab no longer activates it or moves focus to it. These interactions are prevented from triggering the tab’s default mouse-down behavior.
    • Left-clicking continues to activate tabs as expected, with existing disabled-state and modifier-key handling unchanged.

The mousedown handler used the `.left` modifier, so for other buttons it
never ran and never prevented the focus, and a focused tab was activated
in automatic mode. Run it for every button and only activate on the left
one, as Radix does.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@coderabbitai

coderabbitai Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
  • Source mode: Auto
  • Repository: unovue/reka-ui
  • Branch: v2
  • File: .coderabbit.yaml
  • Commit: 318bfc6
  • Layers: Repository YAML
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: c57c2383-145c-440a-903f-e627b700a909
Commits

Reviewing files that changed from the base of the PR and between ace8dde and e54259b.

Files selected for processing: 1
  • packages/core/src/Tabs/Tabs.browser.test.ts

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 6 remain after this review.

Walkthrough

TabsTrigger now activates a tab on mousedown only when the left mouse button is used. Unit and browser tests cover activation, focus, and default-prevention behavior for mouse buttons.

Changes: Tabs selection

Layer / File(s) Summary
Restrict activation to left button
packages/core/src/Tabs/TabsTrigger.vue, packages/core/src/Tabs/Tabs.test.ts, packages/core/src/Tabs/Tabs.browser.test.ts
The mousedown handler checks for event.button === 0. Unit and browser tests verify left-button activation and that middle- and right-button events do not activate or focus a tab.

Priority: Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Low

Merge Risk: Minimal · up to e5425

The supplied evidence identifies no issue that needs resolution before merging.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 2 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title "fix(Tabs): don't activate tabs on right or middle click" matches the main change. The changeset makes TabsTrigger activate only on left-button mousedown (event.button === 0) and prevents de…
Linked Issues check Passed [#2258] requires that tab selection change only for the left mouse button. At the reviewed head, TabsTrigger.vue listens to @mousedown for all buttons. It calls `rootContext.changeModelValue(value…
Out of Scope Changes check Passed The whole-PR diff changes three files. packages/core/src/Tabs/TabsTrigger.vue changes the mousedown handler: .left is replaced by an explicit event.button === 0 check. Existing disabled and Ctrl…
Full details: Title check

Explanation

The title "fix(Tabs): don't activate tabs on right or middle click" matches the main change. The changeset makes TabsTrigger activate only on left-button mousedown (event.button === 0) and prevents default for other buttons, so right and middle clicks no longer activate or focus a tab. The title is short, specific, and names the affected component. It follows a conventional commit style. The objectives describe the same change, and the linked issue #2258 asks for the same behavior.

Full details: Linked Issues check

Explanation

[#2258] requires that tab selection change only for the left mouse button. At the reviewed head, TabsTrigger.vue listens to @mousedown for all buttons. It calls rootContext.changeModelValue(value) only when !disabled &amp;&amp; event.button === 0 &amp;&amp; event.ctrlKey === false. Every other case reaches the else branch, which calls event.preventDefault(). This stops focus, so the @focus automatic-activation path does not select the tab. The change is in the whole-PR diff against the merge base. Tabs.test.ts adds a case for buttons 1 and 2. It checks that value stays 'one' and that event.defaultPrevented is true. Under the previous @mousedown.left listener, a button 1 or 2 event would not reach the handler, so this test checks the fixed behavior. Tabs.browser.test.ts adds real-browser tests for right and middle clicks. They check that the second tab is not focused or activated. No coding requirement from #2258 is unmet. The PR description states that the ssr hydration test fails on v2 in the author's environment. This is outside the scope of this PR. The v3 branch is not part of this review.

Full details: Out of Scope Changes check

Explanation

The whole-PR diff changes three files. packages/core/src/Tabs/TabsTrigger.vue changes the mousedown handler: .left is replaced by an explicit event.button === 0 check. Existing disabled and Ctrl checks remain. packages/core/src/Tabs/Tabs.test.ts adds a unit test for buttons 1 and 2. packages/core/src/Tabs/Tabs.browser.test.ts is a new file with real-browser tests for right and middle clicks on TabsTrigger. Each change supports the fix for #2258. No unrelated component, public API, or behavior change appears in the diff. The else branch that prevents default for non-left clicks also applies to disabled triggers. Those triggers previously reached the same branch for left clicks, so their behavior does not change.

Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • 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.

zernonia and others added 2 commits October 26, 2026 12:20
…browser

jsdom never moves focus on mousedown, so the focus-driven activation from unovue#2258
only reproduces in Chromium.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
@pkg-pr-new

pkg-pr-new Bot commented Oct 26, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/reka-ui@3027

commit: e54259b

@zernonia
zernonia merged commit c3c07e7 into unovue:v2 Oct 26, 2026
8 checks passed
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.

[Bug]: TabsTrigger Allow only left-mouse button to change tab selection

2 participants