Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

As described in the official documentation for react-select, 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?

I've created a sample code in codesandbox.io here

enter image description here

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"));
like image 769
Chris Avatar asked Feb 27 '26 07:02

Chris


1 Answers

If I can offer an alternative to the behaviour you're trying to achieve, instead of hiding the Select with css why don't just mount / unmount it ?

class PopoutExample extends Component {
  state = {
    isOpen: false,
    option: undefined
  };

  toggleOpen = () => {
    this.setState({
      isOpen: !this.state.isOpen
    });
  };

  onSelectChange = option => {
    this.setState({ option, isOpen: !this.state.isOpen });
  };

  render() {
    const { isOpen, option } = this.state;
    return (
      <Dropdown
        target={
          <MainButton onClick={this.toggleOpen}>
            {option ? option.label : "Select a State"}
          </MainButton>
        }
      >
        {isOpen && (
          <Select
            autoFocus
            menuIsOpen
            onChange={this.onSelectChange}
            options={stateOptions}
            value={option}
            controlShouldRenderValue={false}
          />
        )}
      </Dropdown>
    );
  }
}

Here a live example of my solution.

like image 120
Laura Avatar answered Mar 01 '26 23:03

Laura



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!