Skip to content

Replace tick: any with explicit type#6911

Merged
ckifer merged 2 commits intomainfrom
tick-any
Jan 21, 2026
Merged

Replace tick: any with explicit type#6911
ckifer merged 2 commits intomainfrom
tick-any

Conversation

@PavelVanecek
Copy link
Collaborator

@PavelVanecek PavelVanecek commented Jan 20, 2026

Description

Adds a type instead of any, and tests, and website example.

Related Issue

#6645

#6889

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • TypeScript type

Checklist:

  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have added tests to cover my changes.
  • I have added a storybook story or VR test, or extended an existing story or VR test to show my changes

Summary by CodeRabbit

  • New Features

    • Enhanced tick customization for Cartesian axes (XAxis and YAxis) with new tick prop options.
    • Expanded public API exports for tick-related types to support custom tick rendering.
  • Documentation

    • Updated tick prop descriptions across axis components to clarify individual tick label rendering behavior.
    • Added new examples and guidance for custom tick components.
  • Chores

    • Improved internal type safety for axis tick handling.
    • Added comprehensive test coverage for tick rendering functionality.

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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 20, 2026

Walkthrough

This PR refactors the tick rendering system across Cartesian and Polar axes by introducing typed tick content props (BaseTickContentProps, XAxisTickContentProps, YAxisTickContentProps), replacing the generic TickProp with a parameterized TickProp<T>, and consolidating className derivation into a new getClassNameFromUnknown utility. Public API surface is expanded with new type exports and axis-specific tick prop configurations.

Changes

Cohort / File(s) Summary
New Tick Utilities & System
src/util/getClassNameFromUnknown.tsx, src/util/types.ts
Introduces getClassNameFromUnknown(u: unknown): string utility and new tick content prop types: BaseTickContentProps, XAxisTickContentProps, YAxisTickContentProps. Replaces non-generic TickProp with generic TickProp<T> to enable type-specific tick rendering props.
Utility Snapshot Tracking
scripts/snapshots/es6Files.txt, scripts/snapshots/libFiles.txt, scripts/snapshots/typesFiles.txt
Registers new getClassNameFromUnknown utility in ES6, library, and TypeScript declaration snapshots.
Cartesian Axis Type & Props
src/cartesian/CartesianAxis.tsx, src/cartesian/XAxis.tsx, src/cartesian/YAxis.tsx
Updates CartesianAxis to use new tick content props and getClassNameFromUnknown for className derivation; exposes typed tick?: TickProp<XAxisTickContentProps> and tick?: TickProp<YAxisTickContentProps> props on XAxis and YAxis respectively.
Cartesian Component Updates
src/cartesian/Bar.tsx, src/state/cartesianAxisSlice.ts
Adds explicit type annotation for rects selector result and updates TicksSettings.tick to TickProp<any>.
Polar Axis Refactoring
src/polar/PolarAngleAxis.tsx, src/polar/PolarRadiusAxis.tsx, src/polar/Pie.tsx
Refactors tick handling to use BaseTickContentProps and TickProp<BaseTickContentProps>, removes TickItemTextProps, replaces getTickClassName with getClassNameFromUnknown. Removes deprecated getTickClassName export from PolarUtils.ts.
Public API Exports
src/index.ts
Expands exports to include BaseTickContentProps, XAxisTickContentProps, YAxisTickContentProps, XAxisOrientation, YAxisOrientation, XAxisPadding, YAxisPadding, TextAnchor, TextVerticalAnchor.
Cartesian Axis Tests
test/cartesian/XAxis/XAxis.tick.spec.tsx, test/cartesian/YAxis/YAxis.spec.tsx, test/cartesian/YAxis/YAxis.tick.spec.tsx
Adds comprehensive YAxis.tick test suite with 377 lines covering custom tick components, padding propagation, click interactions, and tickFormatter integration; removes obsolete custom tick component tests; adds expectNthCalledWith test helper.
Polar Axis Tests
test/polar/PolarAngleAxis.spec.tsx, test/helper/expectLastCalledWith.ts
Updates to use BaseTickContentProps instead of TickItemTextProps; removes Customized wrapper pattern; adds expectNthCalledWith(spy, n, expected) helper for multi-call assertions.
Storybook & API Documentation
storybook/stories/API/arg-types/XAxisArgs.ts, storybook/stories/API/arg-types/YAxisArgs.ts, storybook/stories/API/arg-types/PolarAngleAxisArgs.ts, storybook/stories/API/arg-types/PolarRadiusAxisArgs.ts
Updates tick prop descriptions to clarify focus on per-tick label rendering, enumerates rendering options (false/true/object/ReactElement/function), and references label prop for axis-level labeling.
Website API Documentation
www/src/docs/api/XAxisAPI.tsx, www/src/docs/api/YAxisAPI.tsx, www/src/docs/api/PolarAngleAxisAPI.tsx, www/src/docs/api/PolarRadiusAxisAPI.tsx, www/src/docs/api/TextAPI.tsx
Expands tick prop documentation with detailed rendering guidance and explicit Options lists; adds examples link to TextAPI for children prop.
Example Components
www/src/docs/exampleComponents/BarChart/BarChartWithMultiXAxis.tsx, www/src/docs/exampleComponents/BarChart/PositiveAndNegativeBarChart.tsx
Types renderQuarterTick with XAxisTickContentProps; adds new CustomYAxisTick component for colored tick rendering based on sign.
Test Verification
omnidoc/verifyExamples.spec.ts
Adds BaseTickContentProps, TextVerticalAnchor, XAxisOrientation, YAxisOrientation, XAxisPadding, YAxisPadding, CartesianTickItem, TextAnchor to required examples list.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Suggested labels

