downshift-js / downshift

🏎 A set of primitives to build simple, flexible, WAI-ARIA compliant React autocomplete, combobox or select dropdown components.

Home Page:http://downshift-js.com/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Clicking the same item twice does not toggle the selected item in combobox

berkin opened this issue · comments

  • downshift version: 8.3.1 (the bug is introduced at version 8.2.4)
  • node version: 18.19.0
  • npm (or yarn) version: 1.22.21

Relevant code or config

        case useCombobox.stateChangeTypes.InputKeyDownEnter:
        case useCombobox.stateChangeTypes.ItemClick:
            return {
              ...changes,
              isOpen: true, // keep menu open after selection.
              highlightedIndex: state.highlightedIndex,
              inputValue: "", // don't add the item string as input value at selection.
            };

What you did:
open the dropdown, select an item then without moving your mouse out click again to unselect it.

What happened:
it does not toggle the item if you click on it twice or more.

Reproduction repository:
https://codesandbox.io/p/sandbox/vigilant-haze-rknm9y

Problem description:
the state returned seems unchanged and it does not trigger the onSelectedItemChange. if i move my mouse out from that item and click again, it works as expected(because highlightedindex is updated in the state). there was a state equality check added in version 8.2.4, it must have caused this issue.

Experiencing the same thing in my combobox. Noticing that onStateChange is not triggered on subsequent clicks in my case, but if I move the mouse to another item and back it is clickable again for one click. The same is the case in the codesandbox example. Downgrading to 8.2.3 and it works again

It makes sense for 8.2.4 to have caused this. I'm thinking how to fix this, since the 8.2.4 patch makes sense. Second clicking an item does not trigger a state change in this case: input is still empty, highlighted item is the same, the menu is still open, selectedItem is still null.

I believe the example we have in the docsite is unfortunate, as it did work simply because we had an issue.

If anyone has any idea on how to fix this or the actual example, I'm all ears. Will update if I come up with something.

We might need to call !isStateEqual(prevStateRef.current, state) as !isStateEqual(getState(prevStateRef.current, action.props), state) and pass selectedItem as null to the example. This sounds to be more accurate to what we want to achieve.

Will need to do some testing as well since we don't want to regress what we did in 8.2.4 or cause some other bug.

This issue is also seen when navigating/selecting via keyboard. I can reproduce in the original post's example.

  • open menu
  • navigate with keyboard to an item
  • press enter - item will be selected
  • press enter again - item will stay selected, but should be deselected

Navigating to another item, then back to the selected item will allow you to deselect it with the enter key.

Downgrading to 8.2.3 also solves the keyboard nav issue.

Just noting that it is also present in Select, both when clicking and using keyboard. I guess the state compare change impacted both hooks. 😢

It was an unfortunate side effect to this proposed way of handling multiple selection. I am working to figure out a way to fix it, as well as keeping the current state compare change. We need that, as React now will trigger a couple of state changes when you click an item in Responsive mode (one click + one mouse move and click). This happened with R18, I'm not sure if it's a bug on their side, but in the meanwhile i'm trying to mitigate it from here. Will keep informing on the progress, but I am also open to external help, to be honest :D

Hey everyone! I think I got it.

#1571

I also released the 8.3.2-alpha.0 version if you'd like to test it out. Please also check the details in the PR, see if they make sense, and let me know what you think!

Tested 8.3.2-alpha.0 and it fixed the multiselect toggle issue for me 👍