Skip to content

fix(desktop): DM close button replaces unread badge on hover#1280

Merged
tlongwell-block merged 1 commit into
mainfrom
fix/dm-x-replaces-unread-badge
Jun 25, 2026
Merged

fix(desktop): DM close button replaces unread badge on hover#1280
tlongwell-block merged 1 commit into
mainfrom
fix/dm-x-replaces-unread-badge

Conversation

@tlongwell-block

Copy link
Copy Markdown
Collaborator

What

In the left sidebar, the DM close (×) button and the unread badge both render at absolute right-1 top-1/2 -translate-y-1/2. The × is hover/focus-gated via SIDEBAR_ROW_ACTION_VISIBILITY_CLASS, but the badge had no gating — so on hover the × stacked directly on top of the unread badge (the reported overlap).

Fix

The badge now hides exactly where the × appears, via a new SIDEBAR_ROW_ACTION_REPLACED_BADGE_CLASS — the symmetric inverse of the × visibility:

  • Mobile (<md): the × is always visible (no hover on touch), so the badge is hidden whenever a hide action exists — avoids a persistent overlap.
  • Desktop (md+): the badge shows at rest and fades out on row hover / focus-within, so the × cleanly replaces it in the same slot.

Applied only when onHideDm is present, so DM rows without a close action keep their always-visible badge (no behavior change).

Three deliberate choices:

  1. onHideDm && guard — only swap when there's an × to replace the badge.
  2. pointer-events-none on the badge — the × (z-10, same slot) reliably takes clicks during the opacity crossfade.
  3. transition-opacity — symmetric crossfade with the ×, no layout shift. The badge stays in the DOM (opacity-0), so its sr-only unread count remains in the a11y tree when a keyboard user tabs to the row.

Verification

  • biome check clean, tsc --noEmit clean
  • pnpm --dir desktop test — 1132 passed
  • Pre-commit + pre-push hooks green (rust/desktop/mobile fmt + tests)

Reviewed earlier in-channel by Dawn and Sami (9/10 on minimal/elegant/correct) and independently validated by Pinky (who caught the mobile overlap case).

@wesb please review.

The DM unread badge and close (x) button both render at
`absolute right-1 top-1/2`. The x is hover/focus-gated via
SIDEBAR_ROW_ACTION_VISIBILITY_CLASS, but the badge had no gating,
so on hover the x stacked on top of the badge.

Hide the badge exactly where the x appears: on mobile (<md) the x
is always visible, so hide the badge whenever a hide action exists;
on desktop (md+) hide it only on row hover/focus-within. Applied
only when onHideDm is present, so non-dismissable DM rows keep their
always-visible badge. The badge is pointer-events-none so the x
reliably takes clicks during the opacity crossfade, and it stays in
the DOM (opacity-0) so its sr-only unread count remains in the
accessibility tree on focus.

Co-authored-by: Tyler Longwell <tlongwell@block.xyz>
Signed-off-by: Tyler Longwell <tlongwell@block.xyz>
@tlongwell-block tlongwell-block merged commit e366372 into main Jun 25, 2026
25 checks passed
@tlongwell-block tlongwell-block deleted the fix/dm-x-replaces-unread-badge branch June 25, 2026 16:21
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