diff --git a/packages/select/src/components/select/select2.tsx b/packages/select/src/components/select/select2.tsx index eefd0054c1..a72b2da5ce 100644 --- a/packages/select/src/components/select/select2.tsx +++ b/packages/select/src/components/select/select2.tsx @@ -302,8 +302,9 @@ export class Select2 extends AbstractPureComponent2, Select2S const menuItemDismiss = menuItem?.matches(`.${Popover2Classes.POPOVER2_DISMISS}`) || menuItem?.matches(`.${CoreClasses.POPOVER_DISMISS}`); + const shouldDismiss = menuItemDismiss ?? true; - this.setState({ isOpen: !menuItemDismiss ?? false }); + this.setState({ isOpen: !shouldDismiss }); this.props.onItemSelect?.(item, event); }; diff --git a/packages/select/test/select2Tests.tsx b/packages/select/test/select2Tests.tsx index 90eb15e533..01c31beba4 100644 --- a/packages/select/test/select2Tests.tsx +++ b/packages/select/test/select2Tests.tsx @@ -15,11 +15,11 @@ */ import { assert } from "chai"; -import { mount } from "enzyme"; +import { HTMLAttributes, mount, ReactWrapper } from "enzyme"; import * as React from "react"; import * as sinon from "sinon"; -import { InputGroup, Keys, MenuItem } from "@blueprintjs/core"; +import { Button, Classes as CoreClasses, InputGroup, Keys, MenuItem } from "@blueprintjs/core"; import { MenuItem2, Popover2 } from "@blueprintjs/popover2"; import { ItemRendererProps, Select2, Select2Props, Select2State } from "../src"; @@ -105,7 +105,7 @@ describe("", () => { const onOpening = sinon.spy(); const modifiers = {}; // our own instance const wrapper = select({ popoverProps: { onOpening, modifiers } }); - wrapper.find("[data-testid='target-button']").simulate("click"); + findTargetButton(wrapper).simulate("click"); assert.strictEqual(wrapper.find(Popover2).prop("modifiers"), modifiers); assert.isTrue(onOpening.calledOnce); }); @@ -116,7 +116,7 @@ describe("", () => { const wrapper = select({ popoverProps: { usePortal: false } }); // should be closed to start assert.strictEqual(wrapper.find(Popover2).prop("isOpen"), false); - wrapper.find("[data-testid='target-button']").simulate("keydown", { which: Keys.ARROW_DOWN }); + findTargetButton(wrapper).simulate("keydown", { which: Keys.ARROW_DOWN }); // ...then open after key down assert.strictEqual(wrapper.find(Popover2).prop("isOpen"), true); }); @@ -128,6 +128,17 @@ describe("", () => { assert.isTrue(handlers.onItemSelect.calledOnce); }); + it("closes Popover2 after selecting active item with the Enter key", () => { + // override isOpen in defaultProps so that the popover can actually be closed + const wrapper = select({ + popoverProps: { usePortal: true }, + }); + findTargetButton(wrapper).simulate("click"); + wrapper.find("input").simulate("keydown", { keyCode: Keys.ENTER }); + wrapper.find("input").simulate("keyup", { keyCode: Keys.ENTER }); + assert.strictEqual(wrapper.find(Popover2).prop("isOpen"), false); + }); + // N.B. it's not worth refactoring these tests to be DRY since there will soon // only be 1 MenuItem component in Blueprint v5 @@ -141,11 +152,11 @@ describe("", () => { assert.strictEqual(wrapper.find(Popover2).prop("isOpen"), false); // popover should open after clicking the button - wrapper.find("[data-testid='target-button']").simulate("click"); + findTargetButton(wrapper).simulate("click"); assert.strictEqual(wrapper.find(Popover2).prop("isOpen"), true); // and should close after the a menu item is clicked - wrapper.find(Popover2).find(".bp4-menu-item").first().simulate("click"); + wrapper.find(Popover2).find(`.${CoreClasses.MENU_ITEM}`).first().simulate("click"); assert.strictEqual(wrapper.find(Popover2).prop("isOpen"), false); }); @@ -159,11 +170,11 @@ describe("", () => { assert.strictEqual(wrapper.find(Popover2).prop("isOpen"), false); // popover should open after clicking the button - wrapper.find("[data-testid='target-button']").simulate("click"); + findTargetButton(wrapper).simulate("click"); assert.strictEqual(wrapper.find(Popover2).prop("isOpen"), true); // and should not close after the a menu item is clicked - wrapper.find(Popover2).find(".bp4-menu-item").first().simulate("click"); + wrapper.find(Popover2).find(`.${CoreClasses.MENU_ITEM}`).first().simulate("click"); assert.strictEqual(wrapper.find(Popover2).prop("isOpen"), true); }); @@ -177,11 +188,11 @@ describe("", () => { assert.strictEqual(wrapper.find(Popover2).prop("isOpen"), false); // popover should open after clicking the button - wrapper.find("[data-testid='target-button']").simulate("click"); + findTargetButton(wrapper).simulate("click"); assert.strictEqual(wrapper.find(Popover2).prop("isOpen"), true); // and should close after the a menu item is clicked - wrapper.find(Popover2).find(".bp4-menu-item").first().simulate("click"); + wrapper.find(Popover2).find(`.${CoreClasses.MENU_ITEM}`).first().simulate("click"); assert.strictEqual(wrapper.find(Popover2).prop("isOpen"), false); }); @@ -195,18 +206,18 @@ describe("", () => { assert.strictEqual(wrapper.find(Popover2).prop("isOpen"), false); // popover should open after clicking the button - wrapper.find("[data-testid='target-button']").simulate("click"); + findTargetButton(wrapper).simulate("click"); assert.strictEqual(wrapper.find(Popover2).prop("isOpen"), true); // and should not close after the a menu item is clicked - wrapper.find(Popover2).find(".bp4-menu-item").first().simulate("click"); + wrapper.find(Popover2).find(`.${CoreClasses.MENU_ITEM}`).first().simulate("click"); assert.strictEqual(wrapper.find(Popover2).prop("isOpen"), true); }); function select(props: Partial> = {}, query?: string) { const wrapper = mount( {...defaultProps} {...handlers} {...props}> - +