How to style react-select options? - reactjs

I have used a react-select for multiselect. Now I want to style it but not getting it.
const selectStyles = {
control: (base) => ({
...base,
fontSize: '16px',
fontWeight: 'bold',
borderRadius: '8px',
padding: '6px 5px',
border: '1px solid #21274F !important',
boxShadow: 'none',
'&:focus': {
border: '0 !important',
},
}),
}
<Select
placeholder='Type Team Name...'
value={getOptions(value)}
options={getOptions(data)}
onChange={(data) => setValue(data || [])}
styles={selectStyles}
isMulti
isClearable
isSearchable
/>
Its looking like this. I want to change the background-color to blue and text = white. How can I achieve this? please help.
EDIT: After applied #Manish Jangir code. It looking like this.
But I want the text ie. 'leadership' to appear white in color and on hover the appering red color on cross to be removed.

There are a lot of custom custom components to style the entire select. Have a look at this. You need to use multiValue component to style to change the styles of a single tag:
const selectStyles = {
control: (base) => ({
...base,
fontSize: '16px',
fontWeight: 'bold',
borderRadius: '8px',
padding: '6px 5px',
border: '1px solid #21274F !important',
boxShadow: 'none',
'&:focus': {
border: '0 !important',
},
}),
multiValue: (base) => ({
...base,
backgroundColor: 'blue',
color: 'white',
}),
}

It's been a while, but adding this here for who would have the same problem and wants to tackle it with custom components and custom styling.
I had the similar issue as well. Creating custom component like in docs and wrapping it around components.Option didn't give me the desired result in terms of styling.
After digging through, I found an example in react.select issues. So instead of creating custom component that wraps components.Option, you can now create your own component and pass in the props as you needed. This would also allow you to style the component with classes easily (in my case, it was Tailwind).

Related

Button on Hover shows boxShadow in ReactJs

