downshift version: 5.2.0node version: 10.19.0npm (or yarn) version: 6.13.4What you did:
What happened:
Highlighted item will get selected. I would expect that nothing would be selected and the menu would close (ie: similar to pressing ESC)
Reproduction repository:
It is debatable. Aria combobox examples do the same thing, only there they clearly make a distinction between the highlight by kb and the one by mouse. But with the repro steps you have, their widget behaves the same.
This is also an edge case. You either use keyboard or mouse, rarely both of them at the same time.
I would like to keep this open, mark it as a bug, and see how to best fix it. It may require some changes in how we handle Blur generally, so it may not be a straightforward fix.
Interesting! I always assumed that a "click outside" would be equivalent to a "cancel"-like action, but see now that the behavior is based on blur (ie: tabbing has same effect).
I think it "feels weird" in the aria examples too (except in the case of example #3 with the inline autocomplete, since blur doesn't change the input text)
I definitely can see this both ways though. In the context of a straightforward form, this is not so problematic. But if selection has immediate side effects (eg: updates something on server), you might want to require explicit selection (ie: hitting enter, clicking the item directly).
I just encountered a similar surprise related to select-on-blur handling.
I have a handler to perform some action on selection of item. I have an item highlighted in the list, but not selected. I then switch to another tab in my browser to check something. When I come back to my app, the action has fired (due to blur).
I would expect nothing to have happened by default.
Good point @martinpengellyphillips! The aria examples do this too-- which suggests to me that the select-on-blur behavior is flawed.
Note that in #1040 I show that this doesn't only happen when using a combination of keyboard and mouse. This happens if you're using only one or the other as well.
So, for anyone ending up on this thread, to stop selecting items on blur, just use:
stateReducer(state, actionAndChanges) {
const { type, changes } = actionAndChanges
if (type === useCombobox.stateChangeTypes.InputBlur && changes.selectedItem !== undefined) {
const {selectedItem, ...changesWithoutItem} = changes
return changesWithoutItem
}
return changes
}
Or something equivalent. Basically just handle this use case in a custom reducer.
I will continue to gather feedback around this issue, as I previously noted, ARIA examples select items on combobox blur, FluentUI does the same. I don't want to change behavior only to get an equivalent issue with people expecting the opposite. So I need more feedback related before I make any change.
I think it would be less of a surprise if the text input value got set to the currently highlighted item. Having it select the highlighted item on blur without the input being set to the currently highlighted item is pretty unexpected I'd say. So I would suggest either change the default to not select the current item on blur. Or keep the input value in sync with the highlighted item.
Personally I would go for the former and remove the selection on blur.
Of course people could change the state reducer to have the current behavior or the alternative behavior I mentioned with keeping the selected item in sync with the highlighted item. That's the beauty of the state reducer :-)
After some thought + checking the 1.2 ARIA example + talking to deque about it, useCombobox will keep selection on (Shift+)Tab. As we already mentioned, you can easily replace this by using the stateReducer.
However, the selection on clicking outside is considered a bug. InputBlur action should return selectedItem only from Tab/Shift+Tab and not from clicking outside. This should be fixed in v6 since it may be considered a breaking behavior.
:tada: This issue has been resolved in version 6.0.0 :tada:
The release is available on:
npm package (@latest dist-tag)Your semantic-release bot :package::rocket:
Most helpful comment
Personally I would go for the former and remove the selection on blur.