'How to change style of react-select selected options?
Right now react-select shows selected options like this

But if we select 10 options out of 20 then this block expands. So instead of displaying each selected option, it will be better if it shows only first selected option + remaining selected option count like this
how can I achieve this in react-select?
Solution 1:[1]
I just made this little piece of code I think it can help you. Here is the live link https://djdz48.csb.app/ and a snippet below:
const App = () => {
const maxOptions = 2; // You can change the value
const [values, setValues] = useState([]); // All values (in console)
const [maxValues, setMaxValues] = useState({});
const [isMaxVal, setIsMaxVal] = useState(false);
const [actualOptions, setActualOptions] = useState(options);
const handleChange = (e) => {
let els = [];
e.map((el) => els.push(el));
if (els.length > maxOptions || values.length > maxOptions) {
if (els.length === 0) {
setValues(els);
setIsMaxVal(false);
} else {
setIsMaxVal(true);
const val = {
key: 1,
label: values[0]["label"] + " +" + (values.length + 1).toString()
};
setValues((values) => {
return [...values, els[els.length - 1]];
});
setMaxValues(val);
let opt = [];
options.map((el) => {
if (!values.includes(el) && !els.includes(el)) {
opt.push(el);
}
});
setActualOptions(opt);
}
} else {
setValues(els);
}
};
// values in real time
useEffect(() => {
console.log(values);
}, [values]);
return (
<div className="App">
<Select
options={isMaxVal ? actualOptions : options}
isMulti={true}
onChange={(e) => handleChange(e)}
value={values.length <= maxOptions ? values : maxValues}
/>
</div>
);
};
export default App;
Solution 2:[2]
As far as I know, this can not be done directly through react-select props, but you can create your custom wrapper to have the desired functionality.
Another approach is to write your custom component and pass it to the Select component like this:
<Select
isMulti
isClearable
options={options}
closeMenuOnSelect={false}
components={{
MultiValue: CustomMultiValue
}}
/>
react-select allows you to write your custom component and use it. So, here's what I've done. First, I've looked for the component I want to modify and write a custom component. There should be different possibilities, but I've decided to write a custom MultiValue component. Then, I've copied the code from the react-select repository and modified it.
The new custom component checks if it is the third selected option. If it is the first or the second option, it works like the original component. If it is the third option, it prints the number, and if it's another option, it prints nothing.
const CustomMultiValue = <
Option,
IsMulti extends boolean,
Group extends GroupBase<Option>
>(
props: MultiValueProps<Option, IsMulti, Group>
) => {
const {
children,
className,
components,
cx,
data,
getStyles,
getValue,
index,
innerProps,
isDisabled,
removeProps,
selectProps
} = props;
const { Container, Label, Remove } = components;
const additionalItems = getValue().length - MAX_ITEMS;
return (
<ClassNames>
{({ css, cx: emotionCx }) => (
<>
{index < 2 ? (
<Container
data={data}
innerProps={{
className: emotionCx(
css(getStyles("multiValue", props)),
cx(
{
"multi-value": true,
"multi-value--is-disabled": isDisabled
},
className
)
),
...innerProps
}}
selectProps={selectProps}
>
<Label
data={data}
innerProps={{
className: emotionCx(
css(getStyles("multiValueLabel", props)),
cx(
{
"multi-value__label": true
},
className
)
)
}}
selectProps={selectProps}
>
{children}
</Label>
<Remove
data={data}
innerProps={{
className: emotionCx(
css(getStyles("multiValueRemove", props)),
cx(
{
"multi-value__remove": true
},
className
)
),
"aria-label": `Remove ${children || "option"}`,
...removeProps
}}
selectProps={selectProps}
/>
</Container>
) : index === 2 ? (
<Container
data={data}
innerProps={{
className: emotionCx(
css(getStyles("multiValue", props)),
cx(
{
"multi-value": true,
"multi-value--is-disabled": isDisabled
},
className
)
),
...innerProps
}}
selectProps={selectProps}
>
<Label
data={data}
innerProps={{
className: emotionCx(
css(getStyles("multiValueLabel", props)),
cx(
{
"multi-value__label": true
},
className
)
)
}}
selectProps={selectProps}
>
{`+ ${additionalItems}`}
</Label>
</Container>
) : null}
</>
)}
</ClassNames>
);
};
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 | yousoumar |
| Solution 2 | crls_b |

