Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions packages/select/src/components/select/select.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,29 @@ describe("<Select>", () => {
expect(wrapper.find(Popover).prop("isOpen")).toBe(true);
});

it("does not close the popover when selecting via Enter on a MenuItem with shouldDismissPopover={false}", () => {
const itemRenderer = (film: Film, { handleClick, handleFocus, modifiers }: any) => {
return (
<MenuItem
active={modifiers.active}
onClick={handleClick}
onFocus={handleFocus}
text={`${film.rank}. ${film.title}`}
shouldDismissPopover={false}
/>
);
};
const wrapper = select({ itemRenderer, popoverProps: { usePortal: false } });

findTargetButton(wrapper).simulate("click");
expect(wrapper.find(Popover).prop("isOpen")).toBe(true);

// simulate keyboard selection: Enter on the input element
wrapper.find("input").simulate("keydown", { key: "Enter" });
wrapper.find("input").simulate("keyup", { key: "Enter" });
expect(wrapper.find(Popover).prop("isOpen")).toBe(true);
});

function select(props: Partial<SelectProps<Film>> = {}, query?: string) {
const wrapper = mount(
<Select<Film> {...defaultProps} {...handlers} {...props}>
Expand Down
9 changes: 7 additions & 2 deletions packages/select/src/components/select/select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -306,8 +306,13 @@ export class Select<T> extends AbstractPureComponent<SelectProps<T>, SelectState
};

private handleItemSelect = (item: T, event?: React.SyntheticEvent<HTMLElement>) => {
const target = event?.target as HTMLElement;
const menuItem = target?.closest(`.${CoreClasses.MENU_ITEM}`);
const target = event?.target as HTMLElement | undefined;
// When selection is triggered via keyboard (Enter), event.target is the input element,
// not the menu item. Fall back to looking up the active menu item in the document so
// that `shouldDismissPopover={false}` is respected in both click and keyboard flows.
const menuItem =
target?.closest(`.${CoreClasses.MENU_ITEM}`) ??
(target?.ownerDocument ?? document).querySelector(`.${CoreClasses.MENU_ITEM}.${CoreClasses.ACTIVE}`);
const menuItemDismiss = menuItem?.matches(`.${CoreClasses.POPOVER_DISMISS}`);
const shouldDismiss = menuItemDismiss ?? true;

Expand Down