authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-09-22 12:22:20-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-09-22 12:22:20-07:00
log1c2f933892cce833823fcfbf3099a51813ba67fb
tree77e27d717a03a699ab29e6fef41558c626deee02
parent4321aa24fd21c2b5360cc58e84de4ccc09c801f9
signature Signed by PGP key B5690EEEBB952194

refactor(web): render menu and popover triggers through Button (#13042)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

9 files changed, 20 insertions(+), 14 deletions(-)

apps/web/src/components/DiffPanel.tsx+2-1
......@@ -672,7 +672,8 @@ export default function DiffPanel({
672672 <div className="flex min-w-0 flex-1 items-center gap-3 [-webkit-app-region:no-drag]">
673673 <DropdownMenu>
674674 <DropdownMenuTrigger
675 className="inline-flex h-6 max-w-full items-center gap-1 rounded-md bg-accent px-2 text-xs font-medium text-accent-foreground outline-none transition-colors hover:bg-accent/80 focus-visible:ring-2 focus-visible:ring-ring"
675 render={<Button size="xs" variant="secondary" />}
676 className="max-w-full"
676677 aria-label={`Diff scope: ${selectedScopeLabel}`}
677678 >
678679 <span className="truncate">{selectedScopeLabel}</span>
apps/web/src/components/chat/useAutoBalanceUpdateBanner.tsx+3-1
......@@ -21,6 +21,7 @@ import {
2121 ServerUpdateProgress,
2222 ServerUpdatesAction,
2323} from "../ServerUpdateAction";
24import { InlineButton } from "../ui/button";
2425import { Popover, PopoverPopup, PopoverTrigger } from "../ui/popover";
2526import type { ComposerBannerStackItem } from "./ComposerBannerStack";
2627import { ComposerServerUpdateIcon } from "./ComposerServerUpdateStatus";
......@@ -95,7 +96,8 @@ export function useAutoBalanceUpdateBanner(
9596 title: (
9697 <Popover>
9798 <PopoverTrigger
98 className="block max-w-full truncate rounded-sm text-left outline-none focus-visible:ring-2 focus-visible:ring-ring"
99 render={<InlineButton />}
100 className="block max-w-full truncate"
99101 aria-label={`${title}. View machines`}
100102 >
101103 {title}
apps/web/src/components/device/DeviceToolVersions.tsx+2-1
......@@ -1,5 +1,6 @@
11import type { ReactNode } from "react";
22import type { DeviceToolVersions as ToolVersions } from "@t3tools/contracts";
3import { InlineButton } from "~/components/ui/button";
34import { Popover, PopoverPopup, PopoverTitle, PopoverTrigger } from "~/components/ui/popover";
45
56export function DeviceToolVersions({
......@@ -32,7 +33,7 @@ export function DeviceToolVersions({
3233 ? `${label}: ${version ? `version ${version}` : selected ? "not installed" : "version unknown"}. Show details`
3334 : undefined
3435 }
35 className="rounded text-xs text-muted-foreground underline decoration-muted-foreground/40 underline-offset-4 hover:text-foreground focus-visible:outline-2 focus-visible:outline-ring"
36 render={<InlineButton tone="muted" />}
3637 >
3738 {kind
3839 ? version
apps/web/src/components/pullRequest/PullRequestCodeTab.tsx+2-1
......@@ -1071,7 +1071,8 @@ function PullRequestCodeTab({
10711071 {orderedCommits.length > 0 ? (
10721072 <DropdownMenu>
10731073 <DropdownMenuTrigger
1074 className="inline-flex h-6 min-w-0 max-w-64 items-center gap-1 rounded-md bg-accent px-2 text-xs font-medium text-accent-foreground outline-none transition-colors hover:bg-accent/80 focus-visible:ring-2 focus-visible:ring-ring"
1074 render={<Button size="xs" variant="secondary" />}
1075 className="min-w-0 max-w-64"
10751076 aria-label={`Diff scope: ${scopeLabel}`}
10761077 >
10771078 <span className="truncate">{scopeLabel}</span>
apps/web/src/components/settings/SettingsBreadcrumb.tsx+3-5
......@@ -2,11 +2,11 @@ import { resolveEnvironmentMachineKind } from "@t3tools/contracts";
22import { LayersIcon } from "lucide-react";
33import type { ReactNode } from "react";
44
5import { cn } from "../../lib/utils";
65import type { SidebarProjectSnapshot } from "../../sidebarProjectGrouping";
76import type { EnvironmentPresentation } from "../../state/environments";
87import { EnvironmentMachineIcon } from "../EnvironmentMachineIcon";
98import { ProjectFavicon } from "../ProjectFavicon";
9import { InlineButton } from "../ui/button";
1010import {
1111 Menu,
1212 MenuPopup,
......@@ -111,10 +111,8 @@ function ScopeMenu({
111111 <Menu>
112112 <MenuTrigger
113113 aria-label={ariaLabel}
114 className={cn(
115 "inline-flex min-w-0 max-w-56 cursor-pointer items-center gap-1.5 rounded-sm text-left transition-colors focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring",
116 narrowed ? "text-foreground" : "text-muted-foreground hover:text-foreground",
117 )}
114 render={<InlineButton tone={narrowed ? "default" : "muted"} />}
115 className="min-w-0 max-w-56 gap-1.5"
118116 >
119117 {icon}
120118 <span className="min-w-0 truncate">{label}</span>
apps/web/src/components/usage/UsagePage.refresh.test.tsx+1-1
......@@ -47,7 +47,7 @@ vi.mock("./usagePagePreferences", () => ({
4747 readUsagePagePreferences: () => ({ metric: state.metric, windowDays: 30 }),
4848 saveUsagePagePreferences: vi.fn(),
4949}));
50vi.mock("../ui/button", () => ({ Button: "button" }));
50vi.mock("../ui/button", () => ({ Button: "button", InlineButton: "button" }));
5151vi.mock("../ui/scroll-area", () => ({ ScrollArea: "div" }));
5252vi.mock("../ui/select", () => ({
5353 Select: "select",
apps/web/src/components/usage/UsagePage.test.tsx+1-1
......@@ -40,7 +40,7 @@ vi.mock("react", async (importOriginal) => {
4040
4141vi.mock("../../env", () => ({ isElectron: false }));
4242vi.mock("../../state/usage", () => ({ useUsage: testState.useUsage }));
43vi.mock("../ui/button", () => ({ Button: "button" }));
43vi.mock("../ui/button", () => ({ Button: "button", InlineButton: "button" }));
4444vi.mock("../ui/scroll-area", () => ({ ScrollArea: "div" }));
4545vi.mock("../ui/select", () => ({
4646 Select: "div",
apps/web/src/components/usage/UsagePage.tsx+5-2
......@@ -39,7 +39,7 @@ import {
3939 formatUsd,
4040 makeWindow,
4141} from "@t3tools/shared/usageFormat";
42import { Button } from "../ui/button";
42import { Button, InlineButton } from "../ui/button";
4343import {
4444 Menu,
4545 MenuCheckboxItem,
......@@ -737,7 +737,10 @@ function UsageEnvironmentFilter({
737737 return (
738738 <>
739739 <Menu>
740 <MenuTrigger className="group/usage-environment inline-flex min-w-0 max-w-full cursor-pointer items-center gap-1 rounded-sm text-left focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-ring">
740 <MenuTrigger
741 render={<InlineButton />}
742 className="group/usage-environment min-w-0 max-w-full gap-1"
743 >
741744 <span className="min-w-0 truncate">{label}</span>
742745 <span className="flex size-3.5 shrink-0 items-center justify-center text-muted-foreground">
743746 {showUsageStatus && pendingCount > 0 ? (
scripts/lint-restyle-ceiling.ts+1-1
......@@ -8,7 +8,7 @@ import * as NodeURL from "node:url";
88// components/ui exports are migrated to variants (see vite.config.ts). This gate keeps the
99// count from growing: CI fails when findings exceed the ceiling. Lower the ceiling when you
1010// migrate a file, and delete this script when the rule becomes an error.
11export const RESTYLE_CEILING = 717;
11export const RESTYLE_CEILING = 668;
1212
1313const RULE = "shadcn(no-restyle)";
1414