table: Read and write the selection as one TableSelection value - #3143
Merged
huacnlee merged 8 commits intoSep 20, 2026
Merged
Conversation
`render_row` still read the raw `selected_row` field, so a row left behind by cell or column selection kept `aria_selected`, its forced bottom border and hover suppression while looking unselected. Use the getters everywhere the "only counts in its mode" rule applies, including `has_selection`, and collapse the getters to `Option::filter`. Drop the trailing `render_frame` from the getter test; nothing consumed that frame. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…umn getters A selected cell has a row and a column, so `selected_row()` and `selected_col()` return them in cell mode instead of `None`. Row and column highlighting stay gated on their own mode so a selected cell never lights up its whole row or column. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The selection is one fact with four shapes, so expose it as `TableState::selection() -> TableSelection` mirroring the select events. The three positional getters go back to being `Some` only when their own kind of thing is selected, so `selected_row()` never names a row that merely contains the selected cell; callers that want that row map it from `selected_cell()`. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…om the getters Restore `is_row` and `is_column`; each positional getter filters its own field through them, and `selection()` aggregates the three getters instead of matching on the mode. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Dispatches to the matching `set_selected_*` or `clear_selection` call so scrolling and events stay identical; persisting and restoring a selection is now one read and one write. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
TableSelection value
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
huacnlee
enabled auto-merge (squash)
September 20, 2026 13:00
Member
|
Thank you. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
After selecting a cell and then a row or column,
selected_cell()still returned the old cell, contrary to its documentation. The other getters also exposed cached selections from inactive modes, andrender_rowread the raw row field, so a row left behind by a cell or column selection keptaria_selected, its forced bottom border and hover suppression while looking unselected.The selection is one fact with four shapes, so this PR exposes it that way:
TableSelectionmirrors the three select events, andselection()/set_selection()read and write it as one value.selected_row(),selected_col()andselected_cell()areSomeonly when their own kind of thing is selected. A selected cell does not surface throughselected_row(); callers that want its row map it fromselected_cell()or match onselection().The native DataTable story no longer displays a stale
cell 5:3footer after selecting a row or column.Public API
gpui-component:pub enum TableSelection { None, Row(usize), Column(usize), Cell(usize, usize) }(new): the current selection as one value, mirroringTableEvent::SelectRow/SelectColumn/SelectCell.TableState<D>::selection(&self) -> TableSelection(new): reads the selection as one value; match on it instead of combining the three positional getters.TableState<D>::set_selection(&mut self, selection: TableSelection, cx: &mut Context<Self>)(new): writes the selection as one value; dispatches to the matchingset_selected_*orclear_selectioncall so scrolling and events are unchanged.TableState<D>::selected_row(&self) -> Option<usize>(corrected):Someonly when a row itself is selected.TableState<D>::selected_col(&self) -> Option<usize>(corrected):Someonly when a column itself is selected.TableState<D>::selected_cell(&self) -> Option<(usize, usize)>(corrected):Someonly when a cell is selected, as documented.Breaking Changes
Each positional getter now answers only for its own kind of selection, so a selected cell no longer surfaces through
selected_row()orselected_col(), and a row or column selection no longer leaves a staleselected_cell(). Callers that used the getters as a history of inactive selections must retain that history themselves. Signatures and internal navigation caches are unchanged.How to Test
cargo test -p gpui-kit --features test-support --test collections --locked: 5 passed.table_selection_getters_follow_the_active_modeassertsselection()and the three getters after every mode transition,clear_selection, and aset_selectionround trip through every variant;table_retains_navigation_positions_when_selection_mode_changescovers resuming row/column keyboard navigation from the retained positions. Both regressions failed on main before the fix.cargo clippy -- --deny warningsandcargo fmt --checkpass.AI-assisted implementation with Codex and Claude Code; diff reviewed and regression/native checks run.
🤖 Generated with Claude Code