Skip to content

feat(hybridFilter): add shift-click range selection#108294

Closed
JonasBa wants to merge 47 commits intomasterfrom
jb/hybridFilter/shift-click
Closed

feat(hybridFilter): add shift-click range selection#108294
JonasBa wants to merge 47 commits intomasterfrom
jb/hybridFilter/shift-click

Conversation

@JonasBa
Copy link
Copy Markdown
Member

@JonasBa JonasBa commented Feb 14, 2026

Implements range selection via shift click making it less tedious to select multiple projects at once (currently requires clicking each checkbox)

JonasBa and others added 30 commits February 11, 2026 11:50
Moves checkbox position to the beginning of the row and unwinds the mess
of checkwraps.

<img width="666" height="624" alt="CleanShot 2026-02-11 at 16 28 05@2x"
src="https://github.com/user-attachments/assets/4fe46a08-9619-49b7-9377-fb58088495cb"
/>

Fix DE-752
…dFilter

- Created useStagedCompactSelect hook that encapsulates all state management
  and business logic for staged selection (commit/cancel/toggle)
- Manages modifier key detection for hybrid single/multiple selection mode
- Hook returns all handlers and state as a single object (stagedSelect)
- Component now focuses on UI rendering while hook handles state logic
- All existing tests pass, no behavior changes
…electProps

- Hook now returns a typed `props` object that matches CompactSelectProps
- Props can be spread directly into CompactSelect: {...stagedSelect.props}
- Separates CompactSelect props from utility functions (commit, toggleOption, etc)
- Improves type safety and makes hook more reusable
- All tests pass, no behavior changes
JonasBa and others added 17 commits February 13, 2026 11:14
The Reset button in the refactored HybridFilter components doesn't have
an aria-label attribute, so the test needs to find it by its text
content instead. This fixes the failing acceptance test for
test_global_selection_header_updates_environment_with_browser_navigation_buttons.
Implements shift-click multi-selection for hybrid filter components,
allowing users to select a range of items by holding shift and clicking.
This works alongside existing Cmd/Ctrl modifier for individual toggles.

- Separate shift key detection from Cmd/Ctrl modifiers
- Add range selection logic that selects all items between anchor and clicked item
- Extract performSingleToggle helper to reduce code duplication
- Track last selected item as anchor point for range selection
- Clear text selection on shift-click to prevent UI glitches
- Keep menu open during shift operations
- Add comprehensive unit tests for shift-click functionality
- Update all consumers to pass options array to hook
- Use Ctrl+row clicks to set anchor instead of checkbox clicks
- This ensures keyboard events are properly captured by CompactSelect
- Fix array ordering in shiftToggleRange to preserve option order
- All 13 tests now passing
The text selection clearing isn't needed for the shift-click functionality.
@JonasBa JonasBa requested review from a team as code owners February 14, 2026 04:36
@github-actions github-actions bot added the Scope: Frontend Automatically applied to PRs that change frontend components label Feb 14, 2026
Copy link
Copy Markdown
Contributor

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

if (!lastSelectedRef.current) {
performSingleToggle(clickedValue);
return;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Falsy check fails for valid zero-value anchors

Medium Severity

The !lastSelectedRef.current check uses a falsy test to detect whether an anchor has been set. Since lastSelectedRef is typed as Value | null where Value extends SelectKey (string | number), a valid anchor value of 0 (or "") would be treated as "no anchor," causing shiftToggleRange to fall back to performSingleToggle instead of performing range selection. The project page filter uses number values for project IDs, making this reachable. The check needs to be a strict === null comparison.

Fix in Cursor Fix in Web

useState,
} from 'react';
import styled from '@emotion/styled';
import {isAppleDevice, isMac} from '@react-aria/utils';
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Orphaned utility after removing its only import

Low Severity

The isModifierKeyPressed utility in static/app/utils/isModifierKeyPressed.tsx is now dead code — this PR removed its only import (from hybridFilter.tsx) and inlined the modifier detection logic directly using isAppleDevice and isMac from @react-aria/utils. No other file in the codebase imports isModifierKeyPressed.

Fix in Cursor Fix in Web

Comment on lines +155 to +160
const getFlatOptions = useCallback(
(opts: Array<SelectOptionOrSection<Value>>): Array<SelectOption<Value>> => {
return opts.flatMap(item => ('options' in item ? item.options : [item]));
},
[]
);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we must have this code a bazillion times 😂

Base automatically changed from jb/hybridfilters/view-components to master February 17, 2026 18:23
@JonasBa JonasBa closed this Feb 17, 2026
JonasBa added a commit that referenced this pull request Feb 17, 2026
Split away from #108294 as we de
didn't merge the upstream change
mchen-sentry pushed a commit that referenced this pull request Feb 24, 2026
Split away from #108294 as we de
didn't merge the upstream change
@github-actions github-actions bot locked and limited conversation to collaborators Mar 5, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Scope: Frontend Automatically applied to PRs that change frontend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants