Skip to content

Remove propTransformer prop from Shape#6738

Merged
ckifer merged 1 commit intomainfrom
propTransformer
Dec 4, 2025
Merged

Remove propTransformer prop from Shape#6738
ckifer merged 1 commit intomainfrom
propTransformer

Conversation

@PavelVanecek
Copy link
Collaborator

@PavelVanecek PavelVanecek commented Dec 4, 2025

Description

This feature is not doing anything other than making the typing more complicated. I think it was necessary in 2.x, but now all the properties that this was checking for, are already defined upstream.

Related Issue

#6645

How Has This Been Tested?

Everything looks like it works the same, let's see what storybook says.

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)
  • Refactoring

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

  • Refactor

    • Streamlined internal component architecture by removing unnecessary abstraction layers and simplifying prop handling logic.
    • Strengthened TypeScript type safety with explicit type annotations.
    • Reduced code complexity while maintaining existing functionality.
  • Tests

    • Updated tests to align with simplified internal implementation.

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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 4, 2025

Walkthrough

This PR refactors shape utility components by removing the ShapePropsType generic parameter and propTransformer abstraction layer. Helper functions (typeGuardSectorProps, typeGuardTrapezoidProps, typeguardBarRectangleProps) that previously validated and transformed props are eliminated, with components now forwarding props directly to Shape components. Related tests are updated.

Changes

Cohort / File(s) Summary
Type Annotation Tightening
src/polar/RadialBar.tsx
Added explicit TypeScript type annotations to map callback: entry parameter typed as RadialBarDataItem, index as number. No runtime behavior changes.
Shape Utility Refactoring
src/util/ActiveShapeUtils.tsx
Removed ShapePropsType generic parameter from ShapeProps interface and Shape function. Removed propTransformer member; Shape now uses defaultPropTransformer directly instead of a provided transformer. Public API signatures updated.
Helper Function Removals
src/util/BarUtils.tsx, src/util/FunnelUtils.tsx, src/util/RadialBarUtils.tsx
Deleted prop transformation helper functions (typeguardBarRectangleProps, typeGuardTrapezoidProps, typeGuardSectorProps). Simplified component implementations to render Shape directly with spread props, removing propTransformer indirection.
Test Updates
test/util/FunnelUtils.spec.tsx
Removed import and test case for typeGuardTrapezoidProps function; related mock setup deleted. Remaining render tests unaffected.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20–25 minutes

  • ActiveShapeUtils.tsx requires careful review due to public API signature changes and the removal of the generic parameter affecting downstream consumers
  • Verify that removal of propTransformer functions does not inadvertently break type safety or prop validation behavior in BarRectangle, FunnelTrapezoid, and RadialBarSector components
  • Ensure defaultPropTransformer behavior correctly replaces the removed transformation logic in all affected utilities
  • Confirm test coverage remains adequate after test case deletion

Suggested reviewers

  • ckifer

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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 accurately summarizes the main change: removing the propTransformer prop from Shape, which aligns with the core refactoring across multiple files.
Description check ✅ Passed The description covers motivation (simplifies typing, unnecessary complexity), related issue, testing approach, and change type selection. However, Motivation/Context section is minimal and Storybook testing status is unclear.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch propTransformer

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: 0

🧹 Nitpick comments (1)
src/util/ActiveShapeUtils.tsx (1)

35-43: Type assertion in defaultPropTransformer.

The as unknown as ShapePropsType assertion on line 42 is technically discouraged per coding guidelines. However, this is an internal implementation detail where the dynamic prop merging makes proper typing impractical. The function correctly merges props and option objects.

If you want to reduce the assertion, consider using a more constrained return type:

-function defaultPropTransformer<OptionType, ExtraProps, ShapePropsType>(
+function defaultPropTransformer<OptionType extends object, ExtraProps extends object>(
   option: OptionType,
   props: ExtraProps,
-): ShapePropsType {
+): OptionType & ExtraProps {
   return {
     ...props,
     ...option,
-  } as unknown as ShapePropsType;
+  };
 }

This would require adjusting the call sites to handle the intersection type appropriately.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6aec882 and 6a89970.

📒 Files selected for processing (6)
  • src/polar/RadialBar.tsx (1 hunks)
  • src/util/ActiveShapeUtils.tsx (3 hunks)
  • src/util/BarUtils.tsx (1 hunks)
  • src/util/FunnelUtils.tsx (1 hunks)
  • src/util/RadialBarUtils.tsx (1 hunks)
  • test/util/FunnelUtils.spec.tsx (1 hunks)
