Skip to content

Make right-click navigation immediate and keep its target clear - #1287

Merged
morgmart merged 1 commit into
mainfrom
morganm/navigation-text-selection
Oct 16, 2026
Merged

morgmart merged 1 commit into
mainfrom
morganm/navigation-text-selection

Conversation

@morgmart

Copy link
Copy Markdown
Contributor

What this does

Right-click navigation without accidentally selecting its label. Context menus now appear immediately, and channel and Solo chat sidebar rows keep their hover highlight until their menu finishes closing—without changing the conversation being viewed.

Messages, inline links, and editors remain selectable. Ordinary dropdowns, popovers, and submenus retain their existing entrance animation, including dropdowns nested inside a right-click target. The existing channel-tab selection protection is unchanged.

Why it matters

Opening a menu previously highlighted words in navigation labels and removed the row's hover fill before the menu appeared. Together with the fade, slide, and blur entrance, this made a quick navigation action feel hesitant and disconnected from its target.

Navigation labels are controls rather than selectable document text. The shared menu now distinguishes context actions from button-opened menus, while keeping normal reading and editing behavior intact.

How it works

  • NavigationItem and the existing sidebar disclosure owners suppress text selection. Selection is not disabled on the context-menu trigger or on readable content.
  • The shared context-menu root exposes its visible lifetime, including dismissal. Channel and Solo sidebar styling uses that state with the existing hover and selected treatments. Canceled or parent-denied opens do not leave a highlight behind.
  • Context menus skip entrance effects and retain only the short opacity fade on dismissal. Ordinary menu and submenu roots reset that classification. Base UI still owns positioning, keyboard handling, dismissal, and focus restoration.
  • The design guide, component registry, and menu specimen document the distinction.

Verification

Checked commit 7b6780515c1a21f2e6b18570bcf0d35ef4c7b644, based on 014898f4484b062efd5793fa885a7433641fc2e6, with the refreshed Vitest 5 runner:

  • 144 design-system tests and 29 sidebar/session tests passed.
  • 38 browser checks passed across Chromium and WebKit: selection and copying, instant entrance, opacity-only dismissal, retained source highlight, keyboard/focus recovery, nested dropdowns, tab behavior, link menus, and menu cleanup after a row moves.
  • Pre-commit formatting/icon/security checks and all normal pre-push gates passed. The first unconstrained run hit two test timeouts; both full files and the complete related-test hook then passed with the documented BUZZ_TEST_WORKERS=2 setting, without changing timeouts or skipping checks.
  • App/design typechecks, design guards, design builds, changed-file Biome, and diff checks passed. Design builds retain the existing bundle-size and asset-resolution warnings.
  • Independent architecture, runtime, product, design-system, and test-honesty reviews completed. Both identified coverage gaps were closed and re-reviewed.
  • Regression controls: removing the submenu classification reset fails the new mounted component test; restoring blur/movement on context dismissal fails both browser engines. Removing instant entrance or source-presence styling also fails the corresponding browser checks. The original unwanted label selection reproduces in WebKit without the selection rules; Chromium does not reproduce that original engine-specific symptom.

Two browser cases were added, with no cases removed. Their browser-only contracts are native text selection and first-render/closing paint plus real portal focus. Scenario data stays minimal. Existing menu-dismiss assertions are unchanged; their exit barrier moved into a shared test helper. Submenu classification and canceled opens are tested with mounted React rather than browser journeys.

Morgan tried the desktop interaction during iteration. Full light/dark, narrow/enlarged-text, and touch acceptance are not claimed; hosted CI remains required. Open navigation work in #1273 and menu API work in #1266 overlap these owners and must preserve this behavior when integrated.

Prevent accidental navigation-label selection while preserving readable content. Keep sidebar source highlights through context-menu dismissal, with instant shared context entrances and unchanged dropdown/submenu motion.

Co-authored-by: goose <goose@users.noreply.github.com>
Signed-off-by: morgmart <98432065+morgmart@users.noreply.github.com>
@morgmart
morgmart requested a review from a team as a code owner October 16, 2026 21:13

@kalvinnchau kalvinnchau left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🤖 Approved. No actionable defects found. Targeted tests, browser checks, and TypeScript checks passed. Required live staging UI validation remains unverified because startup requires Keychain access.

@morgmart
morgmart merged commit 0b92951 into main Oct 16, 2026
61 of 63 checks passed
@morgmart
morgmart deleted the morganm/navigation-text-selection branch October 16, 2026 22:14
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