Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disabled items are highlighted and are selectable by pressing enter after input value change #1599

Closed
jsvossen opened this issue May 1, 2024 · 4 comments · Fixed by #1601
Labels

Comments

@jsvossen
Copy link

jsvossen commented May 1, 2024

  • downshift version:
  • node version:
  • npm (or yarn) version:

Relevant code or config

useCombobox({
    isItemDisabled: () => true,
    defaultHighlightedIndex: 0,
    ...
})

What you did:

  1. Set defaultHighlightedIndex={0} with items that are disabled.
  2. Entered some text in the input field

What happened:
This is related to the bug I filed earlier (#1584)
The disabled items are now properly disabled on open, but after entering text the first one is automatically highlighted and can be selected by pressing enter.
downshift-bug

Reproduction repository:
https://codesandbox.io/p/sandbox/determined-euler-jllv45?file=%2Fsrc%2Findex.tsx%3A19%2C58

Problem description:

defaultHighlightedIndex should not be able to select items that are disabled.

Suggested solution:
Check isItemDisabled before applying highlighted styles or returning the selected item.

@nakulnagariy
Copy link

You could use something like this:

useCombobox({
      stateReducer(_, actionAndChanges) {
        const { changes, type } = actionAndChanges;
        switch (type) {
          case useCombobox.stateChangeTypes.InputKeyDownEnter:
          case useCombobox.stateChangeTypes.ItemClick:
            const isItemDisabled = changes?.selectedItem?.disabled;
            if (!isItemDisabled && changes.selectedItem) {
              handleItemClick(changes.selectedItem);
              /**
               * have a custom function for handling click event
               */
              const newChanges = {
                ...changes,
                inputValue: filterValue,
              };
              return {
                ...newChanges,
                isOpen: isMultiSelect, // keep the menu open after selection.
                highlightedIndex: changes.selectedItem
                  ? options.indexOf(changes?.selectedItem)
                  : 0, // workaround to stay on the same place.
              };
            } else {
              /**
               * For disabled item, just keep the menu open and dont select it
               */
              return {
                isOpen: isMultiSelect,
                highlightedIndex: changes.selectedItem
                  ? options.indexOf(changes?.selectedItem) + 1
                  : 0, // workaround to stay on the same place.
              };
            }

@jsvossen
Copy link
Author

jsvossen commented May 6, 2024

@nakulnagariy Yes, the reducer is what we're doing right now as a workaround until downshift is able to fix the bug on their end. I'm just hoping we can clean this up at some point, especially since we don't actually need a custom reducer for anything else.

@silviuaavram
Copy link
Collaborator

Thanks for reporting it! Will look into it.

@silviuaavram
Copy link
Collaborator

We are going to fix all the possible cases on our end, however we might not be able to do anything when it comes to filtering, because of the order of events.

Open the dropdown by input change, state change, check if defaultHighlightedIndex item is disabled, if not make it highlighted, but then if you filter the items and that item is not on the same position, and instead you have an item that's not disabled, it will not get highlighted because of that previous disabled check.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants