diff --git a/tests/e2e/ui/tests/modelsPage/autoRouterTemplateSelect.spec.ts b/tests/e2e/ui/tests/modelsPage/autoRouterTemplateSelect.spec.ts
new file mode 100644
index 00000000000..98bd1b84f11
--- /dev/null
+++ b/tests/e2e/ui/tests/modelsPage/autoRouterTemplateSelect.spec.ts
@@ -0,0 +1,59 @@
+import { expect, test, type Page as PlaywrightPage } from "@playwright/test";
+import { ADMIN_STORAGE_PATH } from "../../constants";
+import { navigateToPage } from "../../helpers/navigation";
+import { Page } from "../../fixtures/pages";
+
+/**
+ * Opens Add Auto Router and returns the Template select's trigger, which is the
+ * shallowest real page that renders SelectContent with tall multi-line options.
+ */
+async function openTemplateSelect(page: PlaywrightPage) {
+ await navigateToPage(page, Page.Models);
+ await page.getByRole("tab", { name: "Auto-Routers" }).click();
+ await page.getByRole("button", { name: "Add Auto Router" }).click();
+
+ const trigger = page.getByTestId("template-selector");
+ await expect(trigger).toBeVisible();
+ return trigger;
+}
+
+test.describe("Auto Router template select anchoring", () => {
+ test.use({ storageState: ADMIN_STORAGE_PATH });
+
+ test("opens the options below the trigger rather than over it", async ({ page }) => {
+ await page.setViewportSize({ width: 1280, height: 900 });
+ const trigger = await openTemplateSelect(page);
+ const triggerBox = await trigger.boundingBox();
+
+ await trigger.click();
+ const popup = page.locator('[data-slot="select-content"]');
+ await expect(popup).toBeVisible();
+ const popupBox = await popup.boundingBox();
+
+ expect(triggerBox).not.toBeNull();
+ expect(popupBox).not.toBeNull();
+
+ // Item-aligned mode reports "none" and puts the active item over the trigger.
+ await expect(popup).toHaveAttribute("data-side", "bottom");
+ expect(popupBox!.y).toBeGreaterThanOrEqual(triggerBox!.y + triggerBox!.height);
+ });
+
+ test("flips above the trigger instead of covering it when there is no room below", async ({ page }) => {
+ await page.setViewportSize({ width: 1280, height: 560 });
+ const trigger = await openTemplateSelect(page);
+ await trigger.scrollIntoViewIfNeeded();
+ const triggerBox = await trigger.boundingBox();
+
+ await trigger.click();
+ const popup = page.locator('[data-slot="select-content"]');
+ await expect(popup).toBeVisible();
+ const popupBox = await popup.boundingBox();
+
+ expect(triggerBox).not.toBeNull();
+ expect(popupBox).not.toBeNull();
+
+ const overlaps =
+ popupBox!.y < triggerBox!.y + triggerBox!.height && popupBox!.y + popupBox!.height > triggerBox!.y;
+ expect(overlaps).toBe(false);
+ });
+});
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/TeamGuardrailsTab.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/TeamGuardrailsTab.tsx
index c9de758f50d..e309e8130f1 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/TeamGuardrailsTab.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/TeamGuardrailsTab.tsx
@@ -1106,7 +1106,7 @@ export function TeamGuardrailsTab({ accessToken }: TeamGuardrailsTabProps) {
>
-
+
{GUARDRAIL_MODES.map((mode) => (
{mode.label}
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/content_filter/CategoryTable.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/content_filter/CategoryTable.tsx
index fa40ce6ab54..f012923d32f 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/content_filter/CategoryTable.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/content_filter/CategoryTable.tsx
@@ -64,7 +64,7 @@ const CategoryTable: React.FC = ({
-
+
{SEVERITY_ITEMS.map((item) => (
{item.label}
@@ -93,7 +93,7 @@ const CategoryTable: React.FC = ({
-
+
{ACTION_ITEMS.map((item) => (
{item.label}
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/content_filter/CompetitorIntentConfiguration.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/content_filter/CompetitorIntentConfiguration.tsx
index d77dd216c2a..aa9b6798fff 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/content_filter/CompetitorIntentConfiguration.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/content_filter/CompetitorIntentConfiguration.tsx
@@ -194,7 +194,7 @@ const CompetitorIntentConfiguration: React.FC
-
+
{INTENT_TYPES.map((type) => (
{type.label}
@@ -268,7 +268,7 @@ const CompetitorIntentConfiguration: React.FC
-
+
{COMPETITOR_COMPARISON_POLICIES.map((policy) => (
{policy.label}
@@ -292,7 +292,7 @@ const CompetitorIntentConfiguration: React.FC
-
+
{POSSIBLE_COMPETITOR_COMPARISON_POLICIES.map((policy) => (
{policy.label}
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/content_filter/ContentCategoryConfiguration.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/content_filter/ContentCategoryConfiguration.tsx
index 1924133a6cc..f2226a3bc6e 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/content_filter/ContentCategoryConfiguration.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/content_filter/ContentCategoryConfiguration.tsx
@@ -199,7 +199,7 @@ const ContentCategoryConfiguration: React.FC
-
+
{ACTION_ITEMS.map((item) => (
{item.value}
@@ -224,7 +224,7 @@ const ContentCategoryConfiguration: React.FC
-
+
{SEVERITY_ITEMS.map((item) => (
{item.label}
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/content_filter/CustomPatternModal.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/content_filter/CustomPatternModal.tsx
index 64441c90e5a..9813169e85e 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/content_filter/CustomPatternModal.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/content_filter/CustomPatternModal.tsx
@@ -71,7 +71,7 @@ const CustomPatternModal: React.FC = ({
-
+
{ACTION_ITEMS.map((item) => (
{item.label}
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/content_filter/KeywordModal.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/content_filter/KeywordModal.tsx
index 177c0d2fac6..393a508cd18 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/content_filter/KeywordModal.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/content_filter/KeywordModal.tsx
@@ -61,7 +61,7 @@ const KeywordModal: React.FC = ({
-
+
{ACTION_ITEMS.map((item) => (
{item.label}
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/content_filter/KeywordTable.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/content_filter/KeywordTable.tsx
index 5c7e3ef3ab8..5b69b04955f 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/content_filter/KeywordTable.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/content_filter/KeywordTable.tsx
@@ -38,7 +38,7 @@ const KeywordTable: React.FC = ({ keywords, onActionChange, o
-
+
{ACTION_ITEMS.map((item) => (
{item.label}
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/content_filter/PatternModal.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/content_filter/PatternModal.tsx
index e703711a03a..fd353f7d743 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/content_filter/PatternModal.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/content_filter/PatternModal.tsx
@@ -115,7 +115,7 @@ const PatternModal: React.FC = ({
-
+
{ACTION_ITEMS.map((item) => (
{item.label}
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/content_filter/PatternTable.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/content_filter/PatternTable.tsx
index 6dd266f07a0..f4e87119d7b 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/content_filter/PatternTable.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/content_filter/PatternTable.tsx
@@ -58,7 +58,7 @@ const PatternTable: React.FC = ({ patterns, onActionChange, o
-
+
{ACTION_ITEMS.map((item) => (
{item.label}
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/custom_code/CustomCodeModal.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/custom_code/CustomCodeModal.tsx
index 77bac8bb0aa..a69824f32d3 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/custom_code/CustomCodeModal.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/custom_code/CustomCodeModal.tsx
@@ -556,7 +556,7 @@ const CustomCodeModal: React.FC = ({ visible, onClose, onS
-
+
STANDARD
{TEMPLATE_ITEMS.map((template) => (
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/pii_components.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/pii_components.tsx
index 5f8e833af8d..0de7eb1c9ce 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/pii_components.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/pii_components.tsx
@@ -179,7 +179,7 @@ export const PiiEntityList: React.FC = ({
-
+
{actions.map((action) => (
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/tool_permission/ToolPermissionRulesEditor.tsx b/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/tool_permission/ToolPermissionRulesEditor.tsx
index 8fe2bf5bf21..c154d102314 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/tool_permission/ToolPermissionRulesEditor.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/guardrails/_components/tool_permission/ToolPermissionRulesEditor.tsx
@@ -280,7 +280,7 @@ const ToolPermissionRulesEditor: React.FC = ({ v
-
+
{DECISION_ITEMS.map((item) => (
{item.label}
@@ -313,7 +313,7 @@ const ToolPermissionRulesEditor: React.FC = ({ v
-
+
{DECISION_ITEMS.map((item) => (
{item.label}
@@ -350,7 +350,7 @@ const ToolPermissionRulesEditor: React.FC = ({ v
-
+
{ON_DISALLOWED_ITEMS.map((item) => (
{item.label}
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/vector-stores/_components/CreateVectorStore.tsx b/ui/litellm-dashboard/src/app/(dashboard)/vector-stores/_components/CreateVectorStore.tsx
index eae4a3fd799..61d31c2d3d4 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/vector-stores/_components/CreateVectorStore.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/vector-stores/_components/CreateVectorStore.tsx
@@ -342,7 +342,7 @@ const CreateVectorStore: React.FC = ({ accessToken, onSu
-
+
{providerItems.map((item) => (
diff --git a/ui/litellm-dashboard/src/app/(dashboard)/vector-stores/_components/VectorStoreForm.tsx b/ui/litellm-dashboard/src/app/(dashboard)/vector-stores/_components/VectorStoreForm.tsx
index 0c7d8cebb4b..6e2701be51b 100644
--- a/ui/litellm-dashboard/src/app/(dashboard)/vector-stores/_components/VectorStoreForm.tsx
+++ b/ui/litellm-dashboard/src/app/(dashboard)/vector-stores/_components/VectorStoreForm.tsx
@@ -298,7 +298,7 @@ const VectorStoreForm: React.FC = ({
}}
-
+
{Object.entries(VectorStoreProviders).map(([providerEnum, providerDisplayName]) => (
= ({
}}
-
+
{Object.entries(Providers)
.filter(([providerEnum]) => providerEnum === "Bedrock")
.map(([providerEnum, providerDisplayName]) => (
diff --git a/ui/litellm-dashboard/src/components/ui/select.test.tsx b/ui/litellm-dashboard/src/components/ui/select.test.tsx
index 15dd266d38c..308b5ecec3b 100644
--- a/ui/litellm-dashboard/src/components/ui/select.test.tsx
+++ b/ui/litellm-dashboard/src/components/ui/select.test.tsx
@@ -1,5 +1,6 @@
import { describe, expect, it } from "vitest";
import { render, screen } from "@testing-library/react";
+import userEvent from "@testing-library/user-event";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
const ENVIRONMENTS = [
@@ -63,3 +64,40 @@ describe("SelectValue label resolution", () => {
expect(screen.getByTestId("trigger")).toHaveTextContent("Any environment");
});
});
+
+function renderOpenableSelect(contentProps?: React.ComponentProps) {
+ return render(
+ ,
+ );
+}
+
+describe("SelectContent anchoring", () => {
+ it("anchors to the edge of the trigger rather than over it by default", async () => {
+ const user = userEvent.setup();
+ renderOpenableSelect();
+
+ await user.click(screen.getByTestId("trigger"));
+
+ expect(await screen.findByTestId("content")).toHaveAttribute("data-align-trigger", "false");
+ });
+
+ it("still lets a caller opt into item-aligned anchoring", async () => {
+ const user = userEvent.setup();
+ renderOpenableSelect({ alignItemWithTrigger: true });
+
+ await user.click(screen.getByTestId("trigger"));
+
+ expect(await screen.findByTestId("content")).toHaveAttribute("data-align-trigger", "true");
+ });
+});
diff --git a/ui/litellm-dashboard/src/components/ui/select.tsx b/ui/litellm-dashboard/src/components/ui/select.tsx
index 7d009b53084..bca68fee9df 100644
--- a/ui/litellm-dashboard/src/components/ui/select.tsx
+++ b/ui/litellm-dashboard/src/components/ui/select.tsx
@@ -49,7 +49,7 @@ function SelectContent({
sideOffset = 4,
align = "center",
alignOffset = 0,
- alignItemWithTrigger = true,
+ alignItemWithTrigger = false,
...props
}: SelectPrimitive.Popup.Props &
Pick) {