Skip to content

fix(ui): shrink-wrap floating menus and align terminal font and global search spacing - #3187

Merged
kev1n77 merged 7 commits into
GCWing:mainfrom
kev1n77:fmy/ui-main
Sep 22, 2026
Merged

kev1n77 merged 7 commits into
GCWing:mainfrom
kev1n77:fmy/ui-main

Conversation

@kev1n77

@kev1n77 kev1n77 commented Sep 22, 2026

Copy link
Copy Markdown
Collaborator

Summary

This PR fixes four reported Web UI defects: floating menus reserved a fixed width and read far too wide for short labels, the terminal rendered larger than the code surfaces beside it and fell back to SimSun for Simplified Chinese, the select-all row in the terminal and editor menus used a dashed placeholder glyph, and the global search count and back pills looked lopsided around their chevrons. All changes are presentational; no product behavior, protocol, or persisted shape changes.

Type and Areas

Type: bug fix (UI/UX)

Areas: web UI (desktop Web UI; design system packages ui and design-tokens)

Motivation / Impact

  • Floating menus (right-click context menus, and the sidebar settings, theme, session, workspace, session filter, and assistant menus) reserved the default menu width, so short labels, their shortcut column, and submenu chevrons sat far apart behind a wide empty gutter. Menus can now shrink-wrap their widest row; the default stays fixed so anchored pickers are unaffected.
  • ActionItem shortcut hints had no typography rule of their own and inherited the surrounding body size, so Ctrl+Shift+C rendered larger than the 13px label next to it. They now use the meta role, matching SearchField.
  • The terminal select-all row used BoxSelect, which is an alias of SquareDashed, so it read as a dashed placeholder box. It now draws a solid SquareCheckBig glyph in both the terminal and editor menus.
  • The interactive terminal took font.size.base (14px) while the in-chat terminal preview and every other code surface take the xs step (12px), so a shell panel rendered noticeably larger than the code beside it. font.family.mono also named no CJK family, so Simplified Chinese fell through to the platform generic monospace face (SimSun on Windows). The terminal now shares the xs step, re-reads it on the global font preference change, and renders CJK with the same UI families as the rest of the interface.
  • The global search group count pill and the drilldown back pill were lopsided, and padding was not the cause: a lucide chevron inks only x 9..15 of its 24 viewBox, so a square Icon box stays about 34% empty on each side (roughly 5px at the 14-15px boxes these surfaces render). Both pills now cancel that slack on the edge that meets their inline padding, and the back button's asymmetric 3px 6px 3px 4px padding is symmetric.

Verification

  • pnpm --dir design-system run test (token-engine, design-tokens 37, theme 12, ui 283, package-contract, design-lab 61, plus type-check)
  • pnpm --dir src/web-ui run test:run src/shared/context-menu-system (28 passed)
  • pnpm --dir src/web-ui run test:run src/app/components/NavPanel (202 passed)
  • pnpm --dir src/web-ui run test:run src/tools/terminal (44 passed)
  • pnpm run type-check:web
  • pnpm --dir src/web-ui exec eslint on the changed files
  • pnpm run data-migrator:theme:check
  • pnpm run check:web:appearance (typography audit, appearance contracts, theme color audit, theme visual contract); it reports the same pre-existing warnings as the base branch
  • Manual checks: right-click menus in the terminal and editor and the sidebar action menus (row-sized width, shortcut hint size, solid select-all glyph), the terminal at the default and a larger global font size, Simplified Chinese output in the terminal, and the global search count pill hover plus a group drilldown

Two spots are deliberately not pinned by tests yet: the terminal font size, and the two global search declarations. The global search change was validated against compiled stylesheet output, where the visible insets were 4.5px leading against 8.8px trailing on the count pill and 9.1px against 6.5px on the back pill, and now match.

Reviewer Notes

  • Menu gains an opt-in inlineSize="content": the widest row sets the width, floored by the new overlay.menu.minInlineSize token (160px) and still capped by overlay.menu.inlineSize (220px). The default remains a fixed width so anchored pickers and comboboxes keep matching their control.
  • The CJK families are appended after the Latin monospace families and before the generic keyword, which is the only correct position: a proportional CJK face placed earlier also supplies Latin glyphs and would take code rendering off the monospace grid. The generated data-migrator stylesheet and the MiniApp first-paint projection are regenerated from the token.
  • The global search chevron slack is a single local $chevron-box-slack constant placed next to the documented glyph geometry, because it tracks the rendered chevron size rather than the spacing scale.
  • Known follow-up, intentionally out of scope: the open/new project and recent workspace menu in MainNav.tsx keeps its local fit-content width with a min(440px, ...) cap because long paths and hostnames need it, while the shared content cap is 220px. Migrating it needs the cap raised by a token first.
  • Each commit is independent and reverts on its own; the token commit and its regenerated artifacts must stay together.

