feat(tooltip): add Floating UI tooltip primitives - #2020
Merged
Conversation
Size Changes
View raw build statsPrevious (master){
"visx-a11y": {
"esm": 28466,
"lib": 34549
},
"visx-annotation": {
"esm": 19693,
"lib": 23755
},
"visx-axis": {
"esm": 14072,
"lib": 19318
},
"visx-bounds": {
"esm": 1495,
"lib": 1915
},
"visx-brush": {
"esm": 42024,
"lib": 44001
},
"visx-chart": {
"esm": 5680,
"lib": 8613
},
"visx-chord": {
"esm": 1907,
"lib": 2683
},
"visx-clip-path": {
"esm": 1522,
"lib": 2713
},
"visx-curve": {
"esm": 351,
"lib": 2594
},
"visx-delaunay": {
"esm": 1475,
"lib": 2489
},
"visx-demo": {
"esm": 0,
"lib": 0
},
"visx-drag": {
"esm": 9078,
"lib": 11025
},
"visx-event": {
"esm": 3571,
"lib": 5257
},
"visx-geo": {
"esm": 8104,
"lib": 11674
},
"visx-glyph": {
"esm": 7243,
"lib": 11421
},
"visx-gradient": {
"esm": 6928,
"lib": 11581
},
"visx-grid": {
"esm": 9631,
"lib": 12892
},
"visx-group": {
"esm": 502,
"lib": 1030
},
"visx-heatmap": {
"esm": 3496,
"lib": 4564
},
"visx-hierarchy": {
"esm": 8687,
"lib": 13458
},
"visx-kernel": {
"esm": 12168,
"lib": 15402
},
"visx-legend": {
"esm": 14929,
"lib": 20754
},
"visx-marker": {
"esm": 3855,
"lib": 6120
},
"visx-mock-data": {
"esm": 325698,
"lib": 330728
},
"visx-network": {
"esm": 3088,
"lib": 5105
},
"visx-pattern": {
"esm": 7400,
"lib": 10317
},
"visx-point": {
"esm": 791,
"lib": 1901
},
"visx-react-spring": {
"esm": 8724,
"lib": 11009
},
"visx-registry": {
"esm": 116,
"lib": 79
},
"visx-responsive": {
"esm": 11775,
"lib": 14019
},
"visx-sankey": {
"esm": 2501,
"lib": 3894
},
"visx-scale": {
"esm": 19357,
"lib": 31820
},
"visx-shape": {
"esm": 52847,
"lib": 76176
},
"visx-stats": {
"esm": 9258,
"lib": 10690
},
"visx-text": {
"esm": 6416,
"lib": 7990
},
"visx-theme": {
"esm": 22587,
"lib": 31584
},
"visx-threshold": {
"esm": 2067,
"lib": 2758
},
"visx-tooltip": {
"esm": 9212,
"lib": 13672
},
"visx-vendor": {
"esm": 2974,
"lib": 3226
},
"visx-visx": {
"esm": 1718,
"lib": 4399
},
"visx-voronoi": {
"esm": 1909,
"lib": 3235
},
"visx-wordcloud": {
"esm": 1996,
"lib": 2995
},
"visx-xychart": {
"esm": 126022,
"lib": 155810
},
"visx-zoom": {
"esm": 12508,
"lib": 14835
}
}Current{
"visx-a11y": {
"esm": 28466,
"lib": 34549
},
"visx-annotation": {
"esm": 19693,
"lib": 23755
},
"visx-axis": {
"esm": 14072,
"lib": 19318
},
"visx-bounds": {
"esm": 1495,
"lib": 1915
},
"visx-brush": {
"esm": 42024,
"lib": 44001
},
"visx-chart": {
"esm": 5680,
"lib": 8613
},
"visx-chord": {
"esm": 1907,
"lib": 2683
},
"visx-clip-path": {
"esm": 1522,
"lib": 2713
},
"visx-curve": {
"esm": 351,
"lib": 2594
},
"visx-delaunay": {
"esm": 1475,
"lib": 2489
},
"visx-demo": {
"esm": 0,
"lib": 0
},
"visx-drag": {
"esm": 9078,
"lib": 11025
},
"visx-event": {
"esm": 3571,
"lib": 5257
},
"visx-geo": {
"esm": 8104,
"lib": 11674
},
"visx-glyph": {
"esm": 7243,
"lib": 11421
},
"visx-gradient": {
"esm": 6928,
"lib": 11581
},
"visx-grid": {
"esm": 9631,
"lib": 12892
},
"visx-group": {
"esm": 502,
"lib": 1030
},
"visx-heatmap": {
"esm": 3496,
"lib": 4564
},
"visx-hierarchy": {
"esm": 8687,
"lib": 13458
},
"visx-kernel": {
"esm": 12168,
"lib": 15402
},
"visx-legend": {
"esm": 14929,
"lib": 20754
},
"visx-marker": {
"esm": 3855,
"lib": 6120
},
"visx-mock-data": {
"esm": 325698,
"lib": 330728
},
"visx-network": {
"esm": 3088,
"lib": 5105
},
"visx-pattern": {
"esm": 7400,
"lib": 10317
},
"visx-point": {
"esm": 791,
"lib": 1901
},
"visx-react-spring": {
"esm": 8724,
"lib": 11009
},
"visx-registry": {
"esm": 116,
"lib": 79
},
"visx-responsive": {
"esm": 11775,
"lib": 14019
},
"visx-sankey": {
"esm": 2501,
"lib": 3894
},
"visx-scale": {
"esm": 19357,
"lib": 31820
},
"visx-shape": {
"esm": 52847,
"lib": 76176
},
"visx-stats": {
"esm": 9258,
"lib": 10690
},
"visx-text": {
"esm": 6416,
"lib": 7990
},
"visx-theme": {
"esm": 22587,
"lib": 31584
},
"visx-threshold": {
"esm": 2067,
"lib": 2758
},
"visx-tooltip": {
"esm": 38115,
"lib": 46512
},
"visx-vendor": {
"esm": 2974,
"lib": 3226
},
"visx-visx": {
"esm": 1718,
"lib": 4399
},
"visx-voronoi": {
"esm": 1909,
"lib": 3235
},
"visx-wordcloud": {
"esm": 1996,
"lib": 2995
},
"visx-xychart": {
"esm": 126022,
"lib": 155810
},
"visx-zoom": {
"esm": 12508,
"lib": 14835
}
} |
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a new additive @visx/tooltip/floating entrypoint that provides Floating UI鈥揵acked tooltip primitives and chart-focused convenience APIs, while keeping the existing @visx/tooltip surface unchanged.
Changes:
- Introduces
@visx/tooltip/floatingexports (hooks, primitives, chart tooltip components) backed by@floating-ui/react. - Adds anchor conversion utilities + middleware builder for consistent positioning behavior.
- Adds docs (README/Handbook/Migration note) and a focused test + typecheck suite for the new surface.
Reviewed changes
Copilot reviewed 21 out of 22 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| yarn.lock | Locks new @floating-ui/react dependency chain and tabbable. |
| packages/visx-tooltip/package.json | Adds ./floating export map and @floating-ui/react dependency. |
| packages/visx-tooltip/src/floating/index.ts | New client entrypoint exporting the floating tooltip surface. |
| packages/visx-tooltip/src/floating/types.ts | Public types for anchors, interactions, primitives, and hooks. |
| packages/visx-tooltip/src/floating/anchors.ts | Anchor-to-reference conversion utilities (DOM, points, SVG, rect, virtual). |
| packages/visx-tooltip/src/floating/middleware.ts | Builds Floating UI middleware in a consistent order with override modes. |
| packages/visx-tooltip/src/floating/useFloatingTooltip.ts | Core hook managing open/anchor/data state + Floating UI interactions/refs. |
| packages/visx-tooltip/src/floating/context.tsx | Context for sharing tooltip state across primitives. |
| packages/visx-tooltip/src/floating/FloatingTooltip.tsx | Primitive components (Root, Trigger, Portal, Positioner, Content, Arrow). |
| packages/visx-tooltip/src/floating/ChartTooltipContent.tsx | Config-driven chart tooltip content renderer. |
| packages/visx-tooltip/src/floating/ChartTooltip.tsx | Controlled chart tooltip component composing the primitives. |
| packages/visx-tooltip/src/floating/useChartTooltip.ts | Convenience hook for chart-local tooltip state + anchor shorthand handling. |
| packages/visx-tooltip/test/floatingAnchors.test.ts | Tests anchor conversion behavior. |
| packages/visx-tooltip/test/floatingPrimitives.test.tsx | Tests hook behavior, middleware ordering, primitive rendering and attributes. |
| packages/visx-tooltip/test/floatingInteractions.test.tsx | Tests trigger interactions + ARIA wiring and disabled-trigger behavior. |
| packages/visx-tooltip/test/ChartTooltipContent.test.tsx | Tests config precedence, filtering, ordering, and custom renderers. |
| packages/visx-tooltip/test/ChartTooltip.test.tsx | Tests chart hook behavior + portal/renderContent/prop precedence behavior. |
| packages/visx-tooltip/test/floating.typecheck.tsx | Type-level fixture ensuring intended constraints on public APIs. |
| packages/visx-tooltip/test/tsconfig.floating-typecheck.json | Dedicated TS config for the floating typecheck fixture. |
| packages/visx-tooltip/Readme.md | Documents the new @visx/tooltip/floating surface and usage patterns. |
| packages/visx-tooltip/Handbook.md | Detailed handbook covering patterns, anchors, middleware, and styling contracts. |
| MIGRATION.md | Adds a 4.1 migration note for the new additive @visx/tooltip/floating APIs. |
馃挕 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
To be released in
4.1.0Why Floating UI tooltips?
The post-4.0 registry and primitive chart work needs a modern tooltip foundation that can handle collision-aware placement, virtual anchors, SVG coordinates, arrows, portals, and controlled chart state without changing the existing
@visx/tooltipAPIs.This PR adds an additive
@visx/tooltip/floatingsubpath backed by Floating UI. The new surface keeps the visx model intact: users still own the chart render tree, nearest-datum lookup, mark events, and content composition, while visx provides low-level positioning primitives and a convenient chart-tooltip layer.The goal is to make modern dashboard tooltips easier to build consistently across registry charts and product code, while preserving the existing legacy tooltip package behavior for current consumers.
馃挜 Breaking Changes
馃殌 Enhancements
@visx/tooltip/floatingclient subpath with Floating UI-backed tooltip exports.useFloatingTooltipfor controlled/uncontrolled open state, anchor state, data state, middleware configuration, ids, role wiring, and imperative open/close/update behavior.FloatingTooltipprimitives:Provider,Root,Trigger,Portal,Positioner,Content, andArrow.role="label"support.ChartTooltipContentwith config-driven labels, values, colors, icons, hidden items, ordering, formatter precedence, custom renderers, and item keys.useChartTooltipandChartTooltipas a convenience layer for chart-local anchors, SVG-local anchors, hide delays, controlled props, portals, and custom content.@floating-ui/reactas an@visx/tooltipdependency.馃摑 Documentation
packages/visx-tooltip/Readme.md.packages/visx-tooltip/Handbook.mdwith source-validated API patterns, coordinate-space guidance, chart tooltip recipes, primitive usage, interaction notes, middleware notes, and styling contracts.MIGRATION.md4.1 note for the additive@visx/tooltip/floatingAPIs.馃悰 Bug Fix
馃彔 Internal
@visx/tooltip/floatingusage and invalid controlledfloatingOptions.Validation
yarn vitest run --config packages/visx-tooltip/vitest.config.ts packages/visx-tooltip/test/floatingPrimitives.test.tsx packages/visx-tooltip/test/floatingInteractions.test.tsx packages/visx-tooltip/test/ChartTooltip.test.tsxPKG=@visx/tooltip yarn type:pkgyarn tsc -p packages/visx-tooltip/test/tsconfig.floating-typecheck.json --pretty falseyarn vitest run --config packages/visx-tooltip/vitest.config.tsyarn buildyarn testyarn type:update-refs && git diff --exit-codeyarn docs:generategit diff --check && git diff --cached --check