Skip to content

feat: add shape type to pie, support similar patterns to other Recharts components#6482

Merged
ckifer merged 6 commits intomainfrom
feat/add-content-prop-to-pie
Nov 21, 2025
Merged

feat: add shape type to pie, support similar patterns to other Recharts components#6482
ckifer merged 6 commits intomainfrom
feat/add-content-prop-to-pie

Conversation

@ckifer
Copy link
Member

@ckifer ckifer commented Oct 20, 2025

Description

In 3.0 we removed activeIndex which has proved to cause some pain for consumers.

Instead of adding it back, we're moving to a different API for "active" and "inactive" Pie shapes. This will follow similar patterns to custom Label and Tooltips.

Related Issue

A few directly or indirectly related

#6251
#6259
#6052
#5999

Motivation and Context

allow people to do what they want

How Has This Been Tested?

current unit tests pass, need to add more

Screenshots (if appropriate):

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)

Checklist:

need to update docs

  • 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

    • Introduced a shape prop for Pie components enabling flexible sector customization. The prop accepts a React element or function receiving active state information for dynamic rendering.
  • Deprecated

    • activeShape and inactiveShape props are deprecated; use the new shape prop instead. Existing implementations remain supported for backward compatibility.

@ckifer ckifer changed the title feat: add content type to pie, support similar patterns to other Recharts components WIP feat: add content type to pie, support similar patterns to other Recharts components Oct 20, 2025
@codecov
Copy link

codecov bot commented Oct 20, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.17%. Comparing base (8d09b37) to head (158f2a9).
⚠️ Report is 12 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #6482   +/-   ##
=======================================
  Coverage   94.17%   94.17%           
=======================================
  Files         494      494           
  Lines       41644    41656   +12     
  Branches     4819     4817    -2     
=======================================
+ Hits        39218    39230   +12     
  Misses       2421     2421           
  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.

@codecov
Copy link

codecov bot commented Oct 20, 2025

Bundle Report

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

Detailed changes
Bundle name Size Change
recharts/bundle-cjs 1.13MB 42 bytes (0.0%) ⬆️
recharts/bundle-es6 978.79kB 42 bytes (0.0%) ⬆️
recharts/bundle-umd 513.75kB 19 bytes (0.0%) ⬆️

Affected Assets, Files, and Routes:

view changes for bundle: recharts/bundle-cjs

Assets Changed:

Asset Name Size Change Total Size Change (%)
polar/Pie.js 64 bytes 25.25kB 0.25%
util/ActiveShapeUtils.js -22 bytes 5.9kB -0.37%
view changes for bundle: recharts/bundle-umd

Assets Changed:

Asset Name Size Change Total Size Change (%)
Recharts.js 19 bytes 513.75kB 0.0%
view changes for bundle: recharts/bundle-es6

Assets Changed:

Asset Name Size Change Total Size Change (%)
polar/Pie.js 64 bytes 23.55kB 0.27%
util/ActiveShapeUtils.js -22 bytes 4.9kB -0.45%

@ckifer ckifer changed the title WIP feat: add content type to pie, support similar patterns to other Recharts components WIP feat: add shape type to pie, support similar patterns to other Recharts components Oct 30, 2025
@ckifer ckifer force-pushed the feat/add-content-prop-to-pie branch from 668d50b to 0427746 Compare November 18, 2025 08:05
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 18, 2025

Walkthrough

A new shape prop is introduced to the Pie component enabling per-sector custom shape rendering as a function or ReactNode, replacing activeShape and inactiveShape. The Shape utility is refactored to access isActive from props, and tests are updated to account for the new activation flow and state flag propagation.

Changes

