diff --git a/packages/calcite-components/src/components/chip/chip.e2e.ts b/packages/calcite-components/src/components/chip/chip.e2e.ts index f1bf25254b7..84344bda1b9 100644 --- a/packages/calcite-components/src/components/chip/chip.e2e.ts +++ b/packages/calcite-components/src/components/chip/chip.e2e.ts @@ -67,19 +67,6 @@ describe("calcite-chip", () => { expect(eventSpy).toHaveReceivedEvent(); }); - it("should emit event after the close button is clicked", async () => { - const page = await newE2EPage(); - await page.setContent(`cheetos`); - - const eventSpy = await page.spyOnEvent("calciteChipClose", "window"); - - const closeButton = await page.find(`calcite-chip >>> .${CSS.close}`); - - await closeButton.click(); - - expect(eventSpy).toHaveReceivedEvent(); - }); - it("should receive focus when clicked", async () => { const page = await newE2EPage(); await page.setContent(`cheetos`); @@ -98,6 +85,9 @@ describe("calcite-chip", () => { expect(element).toEqualAttribute("appearance", "solid"); expect(element).toEqualAttribute("kind", "neutral"); expect(element).toEqualAttribute("scale", "m"); + + const close = await page.find(`calcite-chip >>> .${CSS.close}`); + expect(close).toBeNull(); }); it("renders requested props when valid props are provided", async () => { @@ -120,20 +110,45 @@ describe("calcite-chip", () => { expect(element).toEqualAttribute("scale", "l"); }); - it("renders a close button when requested", async () => { - const page = await newE2EPage(); - await page.setContent(`Chip content`); + describe("closing", () => { + it("via mouse", async () => { + const page = await newE2EPage(); + await page.setContent(`cheetos`); + const chip = await page.find("calcite-chip"); + const eventSpy = await chip.spyOnEvent("calciteChipClose"); - const close = await page.find("calcite-chip >>> button.close"); - expect(close).not.toBeNull(); - }); + await page.click(`calcite-chip >>> .${CSS.close}`); + expect(eventSpy).toHaveReceivedEventTimes(1); - it("does not render a close button when not requested", async () => { - const page = await newE2EPage(); - await page.setContent(`Chip content`); + await chip.callMethod("setFocus"); + await chip.press("Delete"); + expect(eventSpy).toHaveReceivedEventTimes(1); - const close = await page.find("calcite-chip >>> button.close"); - expect(close).toBeNull(); + await chip.setProperty("closed", false); + await page.waitForChanges(); + + await chip.callMethod("setFocus"); + await chip.press("Backspace"); + expect(eventSpy).toHaveReceivedEventTimes(1); + }); + + it("can be closed via keyboard", async () => { + const page = await newE2EPage(); + await page.setContent(`cheetos`); + const chip = await page.find("calcite-chip"); + const eventSpy = await chip.spyOnEvent("calciteChipClose"); + + await chip.callMethod("setFocus"); + await chip.press("Delete"); + expect(eventSpy).toHaveReceivedEventTimes(1); + + await chip.setProperty("closed", false); + await page.waitForChanges(); + + await chip.callMethod("setFocus"); + await chip.press("Backspace"); + expect(eventSpy).toHaveReceivedEventTimes(2); + }); }); describe("CSS properties for light/dark mode", () => { diff --git a/packages/calcite-components/src/components/chip/chip.tsx b/packages/calcite-components/src/components/chip/chip.tsx index de84a0580ef..1d90e0c3749 100644 --- a/packages/calcite-components/src/components/chip/chip.tsx +++ b/packages/calcite-components/src/components/chip/chip.tsx @@ -71,6 +71,9 @@ export class Chip extends LitElement implements InteractiveComponent, LoadableCo /** When `true`, hides the component. */ @property({ reflect: true }) closed = false; + /** When `true`, the component closes when the Delete or Backspace key is pressed while focused. */ + @property({ reflect: true }) closeOnDelete = false; + /** When `true`, interaction is prevented and the component is displayed with lower opacity. */ @property({ reflect: true }) disabled = false; @@ -222,6 +225,13 @@ export class Chip extends LitElement implements InteractiveComponent, LoadableCo this.handleEmittingEvent(); event.preventDefault(); break; + case "Backspace": + case "Delete": + if (this.closable && !this.closed && this.closeOnDelete) { + event.preventDefault(); + this.close(); + } + break; case "ArrowRight": case "ArrowLeft": case "Home":