feat(ui): refine thread hover feedback - #502
Conversation
Greptile SummaryThe PR makes thread-row hover feedback immediate, keeps actions stable around the IM menu, and adds scrolling for overflowing titles.
Confidence Score: 4/5The PR appears safe to merge, with a non-blocking visual regression where overflowing titles are clipped without an ellipsis before hover. The interaction and menu-state changes have no established blocking failure, but the nested inline-block title prevents the outer text-overflow utility from producing the previous ellipsis. Files Needing Attention: packages/presentation/ui/src/shell/sidebar/thread-row.tsx
|
| Filename | Overview |
|---|---|
| packages/presentation/ui/src/shell/sidebar/row-actions.tsx | Adds thread-specific spacing and action-visibility classes without an identified functional defect. |
| packages/presentation/ui/src/shell/sidebar/thread-row.tsx | Implements immediate preview feedback, controlled menu visibility, and hover title scrolling, but the new nested title structure no longer renders the resting ellipsis correctly. |
Reviews (1): Last reviewed commit: "feat(ui): refine thread hover feedback" | Re-trigger Greptile
There was a problem hiding this comment.
Important
Wrapping the title in an inline-block span removes the truncation ellipsis from every overflowing thread title at rest. Verified in Chrome against this repo's real compiled Tailwind CSS — titles now hard-clip mid-glyph instead of showing ….
Reviewed changes — the full diff at 09e127e (2 files, 1 commit), plus the coss-ui SidebarMenuButton/PreviewCard primitives, group-header.tsx as the other consumer of the shared row-action classes, and the [data-thread-title] E2E selectors in apps/webview/e2e/browser-smoke.e2e.mts.
- Forked row-action classes —
row-actions.tsxgainsTHREAD_ROW_*twins that drop thegroup-has-data-popup-open/menu-item:*variants andtransition-opacity; the originalROW_*constants stay for the group header. - Instant row feedback — the row's hover fill changes from
bg-transparenttobg-sidebar-accentwithtransition-none, and the preview card getsdelay={0}/closeDelay={0}plus classes that neutralize its enter/exit scale-and-fade. - Controlled IM menu — the ellipsis
DropdownMenubecomes controlled through newimMenuOpenstate, which substitutes for the droppeddata-popup-openCSS hook on both the row's trailing padding and the three action buttons' opacity. - Marquee title — the plain truncating
<span>is replaced byOverflowingThreadTitle, which measures overflow viauseSyncExternalStore+ResizeObserverand scrolls an innerinline-blockspan withtranslate-xwhile hovered.
ℹ️ The sidebar's two row surfaces now behave differently, and the diff doesn't say whether that's permanent
group-header.tsx sits directly above these rows in the same sidebar and composes the same PreviewCard + SidebarMenuButton + RowActionsCluster primitives, but it keeps the old treatment: hover:bg-transparent (no hover fill), the default 600ms preview-card delay with its scale-and-fade, transition-opacity on its actions, and data-popup-open pinning them visible. After this PR a user scrolling the sidebar crosses two adjacent row types that respond on different timings. Only you can say whether the header is meant to follow or the fork is deliberate.
Technical details
# Sidebar row-feedback fork: group header vs. thread row
## Affected sites
- `packages/presentation/ui/src/shell/sidebar/row-actions.tsx:7-17` — `ROW_HOVER_PE_CLASS`,
`ROW_HOVER_PE_WIDE_CLASS`, `ROW_ACTION_CLASS`: old behavior, still consumed by the group header.
- `packages/presentation/ui/src/shell/sidebar/row-actions.tsx:19-26` — `THREAD_ROW_*`: new behavior,
consumed only by the thread row.
- `packages/presentation/ui/src/shell/sidebar/group-header.tsx:178` — `hover:bg-transparent`, and
`:224`/`:237` — `ROW_ACTION_CLASS` with its `transition-opacity` and `data-popup-open` pinning.
- `packages/presentation/ui/src/shell/sidebar/group-header.tsx:173` — `PreviewCardTrigger` with no
`delay`/`closeDelay`, so 600ms/300ms defaults.
## Required outcome
- A recorded decision on whether the group header adopts the new timings or the two surfaces stay
divergent. If divergent is intended, the `THREAD_ROW_*` constants should say so (see the inline
comment on `row-actions.tsx:19`), so the next person doesn't "unify" them back.
## Open questions for the human
- Is CODE-650 scoped to thread rows only, with the group header tracked separately?
- If the header is meant to follow, does that land here or in a follow-up?ℹ️ Nitpicks
ROW_HOVER_PE_WIDE_CLASS(row-actions.tsx:11) has no referent left —thread-row.tsxwas its only consumer and now usesTHREAD_ROW_HOVER_PE_WIDE_CLASS.group-header.tsximports onlyROW_HOVER_PE_CLASSandROW_ACTION_CLASS.imMenuOpen && 'pe-21 sm:pe-19'(thread-row.tsx:88) hard-codes the same two valuesTHREAD_ROW_HOVER_PE_WIDE_CLASSencodes one line above, so the pair can drift apart silently. Deriving both from one source would keep them honest.
Claude Opus | 𝕏




Summary
Verification
pnpm check:cipnpm test— 3040 passed, 1 skippedCODE-650