Skip to content

DataGrid: relation cell affordance is too noisy and breaks on multi-line text #30

@jonasnobile

Description

@jonasnobile

Problem

DataGridTooltipLabel (used by DataGridHasOneColumn / DataGridHasManyColumn cell wrappers) is defined as:

// packages/bindx-ui/src/datagrid/ui.tsx
export const DataGridTooltipLabel = uic('span', {
    baseClass: 'cursor-pointer border-dashed border-b border-b-gray-400 hover:border-gray-800',
})

Two things wrong with it, one mechanical and one UX:

1. Mechanical — multi-line text gets a strikethrough

border-bottom on an inline element is rendered per line-fragment. When relation cell content wraps to two or more lines (long names in a narrow column), the inline border-b from the first fragment sits in the gap between line 1 and line 2 and visually intersects the wrapped text — looks like a strikethrough. Same for every wrapped line except the last.

Reproducer: render a DataGridHasOneColumn in a column narrow enough that the relation name wraps. Reproduced in production against @contember/bindx-ui@0.1.37. (Cannot attach screenshot via gh issue create, but the artifact is reliable — bottom border per line-box is standard CSS behavior.)

2. UX — wrong place for the affordance

The dashed underline signals "this term is special / has a tooltip" (the <abbr> convention) or "this is a link". In the datagrid it actually means "click for filter actions" — that's not what users will infer from the visual.

It's also paying the cost in every cell of every relation column on every datagrid, which is a lot of permanent visual noise for a feature that is itself power-user.

Proposal

Move "this column is filterable" from cell to column header. Cells stay visually clean by default; per-cell "filter by this value" stays available as a hover-only or context-menu action.

Concretely:

  • Header: small filter icon (e.g. <FilterIcon className=\"w-3 h-3 text-muted-foreground/60\" />) next to header text on filterable columns. Click opens the existing filter popover.
  • Cell: drop the dashed underline entirely. Optionally show a small filter icon at the right edge of the cell on row hover for the "filter by this value" shortcut. The popover stays the same.

This matches what Linear / Airtable / AG-Grid / Notion do.

Quick-fix alternative

If the larger redesign needs more discussion, a minimal fix for the multi-line artifact is to replace border-b border-dashed with text-decoration: underline dashed (which wraps correctly per line and doesn't bleed into the line-height gap):

export const DataGridTooltipLabel = uic('span', {
    baseClass: 'cursor-pointer [text-decoration:underline_dashed] decoration-gray-400 underline-offset-4 hover:decoration-gray-800',
})

Or wrap the inner content in inline-block.

Happy to send a PR for whichever direction you prefer.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions