adobe / adobe/react-spectrum-charts
Legend item wrapping size should be more dynamic
- Dominant language
- TypeScript
- Stars
- 127
- Forks
- 29
- Avg merge
- 7d 2h
- Merged PRs (30d)
- 21
Description
### Provide a general summary of the issue here
Legend items sometimes render in a single column despite having horizontal space and `direction: "horizontal"` configuration due to hardcoded column width calculation.
This is particularly noticeable with small chart sizes, which are valid and should be supported within reason.
codesandbox: https://codesandbox.io/p/devbox/bold-butterfly-s4q5hg
[legendLabelWrap.json](https://github.com/user-attachments/files/21579881/legendLabelWrap.json)
### 🤔 Expected Behavior?
Legend should utilize available horizontal space efficiently, displaying multiple columns when labels are short enough to fit.
### 😯 Current Behavior
The legend column calculation uses a fixed 220px divisor that doesn't adapt to label content, causing inefficient space usage and forcing single-column layouts when multiple columns would fit.
- Chart width: 435px
- Column calculation: `floor(435 / 220) = 1` column
- Result: Single column layout despite available horizontal space
- Legend labels: "123", "123", "123456" (all much shorter than 220px)
### 💁 Possible Solution
### Utilize `labelLimit` prop
Use the configured `labelLimit` (default 184px) plus padding instead of hardcoded 220px:
```typescript
return { signal: 'floor(width / (labelLimit + symbolWidth + padding))' };
```
### Dynamic Calculation Based on Content
Calculate column width based on the longest actual label in the legend:
```typescript
return { signal: 'floor(width / (maxLabelWidth + symbolWidth + padding))' };
```
### 🔦 Context
**File**: `packages/vega-spec-builder/src/legend/legendUtils.ts`
```typescript
export const getColumns = (position: Position): SignalRef | undefined => {
if (['left', 'right'].includes(position)) return;
return { signal: 'floor(width / 220)' }; // <- Hardcoded 220px
};
```
The 220px divisor appears optimized for worst-case scenarios with maximum-length labels but doesn't consider:
- Actual label content lengths
- The configured `labelLimit` (default: 184px)
- Available space efficiency
### 🖥️ Steps to Reproduce
1. Create a chart with height 200px and width ~300px, varies based on legend content.
2. Add legend with short labels (< 50px each)
3. Set `direction: "horizontal"`
4. Observe single-column layout despite available space
### Version
1.18.1
### What browsers are you seeing the problem on?
Chrome
### If other, please specify.
_No response_
### What operating system are you using?
MacOS 15.5
### 🧢 Your Company/Team
_No response_
### 🕷 Tracking Issue
_No response_
Contributor guide
Research direction
Start in packages/vega-spec-builder/src/legend/legendUtils.ts at getColumns, then reproduce the layout with the linked CodeSandbox and legendLabelWrap.json using a horizontal legend with short labels. Compare the available width with the current fixed divisor and the configured labelLimit. Done means small charts use multiple columns when labels fit, while left and right legend positions remain unchanged.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- react, typescript
- Domain
- data-visualization, frontend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 64/100