CHARTS-180: Fix duplicate items.find() and falsy value guard in BaseLegend#47459
CHARTS-180: Fix duplicate items.find() and falsy value guard in BaseLegend#47459
Conversation
|
Thank you for your PR! When contributing to Jetpack, we have a few suggestions that can help us test and review your patch:
This comment will be updated as you work on your PR and make changes. If you think that some of those checks are not needed for your PR, please explain why you think so. Thanks for cooperation 🤖 Follow this PR Review Process:
If you have questions about anything, reach out in #jetpack-developers for guidance! |
Co-authored-by: adamwoodnz <1017872+adamwoodnz@users.noreply.github.com>
|
@copilot use https://github.com/Automattic/jetpack/blob/trunk/.agents/skills/jetpack-pr.md when creating your PR |
|
Are you an Automattician? Please test your changes on all WordPress.com environments to help mitigate accidental explosions.
Interested in more tips and information?
|
Updated the PR description to follow the template from Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
Proposed changes:
|
|
@claude review please |
|
Claude finished @adamwoodnz's task in 1m 4s —— View job Code Review
The changes are correct and well-targeted. Here's my analysis:
|
There was a problem hiding this comment.
Pull request overview
Fixes legend rendering so falsy-but-valid values (notably numeric 0) are displayed, while also avoiding redundant items.find() calls during render.
Changes:
- Store
items.find(...)result in amatchedItemvariable to avoid duplicate lookups. - Switch the legend value guard from a truthy check to
!= nullso0renders. - Add a unit test verifying that
value: 0is rendered.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
projects/js-packages/charts/src/components/legend/private/base-legend.tsx |
Avoids duplicate find() and changes the value guard to allow rendering 0. |
projects/js-packages/charts/src/components/legend/test/legend.test.tsx |
Adds coverage for rendering numeric zero values in the legend. |
projects/js-packages/charts/changelog/charts-180-fix-duplicate-find-truthy-check-legend |
Documents the fix as a patch-level change. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
projects/js-packages/charts/src/components/legend/private/base-legend.tsx
Outdated
Show resolved
Hide resolved
Code Coverage SummaryCoverage changed in 1 file.
|
The runtime code and docs already treated value as optional, but the type declared it as required. This caused a misleading type guarantee for consumers. Aligns the type and API reference with actual behavior. Made-with: Cursor
|
@claude again please |
|
Claude finished @adamwoodnz's task in 49s —— View job Code Review
The changes are correct, focused, and well-targeted. Here's my analysis of each change:
|
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| { matchedItem?.value != null && ( | ||
| <span className={ styles[ 'legend-item-value' ] }> | ||
| { '\u00A0' } | ||
| { items.find( item => item.label === label.text )?.value } | ||
| { matchedItem.value } | ||
| </span> |
There was a problem hiding this comment.
The new matchedItem?.value != null guard will render an empty value string ('') as a value, which changes existing behavior. Several legend item generators in this repo intentionally set value: '' when values should be hidden (e.g. when showValues is false), and with this change those items will now render an extra value span containing only a non‑breaking space, affecting layout/spacing.
Consider treating empty string as “no value” (e.g. additionally check matchedItem.value !== ''), or update upstream item generators to omit value/use undefined when no value should be displayed (and keep BaseLegend aligned with that contract).
| expect( screen.getByText( '0' ) ).toBeInTheDocument(); | ||
| expect( screen.getByText( '0%' ) ).toBeInTheDocument(); | ||
| } ); | ||
|
|
There was a problem hiding this comment.
The added coverage verifies 0 renders, but it doesn’t cover the existing “hide values by using an empty string” behavior (some code paths set value: '' when values shouldn’t be shown). With the new != null guard, '' would now render an empty value span and can affect layout; adding a test case for value: '' not rendering (or updating fixtures to omit value) would help prevent regressions.
| test( 'does not render value span for empty string values', () => { | |
| const itemsWithEmptyValues = [ | |
| { label: 'Item 1', color: '#ff0000', value: '' }, | |
| { label: 'Item 2', color: '#00ff00', value: '' }, | |
| ]; | |
| const { container } = render( | |
| <BaseLegend items={ itemsWithEmptyValues } orientation="horizontal" /> | |
| ); | |
| expect( container.querySelectorAll( '[data-testid="legend-value"]' ).length ).toBe( 0 ); | |
| } ); |
Empty string values (e.g. from leaderboard legend items) would render a span containing only a non-breaking space, affecting layout. Now BaseLegend also rejects empty strings, and the leaderboard hook omits value entirely instead of setting it to ''. Made-with: Cursor
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const visible = isSeriesVisible( label.text ); | ||
| const handleClick = createClickHandler( label.text ); | ||
| const handleKeyDown = createKeyDownHandler( label.text ); | ||
| const matchedItem = items.find( item => item.label === label.text ); |
There was a problem hiding this comment.
matchedItem is derived via items.find(...) inside labels.map, which keeps this render path at O(n^2) and is still doing extra work every render. Since the component already assumes labels and items are aligned by index (e.g., items[i] is used for glyph rendering), you can use const matchedItem = items[i]; (or const value = items[i]?.value) to avoid any find() and also avoid mismatches if label.text is formatted differently from item.label.
| const matchedItem = items.find( item => item.label === label.text ); | |
| const matchedItem = items[ i ]; |
Labels and items are index-aligned via the ordinal scale domain, so items.find() per label was redundant O(n) work each render. Use items[i] directly. Add regression test to ensure value-label pairing stays correct if alignment assumptions change. Made-with: Cursor
Fixes CHARTS-180: Fix double items.find() and truthy check for legend value
Summary
Fixes legend rendering so falsy-but-valid values (notably numeric
0) are displayed, while also avoiding redundantitems.find()calls during render. Additionally makesBaseLegendItem.valueoptional to align the type with runtime behavior and docs, and guards against empty string values rendering empty spans.Proposed changes:
items.find()result into amatchedItemvariable to avoid calling it twice per label on every render.?.value &&guard with an explicit?.value != null && value !== ''check so falsy-but-valid values (e.g. numeric0) are no longer silently hidden, while empty strings don't produce empty value spans.BaseLegendItem.valueoptional in the type definition and API reference docs — the component already treated it as optional at runtime, and the docs described it as optional.useLeaderboardLegendItemsto omitvalueentirely instead of settingvalue: ''.0values, empty string values, and missing values.Other information:
Jetpack product discussion
N/A — internal charts library fix.
Does this pull request change what data or activity we track or use?
No.
Testing instructions:
jp test js js-packages/charts— all legend and leaderboard legend tests should pass.jp storybook js-packages/charts) and verify:65%,35%) render next to labels.Changelog
Changelog entry added at
projects/js-packages/charts/changelog/charts-180-fix-duplicate-find-truthy-check-legend.