From fd75477ad093caeec810189da57529f9a918c92f Mon Sep 17 00:00:00 2001 From: Yun Long Date: Mon, 13 Jul 2026 16:46:37 +0800 Subject: [PATCH] fix(ui): Misrepresentation of Dropdown list in floating profile --- .../AgentDetailPane/AgentDetailPane.tsx | 1 + web/app/src/shared/styles/globals.css | 7 +++ .../tests/components/AgentActions.test.tsx | 55 ++++++++++++++++++- web/app/tests/shared/appScale.test.ts | 3 + 4 files changed, 65 insertions(+), 1 deletion(-) diff --git a/web/app/src/pages/AgentPage/components/AgentDetailPane/AgentDetailPane.tsx b/web/app/src/pages/AgentPage/components/AgentDetailPane/AgentDetailPane.tsx index b5df5944..818db9a5 100644 --- a/web/app/src/pages/AgentPage/components/AgentDetailPane/AgentDetailPane.tsx +++ b/web/app/src/pages/AgentPage/components/AgentDetailPane/AgentDetailPane.tsx @@ -1195,6 +1195,7 @@ function AgentModelPanel({ }); }} triggerProps={{ "aria-label": t("profileModelProvider"), "aria-required": true }} + contentProps={{ side: "bottom", align: "start", avoidCollisions: false }} options={[ { value: "", label: modelBusy ? t("profileLoadingModels") : t("profileProviderSelect") }, ...providerOptions.map((option) => ({ diff --git a/web/app/src/shared/styles/globals.css b/web/app/src/shared/styles/globals.css index cda64e16..8a320e87 100644 --- a/web/app/src/shared/styles/globals.css +++ b/web/app/src/shared/styles/globals.css @@ -10,11 +10,13 @@ } :root { + --app-ui-floating-layer-scale: 1; --app-ui-viewport-height: 100dvh; } @supports (zoom: 80%) { :root { + --app-ui-floating-layer-scale: 125%; --app-ui-viewport-height: 125dvh; --text-xs-size: 13px; --text-sm-size: 15px; @@ -32,6 +34,11 @@ } } +/* Radix positions poppers in visual viewport coordinates, so cancel the root zoom on its positioning wrapper. */ +[data-radix-popper-content-wrapper] { + zoom: var(--app-ui-floating-layer-scale); +} + html, body, #root { diff --git a/web/app/tests/components/AgentActions.test.tsx b/web/app/tests/components/AgentActions.test.tsx index 17a74682..344d34f5 100644 --- a/web/app/tests/components/AgentActions.test.tsx +++ b/web/app/tests/components/AgentActions.test.tsx @@ -56,6 +56,7 @@ const labels: Record = { profileAdvanced: "Advanced", profileFastMode: "Fast mode", profileModel: "Model", + profileModelProvider: "Model provider", profileModelSection: "Model", profileProvider: "Provider", profileReasoning: "Reasoning", @@ -273,6 +274,58 @@ describe("agent action visibility", () => { expect(screen.getByRole("button", { name: "Edit name" })).toHaveTextContent("测试工程师"); }); + it("keeps the provider dropdown below its trigger", async () => { + const user = userEvent.setup(); + const draft = { + ...agentToDraft(worker), + model_provider_id: "codex", + model_id: "gpt-test", + }; + + render( + , + ); + + await user.click(screen.getByRole("combobox", { name: "Model provider" })); + + expect(screen.getByRole("listbox")).toHaveAttribute("data-side", "bottom"); + }); + it("renders the builtin manager name as fixed text in edit mode", () => { const manager = { ...worker, @@ -800,7 +853,7 @@ describe("agent action visibility", () => { const navigation = screen.getByRole("navigation", { name: "Profile sections" }); expect(within(navigation).getByRole("button", { name: "Profile" })).toHaveAttribute("aria-current", "location"); - expect(screen.getByText("Provider")).toBeInTheDocument(); + expect(screen.getByText("Model provider")).toBeInTheDocument(); expect(screen.queryByDisplayValue("reply in Chinese")).not.toBeInTheDocument(); await user.click(within(navigation).getByRole("button", { name: "Instructions" })); diff --git a/web/app/tests/shared/appScale.test.ts b/web/app/tests/shared/appScale.test.ts index 5053e30a..5677f5ed 100644 --- a/web/app/tests/shared/appScale.test.ts +++ b/web/app/tests/shared/appScale.test.ts @@ -13,12 +13,15 @@ describe("default app scale", () => { const settings = readSource("src/pages/SettingsPage/SettingsPage.module.css"); expect(globals).toContain("@supports (zoom: 80%)"); + expect(globals).toContain("--app-ui-floating-layer-scale: 125%;"); expect(globals).toContain("--app-ui-viewport-height: 125dvh;"); expect(globals).toContain("--text-xs-size: 13px;"); expect(globals).toContain("--text-sm-size: 15px;"); expect(globals).toContain("--text-md-size: 17px;"); expect(globals).toContain("font-size-adjust: 0.65;"); expect(globals).toContain("zoom: 80%;"); + expect(globals).toContain("[data-radix-popper-content-wrapper]"); + expect(globals).toContain("zoom: var(--app-ui-floating-layer-scale);"); expect(globals).toContain("font-size: var(--text-md-size);"); expect(globals).toContain("font-family: var(--font-sans);"); expect(workspace).toContain("height: var(--app-ui-viewport-height);");