That's not really a bug, and not an error - this is a not correct behavior.
There is an option - blurInputOnSelect
blurInputOnSelect: isTouchCapable(),and the effect of it quite simple:
selectOption = (newValue: OptionType) => {
....
if (blurInputOnSelect) {
this.blurInput();
}
__Should it be delayed?__
In normal conditions there are two different events (click/change, blur) comes one after another with a little "gap" between them. But in this case - there is no gap. This results into some differences in the "state management" - blur evens is reported too soon - before the change(or select) event is finishing propagation (state change applied back to the component).
Probably onBlur should be called in setTimeout, or at least a Promise
__Should it even exists?__
For all "touch devices", windows 10 on hybrid devices included, or only when select is caused by "touch" event? Probably here we should check touch event, and execute blur only there, but not as a part of selectOption
Is it a real problem? Yes, it is. We run into it twice this year, causing SEV1s both times.
I believe we are having issues stemming from this as well, on touch devices the onBlur triggers before onChange, sometimes, which prevents the change event entirely.
In our case - onBlur, fired with the still old event, was canceling onChange.
Just wrapping onBlur with setImmediate fixed the problem, and that's a quick fix we might do. Adding blur only for touch-driven selects would make it even better, but that's something good to have, not crusial to have.
Yup, though we're using setTimeout(f, 0) instead of setImmediate(f).
Who will try Promise.resolve().then(onBlur)? Not sure that would not be too fast.
setImmediate is more "correct" way to emulate "browser tick", however, has to be polyfilled.
I wasted an entire day on this. I couldn't figure out why my test wasn't working. Apparently the test environment has touch capabilities...
Lucky one, caught it in tests :)
For select itself, this is not a real issue - as well not an issue for a random form management system - only for the ones which updates data on blur event as well (more common is to listen to onChange only).
However the behaviour of touch, and non-touch devices should not be so different and react-select should match native browser behaviour, letting js process whatever it needs between two events.
It's a bug.
We appear to have this issue with Creatable on iOS (iPad only) where the <input> is receiving the blur event before the chosen option receives its click event, and so the menu closes before an option can be chosen! I'm currently trying to create a workaround. This used to work, so I'm not sure if it's an iOS behaviour change.
In particular, I think the implementation of onInputBlur in Select expects to find document.activeElement inside the menuListRef, but on my iPad the document.activeElement is the document.body.