typescript

Suggested reviewers

  • ckifer
🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: replacing tick any type with explicit types throughout the codebase.
Description check ✅ Passed The description covers key sections (Description, Related Issues, Types of changes, Checklist) but lacks Motivation/Context and How Has This Been Tested details.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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

🤖 Fix all issues with AI agents
In `@src/util/types.ts`:
- Around line 36-39: The import of TickFormatter in src/util/types.ts is a value
import causing a runtime circular dependency with CartesianAxis; change it to a
type-only import so the module system won't evaluate CartesianAxis at runtime
(e.g., replace the current import of TickFormatter with a type-only import for
TickFormatter from '../cartesian/CartesianAxis' and ensure any uses remain
purely type positions).
🧹 Nitpick comments (3)
src/state/cartesianAxisSlice.ts (1)

75-75: Consider using a more specific type or unknown for tick.

The tick property uses TickProp<any>, which retains any in the type system. Per coding guidelines, any should be avoided.

However, based on learnings, DataKey<any> is an intentional exception while proper typing is being developed. If this usage follows the same pattern for shared internal state types (since TicksSettings is used by both XAxis and YAxis with different content props), this may be acceptable as an interim measure.

If intentional, consider adding a comment similar to other exceptions explaining why any is used here.

test/cartesian/YAxis/YAxis.tick.spec.tsx (1)

132-135: Consider using YAxisTickContentProps instead of any for consistency.

These custom tick components use any for props typing, which conflicts with the coding guideline to avoid any. While the test is intentionally loose to verify prop passing, using the explicit type would be more consistent with the PR's objective of replacing any with explicit types.

However, since this is a test file and the assertion is specifically checking a subset of props (props.padding), the any usage is acceptable for test simplicity.

