cmux NEXT: New Tab style switch is round dots again

Merged
TE
24d ago
+212-55

SHOW LEO: this PR acts on Leo's design feedback, so it holds for his OK on the before/after recording before merging.

Leo asked "what happened to the dots at the bottom, why's there text". #20336 (cx-txe89) replaced the New Tab style dots with a row of text radios. The pane does not load ui.css, so the radios' .ui-sr-only never applied: each name drew a native radio circle beside it, which looked clunky and left a gap before "Composer".

This brings back the dots and keeps what #20336 got right.

Changes

  • Dots: one 6px round dot per style, on a 24px hit target. The current dot is in the accent and the rest are dim on the text ink.
  • Accent slide: the accent dot slides to a pick, with no slide under Reduce Motion.
  • Names: a pointer over a dot shows its name above that dot. A pick shows the picked name for a moment, then fades it. The names stay as the radios' accessible names in all 21 locales.
  • Steady row: the name sits outside the row's layout, and every target is a fixed 24px, so the row never moves or shifts.
  • Unchanged from #20336:
    • Arrow keys move between styles.
    • Return and Escape go back to the field, and a click goes back to the field.
    • A pick saves tabs.newTabTemplate.
  • Radio fix: the radio fills its target unseen, through its own rule, so no native circle draws.
  • The gallery state style-switch note is updated, and its play still picks Threads by role and name.

Testing

  • New browser test webviews/test/new-tab-style-dots.test.ts renders the switch with the pane's real screen.css in Chromium. It checks five round dots of 5 to 8px, no visible radio or text at rest, targets of at least 20px, and one row box for every current style.
  • webviews/test/new-tab-style-switch.test.tsx covers the dot names: none at rest, the name on hover, and a pick's name that then fades. It still covers values, accessible names and focus return.
    • This test uses the manual frames from #20431 for the same race. Whichever of the two lands second merges the other.
  • The tests were committed first (red) and then fixed (green). Results are in the comments below. The jsdom test fails on base locally (no name element).
  • bun test test/ui-rules.test.ts passes. The full bun run check fails only on the base format red in modelPickerLayout.ts (#20464, #20470).
  • Captures: real cmux NEXT DEV apps (Mac fleet builds, base de5ceb78 vs head 0cc23f2f), the New Tab page's style switch at rest, with the pointer over Default, after picking Threads, then Default again. Machine name masked. On a capture slot the system pointer can't hover the page, so the pointer reaches each option through a click (a click on the current style changes nothing).

style switch before rest

style switch before hover

style switch after rest

style switch after hover

style switch after picked

style switch before after

Full quality:

Changelog

  • Fixed: the New Tab page's style switch is a row of small round dots again, naming a style on hover and briefly after a pick.

🤖 Generated with Claude Code


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


Summary by cubic

Restores the New Tab style switch as fixed-size round dots with names on hover or briefly after a pick, and saves the selected style as before.

  • Each style gets one 6px round dot on a 24px hit target; the current dot sits in the accent and slides to a new pick (no slide under Reduce Motion).
  • A pointer over a dot shows its name above it; a pick shows the picked name for a moment, then fades it. The names stay as the radios' accessible names in all locales.
  • The radio fills the target unseen, so no native circle draws (the pane does not load ui.css).