Reputation: 93
I have nested options for my <Select />
component and i basically want to remove some styles if the option is selected, there is documentation for normal options but can't find a way to do it for nested ones. Here is what my component looks like:
<Select
id="custom"
name="custom"
options={_.chain(customOptions)
.map(op1 => ({
label: (
<div
className="flex items-center justify-between text-sm font-semibold"
>
<span>
{op1.title}
</span>
</div>
),
options: _.map(op1.tags, tag => ({
label: (
<div
className="mx-2 flex items-center justify-between"
>
<span className="font-semibold indent-2">
{tag}
</span>
</div>
),
value: tag,
group: op1,
})),
}))
.value()}
placeholder="Select Option"
menuPortalTarget={document.body}
type="default"
styles={{
menuPortal: (base: any) => ({ ...base, zIndex: 9999 }),
}}
/>
What is want is to remove font-semibold indent-2
classes from <span>{tag}</span>
for selected tag, is there any way to do this?
Upvotes: 1
Views: 2047
Reputation: 3673
Styling nested options is no different to styling none nested options. The issue with your approach is that you are passing your markdown and style all into the options
prop.
Here are the two 'correct' way of using the library:
1) [Recommended] Styling through 'style' prop
Pass in your raw data into the options
prop.
Pass the styles into the styles
prop as objects.
const customOptions = [
{ groupLabel: "number", items: ["1", "2", "3"] },
{ groupLabel: "words", items: ["one", "two", "three"] }
];
const options = customOptions.map((op1) => ({
label: op1.groupLabel,
options: _.map(op1.items, (item) => ({
label: item,
value: item
}))
}));
const customStyles = {
option: (provided: any, state: { isSelected: any }) => ({
...provided,
borderBottom: "1px dotted pink",
color: state.isSelected ? "red" : "blue",
backgroundColor: state.isSelected ? "grey" : "inherit"
})
};
const App = () => <Select options={options} styles={customStyles} />;
2) Styling through 'components' prop
If you really want to change the markup then you can do this;
Pass in the raw data into the options
prop as before.
Pass in markup and style through the components
prop to override the built in components.
import React from "react";
import Select, { OptionProps, GroupHeadingProps } from "react-select";
import _ from "lodash";
const customOptions = [
{ groupLabel: "number", items: ["1", "2", "3"] },
{ groupLabel: "words", items: ["one", "two", "three"] }
];
const options = customOptions.map((op1) => ({
label: op1.groupLabel,
options: _.map(op1.items, (item) => ({
label: item,
value: item
}))
}));
const Option = ({ innerProps, children, isSelected }: OptionProps<{}>) => {
return (
<div
{...innerProps}
style={{ backgroundColor: isSelected ? "red" : "white" }}
>
{children}
</div>
);
};
const GroupHeading = ({ children }: GroupHeadingProps<{}>) => {
return <div style={{ backgroundColor: "pink" }}>{children}</div>;
};
const App = () => (
<Select options={options} components={{ Option, GroupHeading }} />
);
export default App;
I STRONGLY recommend you go with option 1 - styling through the style
prop. With option 2, you will need to do a lot more work. You basically lose all the things that comes out the box and have to implement your own markup, styling, and accessibility features. It's really only useful for people with really complicated UI, which doesn't seem to be the case for you.
Upvotes: 2