Cursor Tooltip
An elastic tooltip that follows the cursor, tracking its coordinates with a spring and flipping sides automatically near the edges, with keyboard focus anchoring.
npx shadcn@latest add https://webberui.com/r/cursor-tooltip.jsonPlayground
Tune the props live — the code snippet updates as you go, so you can dial in the look you want before copying it.
<CursorTooltip />
Installation
npx shadcn@latest add https://webberui.com/r/cursor-tooltip.jsonOr, once registries are configured in components.json, install it as @webberui/cursor-tooltip.
Usage
import { CursorTooltip } from "@/components/ui/cursor-tooltip";
<CursorTooltip content="Drag to reorder">
<button>Hover me</button>
</CursorTooltip>The tooltip is rendered into document.body through a portal and follows the cursor; content accepts any node, so you can build a rich tooltip with an icon:
<CursorTooltip
variant="smooth"
content={
<span className="flex items-center gap-1.5">
<Sparkles className="size-3.5" /> Done
</span>
}
>
<StatusDot />
</CursorTooltip>Props
| Prop | Type | Default | Description |
|---|---|---|---|
children | React.ReactNode | — | The trigger area; the tooltip shows when the cursor enters it or it receives keyboard focus |
content | React.ReactNode | — | Tooltip content, either text or any node |
variant | "spring" | "smooth" | "instant" | "spring" | Follow feel: elastic spring back / tight tracking / zero-latency lock to the cursor |
offset | number | { x: number; y: number } | 14 | Tooltip offset relative to the cursor (px) |
openDelay | number | 0 | Delay before showing (milliseconds) |
disabled | boolean | false | Disables the tooltip: the trigger area renders as usual, but no tooltip appears |
className | string | — | Appended to the tooltip bubble class |
wrapperClassName | string | — | Appended to the trigger wrapper class |
How it works
- Coordinates are written straight into
useMotionValue, somousemovenever triggers a React re-render;useSpringmakes the tooltip track the cursor with a spring, and low damping is what produces the "elastic" spring back. springhas a pronounced spring back,smoothis tight and barely overshoots, andinstantbinds directly to the raw coordinates for a zero-latency lock.- On first show, the spring
jumps to the cursor position rather than flying in from a corner of the screen. - As the tooltip approaches the right or bottom edge of the viewport it flips to the other side of the cursor automatically and is clamped inside the bounds, so it is never clipped or left covering the cursor.
Accessibility
- The trigger area supports the keyboard through
onFocus/onBlur: on focus the tooltip anchors directly above the trigger area (dropping below it when there is not enough room) instead of at the cursor position. - With a single child,
aria-describedbyis attached to the child itself so assistive technology reads the tooltip content on focus; the tooltip carriesrole="tooltip". - Pressing
Esccloses the tooltip immediately. - When the user has "reduce motion" enabled at the system level, the spring and the scaling are disabled, degrading to a plain fade in / fade out locked to the cursor.
- The tooltip is
pointer-events-none, so it never intercepts pointer events.
Toast Stack
sonner-style collapsing toast stack — new toasts slide in from the edge, collapse into a pile of cards when not hovered, and expand into the full list while pausing the auto-dismiss countdown when the pointer enters the viewport.
Preloader Collection
Three preloader overlay animations — text reveal, staircase slide, and pixel dissolve — each revealing the content with its own signature exit once loading finishes.