Cohort / File(s) Summary
Pie component shape customization
src/polar/Pie.tsx
Added PieShape and PieSectorShapeProps types; introduced shape prop to InternalPieProps and PieProps; updated PieSectors rendering to use conditional shape selection (shape ?? sectorOptions); propagated shape through SectorsWithAnimation; marked activeShape and inactiveShape as deprecated.
Shape utility refactoring
src/util/ActiveShapeUtils.tsx
Changed Shape function to access isActive from props.isActive instead of destructuring parameter; preserved conditional rendering logic.
Storybook example
storybook/stories/API/chart/PieChart.stories.tsx
Added Sector import and implemented custom shape callback rendering a Sector with activeShapeFill applied when segment is active.
Test updates: interaction flow
test/chart/PieChart.spec.tsx
Updated pie sector click/hover tests to precede interactions with explicit hover activation, then target the active shape element; added null assertion for sector element.
Test updates: isActive flag
test/cartesian/Bar.spec.tsx, test/polar/Pie.spec.tsx
Added isActive: false to Bar background function expectedProps; added isActive: true to activeShape payload expectations in Pie tests.
API documentation
www/src/docs/api/Pie.ts
Added shape prop documentation (Object | ReactElement | Function); marked activeShape and inactiveShape as optional and deprecated.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant Pie as Pie Component
    participant Sector as PieSectors
    participant Shape as Shape Renderer
    
    User->>Pie: Render with shape prop
    Pie->>Sector: Pass shape + data + isActive
    Sector->>Shape: shape ?? sectorOptions
    alt shape provided
        Shape->>Shape: Call shape(props) with isActive
    else fallback
        Shape->>Shape: Use default sectorOptions
    end
    Shape-->>User: Render sector (active/inactive)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • src/polar/Pie.tsx: Core logic changes introducing new types and prop handling; verify conditional shape selection and backward compatibility with deprecated props
  • src/util/ActiveShapeUtils.tsx: Confirm isActive access pattern works consistently across all consumers
  • test/*.spec.tsx files: Multiple test files modified with new interaction flows and isActive assertions; ensure test coverage remains adequate
  • Deprecation pathway: Verify that existing code using activeShape/inactiveShape continues to function

Possibly related PRs

  • recharts/recharts#6512: Adds per-component shape customization and modifies ActiveShapeUtils.tsx similarly, indicating parallel or complementary shape abstraction work.

Suggested reviewers

  • PavelVanecek

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: introducing a new shape prop to the Pie component that follows patterns similar to other Recharts components.
Description check ✅ Passed The description covers the key sections with context on the motivation (removing activeIndex, using similar patterns to Label/Tooltip), related issues, and testing status, though several checklist items remain uncompleted.
✨ 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 feat/add-content-prop-to-pie

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.

@ckifer ckifer changed the title WIP feat: add shape type to pie, support similar patterns to other Recharts components feat: add shape type to pie, support similar patterns to other Recharts components Nov 18, 2025
@ckifer ckifer force-pushed the feat/add-content-prop-to-pie branch from 0af1889 to 158f2a9 Compare November 18, 2025 08:10
@ckifer ckifer marked this pull request as ready for review November 18, 2025 08:10
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 (6)
storybook/stories/API/chart/PieChart.stories.tsx (1)

2-25: Shape callback correctly demonstrates new Pie shape API

Importing Sector and using a shape={({ isActive, ...props }) => <Sector {...props} fill={isActive ? activeShape.fill : props.fill} />} is consistent with the new Pie shape contract and keeps isActive out of the rendered Sector props. This story is a good example of the intended usage.

If you want to avoid confusion between the deprecated activeShape prop and the new shape API, you might consider renaming the activeShape arg here to something like activeShapeConfig to signal it’s only used for styling in the story controls.

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

841-849: Background callback expectation updated for isActive flag

Adding isActive: false to the expected background props keeps this test aligned with the new Shape/activation contract. No functional change beyond exposing the flag to custom backgrounds.

You may later want a complementary test that covers isActive: true for backgrounds in an activeBar scenario, to fully lock in the contract.

src/util/ActiveShapeUtils.tsx (1)

27-107: Shape now drives activation via props.isActive, enabling callbacks to see active state

Routing isActive through props and checking props.isActive before wrapping in the active <Layer> lets all option variants (element, function, object, default) observe the active state, while keeping prior behavior for non‑active cases. The function and clone branches still behave as before aside from receiving the extra isActive flag.

If there are other call sites of Shape that conceptually support an active state but do not yet supply isActive, consider adding small tests similar to the Bar background and Pie tests to ensure they also get the flag consistently.

www/src/docs/api/Pie.ts (1)

172-205: Pie API docs correctly introduce shape and deprecate activeShape/inactiveShape

The new shape prop description and the deprecated: true flags on activeShape and inactiveShape are consistent with the implementation and give users a clear migration path toward the shape+isActive pattern.

If there is a central doc section describing the generic Shape helper (object/function/ReactElement semantics), linking to it from the shape prop description here would make the behavior even clearer.

src/polar/Pie.tsx (2)

160-200: New shape typing and deprecation annotations for active/inactive shapes look sound

Defining PieShape and threading shape?: PieShape through InternalPieProps and PieProps, while marking activeShape/inactiveShape as deprecated, matches the intended new API. The separation between internal (InternalPieProps) and external (PieProps) types is preserved and keeps legacy props functional.

If you expect consumers to type their shape callbacks explicitly, consider exporting a public helper type like PieSectorShapeProps = PieSectorDataItem & { isActive: boolean } so users don’t need to re‑declare the intersection themselves.


268-280: PieSectors correctly prioritizes shape over legacy active/inactive shapes and wires isActive

The logic

  • derives isActive from selectActiveTooltipIndex,
  • computes sectorOptions from activeShape/inactiveShape only when applicable, and
  • passes option={shape ?? sectorOptions} along with isActive into Shape,

so that:

  • shape fully controls rendering when provided, using isActive for styling,
  • existing activeShape/inactiveShape behavior is preserved when shape is absent, and
  • default sectors still work when none of these props are set.

This is a clean, backwards‑compatible layering of the new API.

Down the line, you might add a small unit test that exercises shape and activeShape together (e.g. shape defined, activeShape also set) to codify that shape intentionally wins in such scenarios.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8d09b37 and 158f2a9.

📒 Files selected for processing (7)
  • src/polar/Pie.tsx (8 hunks)
  • src/util/ActiveShapeUtils.tsx (1 hunks)
  • storybook/stories/API/chart/PieChart.stories.tsx (2 hunks)
  • test/cartesian/Bar.spec.tsx (1 hunks)
  • test/chart/PieChart.spec.tsx (2 hunks)
  • test/polar/Pie.spec.tsx (1 hunks)
  • www/src/docs/api/Pie.ts (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
storybook/stories/API/chart/PieChart.stories.tsx (2)
src/polar/Pie.tsx (1)
  • Pie (833-873)
src/index.ts (2)
  • Pie (54-54)
  • Sector (32-32)
src/polar/Pie.tsx (2)
src/util/types.ts (1)
  • ActiveShape (1038-1043)
src/util/ActiveShapeUtils.tsx (1)
  • Shape (80-107)
⏰ 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 (4)
test/polar/Pie.spec.tsx (1)

333-406: Active shape mock now correctly asserts isActive: true

Extending the expected activeShape call payload with isActive: true matches the updated Shape behavior and gives good coverage of the new activation signal on Pie sectors.

test/chart/PieChart.spec.tsx (2)

505-539: Update click test to target the active shape layer

The revised sequence (null‑check sector, hover to activate, then click the .recharts-active-shape layer) matches the new rendering model where the active sector is wrapped in its own <Layer>. This keeps the test robust against the extra wrapper without changing the public click contract.


570-582: Mouse leave test accounts for active shape wrapper

Adding the pre‑hover on the active shape before unhovering the sector accurately models how focus/hover transitions work with the new extra <Layer class="recharts-active-shape">. It prevents false negatives caused by the additional DOM layer in tests.

src/polar/Pie.tsx (1)

667-759: Animation path now correctly forwards shape to animated sectors

Passing shape={props.shape} from SectorsWithAnimation into PieSectors ensures that custom shapes are honored during animation as well as in the static case. The rest of the animation step logic is unchanged, so existing behavior should remain intact.

defaultVal: 'null',
isOptional: false,
isOptional: true,
deprecated: true,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Would be great to have an alternative in the description for everything that we deprecate. Same as in code.

@ckifer ckifer merged commit de24f23 into main Nov 21, 2025
29 checks passed
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