From 7efe08a2ee22fbfd4ce1c9981855f7f5e4bea286 Mon Sep 17 00:00:00 2001 From: Urvashi Sharma Date: Tue, 5 May 2026 16:42:37 +0530 Subject: [PATCH 1/2] fix: don't reset search on click within input in multiselect --- src/components/MultiSelect/MultiSelect.tsx | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/components/MultiSelect/MultiSelect.tsx b/src/components/MultiSelect/MultiSelect.tsx index cf9535ca..581d8b7d 100644 --- a/src/components/MultiSelect/MultiSelect.tsx +++ b/src/components/MultiSelect/MultiSelect.tsx @@ -254,6 +254,7 @@ export const MultiSelect: React.FC = ({ helpClassName, }: MultiSelectProps) => { const buttonRef = useRef(null); + const searchMouseDownRef = useRef(false); const [isDropdownOpen, setIsDropdownOpen] = useState(false); const [filter, setFilter] = useState(""); @@ -343,7 +344,11 @@ export const MultiSelect: React.FC = ({ className="multi-select" onToggleMenu={(isOpen) => { if (!isOpen) { - resetSearch(); + if (searchMouseDownRef.current) { + searchMouseDownRef.current = false; + } else { + resetSearch(); + } } // Handle syncing the state when toggling the menu from within the // contextual menu component e.g. when clicking outside. @@ -364,6 +369,9 @@ export const MultiSelect: React.FC = ({ aria-label={label || placeholder || "Search"} disabled={disabled} autoComplete="off" + onMouseDown={() => { + if (isDropdownOpen) searchMouseDownRef.current = true; + }} onChange={(value) => { updateFilter(value); // reopen if dropdown has been closed via ESC From 74c9d9235dbe6fbf1ea1800530489ea6f3864d57 Mon Sep 17 00:00:00 2001 From: H Wilkins Date: Wed, 6 May 2026 09:56:39 +1000 Subject: [PATCH 2/2] refactor: simplify preventing clicks from closing the dropdown, add a test --- src/components/MultiSelect/MultiSelect.test.tsx | 10 +++++++++- src/components/MultiSelect/MultiSelect.tsx | 15 +++++++-------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/components/MultiSelect/MultiSelect.test.tsx b/src/components/MultiSelect/MultiSelect.test.tsx index 72a56e73..9c57bfed 100644 --- a/src/components/MultiSelect/MultiSelect.test.tsx +++ b/src/components/MultiSelect/MultiSelect.test.tsx @@ -228,7 +228,7 @@ it("closes the dropdown when clicking outside of the dropdown", async () => { }); it("closes the dropdown when clicking on the button", async () => { - render(); + render(); await userEvent.click(screen.getByRole("combobox")); expect(screen.getByRole("listbox")).toBeInTheDocument(); await userEvent.click(screen.getByRole("combobox")); @@ -353,6 +353,14 @@ it("opens and closes the dropdown on click", async () => { expect(screen.queryByRole("listbox")).not.toBeInTheDocument(); }); +it("doesn't clear the input on click", async () => { + render(); + const input = screen.getByRole("combobox"); + await userEvent.type(input, "hello"); + await userEvent.click(input); + expect(input).toHaveValue("hello"); +}); + it("can render without sorting alphabetically", async () => { const itemsUnsorted = [ { label: "item B", value: 2 }, diff --git a/src/components/MultiSelect/MultiSelect.tsx b/src/components/MultiSelect/MultiSelect.tsx index 581d8b7d..b889291a 100644 --- a/src/components/MultiSelect/MultiSelect.tsx +++ b/src/components/MultiSelect/MultiSelect.tsx @@ -254,7 +254,6 @@ export const MultiSelect: React.FC = ({ helpClassName, }: MultiSelectProps) => { const buttonRef = useRef(null); - const searchMouseDownRef = useRef(false); const [isDropdownOpen, setIsDropdownOpen] = useState(false); const [filter, setFilter] = useState(""); @@ -344,11 +343,7 @@ export const MultiSelect: React.FC = ({ className="multi-select" onToggleMenu={(isOpen) => { if (!isOpen) { - if (searchMouseDownRef.current) { - searchMouseDownRef.current = false; - } else { - resetSearch(); - } + resetSearch(); } // Handle syncing the state when toggling the menu from within the // contextual menu component e.g. when clicking outside. @@ -369,8 +364,12 @@ export const MultiSelect: React.FC = ({ aria-label={label || placeholder || "Search"} disabled={disabled} autoComplete="off" - onMouseDown={() => { - if (isDropdownOpen) searchMouseDownRef.current = true; + onMouseDown={(event) => { + // When displayed as an input, clicking inside the input should not clear + // the text (e.g. if the user wants to edit what they've typed). + if (variant === "search") { + event.stopPropagation(); + } }} onChange={(value) => { updateFilter(value);