React Select collapsible group
A simple hack to implement collapsible group in react-select
| UPDATED
React Select
If you are working on ReactJS application and you ever need to render select / dropdown component then react-select is one of the best library / component which you can use.
One of the reason I like react-select
is that it is highly extensible. It comes with lots of options / props which you can use to alter the default behavior.
How to use
Add and install react-select
dependency in your react application.
npm install react-select --save
Import and use Select
component from react-select
import React from "react";
import Select from 'react-select';
const options = [
{ value: "blue", label: "Blue" },
{ value: "yellow", label: "Yellow" }
];
export default () => (
<div className="container">
<Select
options={options}
isMulti
menuIsOpen
/>
</div>
);
Grouped Options
Now to render options as a group you just have to change the structure of options array.
const colourOptions = [
{ value: "blue", label: "Blue", color: "#0052CC" },
{ value: "yellow", label: "Yellow", color: "#FFC400" }
];
const flavourOptions = [
{ value: "vanilla", label: "Vanilla", rating: "safe" },
{ value: "chocolate", label: "Chocolate", rating: "good" }
];
const groupedOptions = [
{
label: "Colours",
options: colourOptions
},
{
label: "Flavours",
options: flavourOptions
}
];
Now you can pass groupedOptions
as <Select options={groupedOptions}/>
after this change the options should look like this.
Collapsible grouped options
Now I had a requirement in one of my project where I have to collapse options under a group when it’s header is clicked.
I looked for props in react-select
using which we can achieve it, but as of now there is not such props or options to do it. So I used below hack to make grouped options collapsible.
react-select
internally use GroupHeading
component to render option group header
and it provides a way using which you can replace this internal component with your own component
read more about it here.
import React from "react";
import Select, { components } from "react-select";
// handle options group header click event
// hide and show the options under clicked group
const handleHeaderClick = id => {
const node = document.querySelector(`#${id}`).parentElement
.nextElementSibling;
const classes = node.classList;
if (classes.contains("collapsed")) {
node.classList.remove("collapsed");
} else {
node.classList.add("collapsed");
}
};
// Create custom GroupHeading component, which will wrap
// react-select GroupHeading component inside a div and
// register onClick event on that div
const CustomGroupHeading = props => {
return (
<div
className="group-heading-wrapper"
onClick={() => handleHeaderClick(props.id)}
>
<components.GroupHeading {...props} />
</div>
);
};
// You can tell react-select to use your custom component by passing
// `components` props
export default () => (
<div className="container">
<Select
options={groupedOptions}
isMulti
menuIsOpen
components={{ GroupHeading: CustomGroupHeading }}
/>
</div>
);