JedWatson / JedWatson/react-select
Async menu list height remains unchanged after options loaded
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 28k
- Forks
- 4.1k
- PR merge metrics
- No merged PRs in 30d
Description
I've set a maxMenuHeight on an Async component, but after the options are loaded, the max height is not calculated and instead is set to the maxMenuHeight that is provided. This causes the menu to be cut off by the bottom of the screen and not flip to the top of the select when enough options are returned. I would expect the menu to not flow beyond the window after the options are loaded and still not flip to the top if minMenuHeight has not been reached either.
I was able to write a hack around this by adding a custom component for Menu and forcing innerRef to be called (so that getPlacement on MenuPlacer will be triggered and the max height recalculated) whenever the supplied options have changed (using an MD5 hash for this to ensure that the options truly have changed).
Version: 3.1.0
Test Case:
import ReactSelectAsync from "react-select/async";
export default function TestCase() {
return (
<ReactSelectAsync
maxMenuHeight={2000}
loadOptions={() => new Promise((resolve) => {
setTimeout(function() {
const ret = [];
for (let i = 0; i < 50; i++) {
ret.push({
value: i,
label: `Item ${i}`
});
}
resolve(ret);
}, 1000);
}}
/>
);
}
My Workaround:
import { components } from "react-select";
import { MD5 } from "object-hash";
export class CustomMenu extends React.Component {
_isFirstRender = true;
_menuRef = React.createRef();
render() {
const { children, ...props } = this.props;
return (
<components.Menu {...props} innerRef={this._innerRef}>
{children}
</components.Menu>
);
}
componentDidUpdate() {
const optionsHash = MD5(this.props.options);
if (this._prevOptionsHash !== optionsHash) {
this._prevOptionsHash = optionsHash;
if (!this._isFirstRender && this._menuRef.current != null) {
this.props.innerRef(this._menuRef.current);
}
}
this._isFirstRender = false;
}
_innerRef = (...args) => {
processDomRef(this._menuRef, ...args);
this.props.innerRef(...args);
};
}
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the supplied ReactSelectAsync test case, then trace the Async menu flow into MenuPlacer and its getPlacement logic. Verify that loading options recalculates the available max height and keeps the menu within the window, including the minMenuHeight behavior described in the issue.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- react
- Domain
- frontend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100