JedWatson / react-select

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

react-select focus() doesn't show cursor after change #3832

Open swiss-chris opened 4 years ago

swiss-chris commented 4 years ago

Stackoverflow question: https://stackoverflow.com/questions/58538908/react-select-focus-doesnt-show-cursor-after-change

I'm trying to use ref and focus() to manually set the focus into the control input field. In most instances it works, but not immediately after selecting an Option from the dropdown.

After selecting an option from the dropdown, the control gets the focus but the cursor doesn't appear. It only appears if you start typing (including hitting the Esc key). On subsequent openings of the menu, the cursor appears along with the focus of the entire control field. Any ideas how to get this working in all situations, including immediately after making a selection?

I've created a sample code here: https://codesandbox.io/s/react-select-focus-uk3ic

Screenshot 2019-10-24 at 10 58 00

This is the code:

import React, { Component } from "react";
import ReactDOM from "react-dom";
import Select from "react-select";
import styled from "styled-components";

import { stateOptions } from "./data.js";

class PopoutExample extends Component {
  selectRef = React.createRef();

  state = {
    isOpen: false,
    option: undefined,
  };

  toggleOpen = () => {
    const isOpening = !this.state.isOpen;
    this.setState(
      {
        isOpen: isOpening,
      },
      () => isOpening && setTimeout(() => this.selectRef.focus(), 400),
    );
  };

  onSelectChange = option => {
    this.toggleOpen();
    this.setState({ option });
  };

  render() {
    const { isOpen, option } = this.state;
    return (
      <Dropdown
        target={
          <MainButton onClick={this.toggleOpen}>
            {option ? option.label : "Select a State"}
          </MainButton>
        }
      >
        <Select
          menuIsOpen
          ref={ref => {
            this.selectRef = ref;
          }}
          styles={{
            container: provided => ({
              ...provided,
              display: isOpen ? "block" : "none",
            }),
          }}
          onChange={this.onSelectChange}
          options={stateOptions}
          value={option}
          controlShouldRenderValue={false}
        />
      </Dropdown>
    );
  }
}

const MainButton = styled.button`
  padding: 10px;
  background-color: aqua;
  width: 100%;
`;

const Dropdown = ({ children, target }) => (
  <div>
    {target}
    {children}
  </div>
);

ReactDOM.render(<PopoutExample />, document.getElementById("root"));
dayanlemos commented 4 years ago

I think is the same issue here: https://github.com/JedWatson/react-select/issues/3819

namKolo commented 4 years ago

After debugging with source code, I found the way to workaround with that. https://codesandbox.io/s/react-select-focus-stackoverflow-k36dl

  <Select
      ref={ref => {
          this.selectRef = ref;
        }}
        // this props should be set to false
        // menuIsOpen
        // the key is this props - we should turn it on
         openMenuOnFocus
         styles={{
            container: provided => ({
              ...provided,
              display: isOpen ? "block" : "none"
            })
          }}
          onChange={this.onSelectChange}
          options={stateOptions}
          value={option}
          controlShouldRenderValue={false}
       />

I hope this one can help you.

namKolo commented 4 years ago

@swiss-chris I think this could be workaround for you demofixing

swiss-chris commented 4 years ago

@namKolo What worked for me was a combination of keeping menuIsOpen to true (because I want the dropdown to remember the scroll position), but also adding openMenuOnFocus as you suggested ! Thank you very much for this solution 🙏 !!!

namKolo commented 4 years ago

@swiss-chris Glad to help bro.

bladey commented 4 years ago

Hello -

In an effort to sustain the react-select project going forward, we're closing old issues.

We understand this might be inconvenient but in the best interest of supporting the broader community we have to direct our efforts towards the current major version.

If you aren't using the latest version of react-select please consider upgrading to see if it resolves any issues you're having.

However, if you feel this issue is still relevant and you'd like us to review it - please leave a comment and we'll do our best to get back to you!

lbelavoir commented 4 years ago

From the current example on https://react-select.com/ the bug is still present.

bladey commented 4 years ago

Thanks @lbelavoir!

bladey commented 4 years ago

Duplicate #3819 has further information.

jnachtigall commented 3 years ago

@swiss-chris @namKolo Any idea why your codesandboxes do not work anymore? I get

ModuleNotFoundError
Could not find module in path: '@babel/runtime/helpers/taggedTemplateLiteral' relative to '/src/index.js'

on both of them and googling for this error shows nothing.

Besides this, the workaround with openMenuOnFocus does not work for me.