adobe / adobe/react-spectrum

Shift+click range selection doesn't work in multi-select Select/Picker (anchorKey lost in useSelectState)

Open
#10,147 3 comments 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
15.9k
Forks
1.6k
Avg merge
3d 9m
Merged PRs (30d)
59

Description

### Provide a general summary of the issue here

With `Select` / `Picker` in `selectionMode="multiple"`, shift+click selects only the anchor and the shift-clicked item — not the range between them. The same gesture works correctly in `ListBox`, `GridList`, and `Table`.

Root cause: `useSelectState` stores the selection as a flat `Key[]` (`value`) and rebuilds the listbox's `selectedKeys` from it every render via `convertValue`. `useMultipleSelectionState` then constructs a fresh `Selection` whose
`anchorKey`/`currentKey` are `null`. Because `SelectionManager.extendSelection` reads `selectedKeys.anchorKey`, it never has an anchor to extend from, so the range collapses to the clicked item.

### 🤔 Expected Behavior?

Shift+click selects every item between the previously-clicked anchor and the shift-clicked target (like `ListBox`/`GridList`/`Table`), and shift+ArrowUp/Down extends the selection by keyboard.

### 😯 Current Behavior

Only the anchor and the target are selected; items in between are skipped. Re-shift-clicking from the same anchor does not re-extend the range.

### 💁 Possible Solution

Preserve the `Selection`'s `anchorKey`/`currentKey` through `useSelectState` instead of flattening to a plain array and rebuilding via `convertValue` (which produces `anchorKey: null`). For example, let the inner `useListState` own the
`Selection` as the source of truth, or thread the anchor through alongside `value`.

### 🔦 Context

Building a multi-select dropdown where users expect ListBox-style range
selection. This can't be fixed in userland: the lossy `Selection → Key[] →
anchorless Selection` round-trip is internal to `useSelectState`. This differs
from #7947 / #9543, which were closed as consumer-side `Set` reconstruction —
here the consumer has no control point.

### 🖥️ Steps to Reproduce

Minimal React Aria Components example:

```tsx
import {Select, SelectValue, Label, Button, Popover, ListBox, ListBoxItem} from 'react-aria-components';

function Example() {
return (

Items



One
Two
Three
Four
Five



);
}
```

1. Open the popover.
2. Click "Two".
3. Hold Shift and click "Five".

Expected: Two, Three, Four, Five are selected.
Actual: only Two and Five are selected.

### Version

`@adobe/react-spectrum@3.47.0`, `react-aria-components@1.17.0`, `react-stately@3.46.0`.

### What browsers are you seeing the problem on?

Chrome, Firefox

### If other, please specify.

_No response_

### What operating system are you using?

macOS 26.5

### 🧢 Your Company/Team

_No response_

### 🕷 Tracking Issue

_No response_

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.