fix(combo-box): clear button supports "Space" key

This commit is contained in:
Eric Liu 2025-06-07 12:31:01 -07:00
commit 855bd9a6e1
3 changed files with 36 additions and 14 deletions

View file

@ -75,7 +75,7 @@
} }
}} }}
on:keydown|stopPropagation={(e) => { on:keydown|stopPropagation={(e) => {
if (!disabled && e.key === "Enter") { if (!disabled && (e.key === "Enter" || e.key === " ")) {
dispatch("clear", e); dispatch("clear", e);
} }
}} }}
@ -103,7 +103,7 @@
} }
}} }}
on:keydown|stopPropagation={(e) => { on:keydown|stopPropagation={(e) => {
if (!disabled && e.key === "Enter") { if (!disabled && (e.key === "Enter" || e.key === " ")) {
dispatch("clear", e); dispatch("clear", e);
} }
}} }}

View file

@ -52,5 +52,7 @@
}} }}
on:clear={(e) => { on:clear={(e) => {
console.log("clear", e.type); console.log("clear", e.type);
value = "";
selectedId = undefined;
}} }}
/> />

View file

@ -4,6 +4,9 @@ import ComboBox from "./ComboBox.test.svelte";
import ComboBoxCustom from "./ComboBoxCustom.test.svelte"; import ComboBoxCustom from "./ComboBoxCustom.test.svelte";
describe("ComboBox", () => { describe("ComboBox", () => {
const getClearButton = () =>
screen.getByRole("button", { name: "Clear selected item" });
beforeEach(() => { beforeEach(() => {
vi.clearAllMocks(); vi.clearAllMocks();
}); });
@ -60,16 +63,13 @@ describe("ComboBox", () => {
}, },
}); });
const clearButton = screen.getByRole("button", { await user.click(getClearButton());
name: "Clear selected item",
});
await user.click(clearButton);
expect(consoleLog).toHaveBeenCalledWith("clear", expect.any(String)); expect(consoleLog).toHaveBeenCalledWith("clear", expect.any(String));
expect(screen.getByRole("textbox")).toHaveValue(""); 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"); const consoleLog = vi.spyOn(console, "log");
render(ComboBox, { render(ComboBox, {
props: { props: {
@ -78,9 +78,10 @@ describe("ComboBox", () => {
}, },
}); });
const clearButton = screen.getByRole("button", { expect(consoleLog).not.toHaveBeenCalled();
name: /clear/i, expect(screen.getByRole("textbox")).toHaveValue("Email");
});
const clearButton = getClearButton();
clearButton.focus(); clearButton.focus();
expect(clearButton).toHaveFocus(); expect(clearButton).toHaveFocus();
await user.keyboard("{Enter}"); await user.keyboard("{Enter}");
@ -89,6 +90,27 @@ describe("ComboBox", () => {
expect(screen.getByRole("textbox")).toHaveValue(""); 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", () => { it("should use custom translations when translateWithId is provided", () => {
const customTranslations = { const customTranslations = {
clearSelection: "Remove selected item", clearSelection: "Remove selected item",
@ -205,8 +227,7 @@ describe("ComboBox", () => {
render(ComboBox, { props: { selectedId: "1" } }); render(ComboBox, { props: { selectedId: "1" } });
expect(consoleLog).not.toBeCalled(); expect(consoleLog).not.toBeCalled();
const clearButton = screen.getByRole("button", { name: /clear/i }); await user.click(getClearButton());
await user.click(clearButton);
expect(screen.getByRole("textbox")).toHaveValue(""); expect(screen.getByRole("textbox")).toHaveValue("");
expect(consoleLog).toHaveBeenCalledWith("clear", "clear"); expect(consoleLog).toHaveBeenCalledWith("clear", "clear");
@ -250,8 +271,7 @@ describe("ComboBox", () => {
it("should clear filter on selection clear", async () => { it("should clear filter on selection clear", async () => {
render(ComboBoxCustom, { props: { selectedId: "1" } }); render(ComboBoxCustom, { props: { selectedId: "1" } });
const clearButton = screen.getByLabelText("Clear selected item"); await user.click(getClearButton());
await user.click(clearButton);
const input = screen.getByRole("textbox"); const input = screen.getByRole("textbox");
expect(input).toHaveValue(""); expect(input).toHaveValue("");