From 95c06a83b3afcbb76acfc0a5efe2f178d333ff19 Mon Sep 17 00:00:00 2001 From: Eric Liu Date: Sat, 7 Jun 2025 12:33:59 -0700 Subject: [PATCH] fix(combo-box): clear button supports "Space" key (#2168) Fixes #2166 --- src/ListBox/ListBoxSelection.svelte | 4 +-- tests/ComboBox/ComboBox.test.svelte | 2 ++ tests/ComboBox/ComboBox.test.ts | 44 +++++++++++++++++++++-------- 3 files changed, 36 insertions(+), 14 deletions(-) diff --git a/src/ListBox/ListBoxSelection.svelte b/src/ListBox/ListBoxSelection.svelte index 53074c44..297e2a7f 100644 --- a/src/ListBox/ListBoxSelection.svelte +++ b/src/ListBox/ListBoxSelection.svelte @@ -75,7 +75,7 @@ } }} on:keydown|stopPropagation={(e) => { - if (!disabled && e.key === "Enter") { + if (!disabled && (e.key === "Enter" || e.key === " ")) { dispatch("clear", e); } }} @@ -103,7 +103,7 @@ } }} on:keydown|stopPropagation={(e) => { - if (!disabled && e.key === "Enter") { + if (!disabled && (e.key === "Enter" || e.key === " ")) { dispatch("clear", e); } }} diff --git a/tests/ComboBox/ComboBox.test.svelte b/tests/ComboBox/ComboBox.test.svelte index 198c3e94..4edc6f2a 100644 --- a/tests/ComboBox/ComboBox.test.svelte +++ b/tests/ComboBox/ComboBox.test.svelte @@ -52,5 +52,7 @@ }} on:clear={(e) => { console.log("clear", e.type); + value = ""; + selectedId = undefined; }} /> diff --git a/tests/ComboBox/ComboBox.test.ts b/tests/ComboBox/ComboBox.test.ts index 1bfcea6d..6d55201b 100644 --- a/tests/ComboBox/ComboBox.test.ts +++ b/tests/ComboBox/ComboBox.test.ts @@ -4,6 +4,9 @@ import ComboBox from "./ComboBox.test.svelte"; import ComboBoxCustom from "./ComboBoxCustom.test.svelte"; describe("ComboBox", () => { + const getClearButton = () => + screen.getByRole("button", { name: "Clear selected item" }); + beforeEach(() => { vi.clearAllMocks(); }); @@ -60,16 +63,13 @@ describe("ComboBox", () => { }, }); - const clearButton = screen.getByRole("button", { - name: "Clear selected item", - }); - await user.click(clearButton); + await user.click(getClearButton()); expect(consoleLog).toHaveBeenCalledWith("clear", expect.any(String)); expect(screen.getByRole("textbox")).toHaveValue(""); }); - it("should handle clear selection via keyboard navigation", async () => { + it("should handle clear selection via keyboard navigation (Enter)", async () => { const consoleLog = vi.spyOn(console, "log"); render(ComboBox, { props: { @@ -78,9 +78,10 @@ describe("ComboBox", () => { }, }); - const clearButton = screen.getByRole("button", { - name: /clear/i, - }); + expect(consoleLog).not.toHaveBeenCalled(); + expect(screen.getByRole("textbox")).toHaveValue("Email"); + + const clearButton = getClearButton(); clearButton.focus(); expect(clearButton).toHaveFocus(); await user.keyboard("{Enter}"); @@ -89,6 +90,27 @@ describe("ComboBox", () => { expect(screen.getByRole("textbox")).toHaveValue(""); }); + it("should handle clear selection via keyboard navigation (Space)", async () => { + const consoleLog = vi.spyOn(console, "log"); + render(ComboBox, { + props: { + selectedId: "1", + value: "Email", + }, + }); + + expect(consoleLog).not.toHaveBeenCalled(); + expect(screen.getByRole("textbox")).toHaveValue("Email"); + + const clearButton = getClearButton(); + clearButton.focus(); + expect(clearButton).toHaveFocus(); + await user.keyboard(" "); + + expect(consoleLog).toHaveBeenCalledWith("clear", expect.any(String)); + expect(screen.getByRole("textbox")).toHaveValue(""); + }); + it("should use custom translations when translateWithId is provided", () => { const customTranslations = { clearSelection: "Remove selected item", @@ -205,8 +227,7 @@ describe("ComboBox", () => { render(ComboBox, { props: { selectedId: "1" } }); expect(consoleLog).not.toBeCalled(); - const clearButton = screen.getByRole("button", { name: /clear/i }); - await user.click(clearButton); + await user.click(getClearButton()); expect(screen.getByRole("textbox")).toHaveValue(""); expect(consoleLog).toHaveBeenCalledWith("clear", "clear"); @@ -250,8 +271,7 @@ describe("ComboBox", () => { it("should clear filter on selection clear", async () => { render(ComboBoxCustom, { props: { selectedId: "1" } }); - const clearButton = screen.getByLabelText("Clear selected item"); - await user.click(clearButton); + await user.click(getClearButton()); const input = screen.getByRole("textbox"); expect(input).toHaveValue("");