JedWatson / react-select

The Select Component for React.js
https://react-select.com/
MIT License
27.63k stars 4.13k forks source link

react-select (onMenuScrollToBottom ) is not working with mouse scrolling or arrow keys #4537

Open mzrLab opened 3 years ago

mzrLab commented 3 years ago

hey guys , thanks for creating this awsome library I just want to know why react-select is having problem with mouse scrolling or arrow keys and it's only scrolling with wheel

right now my mouse wheel is not working and it's so hard for me to navigate btw the pages and loading new data to my react-select , thanks for your attention

ebonow commented 3 years ago

Greetings @mzrLab,

To answer you question in regards to "why", once upon a time iOS decided to only call the onScroll handler when the DOM was done scrolling, which caused a lot of inconsistency. As a result, onTouch and onWheel behaviors were used and thus quite a few issues exist as a result of this.

I think we would welcome any PR's which would replace the existing ScrollManager such that:

  1. It replaces the onTouch and onWheel events
  2. It is properly identified as a a DOMEvent (and not synthetic event unless its implementation is changed).
  3. The null check for the ref existence is able to accurately update when the ref changes (I believe there are some issues with portalling and/or menuIsOpen, but it's been awhile since I was able to identify what is broken with this existing implementation).

This will likely be a primary focus once the TypeScript conversion goes through assuming no one submits a PR.

CameronPeet commented 2 years ago

Here is my solution to always scroll to the 'focused' element. Regardless of custom option, or type of navigation used:

Leverages onFocus prop:

    <Select
      components={{ Input, **Option** }}
      ...{yourOtherProps}
      />

const Option = (props: any) => { const ref = React.useRef(null);

// Use layout effect to scroll item into view based on the 'prop.isFocused'
// onFocus events seem to be blocked higher up, and prevent downwards propogation
// Hence using layoutEffect to replicate based on props
useLayoutEffect(() => {
  if (props.isFocused) {
    ref.current?.scrollIntoView({
      behavior: "smooth",
      block: "nearest",
      inline: "start",
    });
  }
}, [props.isFocused]);

// components should be imported from react select : import Select, {components} from 'react-select'
return (
  <components.Option
    {...props}
    innerProps={{
      ...props.innerProps,
      ref: ref,
    }}
  />
);

};