🧰 Additional context used
📓 Path-based instructions (8)
src/**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (DEVELOPING.md)

Run ESLint and Prettier on the codebase using npm run lint

Files:

  • src/util/RadialBarUtils.tsx
  • src/polar/RadialBar.tsx
  • src/util/BarUtils.tsx
  • src/util/ActiveShapeUtils.tsx
  • src/util/FunnelUtils.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (DEVELOPING.md)

Run type checking on the codebase using npm run check-types

**/*.{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

Files:

  • src/util/RadialBarUtils.tsx
  • src/polar/RadialBar.tsx
  • src/util/BarUtils.tsx
  • test/util/FunnelUtils.spec.tsx
  • src/util/ActiveShapeUtils.tsx
  • src/util/FunnelUtils.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/RadialBarUtils.tsx
  • src/polar/RadialBar.tsx
  • src/util/BarUtils.tsx
  • test/util/FunnelUtils.spec.tsx
  • src/util/ActiveShapeUtils.tsx
  • src/util/FunnelUtils.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/RadialBarUtils.tsx
  • src/polar/RadialBar.tsx
  • src/util/BarUtils.tsx
  • src/util/ActiveShapeUtils.tsx
  • src/util/FunnelUtils.tsx
{test,www/test}/**/*.spec.{ts,tsx}

📄 CodeRabbit inference engine (DEVELOPING.md)

Write unit tests in the test or www/test directories with .spec.tsx file extension

Files:

  • test/util/FunnelUtils.spec.tsx
test/**/*.spec.{ts,tsx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

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

Files:

  • test/util/FunnelUtils.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/util/FunnelUtils.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

Files:

  • test/util/FunnelUtils.spec.tsx
🧠 Learnings (10)
📚 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:

  • src/polar/RadialBar.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/polar/RadialBar.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/util/FunnelUtils.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/FunnelUtils.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/util/FunnelUtils.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/util/FunnelUtils.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/util/FunnelUtils.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/util/FunnelUtils.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/util/FunnelUtils.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/util/FunnelUtils.spec.tsx
🧬 Code graph analysis (3)
src/util/RadialBarUtils.tsx (1)
src/util/ActiveShapeUtils.tsx (1)
  • Shape (83-109)
src/util/BarUtils.tsx (1)
src/util/ActiveShapeUtils.tsx (1)
  • Shape (83-109)
test/util/FunnelUtils.spec.tsx (1)
src/util/types.ts (1)
  • Coordinate (88-91)
⏰ 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 (7)
src/polar/RadialBar.tsx (1)

139-139: Good addition of explicit type annotations.

Adding explicit types for entry: RadialBarDataItem and i: number improves type safety and aligns with the coding guidelines requiring explicit TypeScript type annotations for function parameters.

src/util/FunnelUtils.tsx (1)

7-8: Clean simplification of FunnelTrapezoid.

The component now delegates prop handling directly to Shape, which internally uses defaultPropTransformer to merge props. This removes unnecessary indirection while maintaining the same behavior.

src/util/BarUtils.tsx (1)

21-23: LGTM - Correct use of custom activeClassName.

The explicit activeClassName="recharts-active-bar" preserves the existing CSS class behavior for active bars, overriding the default "recharts-active-shape" from the Shape component.

src/util/RadialBarUtils.tsx (1)

20-21: Verify the default activeClassName is intended.

RadialBarSector will use the default activeClassName="recharts-active-shape" from Shape. Confirm this is the expected behavior, or if a custom class like "recharts-active-radial-bar-sector" should be used for consistency with other components (e.g., BarRectangle uses "recharts-active-bar").

test/util/FunnelUtils.spec.tsx (1)

1-42: Test updates correctly reflect the removed helper function.

The test file appropriately removes the import and test case for typeGuardTrapezoidProps while retaining the FunnelTrapezoid rendering tests. The existing tests verify the component still renders with "recharts-active-shape" class when active.

src/util/ActiveShapeUtils.tsx (2)

27-33: Cleaner type definition for ShapeProps.

Removing the ShapePropsType generic parameter and propTransformer property simplifies the public API. The type now clearly defines what callers need to provide.


83-102: Shape function correctly uses internal defaultPropTransformer.

The refactored Shape function maintains the same behavior while eliminating the external propTransformer prop. The internal ShapePropsType generic is appropriately used for type inference within the function body.

@codecov
Copy link

codecov bot commented Dec 4, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.01%. Comparing base (6aec882) to head (6a89970).
⚠️ Report is 3 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #6738      +/-   ##
==========================================
- Coverage   94.02%   94.01%   -0.02%     
==========================================
  Files         500      500              
  Lines       42685    42631      -54     
  Branches     4917     4904      -13     
==========================================
- Hits        40136    40080      -56     
- Misses       2544     2546       +2     
  Partials        5        5              

☔ 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.

Copy link
Member

@ckifer ckifer left a comment

Choose a reason for hiding this comment

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

this wasn't a public thing right?

@ckifer ckifer merged commit 91bf4ad into main Dec 4, 2025
36 of 38 checks passed
@ckifer ckifer deleted the propTransformer branch December 4, 2025 19:25
@PavelVanecek
Copy link
Collaborator Author

As far as I can tell this is all private.

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