Skip to content

Commit 37a6759

Browse files
committed
fix: tooltip pointer interaction
1 parent caa19b9 commit 37a6759

File tree

3 files changed

+80
-0
lines changed

3 files changed

+80
-0
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
"@zag-js/tooltip": patch
3+
---
4+
5+
Fix tooltip not showing when scrolling with pointer over trigger
6+
7+
- Added `onPointerOver` handler to complement `onPointerMove` for better hover detection during scroll events
8+
- This ensures tooltips properly appear when the pointer enters the trigger element via scrolling, not just via pointer
9+
movement
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import { normalizeProps, Portal, useMachine } from "@zag-js/react"
2+
import * as tooltip from "@zag-js/tooltip"
3+
import { ReactNode, useId } from "react"
4+
5+
interface TooltipProps {
6+
children: ReactNode
7+
closeOnPointerDown?: boolean
8+
}
9+
10+
function Tooltip(props: TooltipProps) {
11+
const { children, closeOnPointerDown } = props
12+
const service = useMachine(tooltip.machine, {
13+
id: useId(),
14+
positioning: { placement: "right" },
15+
openDelay: 100,
16+
closeDelay: 100,
17+
closeOnPointerDown,
18+
})
19+
20+
const api = tooltip.connect(service, normalizeProps)
21+
22+
return (
23+
<>
24+
<button {...api.getTriggerProps()}>{children}</button>
25+
<Portal>
26+
{api.open && (
27+
<div {...api.getPositionerProps()}>
28+
<div className="tooltip-content" {...api.getContentProps()}>
29+
<div {...api.getArrowProps()}>
30+
<div {...api.getArrowTipProps()} />
31+
</div>
32+
Tooltip
33+
</div>
34+
</div>
35+
)}
36+
</Portal>
37+
</>
38+
)
39+
}
40+
41+
export default function Page() {
42+
return (
43+
<main>
44+
<div className="root">
45+
<h2>Tooltip Scroll Hover Test</h2>
46+
<p>Hover over items, then scroll to see tooltips appear when cursor lands on items</p>
47+
<div
48+
style={{
49+
height: "400px",
50+
overflow: "auto",
51+
border: "1px solid #ccc",
52+
padding: "10px",
53+
marginTop: "20px",
54+
}}
55+
>
56+
{Array.from({ length: 100 }, (_, idx) => (
57+
<div key={idx} style={{ padding: "10px", borderBottom: "1px solid #eee" }}>
58+
<Tooltip closeOnPointerDown={true}>item {idx}</Tooltip>
59+
</div>
60+
))}
61+
</div>
62+
</div>
63+
</main>
64+
)
65+
}

packages/machines/tooltip/src/tooltip.connect.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,12 @@ export function connect<P extends PropTypes>(
8484
if (event.pointerType === "touch") return
8585
send({ type: "pointer.move" })
8686
},
87+
onPointerOver(event) {
88+
if (event.defaultPrevented) return
89+
if (disabled) return
90+
if (event.pointerType === "touch") return
91+
send({ type: "pointer.move" })
92+
},
8793
onPointerLeave() {
8894
if (disabled) return
8995
send({ type: "pointer.leave" })

0 commit comments

Comments
 (0)