Skip to content

table: Allow turning off the default row hover background - #3436

Open
xhofe wants to merge 1 commit into
longbridge:mainfrom
xhofe:table/row-hover
Open

xhofe wants to merge 1 commit into
longbridge:mainfrom
xhofe:table/row-hover

Conversation

@xhofe

@xhofe xhofe commented Oct 11, 2026 •

Copy link
Copy Markdown
Contributor

Description

DataTable always painted table_hover on a hovered row, so a table that already shows its own row state still picked up that fill. row_hover(false) skips it. The default stays true, so existing tables look the same.

Selected-row background and the right-click outline stay either way. Header and sort-icon hover are unchanged. The hover callback is still registered when the fill is off, so a row that is already under the pointer drops the background on the next frame instead of keeping it until the pointer leaves.

Screenshot

No visual change when row_hover is left at its default. The Data Table story adds a Row Hover menu item, checked by default, to turn the fill off.

Public API

gpui-component

  • gpui_component::table::DataTable::row_hover(self, row_hover: bool) -> Self — when false, a hovered row does not paint the table_hover background. Default is true. Selected-row background and the right-click outline stay either way.

How to Test

  • cargo check -p gpui-component -p gpui-component-story (passed here)
  • cargo run and open the Data Table story. With Row Hover checked, rows still paint the hover background. Uncheck it and hovered rows no longer paint that fill.
  • With Row Hover off, select a row and right-click another. The selection background and the right-click outline still appear.
  • A table that does not call row_hover keeps the previous hover background.

Checklist

  • I have read the CONTRIBUTING document and followed the guidelines.
  • Reviewed the changes in this PR and confirmed AI generated code (If any) is accurate.
  • Passed cargo run for story tests related to the changes.
  • Tested macOS, Windows and Linux platforms performance (if the change is platform-specific)

Made with Cursor

Apps that paint their own row state still inherited table_hover on pointer hover. row_hover(false) skips that fill while leaving selection and the right-click outline in place.

Co-authored-by: Cursor <cursoragent@cursor.com>

@huacnlee huacnlee left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The requirement is reasonable: applications should be able to preserve their own row-state styling without the default hover background overriding it.

However, I do not think row_hover is a good public API design. It adds a switch for one specific styling conflict rather than providing a systematic approach to row styling.

Please address this through the existing TableDelegate::render_tr customization point. Default row and hover styles should provide a fallback, while application-provided styles can override them. Selection and right-click presentation should retain explicitly defined precedence.

The current implementation unconditionally applies .hover(...) after render_tr, so the extension point cannot currently fulfill that contract. Please resolve that style-composition limitation rather than introducing row_hover. This needs to account for GPUI’s hover-style API; calling .hover(...) twice is not a safe composition strategy.

@huacnlee

Copy link
Copy Markdown
Member

To make the requested direction concrete, here is the intended usage inside an application's TableDelegate implementation:

fn render_tr(
    &mut self,
    row_ix: usize,
    _window: &mut Window,
    cx: &mut Context<TableState<Self>>,
) -> Stateful<Div> {
    // Illustrative application-owned row-state color, resolved from the theme.
    let background = cx.theme().tokens.table_even;

    div()
        .id(("row", row_ix))
        .bg(background)
        .hover(move |style| style.bg(background))
}

Here the application explicitly keeps its row-state background on hover. It could equally supply a different hover background or additional hover styling through the same extension point. A delegate that does not specify hover styling should keep DataTable's default table_hover feedback. Selection and right-click presentation should retain their explicitly defined precedence.

This is the intended usage after fixing style composition, not a workaround that works with the current implementation: DataTable currently calls .hover(...) again after render_tr. Please make the default styling compose with application-provided styling safely, accounting for GPUI's hover-style API, rather than adding row_hover(false).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants