feat(legend): add "list" layout for horizontal legends#2784
feat(legend): add "list" layout for horizontal legends#2784maryam-saeidi merged 66 commits intoelastic:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds a new "list" layout option for chart legends to improve space efficiency and usability when displaying many data series. The list layout is now the default for legends positioned at the top or bottom, while maintaining backward compatibility through an optional legendLayout prop that allows users to switch between list and table views.
Changes:
- Added new
LegendLayoutenum withListandTableoptions as a public API - Implemented list-based legend rendering with horizontal wrapping for top/bottom positions
- Enhanced label truncation to support both line-based and pixel-based width limits
Reviewed changes
Copilot reviewed 27 out of 27 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/charts/src/utils/common.tsx | Defines new LegendLayout enum and Layout type |
| packages/charts/src/specs/settings.tsx | Adds legendLayout prop to LegendSpec interface |
| packages/charts/src/utils/themes/theme.ts | Extends LegendLabelOptions with widthLimit property and makes maxLines optional |
| packages/charts/src/components/legend/legend.tsx | Updates rendering logic to conditionally render grid list or list layout |
| packages/charts/src/components/legend/legend_item_list.tsx | New component implementing horizontal list layout for legends |
| packages/charts/src/components/legend/label.tsx | Enhances label truncation with pixel-based width limiting |
| packages/charts/src/common/legend.ts | Adds logic to determine when to display table vs grid list vs list layouts |
| packages/charts/src/state/selectors/get_legend_size.ts | Improves legend height calculation for multi-row list layouts |
| storybook/stories/legend/2_legend_layout.story.tsx | New story demonstrating the legend layout feature |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
buildkite update vrt |
There was a problem hiding this comment.
Thanks for this PR, it really finally improves the Legend in charts.
I've added a couple of comments to be validated/fixed.
I believe there are also a couple of follow ups to fix (adding them after this PR is merged) to improve it:
- in
listmode when you click and disable/hide the items and you have legend values, the legend values of the other series are hidden, causing the legend to shrink. Is a bad UX, we should keep the legend value visible even when hidden
Screen.Recording.2026-02-24.at.17.38.44.mp4
- the
tablelayout has some issues with its sizing causing the legend to show horizontal scrollbars. It looks like a padding problem ofechLegendTable__cellremoving this and adding agrid_gapfixes it, but causes another small visible issue in the table header bottom border. - (DX) the storybook multiselect knob we are using for the legend values doesn't allow us to remove completely the values and see the default behaviour without values. we should find a quick way to fix it.
packages/charts/src/state/selectors/get_legend_max_formatted_value.ts
Outdated
Show resolved
Hide resolved
packages/charts/src/state/selectors/get_legend_max_formatted_value.ts
Outdated
Show resolved
Hide resolved
packages/charts/src/state/selectors/get_longest_legend_formatted_value.ts
Show resolved
Hide resolved
markov00
left a comment
There was a problem hiding this comment.
Changes Looks good to me.
There should be a couple of follows ups as wrote in my last review, but overall looks good.
@maryam-saeidi can you please create an issue for the follow ups so we can keep track of them? thanks
# [71.2.0](v71.1.2...v71.2.0) (2026-02-26) ### Bug Fixes * **metric:** update badge to pill shape with adjusted padding ([#2786](#2786)) ([80be269](80be269)) * **theme:** expose font weight in text style ([#2788](#2788)) ([02f4afa](02f4afa)) ### Features * **legend:** add "list" layout for horizontal legends ([#2784](#2784)) ([8967ce3](8967ce3)) * **legend:** add legendActionOnHover option to show actions on hover ([#2773](#2773)) ([d1be88f](d1be88f))
## Summary This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@elastic/charts](https://togithub.com/elastic/elastic-charts) | dependencies | minor | [`71.1.2` -> `71.2.0`](elastic/elastic-charts@v71.1.2...v71.2.0) | --- ### Release Notes ## [71.2.0](elastic/elastic-charts@v71.1.2...v71.2.0) (2026-02-26) ### Bug Fixes * **metric:** update badge to pill shape with adjusted padding ([#2786](elastic/elastic-charts#2786)) ([80be269](elastic/elastic-charts@80be269)) * **theme:** expose font weight in text style ([#2788](elastic/elastic-charts#2788)) ([02f4afa](elastic/elastic-charts@02f4afa)) ### Features * **legend:** add "list" layout for horizontal legends ([#2784](elastic/elastic-charts#2784)) ([8967ce3](elastic/elastic-charts@8967ce3)) * **legend:** add legendActionOnHover option to show actions on hover ([#2773](elastic/elastic-charts#2773)) ([d1be88f](elastic/elastic-charts@d1be88f))
## Summary This PR contains the following updates: | Package | Type | Update | Change | |---|---|---|---| | [@elastic/charts](https://togithub.com/elastic/elastic-charts) | dependencies | minor | [`71.1.2` -> `71.2.0`](elastic/elastic-charts@v71.1.2...v71.2.0) | --- ### Release Notes ## [71.2.0](elastic/elastic-charts@v71.1.2...v71.2.0) (2026-02-26) ### Bug Fixes * **metric:** update badge to pill shape with adjusted padding ([elastic#2786](elastic/elastic-charts#2786)) ([80be269](elastic/elastic-charts@80be269)) * **theme:** expose font weight in text style ([elastic#2788](elastic/elastic-charts#2788)) ([02f4afa](elastic/elastic-charts@02f4afa)) ### Features * **legend:** add "list" layout for horizontal legends ([elastic#2784](elastic/elastic-charts#2784)) ([8967ce3](elastic/elastic-charts@8967ce3)) * **legend:** add legendActionOnHover option to show actions on hover ([elastic#2773](elastic/elastic-charts#2773)) ([d1be88f](elastic/elastic-charts@d1be88f))
Summary
A new List legend layout is now available for horizontal legends (top/bottom), offering a more space-efficient alternative to the existing GridList/Table layout. In the list layout each legend item flows inline — label, color marker, and values are arranged in a compact row that wraps naturally, making it easier to scan many series without excessive scrolling.
The list layout supports all standard legend features: series highlighting, filtering via actions,
CurrentAndLastValuedisplay with stable column widths, and label truncation.Example usage
Demo
Screen.Recording.2026-02-17.at.10.40.26.mov
Details
Layout & rendering
legendLayout: 'list'option to theSettingsspec, enabling the list layout for horizontal legendsLegendListcomponent (legend_list.tsx) that renders legend items as inline<li>elements with label, color, values, and optional action grouped togetherCurrentAndLastValueshows a—placeholder when no value is available (e.g. on hover)theme.legend.labelOptions.widthLimit)Stable column widths
getLegendMaxFormattedValueto theChartSelectorsinterface, allowing each chart type to provide the longest formatted Y domain valuewithTextMeasure) and used asminWidthonCurrentAndLastValuecells, preventing layout shift on hoverLegend sizing
computeHorizontalLegendRowCountutility that measures items and lays them out greedily row-by-row to determine if the legend fits in 1, 2, or 3+ rows — short-circuiting as soon as a third row is reachedshouldDisplayGridListandshouldDisplayTablehelpers to select the correct layout mode based on legend values, position, and layout configOther
_legend.scss→_legend_grid_list.scssfor clarity2_legend_layout.story.tsx)computeHorizontalLegendRowCountand theshouldDisplay*helpersIssues
Related to elastic/kibana#238777
Checklist
:interactions,:axis)closes #123,fixes #123)packages/charts/src/index.tslightanddarkthemes🤖 This pull request was assisted by Cursor