Checklist

  • This PR is focused and does not include secrets, temporary prompts, generated scratch files, or unrelated artifacts.
  • Relevant verification is recorded above, or skipped checks are explained.
  • User-facing strings, docs, and locales are updated where applicable.

The group count pill and the drilldown back pill both read lopsided, and the
padding was not the cause. A lucide chevron inks only x 9..15 of its 24 viewBox,
so the square Icon box keeps roughly 34% of its width empty on each side -- 4.8px
at the 14px sm box under the count, 5.1px at the 15px box in the back button.
Whichever end of a pill a chevron meets therefore reads about 5px wider than the
padding declares, no matter how even that padding is.

Computed from the compiled stylesheets and the glyph paths: the count pill's
visible insets were 4.5px leading against 8.8px trailing, and the back pill's
were 9.1px leading against 6.5px trailing. The back button also carried an
asymmetric 3px 6px 3px 4px, which the chevron slack then amplified.

Cancel the chevron box slack only on the side that meets the pill's inline
padding, via margin-inline-end on the trailing count chevron and
margin-inline-start on the leading back chevron, and make the back button's
padding symmetric. The slack is one local $chevron-box-slack constant with the
glyph geometry documented next to it, because it tracks the rendered chevron
size rather than the spacing scale. The count pill keeps
--openbitfun-space-1 padding: its hover pill cannot bleed left, since the results
viewport in the modal host has no inline-start padding to bleed into and would
clip the leading radius.

The inner text-to-chevron gap stays untouched. It is a flex gap rather than an
inset, and after the edge fix it no longer reads as one.

Verified with the compiled stylesheet output for both selectors and with
pnpm run check:web:appearance (typography audit, appearance contracts, theme
color audit, theme visual contract), which reports the same pre-existing
warnings as before. No test pins these two declarations yet.
…fallback

The shell panel rendered noticeably larger than the code surfaces beside it and
showed Simplified Chinese in the platform's generic monospace face (SimSun on
Windows), even though the interface text around it looks like a modern sans.

Two separate causes:

- `font.family.mono` names no CJK family, unlike `sans` and `control`, which
  already carry 'PingFang SC', 'Hiragino Sans GB' and 'Microsoft YaHei UI'.
  Chromium therefore fell through to the generic `monospace` CJK face. The CJK
  families are now appended after the Latin monospace families and before the
  generic keyword, which is the only correct position: a proportional CJK face
  placed earlier in the list also supplies Latin glyphs and would take code
  rendering off the monospace grid. The apple-system profile mirrors the stack,
  and the generated data-migrator stylesheet and MiniApp first-paint projection
  are regenerated from the token.

- The interactive terminal took `font.size.base` (14px), while the read-only
  terminal preview inside chat and every other code surface take the `xs` step
  (12px). It now reads `font.size.xs` and re-reads it on `font:after-change`, so
  the panel follows the global font size preference like the other renderers
  that cannot consume a CSS custom property. An explicit `options.fontSize` from
  a caller still wins over both. The chat preview keeps its static `xs` token, so
  the two agree at the default preference.

Verified with pnpm --dir design-system/packages/design-tokens test (37 passed),
pnpm --dir src/web-ui run test:run src/tools/terminal (44 passed),
pnpm run type-check:web, eslint on the changed component, pnpm run
data-migrator:theme:check, and pnpm run check:web:appearance (typography audit,
appearance contracts, theme color audit, theme visual contract), which reports
only the same pre-existing warnings. No test pins the terminal font size yet.
A floating action menu has no shared column to align with, so the default menu width left a wide gap between short labels and their trailing content. Menu now takes an opt-in inlineSize="content" that shrink-wraps the widest row inside the shared menu bounds, capped by overlay.menu.inlineSize and floored by a new overlay.menu.minInlineSize token. The default stays fixed so anchored pickers keep matching their control.
ActionItem .shortcut shared only its display rules with .metadata, so a text hint inherited the surface body size and rendered larger than the 13px label next to it. It now carries the meta typography role, matching SearchField.
BoxSelect is an alias of SquareDashed, so select all read as a dashed placeholder box in the terminal and editor menus.
Right-click menus now shrink-wrap their labels, shortcut column, and submenu chevrons instead of reserving the default menu width.
Applies the shared content-sized menu to the settings, theme, session, workspace, session filter, and assistant menus, and drops the private min-width that the shared floor now owns. The session filter menu measures its own width instead of assuming the default.
@kev1n77
kev1n77 merged commit cc6d497 into GCWing:main Sep 22, 2026
13 checks passed
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.

1 participant