BUG Selecting dropdown item does nothing when input is off screen
-
downshiftversion: 6.1.7 -
nodeversion: 16.13.2 -
npm(oryarn) version: 8.1.2
Relevant code or config
This is a near identical copy+paste from the useCombobox docs. Just modified styles slightly and then added an extra element to the bottom of the page to force scrolling.
Click to expand code snippet
import React, { useState } from 'react'
import { useCombobox } from 'downshift'
const items = [
'Apples',
'Applesaft',
'Apple juice',
'Apple pie',
'Apple jam',
'Apple sauce',
];
const menuStyles = {
listStyleType: "none",
margin: 0,
padding: 0
}
const baseItemStyles = {
padding: '10px'
}
function DropdownCombobox() {
const [inputItems, setInputItems] = useState(items)
const {
isOpen,
getToggleButtonProps,
getLabelProps,
getMenuProps,
getInputProps,
getComboboxProps,
highlightedIndex,
getItemProps,
} = useCombobox({
items: inputItems,
onInputValueChange: ({ inputValue }) => {
setInputItems(
items.filter(item =>
item.toLowerCase().startsWith(inputValue.toLowerCase()),
),
)
},
})
return (
<div>
<label {...getLabelProps()}>Choose an apple:</label>
<div {...getComboboxProps()}>
<input {...getInputProps()} />
<button
type="button"
{...getToggleButtonProps()}
aria-label="toggle menu"
>
↓
</button>
</div>
<ul {...getMenuProps()} style={menuStyles}>
{isOpen &&
inputItems.map((item, index) => (
<li
style={
highlightedIndex === index
? { ...baseItemStyles, backgroundColor: '#bde4ff' }
: { ...baseItemStyles }
}
key={`${item}${index}`}
{...getItemProps({ item, index })}
>
{item}
</li>
))}
</ul>
<p style={{ marginTop: '50rem' }}>Some extra content to make sure the viewport is scrollable.</p>
</div>
)
}
export default DropdownCombobox
What you did:
Using Android Chrome (occasionally seems to repro on MacOS Chrome also)
Simply scroll the page so that the dropdown menu is still visible, but the input no longer is. Tap a result, and nothing will happen.
What happened:
This video shows the end result best:
https://user-images.githubusercontent.com/9998591/151899519-70206077-75f3-4884-bd62-d6a68cd87b58.mp4
When this issue occurs, there is an __item_mouse_moved__ event, but no click event:

Compare that to what happens when you don't scroll the input out of view:

Reproduction repository:
See pages/index.js for example function, and run npm run dev to spin up Next.js dev server.
https://github.com/sean0x42/downshift-focus-bug-repro
Problem description:
Suggested solution:
I have absolutely no idea. I did some digging, but I'm guessing there is a race condition somewhere. If you put a breakpoint anywhere, this appears to resolve the issue. So it's like something timing related that the extra breakpoint slows down the execution enough to resolve.
Hi, I'm not able to reproduce this in a PC using Device Emulation. It works normally regardless of how far the input has been scrolled. Perhaps this is a problem only on mobile devices?
Hi, I'm not able to reproduce this in a PC using Device Emulation. It works normally regardless of how far the input has been scrolled. Perhaps this is a problem only on mobile devices?
It definitely could be. I was testing on a Pixel 4 running Chrome for Android. My coworker could not repro on iOS.
I might be able to get that repro running on GitHub pages, and then it would be easy for anyone to test on mobile. Would that be helpful?
Some browsers attempt to scroll elements into the viewport when they are focused, my guess is that this is what is happening here.
This line runs the input.focus() method when an item is clicked and without the preventScroll option for the focus method then the browser should scroll it into view.
We are not doing the input.focus() anymore in that handler anymore since v7. If the bug persists, please open a new ticket. Thank you!