Skip to content

New Tab: keep dot names visible during keyboard focus - #27341

Merged
teamleaderleo merged 9 commits into
feat-cmux-nextfrom
lane/ui-newtab-dot-focus
Oct 29, 2026
Merged

teamleaderleo merged 9 commits into
feat-cmux-nextfrom
lane/ui-newtab-dot-focus

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Oct 29, 2026 •

Copy link
Copy Markdown
Collaborator

New Tab dot names currently follow pointer hover or a 1.1-second selection timer. Keyboard focus alone does not keep the name displayed: a previously hovered option can still be fading out as another dot gains focus, and an arrow-selected name disappears while its radio remains focused. Keep the keyboard-focused name visible until blur. A fresh pointer hover can preview another name; keyboard interaction clears a stationary pointer's old label.

Leo: "I feel like you guys could be doing more audits of the app. Like there's some amount of, like, satisfying and pretty stuff that can happen that we're not quite taking full advantage of."

Checklist: keyboard discoverability and worst-case interaction. DotSwitch keeps its existing accessible names and layout. It also serves composer look dots, so risk is limited to name visibility across pointer/keyboard transitions. Pointer press clears keyboard-name state, including when clicking the already-selected radio does not fire a change event. Only pointer picks start timed name feedback. Keyboard picks use focus state, so an immediate Tab away clears the name instead of exposing a stale selection timer. No new timer, observer or animation; the pointer selection timer clears on replacement and unmount.

Before / after

Real DotSwitch and shipped styles in the isolated new-tab.dot-focus gallery; synthetic labels only. Captured on ce06325. These captures show the retained-focus behavior. The subsequent immediate-blur correction changes only what happens after keyboard focus leaves; no new screenshot is claimed for that transition.

Case Before After
Tab after hovering the third dot: first dot focused Stale Compact name fading over the third dot Minimal name over the focused first dot
Arrow selection after 1400 ms, light / 340 px Focused second dot without a name Quick actions name retained above focused second dot
Arrow selection after 1400 ms, dark / 760 px Focused second dot without a name Quick actions name retained above focused second dot

The Tab before-shot catches the outgoing hover-label fade. It demonstrates the wrong option's name during the focus transition, not immediate visual absence. The later arrow shots show the fully expired label.

Validation

Gallery sizing gate fix at 079015c8bb1fc8cb37bed801e3f8081d3a8d4435: the fixture fills its stage with height: 100vh instead of declaring a raw 200px control height. The gallery entry continues to own the default stage height. No baseline entry or production code changed. Exact-head fast checks pass the design-token ratchet and all 11 dot-switch tests / 97 assertions. The earlier screenshots retain their original capture geometry; this delta changes only fixture sizing.

Immediate-blur regression: Playwright's clock is installed before page load, paused before ArrowRight, and advanced only 32ms for the focus-restoration frame. Time stays paused through Tab and the visibility assertions, so a slow CI shard cannot accidentally expire the 1100ms pointer timer. Reverting only the pointer-only picked assignment fails all four blur cases; the fixed version passes all 11 tests / 97 assertions, formatting, lint, fixed-wait guard and typecheck in the red/green run. The test awaits the label's actual animations and checks rendered opacity as well as data-shown.

Current head a0f26c66b3dbf9b65eeb8053a9f937e2f959d300 passes web CI, attempt 2. The remaining cmux-next check failure is No new SwiftUI (macOS UI is AppKit), also failing on base f8b0183ff86b6f6a880ead08a5ae589049a8024b; this PR changes only five webview files.

Earlier remote checks passed: targeted formatting and lint, fixed-wait guard, browser tests (4 cases / 44 assertions), existing style-switch tests (3 / 25), and full typecheck (2715 files). Cases covered light/dark × 340/760 px, pointer/keyboard handoff and clicking the already-selected radio. That harness did not explicitly set the gallery's Reduced Motion parameter; the new regression now does and asserts the effective media query.

Baseline comparison used the same fixture and baseline de67de9. Baseline mode deliberately expects the defect; this is a before/after observation, not a red regression-test run. That run passed both browser modes and the existing suite, then failed only at artifact export; captures were subsequently rerun remotely.

DOM state checked across four cases Baseline Fixed
data-shown after Tab and pointer exit 0/4 4/4
data-shown 1400 ms after arrow selection 0/4 4/4
Flag cleared after focus leaves, after the pick timer elapsed 4/4 4/4
Pointer pick returns focus and expires its name 4/4 4/4

