Remove any from Array.isArray, fix violations#6760
Conversation
|
Warning Rate limit exceeded@PavelVanecek has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 7 minutes and 44 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (1)
WalkthroughRefactors selector architecture to resolve axes from GraphicalItemId, adds a new graphicalItemSelectors module, changes area/stacked-data types to StackDataPoint tuples, renames/adds chart-data selector variants, tightens TypeScript types, and adjusts many selector consumers and tests accordingly. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45–75 minutes
Possibly related PRs
Suggested labels
Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/state/selectors/combiners/combineTooltipPayload.ts (1)
90-116: Refine theunknowntype instead of suppressing errors.The multiple
@ts-expect-errorsuppressions (lines 94, 96, 106, 108, 112) violate the coding guideline that requires preferringunknownoveranyand refining the type. These suppressions functionally disable type checking, which is equivalent to usingany.As per coding guidelines, you should define a proper type for the array items and use type guards to validate the structure.
Consider this approach:
+interface TooltipPayloadItem { + name: unknown; + unit: unknown; + dataKey: DataKey<any>; + payload: unknown; +} + +function isTooltipPayloadItem(item: unknown): item is TooltipPayloadItem { + return ( + typeof item === 'object' && + item !== null && + 'name' in item && + 'unit' in item && + 'dataKey' in item && + 'payload' in item + ); +} + if (Array.isArray(tooltipPayload)) { tooltipPayload.forEach(item => { + if (!isTooltipPayloadItem(item)) { + return; + } const newSettings: TooltipEntrySettings = { ...settings, - // @ts-expect-error we're assuming that item has name and unit properties name: item.name, - // @ts-expect-error we're assuming that item has name and unit properties unit: item.unit, color: undefined, fill: undefined, }; agg.push( getTooltipEntry({ tooltipEntrySettings: newSettings, - // @ts-expect-error we're assuming that item has name and unit properties dataKey: item.dataKey, - // @ts-expect-error we're assuming that item has name and unit properties payload: item.payload, // @ts-expect-error getValueByDataKey does not validate the output type value: getValueByDataKey(item.payload, item.dataKey), - // @ts-expect-error we're assuming that item has name and unit properties name: item.name, }), ); });src/component/DefaultTooltipContent.tsx (1)
19-25: Type signature now correctly reflects runtime behavior wherevalueandnamecan beundefined.The
Payloadinterface defines bothnameandvalueas optional properties, making it accurate for theFormattertype to includeundefinedin their signatures. This improves type safety for consumers implementing custom formatters.Consider documenting this as a breaking change if updating from a previous version where these parameters were not typed as optional. Consumers with existing custom formatters must now handle
undefinedvalues explicitly.
🧹 Nitpick comments (6)
test/helper/expectStackGroups.ts (1)
59-117: Normalize error handling and matcher return shape in all three matchersThe new
receivedtypings forrechartsStackedDataMatcher,rechartsStackedSeriesMatcher, andrechartsStackedSeriesPointMatcherare a good improvement, but thecatchblocks can be made type-safe and consistent with the declared matcher result type:
eincatch (e)is effectively untyped (oftenany), which conflicts with the repo’s preference forunknown.- In
rechartsStackedSeriesMatcherandrechartsStackedSeriesPointMatcherthe declared return type usesmessage: () => string, but the error branch returnsmessage: e.message, which is a string (orany), not a function.You can address both points with a small refactor:
-function rechartsStackedDataMatcher(received: ExpectedStackedData, expected: ExpectedStackedData) { +function rechartsStackedDataMatcher(received: ExpectedStackedData, expected: ExpectedStackedData) { try { expectStackedData(received, expected); return { pass: true, message: () => 'Expected stack groups to not match', }; - } catch (e) { + } catch (e: unknown) { + const message = e instanceof Error ? e.message : String(e); // Uncomment the `debugger` here to see the actual error message, or place a breakpoint in your IDE // debugger; return { pass: false, - message: e.message, + message: () => message, }; } } function rechartsStackedSeriesMatcher( - received: ExpectedStackedDataSeries, + received: ExpectedStackedDataSeries, expected: ExpectedStackedDataSeries, ): { pass: boolean; message: () => string } { try { expectStackedSeries(received, expected); return { pass: true, message: () => 'Expected stack series to not match', }; - } catch (e) { + } catch (e: unknown) { + const message = e instanceof Error ? e.message : String(e); // Uncomment the `debugger` here to see the actual error message, or place a breakpoint in your IDE // debugger; return { pass: false, - message: e.message, + message: () => message, }; } } function rechartsStackedSeriesPointMatcher( - received: StackDataPoint, + received: StackDataPoint, expected: StackDataPoint, ): { pass: boolean; message: () => string } { try { if (!Array.isArray(received)) { throw new Error(`stackedSeriesPoint error: expected ${received} to be an array`); } expect(seriesPointToTuple(received)).toEqual(expected); return { pass: true, message: () => 'Expected stack series point to not match', }; - } catch (e) { + } catch (e: unknown) { + const message = e instanceof Error ? e.message : String(e); // Uncomment the `debugger` here to see the actual error message, or place a breakpoint in your IDE // debugger; return { pass: false, - message: e.message, + message: () => message, }; } }This keeps the matchers’ public typings accurate, avoids leaking
anythrough the catch variable, and still surfaces the original error message. As per coding guidelines, this also aligns with the “noany” rule and explicit, accurate return typing in TS.src/util/DataUtils.ts (1)
92-98: Consider caching the string conversion to avoid duplicate calls.
String(ary[i])is called twice per iteration. While this is a minor concern, you could store the result in a variable for a slight efficiency gain.for (let i = 0; i < len; i++) { - if (!cache[String(ary[i])]) { - cache[String(ary[i])] = true; + const key = String(ary[i]); + if (!cache[key]) { + cache[key] = true; } else { return true; } }test/state/selectors/areaSelectors.spec.tsx (1)
12-13: Tests aligned with id‑basedselectAreaAPIUpdating all usages to
selectArea(state, 'area-0', false)matches the new selector signature and stays consistent with the<Area id="area-0" />in the test chart setup. The existing expectations and call‑count assertions continue to validate selector stability correctly.If you touch this file again, consider hoisting
'area-0'into a shared constant to avoid accidental mismatches between chart JSX and selector calls.Also applies to: 25-25, 137-137
src/state/selectors/graphicalItemSelectors.ts (1)
1-11: New graphical‑item axis selectors are correct; possible micro‑DRYBoth
selectXAxisIdFromGraphicalItemIdandselectYAxisIdFromGraphicalItemIdcorrectly scanstate.graphicalItems.cartesianItemsby id and fall back todefaultAxisIdwhen no match or axis id is present, which is a sensible default for cartesian charts.If these are often called together for the same id, consider factoring out a small helper like
selectCartesianItemByIdso you only traversecartesianItemsonce per id and then read bothxAxisIdandyAxisIdfrom that result.test/cartesian/Bar.truncateByDomain.spec.tsx (1)
164-172: Test name doesn't match the selector name.The test name still references the old selector name
selectChartDataWithIndexesIfNotInPanorama, but it now testsselectChartDataWithIndexesIfNotInPanoramaPosition4. Consider updating the test name for consistency.- test('selectChartDataWithIndexesIfNotInPanorama', () => { + test('selectChartDataWithIndexesIfNotInPanoramaPosition4', () => {src/state/selectors/areaSelectors.ts (1)
70-78: UnusedisPanoramaparameter in selector signature.The
isPanoramaparameter at position 3 is unused in this selector but is required for positional alignment withcreateSelectorcomposition. Consider adding a brief comment explaining this pattern for maintainability.const selectSynchronisedAreaSettings: ( state: RechartsRootState, id: GraphicalItemId, isPanorama: boolean, ) => AreaSettings | undefined = createSelector( - [selectUnfilteredCartesianItems, pickAreaId], + // isPanorama is unused here but required for selector position alignment in createSelector + [selectUnfilteredCartesianItems, pickAreaId], (graphicalItems, id: GraphicalItemId) => graphicalItems.filter(item => item.type === 'area').find(item => item.id === id), );
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (28)
scripts/snapshots/es6Files.txt(1 hunks)scripts/snapshots/libFiles.txt(1 hunks)scripts/snapshots/typesFiles.txt(1 hunks)src/animation/AnimationManager.ts(1 hunks)src/cartesian/Area.tsx(4 hunks)src/component/DefaultTooltipContent.tsx(2 hunks)src/state/selectors/areaSelectors.ts(6 hunks)src/state/selectors/axisSelectors.ts(3 hunks)src/state/selectors/barSelectors.ts(9 hunks)src/state/selectors/combiners/combineTooltipPayload.ts(2 hunks)src/state/selectors/dataSelectors.ts(2 hunks)src/state/selectors/graphicalItemSelectors.ts(1 hunks)src/state/selectors/lineSelectors.ts(2 hunks)src/state/selectors/scatterSelectors.ts(2 hunks)src/util/DataUtils.ts(1 hunks)src/util/scale/getNiceTickValues.ts(4 hunks)src/util/scale/util/utils.ts(0 hunks)storybook/stories/API/component/Legend.stories.tsx(1 hunks)test/cartesian/Bar.truncateByDomain.spec.tsx(2 hunks)test/chart/AreaChart.spec.tsx(6 hunks)test/chart/AreaChart.stacked.spec.tsx(10 hunks)test/helper/expectStackGroups.ts(4 hunks)test/state/selectors/areaSelectors.spec.tsx(3 hunks)test/util/errorValue.spec.ts(1 hunks)test/util/isArray.spec-d.ts(1 hunks)test/util/scale/utils.spec.ts(1 hunks)types.d.ts(1 hunks)www/src/components/GuideView/DomainAndTicks/MassBarChartCustomTicks.tsx(1 hunks)
💤 Files with no reviewable changes (1)
- src/util/scale/util/utils.ts
🧰 Additional context used
📓 Path-based instructions (9)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
**/*.{ts,tsx}: Never useanytype (implicit or explicit) in TypeScript code
Preferunknownoveranyand 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 useastype assertions in TypeScript; the only exception isas const
Files:
src/animation/AnimationManager.tssrc/state/selectors/graphicalItemSelectors.tssrc/state/selectors/combiners/combineTooltipPayload.tstest/util/isArray.spec-d.tsstorybook/stories/API/component/Legend.stories.tsxtypes.d.tstest/chart/AreaChart.stacked.spec.tsxwww/src/components/GuideView/DomainAndTicks/MassBarChartCustomTicks.tsxsrc/util/DataUtils.tssrc/util/scale/getNiceTickValues.tstest/state/selectors/areaSelectors.spec.tsxtest/cartesian/Bar.truncateByDomain.spec.tsxtest/util/scale/utils.spec.tssrc/state/selectors/scatterSelectors.tssrc/state/selectors/axisSelectors.tstest/helper/expectStackGroups.tssrc/component/DefaultTooltipContent.tsxtest/chart/AreaChart.spec.tsxsrc/cartesian/Area.tsxsrc/state/selectors/lineSelectors.tstest/util/errorValue.spec.tssrc/state/selectors/barSelectors.tssrc/state/selectors/dataSelectors.tssrc/state/selectors/areaSelectors.ts
**/*.{js,ts,tsx}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Ensure code lints by running
npm run lintand follows Airbnb's Style Guide
Files:
src/animation/AnimationManager.tssrc/state/selectors/graphicalItemSelectors.tssrc/state/selectors/combiners/combineTooltipPayload.tstest/util/isArray.spec-d.tsstorybook/stories/API/component/Legend.stories.tsxtypes.d.tstest/chart/AreaChart.stacked.spec.tsxwww/src/components/GuideView/DomainAndTicks/MassBarChartCustomTicks.tsxsrc/util/DataUtils.tssrc/util/scale/getNiceTickValues.tstest/state/selectors/areaSelectors.spec.tsxtest/cartesian/Bar.truncateByDomain.spec.tsxtest/util/scale/utils.spec.tssrc/state/selectors/scatterSelectors.tssrc/state/selectors/axisSelectors.tstest/helper/expectStackGroups.tssrc/component/DefaultTooltipContent.tsxtest/chart/AreaChart.spec.tsxsrc/cartesian/Area.tsxsrc/state/selectors/lineSelectors.tstest/util/errorValue.spec.tssrc/state/selectors/barSelectors.tssrc/state/selectors/dataSelectors.tssrc/state/selectors/areaSelectors.ts
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/animation/AnimationManager.tssrc/state/selectors/graphicalItemSelectors.tssrc/state/selectors/combiners/combineTooltipPayload.tssrc/util/DataUtils.tssrc/util/scale/getNiceTickValues.tssrc/state/selectors/scatterSelectors.tssrc/state/selectors/axisSelectors.tssrc/component/DefaultTooltipContent.tsxsrc/cartesian/Area.tsxsrc/state/selectors/lineSelectors.tssrc/state/selectors/barSelectors.tssrc/state/selectors/dataSelectors.tssrc/state/selectors/areaSelectors.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (DEVELOPING.md)
All imports from
rechartsmust use the public API entry point; imports from internal paths likerecharts/types/*orrecharts/src/*are not allowed
Files:
src/animation/AnimationManager.tssrc/state/selectors/graphicalItemSelectors.tssrc/state/selectors/combiners/combineTooltipPayload.tstest/util/isArray.spec-d.tsstorybook/stories/API/component/Legend.stories.tsxtypes.d.tstest/chart/AreaChart.stacked.spec.tsxwww/src/components/GuideView/DomainAndTicks/MassBarChartCustomTicks.tsxsrc/util/DataUtils.tssrc/util/scale/getNiceTickValues.tstest/state/selectors/areaSelectors.spec.tsxtest/cartesian/Bar.truncateByDomain.spec.tsxtest/util/scale/utils.spec.tssrc/state/selectors/scatterSelectors.tssrc/state/selectors/axisSelectors.tstest/helper/expectStackGroups.tssrc/component/DefaultTooltipContent.tsxtest/chart/AreaChart.spec.tsxsrc/cartesian/Area.tsxsrc/state/selectors/lineSelectors.tstest/util/errorValue.spec.tssrc/state/selectors/barSelectors.tssrc/state/selectors/dataSelectors.tssrc/state/selectors/areaSelectors.ts
storybook/stories/**/*.stories.tsx
📄 CodeRabbit inference engine (CONTRIBUTING.md)
storybook/stories/**/*.stories.tsx: Use Storybook for smoke tests and add play functions with assertions for actual tests
Update Storybook stories when APIs have been changed to ensure they work as expected
Files:
storybook/stories/API/component/Legend.stories.tsx
**/storybook/**/*.stories.{ts,tsx}
📄 CodeRabbit inference engine (DEVELOPING.md)
When adding new Storybook stories, prioritize high fidelity examples intended for publication on the website and in Storybook UI; use unit tests or VR tests for low fidelity tests
Files:
storybook/stories/API/component/Legend.stories.tsx
test/**/*.spec.{ts,tsx}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Aim for 100% unit test code coverage when writing new code
Files:
test/chart/AreaChart.stacked.spec.tsxtest/state/selectors/areaSelectors.spec.tsxtest/cartesian/Bar.truncateByDomain.spec.tsxtest/util/scale/utils.spec.tstest/chart/AreaChart.spec.tsxtest/util/errorValue.spec.ts
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 thecreateSelectorTestCasehelper function when writing or modifying tests
Use theexpectLastCalledWithhelper function instead ofexpect(spy).toHaveBeenLastCalledWith(...)for better typing and autocompletion
Verify the number of selector calls using the spy object fromcreateSelectorTestCaseto spot unnecessary re-renders and improve performance
MockgetBoundingClientRectin tests using the helper function provided intest/helper/MockGetBoundingClientRect.ts
Usevi.useFakeTimers()in all tests due to Redux autoBatchEnhancer dependency on timers andrequestAnimationFrame
Callvi.runOnlyPendingTimers()to advance timers after renders when not usingcreateSelectorTestCasehelper, and avoidvi.runAllTimers()to prevent infinite loops
UseuserEvent.setup({ advanceTimers: vi.runOnlyPendingTimers })or theuserEventSetuphelper function fromtest/helper/userEventSetup.tswhen creating userEvent instances
When testing tooltips on hover, usevi.runOnlyPendingTimers()after eachuserEvent.hover()call or use theshowTooltiphelper function fromtooltipTestHelpers.tsto account for requestAnimationFrame delays
Files:
test/chart/AreaChart.stacked.spec.tsxtest/state/selectors/areaSelectors.spec.tsxtest/cartesian/Bar.truncateByDomain.spec.tsxtest/util/scale/utils.spec.tstest/chart/AreaChart.spec.tsxtest/util/errorValue.spec.ts
**/*.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.tsxrather than running all tests withnpm test
Files:
test/chart/AreaChart.stacked.spec.tsxtest/state/selectors/areaSelectors.spec.tsxtest/cartesian/Bar.truncateByDomain.spec.tsxtest/util/scale/utils.spec.tstest/chart/AreaChart.spec.tsxtest/util/errorValue.spec.ts
🧠 Learnings (16)
📓 Common learnings
Learnt from: PavelVanecek
Repo: recharts/recharts PR: 6750
File: src/state/selectors/axisSelectors.ts:593-602
Timestamp: 2025-12-08T08:23:26.219Z
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.
📚 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/state/selectors/graphicalItemSelectors.tssrc/state/selectors/combiners/combineTooltipPayload.tsstorybook/stories/API/component/Legend.stories.tsxscripts/snapshots/typesFiles.txtsrc/state/selectors/axisSelectors.tssrc/component/DefaultTooltipContent.tsxsrc/state/selectors/dataSelectors.ts
📚 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} : Prefer `unknown` over `any` and refine the type in TypeScript
Applied to files:
test/util/isArray.spec-d.ts
📚 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/util/isArray.spec-d.tstest/chart/AreaChart.stacked.spec.tsxtest/util/scale/utils.spec.tstest/helper/expectStackGroups.tstest/chart/AreaChart.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/util/isArray.spec-d.tstest/chart/AreaChart.stacked.spec.tsxtest/state/selectors/areaSelectors.spec.tsxtest/cartesian/Bar.truncateByDomain.spec.tsxscripts/snapshots/typesFiles.txttest/util/scale/utils.spec.tssrc/state/selectors/scatterSelectors.tsscripts/snapshots/es6Files.txttest/helper/expectStackGroups.tsscripts/snapshots/libFiles.txttest/chart/AreaChart.spec.tsxsrc/state/selectors/lineSelectors.tstest/util/errorValue.spec.tssrc/state/selectors/barSelectors.ts
📚 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 src/**/*.{ts,tsx} : Do not hardcode any strings or formatting choices in library code; users should provide localized strings as desired
Applied to files:
storybook/stories/API/component/Legend.stories.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:
storybook/stories/API/component/Legend.stories.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/chart/AreaChart.stacked.spec.tsxtest/state/selectors/areaSelectors.spec.tsxtest/cartesian/Bar.truncateByDomain.spec.tsxscripts/snapshots/typesFiles.txtscripts/snapshots/es6Files.txtscripts/snapshots/libFiles.txttest/chart/AreaChart.spec.tsxtest/util/errorValue.spec.ts
📚 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/chart/AreaChart.stacked.spec.tsxtest/state/selectors/areaSelectors.spec.tsxscripts/snapshots/es6Files.txt
📚 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/state/selectors/areaSelectors.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 test/component/**/*.spec.tsx : Use React Testing Library for testing component interactions and behavior upon rendering
Applied to files:
test/state/selectors/areaSelectors.spec.tsx
📚 Learning: 2025-12-06T03:36:59.377Z
Learnt from: CR
Repo: recharts/recharts PR: 0
File: DEVELOPING.md:0-0
Timestamp: 2025-12-06T03:36:59.377Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : All imports from `recharts` must use the public API entry point; imports from internal paths like `recharts/types/*` or `recharts/src/*` are not allowed
Applied to files:
test/cartesian/Bar.truncateByDomain.spec.tsxsrc/state/selectors/axisSelectors.tssrc/state/selectors/barSelectors.tssrc/state/selectors/areaSelectors.ts
📚 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/util/scale/utils.spec.ts
📚 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: Extract pure helper functions for data processing and write unit tests for them
Applied to files:
test/util/scale/utils.spec.ts
📚 Learning: 2025-12-08T08:23:26.219Z
Learnt from: PavelVanecek
Repo: recharts/recharts PR: 6750
File: src/state/selectors/axisSelectors.ts:593-602
Timestamp: 2025-12-08T08:23:26.219Z
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:
test/helper/expectStackGroups.ts
📚 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/helper/expectStackGroups.ts
🧬 Code graph analysis (14)
src/state/selectors/graphicalItemSelectors.ts (3)
src/state/store.ts (1)
RechartsRootState(23-38)src/state/graphicalItemsSlice.ts (1)
GraphicalItemId(19-19)src/state/cartesianAxisSlice.ts (2)
AxisId(8-8)defaultAxisId(9-9)
src/state/selectors/combiners/combineTooltipPayload.ts (1)
src/util/ChartUtils.ts (1)
getValueByDataKey(42-56)
test/chart/AreaChart.stacked.spec.tsx (1)
src/state/selectors/areaSelectors.ts (2)
selectGraphicalItemStackedData(109-131)selectArea(133-202)
test/state/selectors/areaSelectors.spec.tsx (2)
test/helper/selectorTestHelpers.tsx (2)
shouldReturnUndefinedOutOfContext(9-20)shouldReturnFromInitialState(22-35)src/state/selectors/areaSelectors.ts (1)
selectArea(133-202)
test/cartesian/Bar.truncateByDomain.spec.tsx (1)
src/state/selectors/dataSelectors.ts (1)
selectChartDataWithIndexesIfNotInPanoramaPosition4(37-47)
src/state/selectors/scatterSelectors.ts (4)
src/state/cartesianAxisSlice.ts (1)
AxisId(8-8)src/state/graphicalItemsSlice.ts (1)
GraphicalItemId(19-19)src/state/chartDataSlice.ts (1)
ChartDataState(23-40)src/state/selectors/dataSelectors.ts (1)
selectChartDataWithIndexesIfNotInPanoramaPosition4(37-47)
src/state/selectors/axisSelectors.ts (1)
src/state/selectors/dataSelectors.ts (1)
selectChartDataWithIndexesIfNotInPanoramaPosition4(37-47)
test/helper/expectStackGroups.ts (1)
src/util/stacks/stackTypes.ts (1)
StackDataPoint(51-51)
src/component/DefaultTooltipContent.tsx (3)
src/util/DataUtils.ts (1)
isNumOrStr(27-27)src/util/types.ts (1)
TooltipType(81-81)src/component/DefaultLegendContent.tsx (1)
Formatter(24-24)
src/cartesian/Area.tsx (3)
src/state/selectors/areaSelectors.ts (1)
selectArea(133-202)src/util/stacks/stackTypes.ts (1)
StackDataPoint(51-51)src/util/ChartUtils.ts (2)
getValueByDataKey(42-56)getCateCoordinateOfLine(488-527)
src/state/selectors/lineSelectors.ts (1)
src/state/selectors/dataSelectors.ts (1)
selectChartDataWithIndexesIfNotInPanoramaPosition4(37-47)
src/state/selectors/barSelectors.ts (4)
src/context/chartLayoutContext.tsx (1)
selectChartLayout(133-133)src/state/selectors/axisSelectors.ts (1)
selectUnfilteredCartesianItems(311-313)src/state/selectors/graphicalItemSelectors.ts (2)
selectXAxisIdFromGraphicalItemId(5-7)selectYAxisIdFromGraphicalItemId(9-11)src/state/selectors/dataSelectors.ts (1)
selectChartDataWithIndexesIfNotInPanoramaPosition3(49-58)
src/state/selectors/dataSelectors.ts (2)
src/state/store.ts (1)
RechartsRootState(23-38)src/state/chartDataSlice.ts (1)
ChartDataState(23-40)
src/state/selectors/areaSelectors.ts (9)
src/util/types.ts (1)
NullableCoordinate(93-96)src/state/graphicalItemsSlice.ts (1)
GraphicalItemId(19-19)src/state/selectors/graphicalItemSelectors.ts (2)
selectXAxisIdFromGraphicalItemId(5-7)selectYAxisIdFromGraphicalItemId(9-11)src/state/types/AreaSettings.ts (1)
AreaSettings(7-14)src/context/chartLayoutContext.tsx (1)
selectChartLayout(133-133)src/state/cartesianAxisSlice.ts (1)
AxisId(8-8)src/util/stacks/stackTypes.ts (3)
StackDataPoint(51-51)StackSeriesIdentifier(57-57)StackSeries(43-43)src/util/stacks/getStackSeriesIdentifier.ts (1)
getStackSeriesIdentifier(14-18)src/state/selectors/dataSelectors.ts (1)
selectChartDataWithIndexesIfNotInPanoramaPosition3(49-58)
⏰ 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). (1)
- GitHub Check: Build, Test, Pack
🔇 Additional comments (51)
test/util/scale/utils.spec.ts (1)
2-2: Updated import is consistent with utility API changesRemoving
reversefrom the imports cleanly reflects its removal from the underlying utilities; the remaining tests still exercise the other helpers correctly.test/helper/expectStackGroups.ts (2)
14-16: Stronger typing forseriesPointToTuplelooks goodUsing
StackDataPointfor both parameter and return aligns this helper with the stack types and keeps the flow throughactualSeriesToExpectedSeriestype-safe. No further changes needed.
45-57: Typed matcher helpers now match the stacked data aliasesUpdating
expectStackedDataandexpectStackedSeriesto useExpectedStackedData/ExpectedStackedDataSerieskeeps the helpers consistent with the exported types and avoids leakingunknown/anyinto tests, while preserving the runtimeArray.isArraysafety checks. This looks correct.test/util/errorValue.spec.ts (1)
1-63: LGTM!The test file is well-structured with good coverage for
getErrorDomainByDataKey. The use ofdescribe.eachfor parameterized tests and@ts-expect-errorfor invalid input testing is appropriate.scripts/snapshots/typesFiles.txt (1)
152-152: LGTM!The new type declaration file entry is correctly positioned alphabetically in the snapshot list, consistent with the new
graphicalItemSelectors.tssource file added in this PR.src/animation/AnimationManager.ts (1)
4-4: LGTM!Replacing
objectwithRecord<string, unknown>is a solid type improvement. It's more precise for style objects while usingunknowninstead ofanyper the coding guidelines.www/src/components/GuideView/DomainAndTicks/MassBarChartCustomTicks.tsx (1)
84-91: LGTM!Good defensive change to handle potentially undefined values. The null check using loose equality (
== null) correctly catches bothnullandundefined, and returning an empty string is appropriate for formatter functions.types.d.ts (1)
33-48: Good workaround for TypeScript's Array.isArray typing limitation.The override correctly addresses the TypeScript issue where
Array.isArrayonReadonlyArrayproducesany[]. The use ofanyin the parameter type is acceptable here since it must match TypeScript's built-in signature to override it properly. The return typeReadonlyArray<unknown>is the key improvement.The documentation clearly explains the trade-offs and provides guidance on mutation, which is helpful for maintainers.
src/component/DefaultTooltipContent.tsx (2)
12-14: LGTM!The
defaultFormatternow correctly handlesundefinedvalues. TheArray.isArraycheck benefits from the new typed declaration added in this PR.
84-89: LGTM!The explicit typing of
entryasPayload<TValue, TName>andfinalFormatterasFormatter<TValue, TName>improves type safety and removes implicitanyinference.storybook/stories/API/component/Legend.stories.tsx (1)
90-92: Tooltip formatter null‑safety looks goodUsing
value?.toLocaleString()aligns with the YAxis tick formatter and safely handlesnull/undefinedtooltip values without changing the overall behavior.scripts/snapshots/es6Files.txt (1)
152-152: Snapshot list updated consistentlyAdding
"es6/state/selectors/graphicalItemSelectors.js"afterfunnelSelectorskeeps the selector snapshot list ordered and in sync with the new selector module.scripts/snapshots/libFiles.txt (1)
152-152: Lib snapshot entry matches ES6 snapshotThe new
"lib/state/selectors/graphicalItemSelectors.js"entry is correctly placed alongside other selector modules and stays consistent with the es6 snapshot list.src/state/selectors/lineSelectors.ts (1)
5-5: Line selector now wired to Position4 data selector correctlySwitching to
selectChartDataWithIndexesIfNotInPanoramaPosition4and using it as the final dependency inselectLinePointskeeps the selector signature intact while relying only onisPanoramafor data selection. This matches the helper’s intended(state, _, _, isPanorama)contract with no behavioral change.Also applies to: 82-83
src/util/scale/getNiceTickValues.ts (1)
7-7: Local in‑placereverse()is safe and simplifies the utilityDropping the custom
reversehelper and usingvalues.reverse()is fine here:valuesis always a freshly created local array and is only used for the return value, so the in‑place mutation has no observable side effects outside these functions while trimming an unnecessary import.Also applies to: 186-187, 198-199, 236-237
src/state/selectors/scatterSelectors.ts (1)
6-6: Scatter data selector correctly switched to Position4 helper
scatterChartDataSelectornow delegates toselectChartDataWithIndexesIfNotInPanoramaPosition4and explicitly marks axis parameters as unused, which matches the helper’s(state, _, _, isPanorama)contract. This keeps the externalselectScatterPointssignature the same while making the dependency onisPanoramaexplicit and type‑safe.Also applies to: 78-87
src/state/selectors/axisSelectors.ts (4)
40-40: Import update aligns with renamed selector.The import correctly references the new
selectChartDataWithIndexesIfNotInPanoramaPosition4variant, which matches the 4-parameter signature required by selectors likeselectDisplayedDataandselectDisplayedStackedData.
47-47: Consolidated DataUtils imports.Formatting cleanup that consolidates the imports into a single line. No functional change.
432-434: Correct usage of Position4 selector variant.The
selectChartDataWithIndexesIfNotInPanoramaPosition4selector is properly used here. The selector signature(state, _unused1, _unused2, isPanorama)aligns withcreateSelector's parameter passing whereaxisTypeandaxisIdoccupy positions 2 and 3, andisPanoramais at position 4.
587-589: Consistent selector usage for stacked data.Same pattern applied correctly to
selectDisplayedStackedData, ensuring consistent data retrieval behavior across axis selectors.test/cartesian/Bar.truncateByDomain.spec.tsx (1)
10-10: Import updated to new selector variant.Correctly imports the renamed
selectChartDataWithIndexesIfNotInPanoramaPosition4selector.test/chart/AreaChart.stacked.spec.tsx (8)
173-178: Migrated to id-based selector API.Test correctly uses
selectGraphicalItemStackedData(state, areaSettings1.id, false)with the new GraphicalItemId-based signature. This aligns with the broader refactor to resolve axes from item IDs rather than explicit axis parameters.
182-187: Consistent id-based selector usage for second area.Same pattern applied correctly for
areaSettings2.id.
191-241: selectArea now uses GraphicalItemId.The test correctly invokes
selectArea(state, areaSettings1.id, false)matching the updated selector signature(state, id, isPanorama). Expected data structure remains unchanged.
244-297: Second area selection verified.Test for
selectArea(state, areaSettings2.id, false)validates stacked baseline and point calculations. The y-value of the first area correctly becomes the baseline for the second area.
423-429: Second describe block updated consistently.The "without explicit XAxis dataKey" scenario follows the same id-based selector pattern, maintaining test coverage for this edge case.
Also applies to: 432-438, 441-492, 495-548
689-704: Multiple data arrays scenario covered.Tests for "multiple data arrays but each has their own dataKey" correctly use id-based selectors with area-specific data arrays.
Also applies to: 707-730, 733-758
905-920: Same dataKey scenario tested.The "multiple data arrays with the same dataKey" scenario validates stacking behavior when areas share a dataKey, using id-based selectors.
Also applies to: 923-960, 963-1001
1151-1166: Without explicit XAxis dataKey and same dataKey scenario.Final describe block covers the edge case combination, completing test coverage for the id-based selector migration.
Also applies to: 1169-1206, 1209-1247
test/chart/AreaChart.spec.tsx (8)
176-176: Updated to id-based area selection.The test now correctly uses
selectArea(state, 'area-1', false)to retrieve area data by GraphicalItemId.
196-196: Area component now has explicit id.Added
id="area-1"to enable id-based selector lookup. This is required for the new selector API.
249-332: Updated test expectations for stacked percentage chart.The expected output now reflects the
ComputedAreastructure withbaseLine,isRange, andpointsproperties. Values and coordinates are correctly specified for the expand stack offset.
360-360: Consistent id-based selector for number x-axis test.Test correctly uses
selectArea(state, 'area-1', false).
368-368: Area id attribute added for number x-axis scenario.
416-489: Comprehensive expectation for number x-axis stacked area.Test validates baseline and point data when x-axis is type number with domain
['dataMin', 'dataMax']. The stacked values correctly start from 0.
493-501: Number stackId test updated.Test case for numeric stackId now uses id-based selection with
id="area-0"andselectArea(state, 'area-0', false).
512-596: Complete expectation for number stackId scenario.Validates the full
ComputedAreastructure including all 7 data points frompageData.src/state/selectors/barSelectors.ts (9)
19-19: Import updated to Position3 selector variant.The
selectChartDataWithIndexesIfNotInPanoramaPosition3variant matches the 3-parameter signature(state, id, isPanorama)used by bar selectors.
28-28: New imports for GraphicalItemId-based axis resolution.Imports
selectXAxisIdFromGraphicalItemIdandselectYAxisIdFromGraphicalItemIdfrom the newgraphicalItemSelectorsmodule to resolve axis IDs from GraphicalItemId.
56-74: selectAllVisibleBars refactored to use GraphicalItemId-based axis selectors.The selector now derives
xAxisIdandyAxisIdfrom the GraphicalItemId via the new helper selectors, then filters bars by the appropriate axis based on layout. This decouples the selector from explicit axis ID parameters.
84-85: selectBarStackGroups uses new axis resolution.Axis IDs are now resolved from the GraphicalItemId before calling
selectStackGroups.
97-98: selectBarCartesianAxisSize aligned with new pattern.Consistent use of
selectXAxisIdFromGraphicalItemId/selectYAxisIdFromGraphicalItemId.
126-127: selectBarBandSize updated.Same refactoring pattern applied.
152-153: selectAxisBandSize updated.Consistent pattern.
202-231: Helper selectors consistently refactored.
selectXAxisWithScale,selectYAxisWithScale,selectXAxisTicks, andselectYAxisTicksall use the new GraphicalItemId-based axis resolution. This consolidates the axis lookup logic.
279-279: selectBarRectangles uses Position3 data selector.The
selectChartDataWithIndexesIfNotInPanoramaPosition3variant is correctly used here, matching the selector's 3-parameter signature(state, id, isPanorama).src/state/selectors/dataSelectors.ts (1)
37-58: LGTM - Selector variants for positional argument handling.The Position3 and Position4 naming convention correctly reflects the position of the
isPanoramaparameter in reselect'screateSelectorcomposition. Usingunknownfor unused parameters aligns with the coding guidelines.src/cartesian/Area.tsx (2)
843-843: LGTM - Simplified selector API using GraphicalItemId.The selector call correctly uses the new GraphicalItemId-based API, which internally resolves axis IDs from the item's registered state. This aligns with the refactored
selectAreasignature inareaSelectors.ts.
966-981: LGTM - Proper type handling with Array.isArray narrowing.The
valueAsArrayvariable correctly handles both stacked data (already a tuple) and non-stacked data (converted to[baseValue, rawValue]). The@ts-expect-errorcomments are appropriate sincegetValueByDataKeyreturnsunknownand runtime type checking is required.src/state/selectors/areaSelectors.ts (2)
109-131: LGTM - Correct stacked data extraction from d3 series.The selector correctly maps d3's
SeriesPointtoStackDataPointtuples by extracting the lower[0]and upper[1]stack bounds. The composition withselectNumericalAxisStackGroupsproperly resolves the correct axis stack groups based on layout.
133-148: LGTM - Well-structured selector composition.The
selectAreaselector correctly composes all required inputs using the GraphicalItemId-based resolution pattern. The usage ofselectChartDataWithIndexesIfNotInPanoramaPosition3aligns with the 3-parameter signature(state, id, isPanorama).
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #6760 +/- ##
==========================================
- Coverage 93.70% 93.67% -0.04%
==========================================
Files 515 516 +1
Lines 43011 43021 +10
Branches 5018 5011 -7
==========================================
- Hits 40302 40298 -4
- Misses 2703 2717 +14
Partials 6 6 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/state/selectors/areaSelectors.ts (1)
97-107: selectNumericalAxisStackGroups correctly composes the stackGroups lookup.The helper forwards
state, the resolved numerical axis type/id, andisPanoramaintoselectStackGroups, so stack groups are fetched relative to the axis actually used for numeric values. Logic looks sound; any further micro-optimizations (e.g., caching the axis type between usages) would be purely cosmetic.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/state/selectors/areaSelectors.ts(6 hunks)test/util/isArray.spec-d.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
**/*.{ts,tsx}: Never useanytype (implicit or explicit) in TypeScript code
Preferunknownoveranyand 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 useastype assertions in TypeScript; the only exception isas const
Files:
src/state/selectors/areaSelectors.tstest/util/isArray.spec-d.ts
**/*.{js,ts,tsx}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Ensure code lints by running
npm run lintand follows Airbnb's Style Guide
Files:
src/state/selectors/areaSelectors.tstest/util/isArray.spec-d.ts
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/state/selectors/areaSelectors.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (DEVELOPING.md)
All imports from
rechartsmust use the public API entry point; imports from internal paths likerecharts/types/*orrecharts/src/*are not allowed
Files:
src/state/selectors/areaSelectors.tstest/util/isArray.spec-d.ts
🧠 Learnings (13)
📓 Common learnings
Learnt from: PavelVanecek
Repo: recharts/recharts PR: 6750
File: src/state/selectors/axisSelectors.ts:593-602
Timestamp: 2025-12-08T08:23:26.219Z
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.
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
📚 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/state/selectors/areaSelectors.ts
📚 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} : Prefer `unknown` over `any` and refine the type in TypeScript
Applied to files:
test/util/isArray.spec-d.ts
📚 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/util/isArray.spec-d.ts
📚 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/util/isArray.spec-d.ts
📚 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/util/isArray.spec-d.ts
📚 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/util/isArray.spec-d.ts
📚 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/util/isArray.spec-d.ts
📚 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/util/isArray.spec-d.ts
📚 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/util/isArray.spec-d.ts
📚 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:
test/util/isArray.spec-d.ts
📚 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:
test/util/isArray.spec-d.ts
📚 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/util/isArray.spec-d.ts
🧬 Code graph analysis (1)
src/state/selectors/areaSelectors.ts (9)
src/util/types.ts (1)
NullableCoordinate(93-96)src/state/graphicalItemsSlice.ts (1)
GraphicalItemId(19-19)src/state/selectors/axisSelectors.ts (1)
selectStackGroups(635-643)src/state/selectors/graphicalItemSelectors.ts (2)
selectXAxisIdFromGraphicalItemId(5-7)selectYAxisIdFromGraphicalItemId(9-11)src/util/ChartUtils.ts (1)
isCategoricalAxis(103-107)src/state/cartesianAxisSlice.ts (1)
AxisId(8-8)src/util/stacks/stackTypes.ts (4)
StackGroup(32-35)StackDataPoint(51-51)StackSeriesIdentifier(57-57)StackSeries(43-43)src/util/stacks/getStackSeriesIdentifier.ts (1)
getStackSeriesIdentifier(14-18)src/state/selectors/dataSelectors.ts (1)
selectChartDataWithIndexesIfNotInPanoramaPosition3(49-58)
🪛 GitHub Actions: Build and test
test/util/isArray.spec-d.ts
[error] 1-1: ESLint: import/newline-after-import - Expected 1 empty line after import statement. (in /__w/recharts/recharts/test/util/isArray.spec-d.ts) Run 'npm run lint' to fix.
🪛 GitHub Check: Build, Test, Pack
test/util/isArray.spec-d.ts
[failure] 1-1:
Expected 1 empty line after import statement not followed by another import
🔇 Additional comments (8)
test/util/isArray.spec-d.ts (1)
2-42: Type refinement tests forArray.isArraylook solid.The three cases (unknown, union with
number[], union withReadonlyArray<number>) exercise the customArray.isArraytyping well, useunknowninstead ofany, and avoidasassertions, all in line with the repo’s TypeScript guidelines. I don’t see further issues here once the lint error is fixed.src/state/selectors/areaSelectors.ts (7)
2-22: Imports for new stack/axis helpers are consistent with project guidelines.The additional imports for stack types, chart-data selector, and graphical-item axis helpers are all used below and come from local modules or vendor code only; there are no new imports from internal
recharts/*paths. No changes needed.
24-35: AreaPointItem and ComputedArea typings now match tuple-based stacked values.Changing
valueto[number, number]andbaseLinetonumber | ReadonlyArray<AreaPointItem>aligns these types withStackDataPoint = [number, number]and with read-only area point collections, which should work cleanly with the updated stacking pipeline and avoidsany[]-style looseness.
37-47: GraphicalItemId-based X/Y axis helpers are wired to the correct selectors.
selectXAxisWithScale/selectXAxisTicksnow use the X-axis id selector and the Y counterparts use the Y-axis id selector, so both scales and ticks are resolved fromGraphicalItemIdconsistently. This also addresses the earlier issue where X-axis ticks were sourced via the Y-axis selector.
59-78: pickAreaId/selectSynchronisedAreaSettings signatures stay compatible with 3‑arg selectors.
pickAreaIdclearly ignoresstateand returns theGraphicalItemId, andselectSynchronisedAreaSettingsadds anisPanoramaparameter in its public signature while still only depending onstateandidinternally. This keeps it usable alongside other(state, id, isPanorama)selectors without changing behavior.
80-95: Numerical-axis resolution correctly complements isCategoricalAxis.
selectNumericalAxisTypechooses'yAxis'when the X axis is categorical and'xAxis'otherwise, which matches the horizontal/vertical layout rules, andselectNumericalAxisIdFromGraphicalItemIddelegates to the matching X/Y axis-id selector based on that type. This gives a coherent numerical-axis id for stacking per graphical item.
109-131: selectGraphicalItemStackedData safely narrows to the correct series and returns typed tuples.The selector guards against missing
areaSettings,stackGroups,stackId, andstackSeriesIdentifier, then locates the relevantStackSeriesfor the area and maps each point to a[item[0], item[1]]tuple typed asStackDataPoint. This is compatible with the newStackDataPointdefinition and keeps the output strongly typed while ignoring any extra fields on the underlying series points.
133-161: selectArea wiring with stackedData and panorama-aware chart data is consistent.The selector now accepts
(state, graphicalItemId, isPanorama), threadsisPanoramaintoselectChartDataWithIndexesIfNotInPanoramaPosition3, and consumesstackedData: ReadonlyArray<StackDataPoint> | undefinedfromselectGraphicalItemStackedData. Existing guards on layout, axes, ticks, andbandSizeare preserved, socomputeAreaonly runs when all prerequisites are satisfied.
|
Staging Deployment Details
These deployments will remain available for 30 days. To update snapshots: Comment |
1 similar comment
|
Staging Deployment Details
These deployments will remain available for 30 days. To update snapshots: Comment |
Description
I discovered that vanilla typing for Array.isArray turns all read-only arrays into
any[](microsoft/TypeScript#17002) which is unfortunate and creates many holes in our typing so I added a custom type and fixed the newly discovered violations. It cascaded a little but it looks like it compiles just fine now.Related Issue
#6645
Summary by CodeRabbit
Bug Fixes
Refactor
Chores
✏️ Tip: You can customize this high-level summary in your review settings.