From 2585a7eb866504d4cfc4c3dbc6d0f89bc12e63df Mon Sep 17 00:00:00 2001 From: Julius Marminge <51714798+juliusmarminge@users.noreply.github.com> Date: Tue, 22 Sep 2026 20:00:37 -0700 Subject: [PATCH] refactor(web): menu triggers and items stop restyling ui/menu No ui component gained a variant, size, or prop. Every cluster was drift: - ProjectScriptsControl: the menus turned off hover highlighting (highlightItemOnHover={false}) and then rebuilt it on every MenuItem with hover/focus-visible overrides. Both go: the menu highlights on hover the standard way. The shortcut's hover fade moves to a plain wrapper span. - DraftHeroHeadline: the hero project title renders through InlineButton tone="picker", the established in-sentence menu opener (also used by SettingsScopeSentence), instead of a hand-built dotted border. Radio item row layout moves to a plain inner span. - BranchToolbar mobile run-context trigger renders ComposerControl size="xs", the resting composer control its desktop siblings use. - LegacySidebar sort trigger renders Button icon-xs ghost-muted, matching the adjacent Add project button. - Pull requests CompactFilterMenu (non-outlined) renders Button ghost-muted size="sm" instead of a hand-built ghost button. - FileBreadcrumbs ignored-entry muting moves to the label span. - PreviewMoreMenu and PullRequestStackHeader put truncation / flex layout on an inner element instead of MenuGroupLabel. - EnvironmentIconPicker lock note, SnapShotSettings sound rows, and the UsagePage trigger drop their size/checked/gap overrides and take the primitive defaults. Co-Authored-By: Claude Opus 5.5 (1M context) --- apps/web/src/components/BranchToolbar.tsx | 6 +-- apps/web/src/components/LegacySidebar.tsx | 4 +- .../src/components/ProjectScriptsControl.tsx | 35 +++++---------- .../src/components/chat/DraftHeroHeadline.tsx | 45 ++++++++++--------- .../src/components/files/FileBreadcrumbs.tsx | 13 ++++-- .../components/preview/PreviewMoreMenu.tsx | 9 ++-- .../pullRequest/PullRequestStackHeader.tsx | 22 ++++----- .../settings/EnvironmentIconPicker.tsx | 2 +- .../components/settings/SnapShotSettings.tsx | 19 ++------ apps/web/src/components/usage/UsagePage.tsx | 2 +- apps/web/src/routes/_chat.pull-requests.tsx | 15 +++---- scripts/lint-restyle-ceiling.ts | 2 +- 12 files changed, 78 insertions(+), 96 deletions(-) diff --git a/apps/web/src/components/BranchToolbar.tsx b/apps/web/src/components/BranchToolbar.tsx index 607236f2d63b..8e84ec5d1ed9 100644 --- a/apps/web/src/components/BranchToolbar.tsx +++ b/apps/web/src/components/BranchToolbar.tsx @@ -41,7 +41,7 @@ import { } from "./BranchToolbarBranchSelector"; import { BranchToolbarEnvironmentSelector } from "./BranchToolbarEnvironmentSelector"; import { BranchToolbarEnvModeSelector } from "./BranchToolbarEnvModeSelector"; -import { Button } from "./ui/button"; +import { ComposerControl } from "./chat/ComposerControl"; import { Menu, MenuGroup, @@ -206,8 +206,8 @@ const MobileRunContextSelector = memo(function MobileRunContextSelector({ return ( } - className="min-w-0 max-w-[48%] flex-initial justify-start font-normal text-muted-foreground/70 text-xs! hover:text-foreground/80" + render={} + className="min-w-0 max-w-[48%] flex-initial justify-start" data-composer-context-control data-composer-shortcut={[ showEnvironmentPicker && !envLocked ? "composer.host" : "", diff --git a/apps/web/src/components/LegacySidebar.tsx b/apps/web/src/components/LegacySidebar.tsx index c61c4caff93b..fc8bf99a8098 100644 --- a/apps/web/src/components/LegacySidebar.tsx +++ b/apps/web/src/components/LegacySidebar.tsx @@ -2732,9 +2732,7 @@ function ProjectSortMenu({ - } + render={} />} > diff --git a/apps/web/src/components/ProjectScriptsControl.tsx b/apps/web/src/components/ProjectScriptsControl.tsx index eb186ea72f5d..97de05d1d896 100644 --- a/apps/web/src/components/ProjectScriptsControl.tsx +++ b/apps/web/src/components/ProjectScriptsControl.tsx @@ -101,8 +101,6 @@ export default function ProjectScriptsControl({ ), [fileScripts, scripts], ); - const dropdownItemClassName = - "data-highlighted:bg-transparent data-highlighted:text-foreground hover:bg-accent hover:text-accent-foreground focus-visible:bg-accent focus-visible:text-accent-foreground data-highlighted:hover:bg-accent data-highlighted:hover:text-accent-foreground data-highlighted:focus-visible:bg-accent data-highlighted:focus-visible:text-accent-foreground"; const openAddDialog = () => { setEditorRequest({ scriptId: null, initial: EMPTY_PROJECT_SCRIPT_INPUT }); @@ -153,7 +151,6 @@ export default function ProjectScriptsControl({ void importFileScript(fileScript)} > @@ -178,7 +175,7 @@ export default function ProjectScriptsControl({ onRunScript(script)} > @@ -186,17 +183,15 @@ export default function ProjectScriptsControl({ {script.runOnWorktreeCreate ? `${script.name} (setup)` : script.name} - {shortcutLabel && ( - - {shortcutLabel} - - )} + {shortcutLabel && + (presentation === "menu" ? ( + {shortcutLabel} + ) : ( + // The shortcut yields its slot to the edit button on hover. + + {shortcutLabel} + + ))}