The flag measures requested label visibility, not instantaneous opacity during the 80 ms exit fade.

Overlap: #20598 changes style-switch presentation in the same file but does not fix focus-name retention. DotSwitch's API is preserved.

Agent session: agent session

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Bead cx-fc0cyx created for this PR by the cmux coordinator.

@github-actions github-actions Bot added the risk:normal Risk tier (docs/ci/risk-tiers.md) label Oct 29, 2026
@github-actions

github-actions Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

cmux status (one comment, edited in place; each line is updated by the job that owns it)

Review a0f26c6: HQ feed card · gallery before/after runs · checks

App of this head (app.zip, kept 1 day)

gh workflow run reload-build.yml -R manaflow-ai/cmux --ref feat-cmux-next -f tag=pr27341 -f ref=lane/ui-newtab-dot-focus -f platform=macos -f backend_mode=local

Passes: CI passes on a0f26c66b3.

CI passes on a0f26c66b3 (run 40924317636 attempt 2).

Written by scripts/ci/classify_failures.py (ci-failure-attribution.yml); signatures are its SIGNATURES table. A machine verdict is the runner's fault, not this PR's; yours means the failing file is one this PR changes, also red on main that main's latest full suite fails the same way, seen on other PRs that it failed on another pull request's run lately.

red: cmux-next checks (god files, concurrency, crash safety, l10n); base red: the same failure on the base f8b0183; does not block

@blacksmith-sh

blacksmith-sh Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

Found 6 test failures on Blacksmith runners:

Failures

Test View Logs
/tmp/tmp2duk5fil/summary-missing.json (live):/summary-missing.json (live): View Logs
/tmp/tmprj111pj2/summary-fail.json (live):/summary-fail.json (live): View Logs
[new_workspaces] debug.new_workspace timed 0 of 50 new workspace rows/
[new_workspaces] debug.new_workspace timed 0 of 50 new workspace rows
View Logs
[new_workspaces] the window draws no frames/[new_workspaces] the window draws no frames View Logs
[tabs] debug.tab_switch timed 0 of 40 switches/
[tabs] debug.tab_switch timed 0 of 40 switches
View Logs
[tabs] the window draws no frames/[tabs] the window draws no frames View Logs

Fix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex-review-box/gpt-6-astra high, lane-place): SHIP at a0f26c6

SHIP

  1. StyleSwitch.tsx:132: Focus and pointer transitions are consistent. Keyboard labels persist until blur; clicking the selected dot clears keyboard feedback.
  2. StyleSwitch.tsx:88: Pick timers clean up on replacement and unmount. Keyboard selection clears timed feedback, preventing stale labels after blur.
  3. new-tab-dot-focus-browser.test.ts:126: The regression freezes time before selection and advances only 32 ms, keeping assertions inside the 1100 ms expiry window independently of the gallery date stub.
  4. DotSwitch.gallery.css:4: Fixture sizing fits the stage viewport; gallery registration loads the production component and styles.

No blocking defects found at a0f26c66b3dbf9b65eeb8053a9f937e2f959d300. Static review only: Bun, dependencies, and browser binaries were unavailable.

@teamleaderleo
teamleaderleo marked this pull request as ready for review October 29, 2026 21:09
@cursor

cursor Bot commented Oct 29, 2026

Copy link
Copy Markdown

Bugbot needs on-demand usage enabled

Bugbot uses usage-based billing for this team and requires on-demand usage to be enabled.

A team admin can enable on-demand usage in the Cursor dashboard.

@cmux-bot cmux-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

cmux-bot approves a0f26c6: an independent review passed this exact head (review box review-27341-a0f26 receipt by teamleaderleo). A push needs a new review; a later BLOCK at this head dismisses this approval.

@teamleaderleo
teamleaderleo merged commit ab70d79 into feat-cmux-next Oct 29, 2026
233 of 240 checks passed
@teamleaderleo
teamleaderleo deleted the lane/ui-newtab-dot-focus branch October 29, 2026 21:20
@github-actions

github-actions Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

This branch was previously deployed

1 inactive deployment
ci-routing-agent — a0f26c66 Deployed Oct 29, 2026 by teamleaderleo via wait for same-key tree publisher #77615
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk:normal Risk tier (docs/ci/risk-tiers.md)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant