Skip to content

fix(Tooltip): identity-check mouseout target and track node position on view changes#209

Open
w8r wants to merge 7 commits into
developfrom
fix/tooltip-mouseout-identity-and-stale-position
Open

fix(Tooltip): identity-check mouseout target and track node position on view changes#209
w8r wants to merge 7 commits into
developfrom
fix/tooltip-mouseout-identity-and-stale-position

Conversation

@w8r
Copy link
Copy Markdown
Contributor

@w8r w8r commented May 25, 2026

Problem

Two bugs in the hover-triggered <Tooltip> component:

1. Premature close on foreign mouseout

The mouseout listener was firing for any node/edge mouseout, not just the element that triggered the mouseover. Rapidly moving between two adjacent nodes would cause a foreign mouseout to immediately close the tooltip.

Root cause: the handler only checked evt.target?.isNode (correct type) but never verified evt.target === storedTarget (correct identity).

2. Stale tooltip position after node drag or zoom

The tooltip position was computed once at hover time and never updated when:

  • the user drags the node to a new location, or
  • the user zooms (which changes the radius-based offset in graph coordinates).

Fix

Identity check: Mirror target state into a targetRef so the stable event-handler closure can always read the current value. Gate hideTooltip() on evt.target === targetRef.current.

Position tracking: Declare a hoisted onViewUpdate callback (registered on nodesDragProgress and idle) that reads the node's current graph position via node.getPosition(), recomputes the zoom-adjusted offset, calls layer.setPosition(), and triggers the existing overflow re-check by calling setPoint().

A pointRef is added alongside targetRef so both callbacks can read current values from stable closures without being re-registered on every hover change.

Checklist

  • TypeScript typecheck passes (npm run typecheck)
  • Prettier + oxlint pass (husky pre-commit hooks ran clean)
  • No changes to public API or types

w8r and others added 3 commits May 25, 2026 12:10
…on view changes

Two bugs fixed in the hover-event Tooltip:

1. **Premature close on foreign mouseout**
   The `mouseout` listener was firing for *any* node/edge mouseout, not just
   the one that triggered the tooltip. Rapidly moving between nodes or across
   an edge would cause a foreign `mouseout` to immediately close the tooltip.
   Fix: mirror `target` state into a `targetRef` and guard the hide call with
   an identity check (`evt.target === targetRef.current`).

2. **Stale position after node drag or zoom**
   The tooltip position was computed once on hover and never updated when the
   node was dragged or the view zoom changed (zoom affects the radius-based
   offset). Fix: subscribe to `nodesDragProgress` and `idle` events; on each
   fire recompute the node's current graph position and the zoom-adjusted
   offset, then call `layer.setPosition` and trigger the existing overflow
   re-check via `setPoint`.

A `pointRef` is added alongside `targetRef` so both callbacks can read
current values from stable closures without being re-registered on every
hover change.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants