From c94d692864fb579272ece02f070602896b075a29 Mon Sep 17 00:00:00 2001 From: yuneng-jiang Date: Tue, 18 Aug 2026 20:31:23 -0700 Subject: [PATCH] fix(ui): highlight the first member search match so Enter picks it (#37429) * fix(ui): highlight the first member search match so Enter picks it Moving the modal off antd Form swapped antd Select for Base UI Combobox, which highlights nothing until an arrow key moves the cursor. Typing an email and pressing Enter therefore selected no one, and the form submitted anyway, so /team/member_add went out with member.user_email undefined. autoHighlight="always" restores the behaviour antd had. The Enter key still does not submit the form, which the existing test continues to cover. * fix(ui): keep the always-highlight prop past the type check Combobox.Root re-declares autoHighlight as boolean while the AriaCombobox it wraps types it as boolean | "always". Only "always" highlights a list this component filters server-side, since the plain flag highlights on Base UI's own filtering pass, which filter={null} turns off. Verified with next build, the same type check that failed in CI. --- .../user_search_modal.test.tsx | 20 +++++++++++++++++++ .../common_components/user_search_modal.tsx | 3 +++ 2 files changed, 23 insertions(+) diff --git a/ui/litellm-dashboard/src/components/common_components/user_search_modal.test.tsx b/ui/litellm-dashboard/src/components/common_components/user_search_modal.test.tsx index d17948b599e..cbaf00b7131 100644 --- a/ui/litellm-dashboard/src/components/common_components/user_search_modal.test.tsx +++ b/ui/litellm-dashboard/src/components/common_components/user_search_modal.test.tsx @@ -161,6 +161,26 @@ describe("UserSearchModal submit payload", () => { }); }); + it("commits the first match when the typed search is confirmed with Enter", async () => { + const { user, onSubmit } = setup(); + + const input = getEmailSearchInput(); + await user.click(input); + await user.type(input, "pick"); + await waitFor(() => expect(userFilterUICall).toHaveBeenCalled(), { timeout: 3000 }); + await screen.findByRole("option", { name: "picked@example.com" }); + + await user.keyboard("{Enter}"); + await user.click(save()); + + await waitFor(() => expect(onSubmit).toHaveBeenCalledTimes(1)); + expect(onSubmit.mock.calls[0][0]).toStrictEqual({ + user_email: "picked@example.com", + user_id: "u-1", + role: "user", + }); + }); + it("does not submit on Enter in any field, while the button still does", async () => { const { user, onSubmit } = setup(); diff --git a/ui/litellm-dashboard/src/components/common_components/user_search_modal.tsx b/ui/litellm-dashboard/src/components/common_components/user_search_modal.tsx index 801d19244f8..aeead9d82e6 100644 --- a/ui/litellm-dashboard/src/components/common_components/user_search_modal.tsx +++ b/ui/litellm-dashboard/src/components/common_components/user_search_modal.tsx @@ -165,6 +165,9 @@ const UserSearchModal: React.FC = ({ { controlProps.onChange(option?.value);