'How can I make collapse/expand for selected tags feature in react-select like props "limitTags" in material UI autocomplete

I am using Select in react-select in order to select multiple values.

    isMulti
    options={colourOptions}
  />

How can I make collapse/expand for selected tags feature just similar to props

limitTags

in material UI autocomplete

<Autocomplete
  multiple
  limitTags={2}
  options={top100Films}
/>

enter image description here

I have read all the docs of react-select but still cannot find the similar prop. Thank you



Solution 1:[1]

The very initial thing coming to my mind is creating a wrapper to play with ReactSelect props. So you can check if it's focused or not and limit the number of options passing as value to it etc.

import ReactSelect, { components } from "react-select";
import { useState } from "react";

// sample options
const options = [
  { value: "chocolate", label: "Chocolate" },
  { value: "strawberry", label: "Strawberry" },
  { value: "vanilla", label: "Vanilla" },
  { value: "apple", label: "Apple" },
  { value: "banaba", label: "Banana" },
  { value: "biscuit", label: "Biscuit" }
];
// more option blueprint!
const moreOption = { value: "__more__" };

export function Select({ limitTags, ...rest }) {
  const [selected, setSelected] = useState([]);
  const [focused, setFocused] = useState(false);

  const moreCount = selected.length - limitTags;
  const limitSelected = limitTags > 0 && !focused && moreCount > 0;
  // if value should be limited to `limitTags`
  // will cut them and add a tag showing how many tags are hidden
  const visibleSelected = limitSelected
    ? [
        ...selected.slice(0, limitTags),
        { ...moreOption, label: `+${moreCount}` }
      ]
    : selected;

  const handleChange = (options) => {
    setSelected(options);
  };

  return (
    <ReactSelect
      {...rest}
      value={visibleSelected}
      onFocus={() => setFocused(true)}
      onBlur={() => setFocused(false)}
      onChange={handleChange}
      components={{
        // remove `MultiValueRemove` if option is more!
        MultiValueRemove: (props) =>
          props.data.value === moreOption.value ? null : (
            <components.MultiValueRemove {...props} />
          )
      }}
    />
  );
}

export default function App() {
  return (
    <div className="App">
      <Select limitTags={2} options={options} isMulti />
    </div>
  );
}

Notice!

  • Maybe you need to customize it and work on performance things.
  • visibleSelected may contains more option so do not use it to get selected options. Use selected instead.

Here is the code on CodeSandbox. I hope it helps you.

Good luck.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Adel Armand