Skip to content

Tooltip positions are now a function instead of array#6844

Merged
ckifer merged 1 commit intomainfrom
tooltippayload-types
Jan 4, 2026
Merged

Tooltip positions are now a function instead of array#6844
ckifer merged 1 commit intomainfrom
tooltippayload-types

Conversation

@PavelVanecek
Copy link
Collaborator

@PavelVanecek PavelVanecek commented Jan 3, 2026

Description

The positions being sometimes array and sometimes map makes it challenging to type so I changed it to a function which is trivial to type properly.

Also includes:

  • expect.functionReturning helper so that we can have unit tests for what the function is supposed to return
  • Switched data array to be readonly unknown, instead of writable any, in some places
  • I noticed that we have two identical Pie examples so I merged them (and added a defaultIndex to the screenshot because why not have it test the tooltip positioning too)

Related Issue

#6645

Summary by CodeRabbit

Release Notes

  • Refactor
    • Refactored tooltip positioning system to use dynamic function-based coordinate lookup instead of precomputed static arrays for improved performance and flexibility.
    • Enhanced type safety for chart data handling, improving data consistency across all components.
    • Unified tooltip configuration API for improved consistency and developer experience across all chart types.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 3, 2026

Walkthrough

This PR systematically refactors the tooltip positioning API across the charting library by replacing static positions arrays with dynamic getPosition() functions. It modernizes type definitions—changing ChartData to ReadonlyArray<unknown>, updating component signatures from any[] to typed parameters, and adjusting selector dependencies—while introducing test helpers and updating test expectations to align with the new patterns.

Changes

Cohort / File(s) Summary
Chart component tooltip positioning
src/cartesian/Area.tsx, src/cartesian/Bar.tsx, src/cartesian/Line.tsx, src/cartesian/Scatter.tsx, src/cartesian/Funnel.tsx, src/polar/Pie.tsx, src/polar/Radar.tsx, src/polar/RadialBar.tsx, src/chart/Sankey.tsx
Replaced static positions arrays or undefined placeholders with dynamic getPosition functions in tooltip configurations; added noop imports from DataUtils; updated function signatures (e.g., computeBarRectangles, computeLinePoints) to accept ChartData instead of any[].
Core type and state layer
src/state/chartDataSlice.ts, src/state/tooltipSlice.ts, src/state/optionsSlice.ts, src/util/DataUtils.ts, src/util/types.ts
Changed ChartData from unknown[] to ReadonlyArray<unknown>; updated TooltipPayloadConfiguration to use getPosition instead of positions; made tooltipPayloadSearcher mandatory in ChartOptions; changed noop() return type from void to undefined; updated BaseChartProps.data to use ChartData type.
Selector and combiner refactoring
src/state/selectors/combiners/combineCoordinateForDefaultIndex.ts, src/state/selectors/selectTooltipPayloadSearcher.ts, src/state/selectors/selectors.ts, src/state/selectors/tooltipSelectors.ts, src/state/selectors/touchSelectors.ts
Removed TooltipPayloadSearcher dependency from coordinate selectors; replaced tooltipPayloadSearcher parameter with direct getPosition calls from TooltipPayloadConfiguration; updated selector input lists and combiner logic.
Complex chart components
src/cartesian/Brush.tsx, src/chart/SunburstChart.tsx, src/chart/Treemap.tsx
Added helper functions in Brush; changed Sunburst from Map serialization to function-based positioning and reduced export visibility of addToSunburstNodeIndex; converted Treemap to use undefined instead of null, updated treemapPayloadSearcher return type, and applied noop-based position configuration.
Test infrastructure and helpers
test/helper/expectFunctionReturning.ts, test/tsconfig.json, vitest.config.mts
Added new custom matcher expectFunctionReturning for validating functions returning expected values across input sets; extended test configuration to include helper file.
Test updates
test/cartesian/Area.spec.tsx, test/cartesian/Bar.spec.tsx, test/chart/ScatterChart.spec.tsx, test/component/Tooltip/*.spec.tsx, test/polar/Pie.spec.tsx, test/state/selectors/*.spec.tsx
Replaced static positions expectations with getPosition function expectations using new expect.functionReturning matcher; updated tooltip payload assertions across multiple test suites; removed Customized wrapper usage in some selectors.
Documentation and examples
test-vr/tests/www/PieChartApiExamples.spec-vr.tsx, www/src/docs/apiExamples/PieChart/PieChartExample.tsx, www/src/docs/apiExamples/PieChart/index.tsx, www/src/docs/exampleComponents/PieChart/TwoLevelPieChart.tsx
Removed PieChartExample component file; updated examples index to reference TwoLevelPieChart; extended TwoLevelPieChart component to accept and render defaultIndex prop for Tooltip.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • Strict tsconfig  #6842: Coordinated type-and-API changes around tooltip payloads and chart data structures (replacing positions arrays with getPosition, introducing ChartData typing fixes).
  • Fix: Tooltip payload data include unrelated items #6773: Modifies src/state/tooltipSlice.ts directly, updating tooltip payload configuration shape and related selectors.
  • Ts strict #6750: Overlapping TypeScript and tooltip-related selector/combiner changes in coordinate computation and utility typings.

Suggested labels

refactor, typescript

Suggested reviewers

  • ckifer

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 21.43% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: converting tooltip positions from arrays/maps to functions. It aligns well with the core objective of the PR.
Description check ✅ Passed The description covers the main motivation, key changes, and related issue. While not all template sections are filled, the most critical information is present and substantive.
✨ Finishing touches
  • 📝 Generate docstrings

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.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (5)
vitest.config.mts (1)

36-41: Minor path style inconsistency.

The new entry uses './test/helper/expectFunctionReturning.ts' with a leading ./, while the other entries don't have this prefix. Consider removing the leading ./ for consistency:

Suggested fix
          setupFiles: [
            'test/vitest.setup.ts',
            'test/helper/toBeRechartsScale.ts',
            'test/helper/expectStackGroups.ts',
-            './test/helper/expectFunctionReturning.ts',
+            'test/helper/expectFunctionReturning.ts',
          ],
src/cartesian/Bar.tsx (1)

963-963: Consider improving handling of unknown entry type.

While typing entry as unknown (line 963) is safer than any, the spread operation at line 1039 requires a ts-expect-error suppression. This is a common pattern when dealing with user-provided data, but consider alternatives:

  1. Document why it's safe: Add a comment explaining that entry comes from displayedData and is expected to be an object
  2. Add runtime validation: Check if entry is an object before spreading
  3. Use a type assertion with validation: ...(entry && typeof entry === 'object' ? entry : {})

The current approach works but could be more explicit about the assumptions being made.

🔎 Alternative approach with runtime check
       const barRectangleItem: BarRectangleItem = {
-        // @ts-expect-error spread of unknown type
-        ...entry,
+        ...(entry != null && typeof entry === 'object' ? entry : {}),
         stackedBarStart,
         x,
         y,

Also applies to: 1039-1039

src/cartesian/Funnel.tsx (1)

230-230: Index conversion is intentional but could be more explicit.

The Number(index) pattern is consistent with other array-based components like Scatter and is well-protected by optional chaining. However, since TooltipIndex is string | null, explicitly documenting that indices are guaranteed to be numeric strings—or adding a defensive check—would improve clarity. This is a minor code clarity suggestion rather than a functional issue; the current implementation already handles invalid indices gracefully.

test/helper/expectFunctionReturning.ts (2)

27-51: Consider alternative to type assertions for tuple splitting.

Lines 41-42 use as type assertions to split the test case tuple into arguments and expected return value. While this is functionally correct, the coding guideline states: "Do not use as type assertions in TypeScript; the only exception is as const".

Additionally, line 27 uses any[] in the generic constraint TArgs extends any[], which violates the guideline to never use any type. Consider using unknown[] instead, though this may require additional type refinements.

Alternative approach using unknown[]
-export function expectFunctionReturning<TArgs extends any[], TReturn>(
+export function expectFunctionReturning<TArgs extends unknown[], TReturn>(
   actual: unknown,
   cases: Array<[...args: TArgs, returnValue: TReturn]>,
 ): SyncExpectationResult {

Note: The type assertions on lines 41-42 are harder to eliminate without significant refactoring, as TypeScript cannot infer the split of a tuple. If this becomes a priority, consider using a different data structure for test cases.

Based on coding guidelines.


57-67: Consistent use of unknown[] in type definitions.

Line 58 uses any[] in the generic constraint, similar to line 27. For consistency with the suggestion above, consider using unknown[] here as well.

🔎 Proposed fix
 interface CustomMatchers {
-  functionReturning: <TArgs extends any[], TReturn>(
+  functionReturning: <TArgs extends unknown[], TReturn>(
     cases: Array<[...args: TArgs, returnValue: TReturn]>,
   ) => (...args: TArgs) => TReturn;
 }

Based on coding guidelines.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8bb5aa4 and 20ea880.

⛔ Files ignored due to path filters (6)
  • test-vr/__snapshots__/tests/www/PieChartApiExamples.spec-vr.tsx-snapshots/PieChartExample-1-chromium-linux.png is excluded by !**/*.png
  • test-vr/__snapshots__/tests/www/PieChartApiExamples.spec-vr.tsx-snapshots/PieChartExample-1-firefox-linux.png is excluded by !**/*.png
  • test-vr/__snapshots__/tests/www/PieChartApiExamples.spec-vr.tsx-snapshots/PieChartExample-1-webkit-linux.png is excluded by !**/*.png
  • test-vr/__snapshots__/tests/www/PieChartApiExamples.spec-vr.tsx-snapshots/TwoLevelPieChart-1-chromium-linux.png is excluded by !**/*.png
  • test-vr/__snapshots__/tests/www/PieChartApiExamples.spec-vr.tsx-snapshots/TwoLevelPieChart-1-firefox-linux.png is excluded by !**/*.png
  • test-vr/__snapshots__/tests/www/PieChartApiExamples.spec-vr.tsx-snapshots/TwoLevelPieChart-1-webkit-linux.png is excluded by !**/*.png
📒 Files selected for processing (38)
  • src/cartesian/Area.tsx
  • src/cartesian/Bar.tsx
  • src/cartesian/Brush.tsx
  • src/cartesian/Funnel.tsx
  • src/cartesian/Line.tsx
  • src/cartesian/Scatter.tsx
  • src/chart/Sankey.tsx
  • src/chart/SunburstChart.tsx
  • src/chart/Treemap.tsx
  • src/polar/Pie.tsx
  • src/polar/Radar.tsx
  • src/polar/RadialBar.tsx
  • src/state/chartDataSlice.ts
  • src/state/optionsSlice.ts
  • src/state/selectors/combiners/combineCoordinateForDefaultIndex.ts
  • src/state/selectors/selectTooltipPayloadSearcher.ts
  • src/state/selectors/selectors.ts
  • src/state/selectors/tooltipSelectors.ts
  • src/state/selectors/touchSelectors.ts
  • src/state/tooltipSlice.ts
  • src/util/DataUtils.ts
  • src/util/types.ts
  • test-vr/tests/www/PieChartApiExamples.spec-vr.tsx
  • test/cartesian/Area.spec.tsx
  • test/cartesian/Bar.spec.tsx
  • test/chart/ScatterChart.spec.tsx
  • test/component/Tooltip/Tooltip.payload.spec.tsx
  • test/component/Tooltip/Tooltip.visibility.spec.tsx
  • test/component/Tooltip/itemSorter.spec.tsx
  • test/helper/expectFunctionReturning.ts
  • test/polar/Pie.spec.tsx
  • test/state/selectors/axisSelectors.spec.tsx
  • test/state/selectors/selectors.spec.tsx
  • test/tsconfig.json
  • vitest.config.mts
  • www/src/docs/apiExamples/PieChart/PieChartExample.tsx
  • www/src/docs/apiExamples/PieChart/index.tsx
  • www/src/docs/exampleComponents/PieChart/TwoLevelPieChart.tsx
💤 Files with no reviewable changes (3)
  • src/state/selectors/tooltipSelectors.ts
  • www/src/docs/apiExamples/PieChart/PieChartExample.tsx
  • src/state/selectors/selectors.ts
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

**/*.{ts,tsx}: Never use any type (implicit or explicit) in TypeScript code
Prefer unknown over any and refine the type in TypeScript
Type function parameters and return values explicitly in TypeScript, do not rely on implicit any or inference; exceptions are React components and trivial functions
Do not use as type assertions in TypeScript; the only exception is as const