I want this button to show boxShadow only at Hover. How to do that ?
Button code:
<CButton
style={{
float: 'right',
marginBottom: '15px',
marginRight: '30px',
backgroundColor: '#06ac06',
border: 'none',
boxShadow: '0 12px 16px 0 rgba(0,0,0,0.24),0 17px 50px 0 rgba(0,0,0,0.19)',
}}
</CButton>
Pseudo-classes like :hover are not available as inline style. You can implement the hover behavior in JS through a React state + onMouseEnter and onMouseLeave listeners (and then set the box-shadow value based on the state). But as you can see, this approach requires too much boilerplate. I would suggest using CSS-in-JS library like styled-components, utility class like Tailwind, or SCSS.
Try this code: https://codesandbox.io/s/kind-morning-s5sh64?file=/src/App.js
const [isHover, setIsHover] = useState(false)
//...
<CButton
onMouseEnter={() => setIsHover(true)}
onMouseLeave={() => setIsHover(false)}
style={{
float: 'right',
marginBottom: '15px',
marginRight: '30px',
backgroundColor: '#06ac06',
border: 'none',
transition: 'box-shadow .3s', //added for Smouth transition
boxShadow: `5px 5px 18px -3px rgba(0,0,0,${isHover ? 0.27 : 0})`,
}}
>
</CButton>
```

How to set border color using MUI styled components?

I am trying to add a border color to a styled component using MUI:
const Style = styled('div')(({ theme }) => ({
display: 'flex',
flexDirection: 'column',
borderColor: theme.palette.success.main,
border: 10,
borderTop: 10,
width: INFO_WIDTH
}));
However, I don't see any change in the effect:
Screenshot of browser
I'm trying to follow the guidelines specified by MUI but it's not working. Does anyone know a workaround?
The guidelines you linked to are for the sx prop (or lower-level usage of #mui/system) -- not the styled API. One key difference between the two is that for the sx prop, a numeric border value is treated as a shorthand for ${value}px solid. The styled API does not automatically add solid, so border: 10 just becomes border: 10px which is not sufficient for causing a border to be displayed.
A separate issue with your example is that you specify borderColor before border. Since border is a shorthand for border-width, border-style, and border-color, even when you don't specify a color with the border value, a previously specified border-color will be overridden with the default.
Below is an example showing the correct syntax for specifying the border for both sx and styled:
import * as React from "react";
import Box from "#mui/material/Box";
import { styled } from "#mui/material/styles";
const StyledDiv = styled("div")(({ theme }) => ({
border: "10px solid",
borderColor: theme.palette.success.main,
width: "5rem",
height: "5rem",
margin: theme.spacing(1)
}));
export default function BorderSubtractive() {
return (
<Box sx={{ display: "flex", justifyContent: "center" }}>
<Box
sx={{
border: 10,
borderColor: "success.main",
width: "5rem",
height: "5rem",
m: 1
}}
/>
<StyledDiv />
</Box>
);
}

How to Access Theme Colors Through SX in Material UI

How do I access the colors of the theme through using sx?
I tried below but it doesn't work.
<Card
sx={{
border: "2px solid primary.main",
}}
>
As an alternative, you should be able to do:
<Card sx={{border: "2px solid", borderColor: "primary.main"}}>
The shorthand "border" doesn't seem to access the theme colors properly. Hope that's helpful.
Update: Just wanted to add to this that you could also use a function value to set the border color according to your theme.
<Card sx={{border: "2px solid", borderColor: (theme) => theme.palette.primary.main}}>
The useTheme() hook will help:
export default function App() {
const theme = useTheme()
return <Card sx={{ border: `2px solid ${theme.palette.primary.main}` }}>...
}

Underline animation on hover MUI

Before anyone removes this question and says it is similar to this one please hear me out. I am trying to do almost exactly what is being done in that post. The issue is the person who responded just gave some CSS which does not answer the question at hand. I am trying to do this FULLY in MUI. I would preferably want to be able to style my component using the makeStyles hook.
How would one implement an underline animation below a typography component such as the ones on the navigation bar here? I am really new to JS and MUI so I would appreciate something which is well explained and implemented so I can learn the terminology as well as the frameworks themselves.
This is my code so far. It's just like the one in the first link.
const useStyles = makeStyles({
link: {
color: "white",
position: "relative",
"&:before": {
content: "",
position: "absolute",
width: "0",
height: "2px",
bottom: "0",
left: "0",
backgroundColor: "#FFF",
visibility: "hidden",
transition: "all 0.3s ease-in-out",
},
"&:before:hover": {
visibility: "visible",
width: "100%"
}
}
});
function NavButton(props){
const classes = useStyles();
return (
<a href={`/#${props.text}`}>
<Link className={classes.link}>
<Typography>{props.text}</Typography>
</Link>
{/*<p className={"hover-underline-animation"}*/}
{/* {props.text}*/}
{/*</p>*/}
</a>
);
}
I am receptive to any other types of input. These questions are just as much a way for me to learn as a way to get an answer.
Working code
const useStyles = makeStyles({
link: {
color: 'white',
position: 'relative',
'&:before': {
content: "''",
position: 'absolute',
width: '0',
height: '2px',
bottom: '-3px',
left: '50%',
transform: 'translate(-50%,0%)',
backgroundColor: 'red',
visibility: 'hidden',
transition: 'all 0.3s ease-in-out',
},
'&:hover:before': {
visibility: 'visible',
width: '100%',
},
},
});
<Link underline="never" className={classes.link}>
<Typography component="span">link</Typography>
</Link>
Some explanation why your code didn't work:
Change content: "" to content: "''". Related answer.
Add underline="never" to Link to remove the built-in underline in the anchor element when hovering.
Change the Typography's root component to span or set its display to inline to make the container width and the underline width match the text content.
Change &:before:hover to &:hover:before: The former means hover the underline to run the animation, but its width is 0 so it can't be hovered, the latter means hover the link to run the line animation.
Add these 2 lines to make the underline expands from the middle:
left: '50%',
transform: 'translate(-50%,0%)',
I have spent hours trying to find the right combination to use Link and override the webkit underline to prevent the links in my navigation from having an underline without explicitly adding text-decoration: none to my global CSS. I had to add 'textDecoration: 'none' to the makeStyles function in this example and of course change red to blue but this works beautifully for my nav bar.
const useStyles = makeStyles({
link: {
color: 'white',
position: 'relative',
textDecoration: 'none',
'&:before': {
content: "''",
position: 'absolute',
width: '0',
height: '2px',
bottom: '-3px',
left: '50%',
transform: 'translate(-50%,0%)',
backgroundColor: 'blue',
visibility: 'hidden',
transition: 'all 0.3s ease-in-out',
},
'&:hover:before': {
visibility: 'visible',
width: '100%',
},
},
})

Changing height of react-select component

