Skip to content

Commit 603f585

Browse files
fix(web): MCP app permission prompts no longer overflow the screen
The confirm dialog behind MCP App permission requests rendered the full tool arguments as its description with nothing bounding its height, so a large payload (say, an Excalidraw document) grew the dialog past the viewport and left Cancel/Confirm off screen. The alert dialog description now wraps anywhere and scrolls within a capped region, the header can shrink inside the height-capped popup, and the title stays put — so the actions are always reachable and the whole payload stays inspectable. Covers web and desktop; mobile uses the OS alert, which already scrolls its message and pins its actions. restful-walrus-ultra via Muse Code in T3 Code
1 parent c73b454 commit 603f585

2 files changed

Lines changed: 50 additions & 3 deletions

File tree

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { renderToStaticMarkup } from "react-dom/server";
2+
import { describe, expect, it } from "vite-plus/test";
3+
4+
import {
5+
AlertDialog,
6+
AlertDialogDescription,
7+
AlertDialogFooter,
8+
AlertDialogHeader,
9+
AlertDialogTitle,
10+
} from "./alert-dialog";
11+
12+
describe("alert dialog description", () => {
13+
it("keeps a long payload in a bounded scroll region so the actions stay put", () => {
14+
const payload = `{elements:[${"x".repeat(4_000)}]}`;
15+
const markup = renderToStaticMarkup(
16+
<AlertDialog>
17+
<AlertDialogHeader>
18+
<AlertDialogTitle>Allow excalidraw to run export_to_excalidraw?</AlertDialogTitle>
19+
<AlertDialogDescription>{payload}</AlertDialogDescription>
20+
</AlertDialogHeader>
21+
<AlertDialogFooter>Cancel</AlertDialogFooter>
22+
</AlertDialog>,
23+
);
24+
const header = /<div[^>]*data-slot="alert-dialog-header"[^>]*>/.exec(markup)?.[0] ?? "";
25+
const description = /<p[^>]*data-slot="alert-dialog-description"[^>]*>/.exec(markup)?.[0] ?? "";
26+
27+
// The whole payload stays available to inspect, untruncated…
28+
expect(markup).toContain(payload);
29+
// …but bounded: the header may shrink inside the height-capped popup and
30+
// the description scrolls instead of pushing the footer off screen.
31+
expect(header).toContain("min-h-0");
32+
expect(description).toContain("max-h-[min(24rem,60dvh)]");
33+
expect(description).toContain("overflow-y-auto");
34+
expect(description).toContain("overscroll-contain");
35+
expect(description).toContain("wrap-anywhere");
36+
expect(markup.indexOf("</p>")).toBeLessThan(markup.indexOf("Cancel"));
37+
});
38+
});

‎apps/web/src/components/ui/alert-dialog.tsx‎

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,10 @@ function AlertDialogPopup({
7070
function AlertDialogHeader({ className, ...props }: React.ComponentProps<"div">) {
7171
return (
7272
<div
73-
className={cn("flex flex-col gap-2 p-6 text-center max-sm:pb-4 sm:text-left", className)}
73+
className={cn(
74+
"flex min-h-0 flex-col gap-2 p-6 text-center max-sm:pb-4 sm:text-left",
75+
className,
76+
)}
7477
data-slot="alert-dialog-header"
7578
{...props}
7679
/>
@@ -101,7 +104,7 @@ function AlertDialogFooter({
101104
function AlertDialogTitle({ className, ...props }: AlertDialogPrimitive.Title.Props) {
102105
return (
103106
<AlertDialogPrimitive.Title
104-
className={cn("wrap-anywhere font-semibold text-xl leading-none", className)}
107+
className={cn("wrap-anywhere shrink-0 font-semibold text-xl leading-none", className)}
105108
data-slot="alert-dialog-title"
106109
{...props}
107110
/>
@@ -111,7 +114,13 @@ function AlertDialogTitle({ className, ...props }: AlertDialogPrimitive.Title.Pr
111114
function AlertDialogDescription({ className, ...props }: AlertDialogPrimitive.Description.Props) {
112115
return (
113116
<AlertDialogPrimitive.Description
114-
className={cn("text-muted-foreground text-sm", className)}
117+
className={cn(
118+
// A long description (say, the arguments of a tool call awaiting
119+
// approval) scrolls in place instead of pushing the actions out of
120+
// the popup, which the viewport already caps.
121+
"wrap-anywhere max-h-[min(24rem,60dvh)] min-h-0 overflow-y-auto overscroll-contain text-muted-foreground text-sm select-text",
122+
className,
123+
)}
115124
data-slot="alert-dialog-description"
116125
{...props}
117126
/>

0 commit comments

Comments
 (0)