Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React-Select losing focus for custom component "ValueContainer"

We have a use case where we have to render multiple different versions of the value container for the multiselect dropdown depending on how many options are selected. The code snippet below shows one of the cases. Another version of this renders a <SingleValue /> instead of placeholder.

<ValueContainer {...props}>
    <Placeholder {...props}>
    {!props.selectProps.inputValue && `${length} selected`}
    </Placeholder>
    {children[1]}
</ValueContainer>

This seems to be working well, however we lose keyboard navigation upon selection of one of the options. Am I forgetting to pass certain props or a ref?

An example of dropped keyboard navigation for custom ValueContainers can be found here: https://codesandbox.io/s/rjvkzk1nn?from-embed

like image 921
Patrick Martin Avatar asked Dec 19 '25 06:12

Patrick Martin


1 Answers

Keyboard is not working anymore because you miss the Input component that is focused when you open the Menu.

ValueContainer has two objects when there's no value selected:

  • Placeholder
  • Input

when you select one (or multiple) value(s) then it changes for:

  • SingleValue or MultiValue
  • Input

with your previous example, you were removing those two.

To keep the keyboard features, you need to keep the Input component. The following code is a combination of your code and expectation and keeping the Input component:

const ValueContainer = ({ children, ...props }) => {
  const { getValue, hasValue } = props;
  const newChildren = _.cloneDeep(children);
  const nbValues = getValue().length;
  newChildren[0] = `${nbValues} items selected`;

  if (!hasValue) {
    return (
      <components.ValueContainer {...props}>
        {children}
      </components.ValueContainer>
    );
  }
  return (
    <components.ValueContainer {...props}>
      {newChildren}
    </components.ValueContainer>
  );
};

const options = [
  { label: "label 1", value: 1 },
  { label: "label 2", value: 2 },
  { label: "label 3", value: 3 },
  { label: "label 4", value: 4 }
];

function App() {
  const components = { ValueContainer };
  return <Select isMulti components={components} options={options} />;
}

Live example.

like image 87
Laura Avatar answered Dec 20 '25 21:12

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!