All imports from recharts must use the public API entry point (e.g., import { TooltipIndex } from 'recharts'). Imports from internal paths like recharts/types/* or recharts/src/* are not allowed and will fail the linter.

Files:

  • src/util/DataUtils.ts
  • src/util/types.ts
  • src/cartesian/Scatter.tsx
  • www/src/docs/apiExamples/PieChart/index.tsx
  • test/cartesian/Area.spec.tsx
  • test/component/Tooltip/Tooltip.payload.spec.tsx
  • src/polar/Pie.tsx
  • src/chart/Sankey.tsx
  • src/state/optionsSlice.ts
  • test/component/Tooltip/itemSorter.spec.tsx
  • src/cartesian/Funnel.tsx
  • src/polar/RadialBar.tsx
  • test/cartesian/Bar.spec.tsx
  • src/cartesian/Line.tsx
  • src/state/selectors/combiners/combineCoordinateForDefaultIndex.ts
  • src/state/chartDataSlice.ts
  • test/state/selectors/axisSelectors.spec.tsx
  • www/src/docs/exampleComponents/PieChart/TwoLevelPieChart.tsx
  • test-vr/tests/www/PieChartApiExamples.spec-vr.tsx
  • test/polar/Pie.spec.tsx
  • test/chart/ScatterChart.spec.tsx
  • test/component/Tooltip/Tooltip.visibility.spec.tsx
  • src/cartesian/Bar.tsx
  • src/state/tooltipSlice.ts
  • test/helper/expectFunctionReturning.ts
  • src/state/selectors/selectTooltipPayloadSearcher.ts
  • src/chart/SunburstChart.tsx
  • src/state/selectors/touchSelectors.ts
  • src/polar/Radar.tsx
  • src/cartesian/Brush.tsx
  • test/state/selectors/selectors.spec.tsx
  • src/chart/Treemap.tsx
  • src/cartesian/Area.tsx
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Ensure code lints by running npm run lint and follows Airbnb's Style Guide

Files:

  • src/util/DataUtils.ts
  • src/util/types.ts
  • src/cartesian/Scatter.tsx
  • www/src/docs/apiExamples/PieChart/index.tsx
  • test/cartesian/Area.spec.tsx
  • test/component/Tooltip/Tooltip.payload.spec.tsx
  • src/polar/Pie.tsx
  • src/chart/Sankey.tsx
  • src/state/optionsSlice.ts
  • test/component/Tooltip/itemSorter.spec.tsx
  • src/cartesian/Funnel.tsx
  • src/polar/RadialBar.tsx
  • test/cartesian/Bar.spec.tsx
  • src/cartesian/Line.tsx
  • src/state/selectors/combiners/combineCoordinateForDefaultIndex.ts
  • src/state/chartDataSlice.ts
  • test/state/selectors/axisSelectors.spec.tsx
  • www/src/docs/exampleComponents/PieChart/TwoLevelPieChart.tsx
  • test-vr/tests/www/PieChartApiExamples.spec-vr.tsx
  • test/polar/Pie.spec.tsx
  • test/chart/ScatterChart.spec.tsx
  • test/component/Tooltip/Tooltip.visibility.spec.tsx
  • src/cartesian/Bar.tsx
  • src/state/tooltipSlice.ts
  • test/helper/expectFunctionReturning.ts
  • src/state/selectors/selectTooltipPayloadSearcher.ts
  • src/chart/SunburstChart.tsx
  • src/state/selectors/touchSelectors.ts
  • src/polar/Radar.tsx
  • src/cartesian/Brush.tsx
  • test/state/selectors/selectors.spec.tsx
  • src/chart/Treemap.tsx
  • src/cartesian/Area.tsx
src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Do not hardcode any strings or formatting choices in library code; users should provide localized strings as desired

Files:

  • src/util/DataUtils.ts
  • src/util/types.ts
  • src/cartesian/Scatter.tsx
  • src/polar/Pie.tsx
  • src/chart/Sankey.tsx
  • src/state/optionsSlice.ts
  • src/cartesian/Funnel.tsx
  • src/polar/RadialBar.tsx
  • src/cartesian/Line.tsx
  • src/state/selectors/combiners/combineCoordinateForDefaultIndex.ts
  • src/state/chartDataSlice.ts
  • src/cartesian/Bar.tsx
  • src/state/tooltipSlice.ts
  • src/state/selectors/selectTooltipPayloadSearcher.ts
  • src/chart/SunburstChart.tsx
  • src/state/selectors/touchSelectors.ts
  • src/polar/Radar.tsx
  • src/cartesian/Brush.tsx
  • src/chart/Treemap.tsx
  • src/cartesian/Area.tsx
test/**/*.spec.{ts,tsx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Aim for 100% unit test code coverage when writing new code

Files:

  • test/cartesian/Area.spec.tsx
  • test/component/Tooltip/Tooltip.payload.spec.tsx
  • test/component/Tooltip/itemSorter.spec.tsx
  • test/cartesian/Bar.spec.tsx
  • test/state/selectors/axisSelectors.spec.tsx
  • test/polar/Pie.spec.tsx
  • test/chart/ScatterChart.spec.tsx
  • test/component/Tooltip/Tooltip.visibility.spec.tsx
  • test/state/selectors/selectors.spec.tsx
test/**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (test/README.md)

test/**/*.{test,spec}.{ts,tsx}: Aim for 100% unit test code coverage when writing new code
Prefer to use the createSelectorTestCase helper function when writing or modifying tests
Use the expectLastCalledWith helper function instead of expect(spy).toHaveBeenLastCalledWith(...) for better typing and autocompletion
Verify the number of selector calls using the spy object from createSelectorTestCase to spot unnecessary re-renders and improve performance
Mock getBoundingClientRect in tests using the helper function provided in test/helper/MockGetBoundingClientRect.ts
Use vi.useFakeTimers() in all tests due to Redux autoBatchEnhancer dependency on timers and requestAnimationFrame
Call vi.runOnlyPendingTimers() to advance timers after renders when not using createSelectorTestCase helper, and avoid vi.runAllTimers() to prevent infinite loops
Use userEvent.setup({ advanceTimers: vi.runOnlyPendingTimers }) or the userEventSetup helper function from test/helper/userEventSetup.ts when creating userEvent instances
When testing tooltips on hover, use vi.runOnlyPendingTimers() after each userEvent.hover() call or use the showTooltip helper function from tooltipTestHelpers.ts to account for requestAnimationFrame delays

Files:

  • test/cartesian/Area.spec.tsx
  • test/component/Tooltip/Tooltip.payload.spec.tsx
  • test/component/Tooltip/itemSorter.spec.tsx
  • test/cartesian/Bar.spec.tsx
  • test/state/selectors/axisSelectors.spec.tsx
  • test/polar/Pie.spec.tsx
  • test/chart/ScatterChart.spec.tsx
  • test/component/Tooltip/Tooltip.visibility.spec.tsx
  • test/state/selectors/selectors.spec.tsx
**/*.spec.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

When running unit tests, prefer to run a single test file using npm run test -- path/to/TestFile.spec.tsx rather than running all tests with npm test

Unit tests should be placed in the test directory, with some tests also allowed in www/test. Test files follow the naming convention *.spec.tsx.

Files:

  • test/cartesian/Area.spec.tsx
  • test/component/Tooltip/Tooltip.payload.spec.tsx
  • test/component/Tooltip/itemSorter.spec.tsx
  • test/cartesian/Bar.spec.tsx
  • test/state/selectors/axisSelectors.spec.tsx
  • test/polar/Pie.spec.tsx
  • test/chart/ScatterChart.spec.tsx
  • test/component/Tooltip/Tooltip.visibility.spec.tsx
  • test/state/selectors/selectors.spec.tsx
test/component/**/*.spec.tsx

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Use React Testing Library for testing component interactions and behavior upon rendering

Files:

  • test/component/Tooltip/Tooltip.payload.spec.tsx
  • test/component/Tooltip/itemSorter.spec.tsx
  • test/component/Tooltip/Tooltip.visibility.spec.tsx
🧠 Learnings (29)
📓 Common learnings
Learnt from: PavelVanecek
Repo: recharts/recharts PR: 6669
File: www/src/docs/exampleComponents/ScatterChart/ScatterChartWithLabels.tsx:2-2
Timestamp: 2025-11-23T13:30:10.395Z
Learning: The `TooltipIndex` type from recharts is defined in `src/state/tooltipSlice.ts` but is not currently exported from the public API entry points. It should not be imported from `recharts/types/state/tooltipSlice` as this is an internal implementation path. An ESLint rule is needed to prevent regressions.
Learnt from: CR
Repo: recharts/recharts PR: 0
File: test/README.md:0-0
Timestamp: 2025-11-25T01:23:08.250Z
Learning: Applies to test/**/*.{test,spec}.{ts,tsx} : When testing tooltips on hover, use `vi.runOnlyPendingTimers()` after each `userEvent.hover()` call or use the `showTooltip` helper function from `tooltipTestHelpers.ts` to account for requestAnimationFrame delays
📚 Learning: 2025-12-16T08:12:13.355Z
Learnt from: PavelVanecek
Repo: recharts/recharts PR: 6783
File: test/util/ChartUtils.spec.tsx:15-16
Timestamp: 2025-12-16T08:12:13.355Z
Learning: In the recharts codebase, files in the `test` folder are allowed to import from internal paths (e.g., `../../src/state/cartesianAxisSlice`) and do not need to use the public API entry point (`src/index.ts`). The public API import restriction applies only to non-test code.

Applied to files:

  • src/util/types.ts
  • www/src/docs/apiExamples/PieChart/index.tsx
  • vitest.config.mts
  • src/cartesian/Line.tsx
  • src/state/chartDataSlice.ts
  • www/src/docs/exampleComponents/PieChart/TwoLevelPieChart.tsx
  • test-vr/tests/www/PieChartApiExamples.spec-vr.tsx
  • src/cartesian/Bar.tsx
  • test/tsconfig.json
  • src/chart/SunburstChart.tsx
  • src/chart/Treemap.tsx
  • src/cartesian/Area.tsx
📚 Learning: 2025-12-26T15:59:11.254Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: DEVELOPING.md:0-0
Timestamp: 2025-12-26T15:59:11.254Z
Learning: Applies to **/*.{ts,tsx} : All imports from `recharts` must use the public API entry point (e.g., `import { TooltipIndex } from 'recharts'`). Imports from internal paths like `recharts/types/*` or `recharts/src/*` are not allowed and will fail the linter.

Applied to files:

  • src/util/types.ts
  • www/src/docs/apiExamples/PieChart/index.tsx
  • test/cartesian/Area.spec.tsx
  • src/polar/Pie.tsx
  • src/chart/Sankey.tsx
  • src/state/optionsSlice.ts
  • src/polar/RadialBar.tsx
  • src/cartesian/Line.tsx
  • src/state/selectors/combiners/combineCoordinateForDefaultIndex.ts
  • www/src/docs/exampleComponents/PieChart/TwoLevelPieChart.tsx
  • test-vr/tests/www/PieChartApiExamples.spec-vr.tsx
  • test/chart/ScatterChart.spec.tsx
  • test/component/Tooltip/Tooltip.visibility.spec.tsx
  • src/cartesian/Bar.tsx
  • test/tsconfig.json
  • src/chart/SunburstChart.tsx
  • src/state/selectors/touchSelectors.ts
  • src/polar/Radar.tsx
  • test/state/selectors/selectors.spec.tsx
  • src/chart/Treemap.tsx
  • src/cartesian/Area.tsx
📚 Learning: 2025-11-23T13:30:10.395Z
Learnt from: PavelVanecek
Repo: recharts/recharts PR: 6669
File: www/src/docs/exampleComponents/ScatterChart/ScatterChartWithLabels.tsx:2-2
Timestamp: 2025-11-23T13:30:10.395Z
Learning: The `TooltipIndex` type from recharts is defined in `src/state/tooltipSlice.ts` but is not currently exported from the public API entry points. It should not be imported from `recharts/types/state/tooltipSlice` as this is an internal implementation path. An ESLint rule is needed to prevent regressions.

Applied to files:

  • src/util/types.ts
  • src/cartesian/Scatter.tsx
  • test/cartesian/Area.spec.tsx
  • test/component/Tooltip/Tooltip.payload.spec.tsx
  • src/polar/Pie.tsx
  • src/chart/Sankey.tsx
  • src/state/optionsSlice.ts
  • test/component/Tooltip/itemSorter.spec.tsx
  • src/cartesian/Funnel.tsx
  • src/polar/RadialBar.tsx
  • test/cartesian/Bar.spec.tsx
  • src/cartesian/Line.tsx
  • src/state/selectors/combiners/combineCoordinateForDefaultIndex.ts
  • src/state/chartDataSlice.ts
  • www/src/docs/exampleComponents/PieChart/TwoLevelPieChart.tsx
  • test/chart/ScatterChart.spec.tsx
  • test/component/Tooltip/Tooltip.visibility.spec.tsx
  • src/cartesian/Bar.tsx
  • src/state/tooltipSlice.ts
  • src/state/selectors/selectTooltipPayloadSearcher.ts
  • src/chart/SunburstChart.tsx
  • src/state/selectors/touchSelectors.ts
  • src/polar/Radar.tsx
  • src/cartesian/Brush.tsx
  • test/state/selectors/selectors.spec.tsx
  • src/chart/Treemap.tsx
  • src/cartesian/Area.tsx
📚 Learning: 2025-12-08T08:23:26.261Z
Learnt from: PavelVanecek
Repo: recharts/recharts PR: 6750
File: src/state/selectors/axisSelectors.ts:593-602
Timestamp: 2025-12-08T08:23:26.261Z
Learning: In the recharts codebase, `DataKey<any>` is an intentional exception to the "no any" rule while proper typing is being developed. This should not be flagged in reviews.

Applied to files:

  • src/util/types.ts
  • src/state/chartDataSlice.ts
  • src/cartesian/Bar.tsx
  • src/state/tooltipSlice.ts
📚 Learning: 2025-12-14T13:58:49.197Z
Learnt from: PavelVanecek
Repo: recharts/recharts PR: 6771
File: src/shape/Curve.tsx:39-40
Timestamp: 2025-12-14T13:58:49.197Z
Learning: In the recharts codebase, hooks like useAppSelector and other hooks (e.g., useChartLayout()) return undefined when used outside Redux Provider context, instead of throwing. This enables components that call these hooks, such as Curve, to operate in standalone mode by falling back to prop values. During code reviews, ensure TSX files gracefully handle undefined results from hooks and implement fallbacks (e.g., via default props or explicit prop-based values) rather than assuming the hook is always within Provider.

Applied to files:

  • src/cartesian/Scatter.tsx
  • src/polar/Pie.tsx
  • src/chart/Sankey.tsx
  • src/cartesian/Funnel.tsx
  • src/polar/RadialBar.tsx
  • src/cartesian/Line.tsx
  • src/cartesian/Bar.tsx
  • src/chart/SunburstChart.tsx
  • src/polar/Radar.tsx
  • src/cartesian/Brush.tsx
  • src/chart/Treemap.tsx
  • src/cartesian/Area.tsx
📚 Learning: 2025-12-16T08:12:06.809Z
Learnt from: PavelVanecek
Repo: recharts/recharts PR: 6783
File: test/util/ChartUtils.spec.tsx:15-16
Timestamp: 2025-12-16T08:12:06.809Z
Learning: In tests (files under any test directory, e.g., test/, __tests__/, etc.), allow importing internal module paths (e.g., ../../src/...) and do not require imports to use the public API entry point (src/index.ts). The public API import restriction should apply only to non-test code. During reviews, accept internal imports in test files and enforce the public API pattern only for non-test code.

Applied to files:

  • test/cartesian/Area.spec.tsx
  • test/component/Tooltip/Tooltip.payload.spec.tsx
  • test/component/Tooltip/itemSorter.spec.tsx
  • test/cartesian/Bar.spec.tsx
  • test/state/selectors/axisSelectors.spec.tsx
  • test/polar/Pie.spec.tsx
  • test/chart/ScatterChart.spec.tsx
  • test/component/Tooltip/Tooltip.visibility.spec.tsx
  • test/state/selectors/selectors.spec.tsx
📚 Learning: 2025-11-25T01:23:08.250Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: test/README.md:0-0
Timestamp: 2025-11-25T01:23:08.250Z
Learning: Applies to test/**/*.{test,spec}.{ts,tsx} : When testing tooltips on hover, use `vi.runOnlyPendingTimers()` after each `userEvent.hover()` call or use the `showTooltip` helper function from `tooltipTestHelpers.ts` to account for requestAnimationFrame delays

Applied to files:

  • test/cartesian/Area.spec.tsx
  • test/component/Tooltip/Tooltip.payload.spec.tsx
  • test/component/Tooltip/itemSorter.spec.tsx
  • test/cartesian/Bar.spec.tsx
  • test/chart/ScatterChart.spec.tsx
  • test/component/Tooltip/Tooltip.visibility.spec.tsx
  • src/state/selectors/touchSelectors.ts
  • test/state/selectors/selectors.spec.tsx
📚 Learning: 2025-11-25T01:23:08.250Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: test/README.md:0-0
Timestamp: 2025-11-25T01:23:08.250Z
Learning: Applies to test/**/*.{test,spec}.{ts,tsx} : Mock `getBoundingClientRect` in tests using the helper function provided in `test/helper/MockGetBoundingClientRect.ts`

Applied to files:

  • test/cartesian/Area.spec.tsx
  • test/component/Tooltip/Tooltip.payload.spec.tsx
  • test/component/Tooltip/itemSorter.spec.tsx
  • test/cartesian/Bar.spec.tsx
  • test/state/selectors/axisSelectors.spec.tsx
  • test/polar/Pie.spec.tsx
  • test/chart/ScatterChart.spec.tsx
  • test/component/Tooltip/Tooltip.visibility.spec.tsx
  • test/helper/expectFunctionReturning.ts
  • test/tsconfig.json
  • test/state/selectors/selectors.spec.tsx
📚 Learning: 2025-11-25T01:23:08.250Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: test/README.md:0-0
Timestamp: 2025-11-25T01:23:08.250Z
Learning: Applies to test/**/*.{test,spec}.{ts,tsx} : Verify the number of selector calls using the spy object from `createSelectorTestCase` to spot unnecessary re-renders and improve performance

Applied to files:

  • test/cartesian/Area.spec.tsx
  • test/component/Tooltip/Tooltip.payload.spec.tsx
  • test/component/Tooltip/itemSorter.spec.tsx
  • test/cartesian/Bar.spec.tsx
  • test/state/selectors/axisSelectors.spec.tsx
  • test-vr/tests/www/PieChartApiExamples.spec-vr.tsx
  • test/polar/Pie.spec.tsx
  • test/chart/ScatterChart.spec.tsx
  • test/component/Tooltip/Tooltip.visibility.spec.tsx
  • test/helper/expectFunctionReturning.ts
  • src/state/selectors/touchSelectors.ts
  • test/state/selectors/selectors.spec.tsx
📚 Learning: 2025-11-25T01:23:08.250Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: test/README.md:0-0
Timestamp: 2025-11-25T01:23:08.250Z
Learning: Applies to test/**/*.{test,spec}.{ts,tsx} : Use the `expectLastCalledWith` helper function instead of `expect(spy).toHaveBeenLastCalledWith(...)` for better typing and autocompletion

Applied to files:

  • test/cartesian/Area.spec.tsx
  • test/component/Tooltip/Tooltip.payload.spec.tsx
  • test/component/Tooltip/itemSorter.spec.tsx
  • test/cartesian/Bar.spec.tsx
  • vitest.config.mts
  • test/state/selectors/axisSelectors.spec.tsx
  • test/polar/Pie.spec.tsx
  • test/chart/ScatterChart.spec.tsx
  • test/component/Tooltip/Tooltip.visibility.spec.tsx
  • test/helper/expectFunctionReturning.ts
  • test/tsconfig.json
  • test/state/selectors/selectors.spec.tsx
📚 Learning: 2025-11-25T01:23:08.250Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: test/README.md:0-0
Timestamp: 2025-11-25T01:23:08.250Z
Learning: Applies to test/**/*.{test,spec}.{ts,tsx} : Prefer to use the `createSelectorTestCase` helper function when writing or modifying tests

Applied to files:

  • test/cartesian/Area.spec.tsx
  • test/component/Tooltip/Tooltip.payload.spec.tsx
  • test/component/Tooltip/itemSorter.spec.tsx
  • test/cartesian/Bar.spec.tsx
  • vitest.config.mts
  • test/state/selectors/axisSelectors.spec.tsx
  • test/component/Tooltip/Tooltip.visibility.spec.tsx
  • test/helper/expectFunctionReturning.ts
  • test/tsconfig.json
  • test/state/selectors/selectors.spec.tsx
📚 Learning: 2025-11-25T01:23:08.250Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: test/README.md:0-0
Timestamp: 2025-11-25T01:23:08.250Z
Learning: Applies to test/**/*.{test,spec}.{ts,tsx} : Use `userEvent.setup({ advanceTimers: vi.runOnlyPendingTimers })` or the `userEventSetup` helper function from `test/helper/userEventSetup.ts` when creating userEvent instances

Applied to files:

  • test/cartesian/Area.spec.tsx
  • test/cartesian/Bar.spec.tsx
  • vitest.config.mts
📚 Learning: 2025-11-25T01:22:59.729Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-11-25T01:22:59.729Z
Learning: Applies to test/component/**/*.spec.tsx : Use React Testing Library for testing component interactions and behavior upon rendering

Applied to files:

  • test/cartesian/Area.spec.tsx
  • test/cartesian/Bar.spec.tsx
  • vitest.config.mts
  • test/state/selectors/axisSelectors.spec.tsx
  • test-vr/tests/www/PieChartApiExamples.spec-vr.tsx
  • test/state/selectors/selectors.spec.tsx
📚 Learning: 2025-11-25T01:23:08.250Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: test/README.md:0-0
Timestamp: 2025-11-25T01:23:08.250Z
Learning: Applies to test/**/*.{test,spec}.{ts,tsx} : Call `vi.runOnlyPendingTimers()` to advance timers after renders when not using `createSelectorTestCase` helper, and avoid `vi.runAllTimers()` to prevent infinite loops

Applied to files:

  • test/cartesian/Area.spec.tsx
  • test/cartesian/Bar.spec.tsx
  • vitest.config.mts
  • test/state/selectors/axisSelectors.spec.tsx
  • test-vr/tests/www/PieChartApiExamples.spec-vr.tsx
  • test/component/Tooltip/Tooltip.visibility.spec.tsx
  • test/state/selectors/selectors.spec.tsx
📚 Learning: 2025-12-14T13:58:58.361Z
Learnt from: PavelVanecek
Repo: recharts/recharts PR: 6771
File: src/shape/Curve.tsx:39-40
Timestamp: 2025-12-14T13:58:58.361Z
Learning: In the recharts codebase, `useAppSelector` and hooks like `useChartLayout()` are designed to return `undefined` when used outside Redux Provider context, rather than throwing errors. This allows components like `Curve` that call these hooks to work standalone by falling back to prop values.

Applied to files:

  • src/state/optionsSlice.ts
  • test/state/selectors/axisSelectors.spec.tsx
  • www/src/docs/exampleComponents/PieChart/TwoLevelPieChart.tsx
  • test-vr/tests/www/PieChartApiExamples.spec-vr.tsx
  • src/state/selectors/selectTooltipPayloadSearcher.ts
  • src/state/selectors/touchSelectors.ts
  • test/state/selectors/selectors.spec.tsx
📚 Learning: 2025-11-25T01:23:08.250Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: test/README.md:0-0
Timestamp: 2025-11-25T01:23:08.250Z
Learning: Applies to test/**/*.{test,spec}.{ts,tsx} : Use `vi.useFakeTimers()` in all tests due to Redux autoBatchEnhancer dependency on timers and `requestAnimationFrame`

Applied to files:

  • test/component/Tooltip/itemSorter.spec.tsx
  • vitest.config.mts
  • test/state/selectors/axisSelectors.spec.tsx
  • test-vr/tests/www/PieChartApiExamples.spec-vr.tsx
  • test/helper/expectFunctionReturning.ts
  • test/tsconfig.json
  • test/state/selectors/selectors.spec.tsx
📚 Learning: 2025-11-25T01:22:59.729Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-11-25T01:22:59.729Z
Learning: Applies to storybook/stories/**/*.stories.tsx : Use Storybook for smoke tests and add play functions with assertions for actual tests

Applied to files:

  • test/cartesian/Bar.spec.tsx
  • test-vr/tests/www/PieChartApiExamples.spec-vr.tsx
  • test/helper/expectFunctionReturning.ts
📚 Learning: 2025-12-26T15:59:11.254Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: DEVELOPING.md:0-0
Timestamp: 2025-12-26T15:59:11.254Z
Learning: Applies to **/*.spec.{ts,tsx} : Unit tests should be placed in the `test` directory, with some tests also allowed in `www/test`. Test files follow the naming convention `*.spec.tsx`.

Applied to files:

  • vitest.config.mts
  • test/tsconfig.json
📚 Learning: 2025-12-26T15:59:11.254Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: DEVELOPING.md:0-0
Timestamp: 2025-12-26T15:59:11.254Z
Learning: Applies to test-vr/**/*.spec.ts : Visual regression tests should follow the naming convention `*.spec.ts` and be placed in the `test-vr` directory. When updating snapshots, new files created in `test-vr/__snapshots__` should be committed to the repository.

Applied to files:

  • vitest.config.mts
  • test-vr/tests/www/PieChartApiExamples.spec-vr.tsx
  • test/chart/ScatterChart.spec.tsx
  • test/tsconfig.json
📚 Learning: 2025-11-25T01:23:14.977Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T01:23:14.977Z
Learning: Applies to **/*.spec.{ts,tsx} : When running unit tests, prefer to run a single test file using `npm run test -- path/to/TestFile.spec.tsx` rather than running all tests with `npm test`

Applied to files:

  • vitest.config.mts
  • test/tsconfig.json
📚 Learning: 2025-11-25T01:22:59.729Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-11-25T01:22:59.729Z
Learning: Applies to test/**/*.spec.{ts,tsx} : Aim for 100% unit test code coverage when writing new code

Applied to files:

  • vitest.config.mts
📚 Learning: 2025-11-25T01:23:08.250Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: test/README.md:0-0
Timestamp: 2025-11-25T01:23:08.250Z
Learning: Applies to test/**/*.{test,spec}.{ts,tsx} : Aim for 100% unit test code coverage when writing new code

Applied to files:

  • vitest.config.mts
📚 Learning: 2025-11-19T14:08:01.728Z
Learnt from: PavelVanecek
Repo: recharts/recharts PR: 6659
File: www/src/components/GuideView/Performance/index.tsx:232-250
Timestamp: 2025-11-19T14:08:01.728Z
Learning: In Recharts version 3.4.2, object-as-prop optimizations were introduced to reduce unnecessary re-renders when new object references are passed as props. This affects the recommendation for the `react-perf/jsx-no-new-object-as-prop` ESLint rule.

Applied to files:

  • www/src/docs/exampleComponents/PieChart/TwoLevelPieChart.tsx
📚 Learning: 2025-11-16T09:14:24.918Z
Learnt from: PavelVanecek
Repo: recharts/recharts PR: 6640
File: src/cartesian/Bar.tsx:156-159
Timestamp: 2025-11-16T09:14:24.918Z
Learning: In recharts, SSR (Server-Side Rendering) is not yet supported—charts don't render at all in SSR environments. The `isAnimationActive: 'auto'` mode is preparatory work for future SSR support, so testing of this mode should be deferred until SSR support is actually implemented.

Applied to files:

  • www/src/docs/exampleComponents/PieChart/TwoLevelPieChart.tsx
📚 Learning: 2025-11-25T01:22:59.729Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-11-25T01:22:59.729Z
Learning: Applies to storybook/stories/**/*.stories.tsx : Update Storybook stories when APIs have been changed to ensure they work as expected

Applied to files:

  • test/chart/ScatterChart.spec.tsx
📚 Learning: 2025-12-26T15:59:11.254Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: DEVELOPING.md:0-0
Timestamp: 2025-12-26T15:59:11.254Z
Learning: For release testing, use `yalc` to test Recharts changes in a test package as close as possible to the results of `npm publish` to ensure no unintended breaking changes are published.

Applied to files:

  • test/chart/ScatterChart.spec.tsx
📚 Learning: 2025-11-25T01:22:59.729Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-11-25T01:22:59.729Z
Learning: Applies to **/*.{ts,tsx} : Type function parameters and return values explicitly in TypeScript, do not rely on implicit any or inference; exceptions are React components and trivial functions

Applied to files:

  • test/tsconfig.json
📚 Learning: 2025-11-25T01:22:59.729Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-11-25T01:22:59.729Z
Learning: Applies to **/*.{ts,tsx} : Do not use `as` type assertions in TypeScript; the only exception is `as const`

Applied to files:

  • test/tsconfig.json
🧬 Code graph analysis (21)
src/util/types.ts (1)
src/state/chartDataSlice.ts (1)
  • ChartData (15-15)
test/cartesian/Area.spec.tsx (1)
src/util/DataUtils.ts (1)
  • noop (210-210)
test/component/Tooltip/Tooltip.payload.spec.tsx (1)
src/util/DataUtils.ts (1)
  • noop (210-210)
src/chart/Sankey.tsx (1)
src/util/DataUtils.ts (1)
  • noop (210-210)
src/state/optionsSlice.ts (1)
src/state/tooltipSlice.ts (1)
  • TooltipPayloadSearcher (46-51)
test/component/Tooltip/itemSorter.spec.tsx (1)
src/util/DataUtils.ts (1)
  • noop (210-210)
test/cartesian/Bar.spec.tsx (1)
src/util/DataUtils.ts (1)
  • noop (210-210)
src/cartesian/Line.tsx (2)
src/util/DataUtils.ts (1)
  • noop (210-210)
src/state/chartDataSlice.ts (1)
  • ChartData (15-15)
src/state/selectors/combiners/combineCoordinateForDefaultIndex.ts (1)
src/util/types.ts (1)
  • Coordinate (126-129)
test/state/selectors/axisSelectors.spec.tsx (1)
test/helper/expectAxisTicks.ts (1)
  • ExpectAxisDomain (39-51)
www/src/docs/exampleComponents/PieChart/TwoLevelPieChart.tsx (1)
src/state/tooltipSlice.ts (1)
  • TooltipIndex (39-39)
test-vr/tests/www/PieChartApiExamples.spec-vr.tsx (1)
www/src/docs/exampleComponents/PieChart/TwoLevelPieChart.tsx (1)
  • TwoLevelPieChart (26-62)
test/component/Tooltip/Tooltip.visibility.spec.tsx (1)
src/util/DataUtils.ts (1)
  • noop (210-210)
src/cartesian/Bar.tsx (3)
src/util/DataUtils.ts (1)
  • noop (210-210)
src/state/chartDataSlice.ts (1)
  • ChartData (15-15)
src/index.ts (1)
  • BarRectangleItem (86-86)
src/state/tooltipSlice.ts (1)
src/util/types.ts (2)
  • DataKey (91-91)
  • Coordinate (126-129)
src/state/selectors/selectTooltipPayloadSearcher.ts (2)
src/state/store.ts (1)
  • RechartsRootState (23-38)
src/state/tooltipSlice.ts (1)
  • TooltipPayloadSearcher (46-51)
src/polar/Radar.tsx (1)
src/util/DataUtils.ts (1)
  • noop (210-210)
src/cartesian/Brush.tsx (2)
src/state/chartDataSlice.ts (1)
  • ChartData (15-15)
src/util/DataUtils.ts (1)
  • isNotNil (202-204)
test/state/selectors/selectors.spec.tsx (1)
src/util/DataUtils.ts (1)
  • noop (210-210)
src/chart/Treemap.tsx (3)
src/state/tooltipSlice.ts (2)
  • TooltipPayloadSearcher (46-51)
  • TooltipIndex (39-39)
src/index.ts (2)
  • TooltipIndex (17-17)
  • TreemapNode (105-105)
src/util/DataUtils.ts (1)
  • noop (210-210)
src/cartesian/Area.tsx (2)
src/state/chartDataSlice.ts (1)
  • ChartData (15-15)
src/util/DataUtils.ts (1)
  • noop (210-210)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Build, Test, Pack
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (56)
test/state/selectors/axisSelectors.spec.tsx (1)

176-176: LGTM! Test structure simplification.

The direct usage of ExpectAxisDomain removes an unnecessary wrapper layer, making these tests more straightforward while maintaining identical functionality and assertions.

Also applies to: 241-241, 1452-1452

test/tsconfig.json (1)

11-11: LGTM!

The new helper file is correctly added to the TypeScript include list, following the same pattern as the existing toBeRechartsScale.ts entry.

src/state/tooltipSlice.ts (2)

46-51: LGTM - Type simplification.

Removing the unused generic R from TooltipPayloadSearcher simplifies the type while maintaining the same functionality. The return type T | undefined is appropriate for the searcher pattern.


76-80: LGTM - Good API improvement.

Replacing the optional positions array/map with a required getPosition function is a clean design choice that:

  1. Eliminates the type ambiguity between array and map
  2. Makes the positioning logic lazy and dynamic
  3. Uses NonNullable<TooltipIndex> to ensure callers handle null indices before calling

The added documentation clearly explains the expected behavior.

test/cartesian/Area.spec.tsx (2)

25-25: LGTM!

The import of noop from the internal path is appropriate for test files. Based on learnings, test files are allowed to import from internal paths.


869-887: LGTM - Test expectation updated correctly.

The test expectation is properly updated to use getPosition: noop instead of the previous positions: undefined, aligning with the new tooltip positioning API.

src/util/types.ts (2)

36-36: LGTM - Good type import addition.

Adding the ChartData import centralizes the data type definition, ensuring consistency across the codebase.


1332-1332: Type improvement from any[] to ChartData is sound and beneficial.

Changing data to ChartData (ReadonlyArray<unknown>) in the BaseChartProps interface is a positive change that:

  1. Eliminates any type per coding guidelines
  2. Makes the data array readonly, preventing accidental mutations
  3. Uses unknown for better type safety

As a public API change in component props, consumers who attempt direct array mutations will see TypeScript errors—the intended behavior. No evidence of such mutations exists in the codebase.

test/cartesian/Bar.spec.tsx (3)

46-46: LGTM!

The import of noop from the internal path is appropriate for test files per coding guidelines.


1616-1651: LGTM - Test expectations updated correctly.

The tooltip item payload expectations are properly updated to use getPosition: noop instead of the previous positions: undefined, correctly reflecting the new API structure.


1689-1724: LGTM - Consistent updates across test cases.

The post-hover tooltip state expectations maintain consistency with the pre-hover state, using getPosition: noop for both tooltip item payloads.

src/state/optionsSlice.ts (2)

21-21: LGTM - Good type tightening.

Making tooltipPayloadSearcher required instead of optional eliminates the need for null checks when accessing this property throughout the codebase.


43-48: LGTM - Appropriate default value.

The default () => undefined is a valid implementation of TooltipPayloadSearcher that safely returns undefined for any input. In TypeScript, functions with fewer parameters are assignable to function types with more parameters, so this is type-safe.

src/util/DataUtils.ts (1)

210-210: LGTM!

The return type change from void to undefined is appropriate. This aligns with the function's usage as a getPosition placeholder in tooltip configurations, where getPosition: (index) => Coordinate | undefined is expected, and noop serves as a no-op implementation returning undefined.

test/component/Tooltip/Tooltip.payload.spec.tsx (2)

83-83: LGTM!

The import of noop from DataUtils is appropriate for updating test expectations to match the new getPosition-based tooltip payload configuration API.


974-974: LGTM!

The test expectations correctly updated from positions: undefined to getPosition: noop, aligning with the refactored tooltip positioning API. The changes are consistent across all three payload configuration expectations.

Also applies to: 1028-1028, 1082-1082

test/component/Tooltip/itemSorter.spec.tsx (3)

39-39: LGTM!

The import of noop from DataUtils supports the updated test expectations for the new getPosition-based tooltip configuration API.


86-86: LGTM!

The test expectations correctly updated from positions: undefined to getPosition: noop for Area, Bar, and Line components. This aligns with the refactored tooltip positioning API.

Also applies to: 103-103, 120-120


306-313: The expect.functionReturning helper is properly available. The custom matcher is defined in test/helper/expectFunctionReturning.ts, extended to the expect object, and has proper TypeScript type declarations for AsymmetricMatchersContaining. The test code at these lines correctly uses this available helper.

src/cartesian/Line.tsx (5)

25-25: LGTM!

The import of noop supports the new getPosition-based tooltip configuration pattern.


69-69: LGTM!

The import of ChartData enables stronger typing for the component's data props, replacing the previous any[] type.


170-170: LGTM! Improved type safety.

Changing the data prop type from any[] to ChartData (which is ReadonlyArray<unknown>) improves type safety while maintaining flexibility. The readonly constraint is appropriate since the component should not mutate input data.


363-363: LGTM!

The change from positions: undefined to getPosition: noop aligns with the refactored tooltip positioning API. Line chart doesn't provide positional data per point (unlike Scatter), so noop is the appropriate placeholder.


927-927: LGTM!

The parameter type change from any[] to ChartData improves type safety. This function signature now matches the improved typing established throughout the component.

src/cartesian/Scatter.tsx (1)

399-399: LGTM! The index parameter type is correct.

The refactor from a precomputed positions array to a dynamic getPosition accessor function is correct and more memory-efficient. The index parameter is TooltipIndex (a string), and using Number(index) for array access is the appropriate pattern. All callers properly pass valid string indices through the tooltip state selectors, consistent with implementations in Pie and Funnel charts.

src/polar/RadialBar.tsx (2)

17-17: LGTM!

The import of noop is consistent with the PR's refactoring pattern across other chart components.


443-443: LGTM!

Replacing positions: undefined with getPosition: noop aligns with the PR objective to standardize tooltip positioning with a function-based API. Using noop is appropriate for RadialBar since it doesn't provide position data.

www/src/docs/apiExamples/PieChart/index.tsx (1)

2-8: LGTM!

The consolidation of duplicate Pie examples by replacing PieChartExample with TwoLevelPieChart is consistent and well-structured. The imports and references are updated correctly.

test-vr/tests/www/PieChartApiExamples.spec-vr.tsx (1)

56-56: LGTM!

Adding defaultIndex="1" exercises the tooltip positioning functionality as intended by the PR, providing valuable visual regression coverage for the new getPosition API.

src/state/selectors/touchSelectors.ts (2)

27-29: LGTM!

The null check for tooltipIndex is a proper guard before attempting to call getPosition, preventing potential runtime errors.


36-40: LGTM!

The refactoring from array-based positions to function-based getPosition(tooltipIndex) simplifies the tooltip positioning API and improves type safety. The null check and function call pattern are implemented correctly.

src/state/selectors/selectTooltipPayloadSearcher.ts (1)

4-5: Verification confirms the type change is correct. tooltipPayloadSearcher is always defined: it's a required field in ChartOptions, initialized to () => undefined in the initial state, and no reducer can mutate it to undefined. The return type change from optional to required is safe.

test/component/Tooltip/Tooltip.visibility.spec.tsx (2)

94-94: LGTM! Test expectations updated correctly.

The test now correctly expects getPosition: noop in tooltip payload configurations instead of the previous positions: undefined, aligning with the PR's shift to function-based position resolution.

Also applies to: 1125-1125, 1217-1217


987-993: LGTM! Dynamic position validation using new test helper.

The test correctly validates the getPosition function using expect.functionReturning, which verifies that each sector index ('0' to '4') maps to its corresponding coordinate. This properly exercises the new function-based position API.

src/state/selectors/combiners/combineCoordinateForDefaultIndex.ts (1)

2-2: LGTM! Simplified position lookup using configuration's getPosition method.

The refactor correctly removes the tooltipPayloadSearcher parameter and instead accesses getPosition directly from the first tooltip configuration. The optional chaining handles empty configurations safely, and the fallback to tooltipTicks preserves existing behavior when getPosition returns undefined.

Also applies to: 11-25

src/state/chartDataSlice.ts (1)

2-2: LGTM! Proper use of readonly types with Immer.

The type change from unknown[] to ReadonlyArray<unknown> improves immutability guarantees, and castDraft is correctly used to handle the assignment of readonly payload into mutable draft state.

Also applies to: 15-15, 59-59

src/cartesian/Area.tsx (1)

23-23: LGTM! Improved typing and tooltip configuration.

The changes properly:

  • Replace any[] with the typed ChartData (aligning with the "no any" coding guideline)
  • Use getPosition: noop instead of positions: undefined to match the new function-based position API
  • Import noop from the utilities module

Based on learnings, this follows the established pattern for tooltip position resolution across chart components.

Also applies to: 99-99, 354-354

src/polar/Radar.tsx (2)

6-6: LGTM!

The noop import is necessary for the tooltip configuration change at line 218, aligning with the PR's pattern of replacing static positions with dynamic getPosition functions.


218-218: LGTM!

The change from positions: undefined to getPosition: noop is consistent with the PR's objective to unify tooltip positioning with a function-based API. The existing comment (lines 211-216) appropriately documents why returning undefined is correct for Radar charts.

src/chart/Sankey.tsx (1)

30-30: LGTM!

The changes align with the PR's objective to replace static positions with a dynamic getPosition function. Using noop (which returns undefined) is appropriate for Sankey charts where tooltip positioning is not defined per item.

Also applies to: 551-551

src/polar/Pie.tsx (1)

444-444: Efficient lazy position lookup!

The change from a static positions array to a dynamic getPosition function improves efficiency by avoiding the creation of an intermediate array. The use of Number(index) conversion and optional chaining (?.) provides appropriate safety for index lookups.

src/chart/SunburstChart.tsx (2)

144-144: LGTM!

The change from convertMapToRecord(positions) to a direct getPosition function using Map.get() is more efficient and aligns with the PR's pattern of using dynamic position lookups.


180-185: No action required—function is internal.

addToSunburstNodeIndex was never exported through the public API (src/index.ts) and has no usage outside SunburstChart.tsx. It is purely an internal utility function, so removing the export (if previously present) is not a breaking change and appropriately maintains a minimal public API surface.

test/chart/ScatterChart.spec.tsx (1)

1733-1740: LGTM!

The test updates correctly reflect the API change from static positions arrays to dynamic getPosition functions. The use of expect.functionReturning([...]) appropriately validates both that getPosition is a function and that it returns the expected coordinate values for each index.

Also applies to: 1935-1942, 1972-1979, 2315-2319

src/cartesian/Brush.tsx (2)

161-172: Good helper extraction for aria label generation.

The getNameFromUnknown and getAriaLabel helper functions properly encapsulate the logic for extracting string names from unknown data types and composing aria labels. The type guards in getNameFromUnknown are correct.

However, consider what happens when data[startIndex] or data[endIndex] don't have a name property - the aria label will display "Min value: undefined, Max value: undefined". While this isn't critical, you might want to handle this edge case more gracefully (e.g., fallback to index numbers).


127-127: Excellent type safety improvement from any[] to ChartData.

The systematic replacement of any[] with ChartData (which is ReadonlyArray<unknown>) across PropertiesFromContext, TextOfTickProps, getIndex parameter, BrushText, Panorama, and State.prevData improves type safety while maintaining flexibility for various data shapes. This aligns well with the PR's objective to modernize type definitions.

Also applies to: 239-239, 287-287, 339-339, 425-425, 464-464

www/src/docs/exampleComponents/PieChart/TwoLevelPieChart.tsx (1)

1-1: LGTM! Clean addition of defaultIndex support.

The changes properly add Tooltip with defaultIndex support to the example component. The typing is correct, using TooltipIndex from the public API, and the component signature is cleanly extended.

Also applies to: 26-32, 58-58

test/state/selectors/selectors.spec.tsx (1)

38-38: LGTM! Test updates properly align with the new API.

The test updates consistently replace positions arrays with getPosition: noop, which is appropriate for tests that don't need actual tooltip positioning logic. The import of noop from DataUtils and removal of the Customized wrapper simplify the test setup.

Also applies to: 53-53, 90-90, 128-128, 265-265, 278-278, 323-323, 336-336, 370-370, 416-416, 510-510

src/cartesian/Bar.tsx (2)

25-25: LGTM! Consistent use of noop for tooltip positioning.

The import and usage of noop for getPosition is consistent with the refactoring pattern across other components. Since Bar tooltips compute positions dynamically elsewhere, using noop here is appropriate.

Also applies to: 414-414


88-88: Good type safety improvement with ChartData.

Changing the displayedData parameter from implicit any[] to ChartData (ReadonlyArray<unknown>) in computeBarRectangles improves type safety and consistency with the broader refactoring across the codebase.

Also applies to: 951-951

src/chart/Treemap.tsx (5)

76-89: LGTM: Enhanced type guard with explicit runtime checks.

The explicit typeof checks on lines 84-87 improve the robustness of the isTreemapNode type guard by verifying that x, y, width, and height are not only present but are also numbers at runtime.


91-99: LGTM: Explicit function signature improves type safety.

The updated treemapPayloadSearcher signature with explicit parameters and return type TreemapNode | undefined (instead of unknown) provides better type safety and clarity.


625-655: LGTM: Tooltip configuration updated to use new getPosition API.

The change from positions: undefined to getPosition: noop aligns with the PR objective to replace static position arrays with dynamic functions. The noop placeholder is appropriate given the TODO comment indicating that proper position computation is not yet implemented for Treemap.


964-996: LGTM: Proper use of unknown type with type guard.

Line 974 correctly uses unknown instead of any, followed by the isTreemapNode type guard on line 975 to safely narrow the type before accessing properties. This follows the coding guideline to prefer unknown over any and refine the type.

Based on coding guidelines.


483-483: Null-to-undefined migration is complete and safe.

The change to currentRoot: TreemapNode | undefined (lines 483, 508) is correctly paired with the default initialization, and the codebase uses loose equality checks (== null) which safely handle both null and undefined values. The migration is scoped appropriately—only currentRoot was changed to undefined while formatRoot correctly remains null.

test/polar/Pie.spec.tsx (1)

987-993: LGTM! Correctly implements the new function-based tooltip positioning API.

The test now validates that getPosition is a function returning position coordinates keyed by sector index, replacing the previous static positions array. The use of expect.functionReturning appropriately tests the function's return value without prematurely calling it during state validation.

Comment on lines +3 to +8
interface SyncExpectationResult {
pass: boolean;
message: () => string;
actual?: any;
expected?: any;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Replace any with unknown in interface definition.

Lines 6-7 use the any type, which violates the coding guideline to never use any in TypeScript code. Use unknown instead.

🔎 Proposed fix
 interface SyncExpectationResult {
   pass: boolean;
   message: () => string;
-  actual?: any;
-  expected?: any;
+  actual?: unknown;
+  expected?: unknown;
 }

Based on coding guidelines: "Never use any type (implicit or explicit) in TypeScript code" and "Prefer unknown over any and refine the type in TypeScript".

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
interface SyncExpectationResult {
pass: boolean;
message: () => string;
actual?: any;
expected?: any;
}
interface SyncExpectationResult {
pass: boolean;
message: () => string;
actual?: unknown;
expected?: unknown;
}
🤖 Prompt for AI Agents
In test/helper/expectFunctionReturning.ts around lines 3 to 8, the
SyncExpectationResult interface uses the any type for the optional actual and
expected properties; replace both occurrences of any with unknown to comply with
the guideline to never use any and prefer unknown so callers must narrow the
types before use.

@codecov
Copy link

codecov bot commented Jan 3, 2026

Codecov Report

❌ Patch coverage is 96.96970% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 93.89%. Comparing base (8bb5aa4) to head (20ea880).
⚠️ Report is 4 commits behind head on main.

Files with missing lines Patch % Lines
src/state/selectors/touchSelectors.ts 66.66% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #6844      +/-   ##
==========================================
+ Coverage   93.85%   93.89%   +0.04%     
==========================================
  Files         531      530       -1     
  Lines       49391    49351      -40     
  Branches     5163     5166       +3     
==========================================
- Hits        46355    46339      -16     
+ Misses       3029     3005      -24     
  Partials        7        7              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@github-actions
Copy link
Contributor

github-actions bot commented Jan 3, 2026

Staging Deployment Details

These deployments will remain available for 30 days.

To update snapshots: Comment /update-snapshots on this PR to automatically update the baseline screenshots.

@codecov
Copy link

codecov bot commented Jan 4, 2026

Bundle Report

Changes will increase total bundle size by 306 bytes (0.01%) ⬆️. This is within the configured threshold ✅

Detailed changes
Bundle name Size Change
recharts/bundle-cjs 1.2MB 45 bytes (0.0%) ⬆️
recharts/bundle-es6 1.04MB 135 bytes (0.01%) ⬆️
recharts/bundle-umd 527.92kB 126 bytes (0.02%) ⬆️

Affected Assets, Files, and Routes:

view changes for bundle: recharts/bundle-es6

Assets Changed:

Asset Name Size Change Total Size Change (%)
chart/Sankey.js 3 bytes 29.65kB 0.01%
chart/Treemap.js 8 bytes 28.03kB 0.03%
cartesian/Area.js 3 bytes 27.59kB 0.01%
cartesian/Brush.js 154 bytes 27.31kB 0.57%
cartesian/Bar.js 3 bytes 26.1kB 0.01%
cartesian/Line.js 3 bytes 24.89kB 0.01%
polar/Pie.js 149 bytes 24.64kB 0.61%
cartesian/Scatter.js 137 bytes 22.75kB 0.61%
polar/RadialBar.js 3 bytes 19.83kB 0.02%
cartesian/Funnel.js 84 bytes 17.66kB 0.48%
polar/Radar.js 3 bytes 16.4kB 0.02%
state/selectors/tooltipSelectors.js -30 bytes 14.14kB -0.21%
chart/SunburstChart.js -212 bytes 11.69kB -1.78%
state/selectors/selectors.js -30 bytes 6.34kB -0.47%
state/chartDataSlice.js 46 bytes 1.93kB 2.44%
state/optionsSlice.js 6 bytes 1.21kB 0.5%
state/selectors/touchSelectors.js -195 bytes 960 bytes -16.88%
view changes for bundle: recharts/bundle-cjs

Assets Changed:

Asset Name Size Change Total Size Change (%)
chart/Sankey.js 8 bytes 31.37kB 0.03%
chart/Treemap.js 13 bytes 29.71kB 0.04%
cartesian/Area.js 8 bytes 29.46kB 0.03%
cartesian/Brush.js 170 bytes 28.64kB 0.6%
cartesian/Bar.js 8 bytes 27.82kB 0.03%
cartesian/Line.js 8 bytes 26.5kB 0.03%
polar/Pie.js 149 bytes 26.38kB 0.57%
cartesian/Scatter.js 137 bytes 24.38kB 0.57%
polar/RadialBar.js 8 bytes 21.29kB 0.04%
cartesian/Funnel.js 84 bytes 19.13kB 0.44%
polar/Radar.js 8 bytes 17.87kB 0.04%
state/selectors/tooltipSelectors.js -60 bytes 17.54kB -0.34%
chart/SunburstChart.js -271 bytes 12.96kB -2.05%
state/selectors/selectors.js -60 bytes 7.92kB -0.75%
state/chartDataSlice.js 54 bytes 2.35kB 2.35%
state/optionsSlice.js 6 bytes 1.52kB 0.4%
state/selectors/touchSelectors.js -225 bytes 1.15kB -16.33%
view changes for bundle: recharts/bundle-umd

Assets Changed:

Asset Name Size Change Total Size Change (%)
Recharts.js 126 bytes 527.92kB 0.02%

@ckifer ckifer merged commit de9381c into main Jan 4, 2026
44 checks passed
@ckifer ckifer deleted the tooltippayload-types branch January 4, 2026 05:52
@coderabbitai coderabbitai bot mentioned this pull request Jan 24, 2026
7 tasks
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.

2 participants