Skip to content

feat(HoverCard): add enableTouch prop for touch devices#2687

Merged
zernonia merged 1 commit into
unovue:v2from
benjamincanac:feat/hover-card-enable-touch
Jun 10, 2026
Merged

feat(HoverCard): add enableTouch prop for touch devices#2687
zernonia merged 1 commit into
unovue:v2from
benjamincanac:feat/hover-card-enable-touch

Conversation

@benjamincanac

@benjamincanac benjamincanac commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

🔗 Linked issue

Resolves #1969 (also covers nuxt/ui#2346)

❓ 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

HoverCard ignores touch input by design (ported from Radix), so it can't be opened on mobile. The trigger only reacts to real pointer hover (pointerenter/pointerleave, both wrapped in excludeTouch) and focus, neither of which reliably fires on a tap.

This adds an opt-in enableTouch prop on HoverCardRoot (defaults to false, so existing/Radix behavior is unchanged). When enabled, tapping the trigger toggles the card open/closed:

  • Handled on pointerup and gated to pointerType === 'touch', so mouse/hover behavior is untouched and a scroll gesture (which fires pointercancel, not pointerup) won't accidentally open it.
  • Opens immediately via onOpenChange(true) / closes via onDismiss(). DismissableLayer defers its own dismiss to the click event on touch, which runs after our pointerup and resolves idempotently (no close-then-reopen race).

It's kept opt-in rather than always-on because always enabling it would override HoverCard's intentional "supplemental, non-interactive, not-for-touch" semantics and would conflict when the trigger is a real link (tap would both navigate and toggle).

Also includes a small correctness fix: handleDismiss now clears the pending open timer, so a dismiss can't be reopened by a lingering focus/hover open timer (a latent bug on desktop too).

📝 Checklist

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

Summary by CodeRabbit

  • New Features

    • HoverCard now supports touch interaction via the new enableTouch prop. When enabled, touch taps on the trigger toggle the card open/closed (disabled by default).
  • Documentation

    • Updated HoverCardRoot documentation to describe the enableTouch prop and its behavior.

HoverCard ignores touch input by design (Radix parity), so it can't be
opened on mobile. Add an opt-in `enableTouch` prop that lets a tap toggle
the card open/closed, gated to `pointerType === 'touch'` so hover/mouse
behavior is unchanged. Toggle runs on `pointerup` so a scroll gesture
(which fires `pointercancel`) won't trigger it.

Also clear the pending open timer in `handleDismiss` so a dismiss can't be
reopened by a lingering focus/hover open timer.

Resolves unovue#1969
@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds touch pointer support to the HoverCard component via a new enableTouch prop. When enabled, touch taps on the trigger toggle the card open/closed. The root component threads the prop through context, the trigger implements a dedicated touch handler, tests validate the behavior, and documentation describes the feature.

Changes

HoverCard touch support

Layer / File(s) Summary
Root component prop and context threading
packages/core/src/HoverCard/HoverCardRoot.vue
HoverCardRootProps gains optional enableTouch prop (default false), HoverCardRootContext extends with enableTouch: Ref<boolean>, and setup code extracts and provides it. handleDismiss clears the open timer before closing to prevent stale delayed opens.
Trigger touch event handler
packages/core/src/HoverCard/HoverCardTrigger.vue
handleTouch handler gates on touch pointer type, dismisses if already open, or opens the card. The trigger template wires @pointerup="handleTouch" to the underlying Primitive.
Touch behavior tests and story integration
packages/core/src/HoverCard/HoverCard.test.ts, packages/core/src/HoverCard/story/_HoverCard.vue
Test suite verifies touch taps are ignored by default and toggle the card when enableTouch: true, including timer cancellation on close. Story component exposes enableTouch prop and passes it to HoverCardRoot.
enableTouch prop documentation
docs/content/meta/HoverCardRoot.md
Props metadata and rendered table document enableTouch as an optional boolean (default false) that enables touch-driven toggle behavior.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 A rabbit taps the screen with glee,
Cards hover open, wild and free,
Touch by touch, the state does flow,
Now mobile friends shall have their show!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely summarizes the main feature addition: an enableTouch prop for HoverCard to support touch devices.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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 and usage tips.

@pkg-pr-new

pkg-pr-new Bot commented Jun 9, 2026

Copy link
Copy Markdown

Open in StackBlitz

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

commit: e39aacb

@zernonia zernonia merged commit 40232d3 into unovue:v2 Jun 10, 2026
7 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]: Add touch support option for mobile devices

2 participants