I am using the react-select component along with bootstrap v4
all of bootstraps stuff is based on 35px height it seems, the default height of the react-select component is 38px, which looks a little odd.
Any ideas how I can change the height of the component?
It is using some weird JS styling library I have never come across before. I have managed to get it to mimic the outline on focus using it, but the height escapes me, any help much appreceiated
You can play with it here
Spending hours, I end up with this to get exact 30px height of react select with border 1px:
const customStyles = {
control: (provided, state) => ({
...provided,
background: '#fff',
borderColor: '#9e9e9e',
minHeight: '30px',
height: '30px',
boxShadow: state.isFocused ? null : null,
}),
valueContainer: (provided, state) => ({
...provided,
height: '30px',
padding: '0 6px'
}),
input: (provided, state) => ({
...provided,
margin: '0px',
}),
indicatorSeparator: state => ({
display: 'none',
}),
indicatorsContainer: (provided, state) => ({
...provided,
height: '30px',
}),
};
You can add your styles to any part of the select components, take a look at the relevant docs
here is a working demo of what you ask for.
In your case the code that you need to add will look something like this:
const customStyles = {
control: base => ({
...base,
height: 35,
minHeight: 35
})
};
and in the select component:
<Select
className="basic-single"
classNamePrefix="select"
defaultValue={colourOptions[0]}
isDisabled={isDisabled}
isLoading={isLoading}
isClearable={isClearable}
isRtl={isRtl}
isSearchable={isSearchable}
name="color"
options={colourOptions}
styles={customStyles}
/>
The reason why you're not able to make it less than 36px is that the dropdownIndicator and indicatorContainer(clear icon is displayed) are taking 20px (icon) + 8px padding in all sides. If you reduce that padding, the minHeight will actually work.
dropdownIndicator: (styles) => ({
...styles,
paddingTop: 7,
paddingBottom: 7,
}),
clearIndicator: (styles) => ({
...styles,
paddingTop: 7,
paddingBottom: 7,
}),
You can play around with the padding of the dropdownIndicator and clearIndicator.
I noticed that you can't go under 30px in minHeight because of the valueContainer, unless you change its height/padding.
CSS Way
You can specify classNamePrefix and use it to override CSS styles.
<Select classNamePrefix="mySelect" />
.mySelect__value-container{
height: 35px;
}
I was barely able to make the Select component as small as 32px (in my browser) using the theme attribute. It works well when the height is greater than 45px. You can also omit the baseUnit attribute.
It didn't work for small sizes.
const theme = (theme: Theme) => ({
...theme,
spacing: {
...theme.spacing,
controlHeight: 30,
baseUnit: 0,
}
});
<Select options={props.options} theme={theme}/>
I was able to over write the menu-list's css style:
/* over write css in react-select module */
.Select__menu-list {
max-height: 120px !important;
}
If you only want to resize the box use this.
.create-select {
width: 160px;
float: right;
color: #000;
[class$="ValueContainer"] {
min-height: 28px !important;
max-height: 28px;
}
[class$="IndicatorsContainer"] {
min-height: 28px !important;
max-height: 28px;
}
[class$="-Input"] {
min-height: 28px !important;
max-height: 28px;
padding: 0px;
}
[class$="-control"] {
min-height: 28px !important;
max-height: 28px;
}
}
Cause
The .control has a min-height of 38px defined.
Fix
Change the min-height on the .control to your desired height.
const customStyles = {
control: (provided, state) => ({
...provided,
minHeight: '30px',
...additionalStyles
}),
};
In my case, I had to just set the css height property for the class
__value-container
Here is the code:
.react-select__value-container {
height: 3rem;
}
export const customStyles = {
control: (provided: Record<string, unknown>, state: any) => ({
...provided,
height: 42,
boxShadow: 'none',
borderColor: 'none',
'&:hover': {
color: '#60B3D1'
},
border: state.isFocused ? '1.5px solid #60B3D1' : '1.5px solid #cbd5e1'
}),
option: (styles: any, state: any) => ({
...styles,
color: state.isSelected ? '#FFF' : styles.color,
backgroundColor: state.isSelected ? '#60B3D1' : styles.color,
borderBottom: '1px solid rgba(0, 0, 0, 0.125)',
'&:hover': {
color: '#FFF',
backgroundColor: '#60B3D1'
}
}),
input: (base: any) => ({
...base,
'input:focus': {
boxShadow: 'none',
border: '1px solid #60B3D1'
}
}),
menuPortal: (base: any) => ({ ...base, zIndex: 9999 })
}
<Select styles={customStyles } />
This really works well for me

Resources