🐛(react) fix closing of menu via toggle button

Previously it was not possible to close the menu when clicking on
the toggle button on search select. It was caused by a conflicting
state update.
1. Downshift triggers closing the menu from getToggleButtonProps
2. wrapperProps was calling downshiftReturn.openMenu()
This commit is contained in:
Nathan Vasse
2023-11-28 16:28:00 +01:00
committed by NathanVss
parent b25aa8f078
commit 7ddcfeb4bc
5 changed files with 20 additions and 7 deletions

View File

@@ -120,7 +120,11 @@ export const SelectMonoSearchable = forwardRef<SelectHandle, SubProps>(
wrapperProps: {
onClick: () => {
inputRef.current?.focus();
downshiftReturn.openMenu();
// This is important because if we don't check that: when clicking on the toggle button
// when the menu is open, it will close and reopen immediately.
if (!downshiftReturn.isOpen) {
downshiftReturn.openMenu();
}
},
},
toggleButtonProps: downshiftReturn.getToggleButtonProps({

View File

@@ -136,7 +136,7 @@ describe("<Select/>", () => {
expectMenuToBeOpen(menu);
expectOptions(["Paris", "Panama"]);
await user.type(input, "r");
await user.type(input, "r", { skipClick: true });
expectOptions(["Paris"]);
// Select option.
@@ -211,7 +211,7 @@ describe("<Select/>", () => {
expectMenuToBeOpen(menu);
expectOptions(["Paris", "Panama"]);
await user.type(input, "rr");
await user.type(input, "rr", { skipClick: true });
expectNoOptions();
expect(input).toHaveValue("Parr");

View File

@@ -136,7 +136,11 @@ export const SelectMultiSearchable = forwardRef<SelectHandle, SubProps>(
wrapperProps: {
onClick: () => {
inputRef.current?.focus();
downshiftReturn.openMenu();
// This is important because if we don't check that: when clicking on the toggle button
// when the menu is open, it will close and reopen immediately.
if (!downshiftReturn.isOpen) {
downshiftReturn.openMenu();
}
},
},
toggleButtonProps: downshiftReturn.getToggleButtonProps(),

View File

@@ -1247,7 +1247,7 @@ describe("<Select multi={true} />", () => {
await user.type(input, "Par");
expectOptions(["Paris"]);
await user.type(input, "{enter}");
await user.type(input, "{enter}", { skipClick: true });
await waitFor(() => expectSelectedOptions(["Paris"]));
});
@@ -1504,9 +1504,9 @@ describe("<Select multi={true} />", () => {
const user = userEvent.setup();
await user.click(input);
await waitFor(() => expectOptions(["Paris", "New York", "Tokyo"]));
await user.type(input, "New");
await user.type(input, "New", { skipClick: true });
await waitFor(() => expectOptions(["New York"]));
await user.type(input, "{enter}}");
await user.type(input, "{enter}}", { skipClick: true });
expectSelectedOptions(["London", "New York"]);
screen.getByText('Value = ["london","new_york"]|');