In React-Select V2, we're able to create option groups by passing an options
param like so:
options = [
{ label: 'Group', options: [
{ label: 'Option 1', value: '1' },
{ label: 'Option 2', value: '2' }
]}
]
I need to be able to go another layer deep, something like:
options = [
{ label: 'Group', options: [
{ label: 'Option 1', value: '1' },
{ label: 'Option 2', options: [
{ label: 'Option 2-a', value: '2a' },
{ label: 'Option 2-b', value: '2b' },
]}
]}
]
Which would display the options "Option 2-a" and "Option 2-b" in a group under "Option 2". The approach above doesn't work out of the box, so I want to know if there's a way to create nested groups in React-Select V2.
In React-Select V2, we're able to create option groups by passing an options
param like so:
options = [
{ label: 'Group', options: [
{ label: 'Option 1', value: '1' },
{ label: 'Option 2', value: '2' }
]}
]
I need to be able to go another layer deep, something like:
options = [
{ label: 'Group', options: [
{ label: 'Option 1', value: '1' },
{ label: 'Option 2', options: [
{ label: 'Option 2-a', value: '2a' },
{ label: 'Option 2-b', value: '2b' },
]}
]}
]
Which would display the options "Option 2-a" and "Option 2-b" in a group under "Option 2". The approach above doesn't work out of the box, so I want to know if there's a way to create nested groups in React-Select V2.
Share Improve this question asked Nov 2, 2018 at 13:56 Andrea RosalesAndrea Rosales 1,0581 gold badge8 silver badges12 bronze badges 3- 2 This is an interesting use case that I don't think React-Select currently supports. Would be a great feature request though. – Steve -Cutter- Blades Commented Nov 2, 2018 at 19:01
- agreed with @Steve-Cutter-Blades you should do a feature request. As in V2, groups have been implemented, it could be a finish – Laura Commented Nov 2, 2018 at 20:21
- 1 This issue has been a requested feature for react-select and has now been implemented in this PR. You can find a working example here codesandbox.io/s/react-codesandboxer-example-8xxyx?file=/… – Waweru Kamau Commented Jul 23, 2020 at 7:11
1 Answer
Reset to default 3For anyone who es here with a similar need, I implemented this recursive work-around.
const renderNestedOption = (props, label, nestedOptions) => {
const {
cx,
getStyles,
innerProps,
selectOption,
} = props;
// Will be applied to nested optgroup headers
const nestedLabelClassName = cx(
css(getStyles('groupHeading', props)),
{ option: true },
'nested-optgroup-label',
);
return (
<div className="nested-optgroup">
<div className={nestedLabelClassName}>
{label}
</div>
{nestedOptions.map((nestedOption) => {
if (nestedOption.options) {
// Read below
// Read above
return renderNestedOption(props, nestedOption.label, nestedOption.options);
}
const nestedInnerProps = innerProps;
nestedInnerProps.onClick = () => selectOption(nestedOption);
return (
<div className="nested-optgroup-option" key={nestedOption.value}>
<ponents.Option {...props} innerProps={nestedInnerProps}>
{nestedOption.label}
</ponents.Option>
</div>
);
})}
</div>
);
};
const Option = (props) => {
const {
children,
data,
} = props;
const nestedOptions = data.options;
if (nestedOptions) {
const label = data.label;
return renderNestedOption(props, label, nestedOptions);
}
return (
<ponents.Option {...props}>
{children}
</ponents.Option>
);
};
Then in your select ponent, replace the Option
ponent with the custom Option
ponent we just created.
EDIT
There's an open pull request to support this functionality: https://github./JedWatson/react-select/pull/2750