🐛(react) fix failing selection of last removed item

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.
This commit is contained in:
Nathan Vasse
2023-09-15 16:11:53 +02:00
committed by NathanVss
parent 111bb677c4
commit 8470126b1f
4 changed files with 68 additions and 1 deletions

View File

@@ -0,0 +1,5 @@
---
"@openfun/cunningham-react": patch
---
fix failing selection of last removed item

View File

@@ -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) {

View File

@@ -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;

View File

@@ -724,6 +724,67 @@ describe("<Select multi={true} />", () => {
const label = screen.getByText("Cities");
expect(Array.from(label.classList)).toContain("offscreen");
});
it("is possible to select again the last deleted item", async () => {
render(
<CunninghamProvider>
<Select
label="Cities"
options={[
{
label: "Paris",
value: "paris",
},
{
label: "London",
value: "london",
},
{
label: "New York",
value: "new_york",
},
{
label: "Tokyo",
value: "tokyo",
},
]}
multi={true}
/>
</CunninghamProvider>,
);
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 () => {