Optional: Use explicit type for consistency
-      const CustomYAxisTick = (props: any) => {
+      const CustomYAxisTick = (props: YAxisTickContentProps) => {
         expect(props.padding).toEqual(expectedPadding);
         return <text>Custom Tick</text>;
       };

Also applies to: 149-152, 182-185

test/cartesian/XAxis/XAxis.tick.spec.tsx (1)

122-125: Same any usage pattern as YAxis tests.

These custom tick components use any for props typing. As noted in the YAxis review, this is acceptable for test simplicity, though using XAxisTickContentProps would be more consistent with the PR's objective.

Also applies to: 139-142, 172-175

@ckifer
Copy link
Member

ckifer commented Jan 20, 2026

Conflicts

@codecov
Copy link

codecov bot commented Jan 20, 2026

Codecov Report

❌ Patch coverage is 98.06452% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 94.26%. Comparing base (5586fb2) to head (8679bcf).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
...omponents/BarChart/PositiveAndNegativeBarChart.tsx 86.36% 3 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff            @@
##             main    #6911    +/-   ##
========================================
  Coverage   94.25%   94.26%            
========================================
  Files         568      569     +1     
  Lines       55607    55728   +121     
  Branches     5182     5185     +3     
========================================
+ Hits        52413    52532   +119     
- Misses       3185     3187     +2     
  Partials        9        9            

☔ 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

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.

1 similar comment
@github-actions
Copy link
Contributor

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 21, 2026

Bundle Report

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

Detailed changes
Bundle name Size Change
recharts/bundle-cjs 1.21MB 460 bytes (0.04%) ⬆️
recharts/bundle-es6 1.05MB 274 bytes (0.03%) ⬆️
recharts/bundle-umd 529.48kB 1 bytes (0.0%) ⬆️

Affected Assets, Files, and Routes:

view changes for bundle: recharts/bundle-es6

Assets Changed:

Asset Name Size Change Total Size Change (%)
polar/Pie.js -107 bytes 24.61kB -0.43%
cartesian/CartesianAxis.js 363 bytes 16.2kB 2.29%
polar/PolarAngleAxis.js -12 bytes 11.21kB -0.11%
polar/PolarRadiusAxis.js 64 bytes 10.19kB 0.63%
util/PolarUtils.js -212 bytes 4.42kB -4.58%
util/getClassNameFromUnknown.js (New) 178 bytes 178 bytes 100.0% 🚀
view changes for bundle: recharts/bundle-cjs

Assets Changed:

Asset Name Size Change Total Size Change (%)
polar/Pie.js -77 bytes 26.37kB -0.29%
cartesian/CartesianAxis.js 393 bytes 17.49kB 2.3%
polar/PolarAngleAxis.js 19 bytes 12.65kB 0.15%
polar/PolarRadiusAxis.js 95 bytes 11.64kB 0.82%
util/PolarUtils.js -280 bytes 4.82kB -5.49%
util/getClassNameFromUnknown.js (New) 310 bytes 310 bytes 100.0% 🚀
view changes for bundle: recharts/bundle-umd

Assets Changed:

Asset Name Size Change Total Size Change (%)
Recharts.js 1 bytes 529.48kB 0.0%

PavelVanecek and others added 2 commits January 21, 2026 20:05
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
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: 2

🤖 Fix all issues with AI agents
In `@test/cartesian/YAxis/YAxis.tick.spec.tsx`:
- Around line 132-135: The test custom tick components currently use the any
type (e.g., CustomYAxisTick) — replace their props annotations with the public
YAxisTickContentProps type used elsewhere in this file; update every custom
Y-axis tick component in this test (including the other occurrences in the same
file) to use YAxisTickContentProps for the props parameter so the tests comply
with the no-any rule.
- Around line 337-345: The tickFormatter in the test YAxis.tick.spec.tsx uses
toLocaleDateString without a fixed timezone which makes the expected strings
locale/timezone dependent; update the tickFormatter (the const tickFormatter
function) to include timeZone: 'UTC' in the options passed to toLocaleDateString
so the output is deterministic across environments.
🧹 Nitpick comments (2)
src/util/types.ts (1)

36-38: Use type-only imports for the new axis/text types.

These are only used in type positions, so import type avoids the circular dependency with cartesianAxisSlice and reduces risk of bundler issues.

♻️ Suggested change
-import { XAxisOrientation, XAxisPadding, YAxisOrientation, YAxisPadding } from '../state/cartesianAxisSlice';
-import { TextAnchor, TextVerticalAnchor } from '../component/Text';
+import type { XAxisOrientation, XAxisPadding, YAxisOrientation, YAxisPadding } from '../state/cartesianAxisSlice';
+import type { TextAnchor, TextVerticalAnchor } from '../component/Text';
test/cartesian/YAxis/YAxis.tick.spec.tsx (1)

38-39: Confirm fake timers are enabled for this suite.
If this isn’t already handled in test setup, consider enabling vi.useFakeTimers() for this describe block to avoid rAF/timer flakiness. As per coding guidelines, please ensure fake timers are enabled for test suites.

Comment on lines +132 to +135
const CustomYAxisTick = (props: any) => {
expect(props.padding).toEqual(expectedPadding);
return <text>Custom Tick</text>;
};
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 | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, check if the test file exists and examine the specified lines
cat -n test/cartesian/YAxis/YAxis.tick.spec.tsx | sed -n '125,190p'

Repository: recharts/recharts

Length of output: 2711


🏁 Script executed:

# Search for YAxisTickContentProps definition
rg "YAxisTickContentProps" --type ts --type tsx

Repository: recharts/recharts

Length of output: 88


🏁 Script executed:

# Check the imports in the test file
head -30 test/cartesian/YAxis/YAxis.tick.spec.tsx

Repository: recharts/recharts

Length of output: 910


🏁 Script executed:

# Verify YAxisTickContentProps is exported from public API
rg "export.*YAxisTickContentProps" src/

Repository: recharts/recharts

Length of output: 211


🏁 Script executed:

# Check the definition of YAxisTickContentProps to ensure it's appropriate for tick components
rg -A 5 "type YAxisTickContentProps" src/

Repository: recharts/recharts

Length of output: 408


Replace any in custom tick test components with proper type annotation.
Type the custom tick props as YAxisTickContentProps to comply with the no‑any rule. The type is already available from the public API and used elsewhere in the same test file.

Proposed fix
-      const CustomYAxisTick = (props: any) => {
+      const CustomYAxisTick = (props: YAxisTickContentProps) => {
         expect(props.padding).toEqual(expectedPadding);
         return <text>Custom Tick</text>;
       };
-      const CustomYAxisTick = (props: any) => {
+      const CustomYAxisTick = (props: YAxisTickContentProps) => {
         expect(props.padding).toBe(expectedPadding);
         return <text>Custom Tick</text>;
       };
-      const CustomYAxisTick = (props: any) => {
+      const CustomYAxisTick = (props: YAxisTickContentProps) => {
         expect(props.padding).toEqual({ top: 0, bottom: 0 });
         return <text>Custom Tick</text>;
       };

Also applies to: 149-152, 182-185

🤖 Prompt for AI Agents
In `@test/cartesian/YAxis/YAxis.tick.spec.tsx` around lines 132 - 135, The test
custom tick components currently use the any type (e.g., CustomYAxisTick) —
replace their props annotations with the public YAxisTickContentProps type used
elsewhere in this file; update every custom Y-axis tick component in this test
(including the other occurrences in the same file) to use YAxisTickContentProps
for the props parameter so the tests comply with the no-any rule.

Comment on lines +337 to +345
it('should render ticks formatted by tickFormatter', () => {
const tickFormatter = (value: number) =>
new Date(value).toLocaleDateString('en-US', {
year: 'numeric',
month: 'numeric',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
});
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

🧩 Analysis chain

🏁 Script executed:

sed -n '330,360p' test/cartesian/YAxis/YAxis.tick.spec.tsx

Repository: recharts/recharts

Length of output: 1044


🏁 Script executed:

sed -n '337,380p' test/cartesian/YAxis/YAxis.tick.spec.tsx

Repository: recharts/recharts

Length of output: 1076


🏁 Script executed:

grep -n "dateWithValueData" test/cartesian/YAxis/YAxis.tick.spec.tsx | head -5

Repository: recharts/recharts

Length of output: 207


🏁 Script executed:

find . -path "./storybook/stories/data*" -type f | head -10

Repository: recharts/recharts

Length of output: 436


🏁 Script executed:

find . -path "./storybook/stories/data*" -type f | xargs grep -l "dateWithValueData" | head -5

Repository: recharts/recharts

Length of output: 93


🏁 Script executed:

cat storybook/stories/data/Time.ts

Repository: recharts/recharts

Length of output: 1693


Pin timezone in tickFormatter to avoid locale-dependent tests.

The test expects hardcoded strings like '12/31/2016, 12:00 AM', but toLocaleDateString without an explicit timezone will format differently across CI environments and developer machines with different system timezones. Add timeZone: 'UTC' to ensure consistent output.

const tickFormatter = (value: number) =>
  new Date(value).toLocaleDateString('en-US', {
    year: 'numeric',
    month: 'numeric',
    day: 'numeric',
    hour: 'numeric',
    minute: 'numeric',
+   timeZone: 'UTC',
  });
📝 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
it('should render ticks formatted by tickFormatter', () => {
const tickFormatter = (value: number) =>
new Date(value).toLocaleDateString('en-US', {
year: 'numeric',
month: 'numeric',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
});
it('should render ticks formatted by tickFormatter', () => {
const tickFormatter = (value: number) =>
new Date(value).toLocaleDateString('en-US', {
year: 'numeric',
month: 'numeric',
day: 'numeric',
hour: 'numeric',
minute: 'numeric',
timeZone: 'UTC',
});
🤖 Prompt for AI Agents
In `@test/cartesian/YAxis/YAxis.tick.spec.tsx` around lines 337 - 345, The
tickFormatter in the test YAxis.tick.spec.tsx uses toLocaleDateString without a
fixed timezone which makes the expected strings locale/timezone dependent;
update the tickFormatter (the const tickFormatter function) to include timeZone:
'UTC' in the options passed to toLocaleDateString so the output is deterministic
across environments.

@github-actions
Copy link
Contributor

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.

@ckifer ckifer merged commit 8ea7355 into main Jan 21, 2026
47 checks passed
@PavelVanecek PavelVanecek deleted the tick-any branch January 21, 2026 16:33
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