From 8470126b1f57c7446ceb45fab9faa9e0ebc6888e Mon Sep 17 00:00:00 2001 From: Nathan Vasse Date: Fri, 15 Sep 2023 16:11:53 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B(react)=20fix=20failing=20selection?= =?UTF-8?q?=20of=20last=20removed=20item?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previsouly when selecting item A and then removing it, it was impossible to select it again. This was caused by the internal memory of useSelect that only provides undefined selectedItem inside the onStateChange callback when the item has not changed. So by forcing it everytime to null it is now providing it everytime. --- .changeset/sweet-rats-poke.md | 5 ++ .../Forms/Select/multi-searchable.tsx | 2 +- .../components/Forms/Select/multi-simple.tsx | 1 + .../components/Forms/Select/multi.spec.tsx | 61 +++++++++++++++++++ 4 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 .changeset/sweet-rats-poke.md diff --git a/.changeset/sweet-rats-poke.md b/.changeset/sweet-rats-poke.md new file mode 100644 index 0000000..162dd86 --- /dev/null +++ b/.changeset/sweet-rats-poke.md @@ -0,0 +1,5 @@ +--- +"@openfun/cunningham-react": patch +--- + +fix failing selection of last removed item diff --git a/packages/react/src/components/Forms/Select/multi-searchable.tsx b/packages/react/src/components/Forms/Select/multi-searchable.tsx index e79a821..9b2a0e6 100644 --- a/packages/react/src/components/Forms/Select/multi-searchable.tsx +++ b/packages/react/src/components/Forms/Select/multi-searchable.tsx @@ -37,7 +37,7 @@ export const SelectMultiSearchable = (props: SubProps) => { items: options, itemToString: optionToString, defaultHighlightedIndex: 0, // after selection, highlight the first item. - selectedItem: null, + selectedItem: null, // Important, without this we are not able to re-select the last removed option. stateReducer: (state, actionAndChanges) => { const { changes, type } = actionAndChanges; switch (type) { diff --git a/packages/react/src/components/Forms/Select/multi-simple.tsx b/packages/react/src/components/Forms/Select/multi-simple.tsx index 9712da0..d1d341c 100644 --- a/packages/react/src/components/Forms/Select/multi-simple.tsx +++ b/packages/react/src/components/Forms/Select/multi-simple.tsx @@ -32,6 +32,7 @@ export const SelectMultiSimple = (props: SubProps) => { const downshiftReturn = useSelect({ items: options, itemToString: optionToString, + selectedItem: null, // Important, without this we are not able to re-select the last removed option. defaultHighlightedIndex: 0, // after selection, highlight the first item. stateReducer: (state, actionAndChanges) => { const { changes, type } = actionAndChanges; diff --git a/packages/react/src/components/Forms/Select/multi.spec.tsx b/packages/react/src/components/Forms/Select/multi.spec.tsx index 92e2013..9c241ed 100644 --- a/packages/react/src/components/Forms/Select/multi.spec.tsx +++ b/packages/react/src/components/Forms/Select/multi.spec.tsx @@ -724,6 +724,67 @@ describe(" + , + ); + + const input = screen.getByRole("combobox", { + name: "Cities", + }); + expectSelectedOptions([]); + + const user = userEvent.setup(); + await user.click(input); + + // Select options. + await user.click( + screen.getByRole("option", { + name: "Paris", + }), + ); + expectSelectedOptions(["Paris"]); + + // Clear selection. + const clearButton = screen.getByRole("button", { + name: "Clear all selections", + }); + await user.click(clearButton); + expectSelectedOptions([]); + + // Select again London. + await user.click(input); + await user.click( + screen.getByRole("option", { + name: "Paris", + }), + ); + expectSelectedOptions(["Paris"]); + }); }); describe("Searchable", async () => {