JedWatson / react-select

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

the selected value is not the first displayed #4368

Closed alexandrebouttier closed 3 years ago

alexandrebouttier commented 3 years ago

Hello, I have a little problem I have several options in my select, and I would like the value to be selected to be scrolled directly to the top to be the first of the options

it works with an old version 1.0.0-rc.2, following the migration to 3.1.1 it no longer works

   <Select
        className="Select react-select-container condition-source"
        classNamePrefix="react-select"
        name="form-field-name"
        styles={{
          option: (provided, state) => ({
            ...provided,
            backgroundColor: state.isFocused && "#f18200",
            color: state.isFocused && "white",
            ":active": {
              backgroundColor: state.isActive && "#f18200",
            },
          }),
        }}
        autoFocus
        value={valueSelect}
        options={options}
        menuShouldScrollIntoView
        placeholder={valueSelect ? valueSelect : "Choisissez une question"}
        onChange={this.onSelectChange.bind(this)}
        clearable={false}
      />
ebonow commented 3 years ago

Greetings @alexandrebouttier ,

The default behavior now is such that the selected item is scrolled so that it is the bottom most item. I don't know if/when this changed nor do I know any rationale for this.

However, here is a solution I created in response to https://github.com/JedWatson/react-select/issues/4305

Demo: codesandbox

Please let me know if this resolves your use-case.

alexandrebouttier commented 3 years ago

Thank you @ebonow for your solution it worked for me

SOLUTION by @ebonow :

import React, { useState, useRef } from "react";
import Select, { components } from "react-select";

const optionGenerator = (n) =>
  Array(n)
    .fill()
    .map((x, i) => ({ label: `Option ${i + 1}`, value: i + 1 }));

const App = (props) => {
  const selectRef = useRef();
  const options = useRef(optionGenerator(100)).current;

  const onMenuOpen = () => {
    setTimeout(() => {
      const { focusedOptionRef } = selectRef.current.select;
      console.log(selectRef.current.select);
      focusedOptionRef &&
        focusedOptionRef.scrollIntoView({ behavior: "smooth" });
    }, 1);
  };

  return (
    <Select
      ref={selectRef}
      options={options}
      onMenuOpen={onMenuOpen}
      onChange={onChange}
    />
  );
};

export default App;
sayantandas9412 commented 11 months ago

This solution works perfectly for single select value, what if we are using isMulti=true, in case of Multi select what changes do we need to make?

JEphron commented 1 month ago

Looks like selectRef.current no longer contains a select property. focusedOptionRef is now on selectRef.current

So in the posted solution, onMenuOpen now looks like this:


  const onMenuOpen = () => {
    setTimeout(() => {
      const { focusedOptionRef } = selectRef.current;
      focusedOptionRef &&
        focusedOptionRef.scrollIntoView({ behavior: "smooth" });
    }, 1);
  };