adobe / adobe/react-spectrum-charts

Legend item wrapping size should be more dynamic

Open
#613 1 comment 0 reactions 0 assignees View on GitHub
bug
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

Image

### 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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.