Focus doesn't work with hover for MUI styled component? - css

Not sure why this doesn't work, but I can't seem to use focus and hover in the same MUI styled component for React. Here is a code sandbox to illustrate what I mean. When I click on the Select element, the background and border don't change colors:
const SelectStyle = styled(Select)(({ theme }) => ({
width: "175px",
border: `1px solid #C4CDD5`,
borderRadius: 3,
fontSize: "1.2rem",
"&:hover": {
backgroundColor: "#DFE3E8",
border: `1px solid #919EAB`
},
"&:focus": {
backgroundColor: "#54D62C",
border: `1px solid #AAF27F`
},
"& .MuiSelect-select": {
paddingTop: 5,
paddingBottom: 5,
fontSize: "1.2rem",
alignItems: "center",
display: "inline-flex"
}
}));
Not sure why this is or how to fix it?

Override .Mui-focused class like this :
"&.Mui-focused": {
backgroundColor: "#54D62C",
border: `1px solid #AAF27F`
}
Here is working example.

Related

Styling textarea in MUI using Styled Components

I am trying to change the border color on focus on a textarea component in MUI. I am using styled components:
import "./styles.css";
import { styled } from "#mui/material/styles";
const TextAreaStyle = styled("textarea")(({ theme }) => ({
border: `2px solid #F9FAFB`,
width: "100%",
flexGrow: 1,
boxSizing: "border-box",
borderRadius: 3,
backgroundColor: "#f8f8f8",
// font-size: 16px;
resize: "none",
"&:focus": {
border: `2px solid #454F5B`
},
"&:hover": {
border: `2px solid #F4F6F8`
}
}));
export default function App() {
return (
<div className="App">
<TextAreaStyle />
</div>
);
}
Sandbox: https://codesandbox.io/s/youthful-sammet-qhsfqf?file=/src/App.js
However, while the hover works, the focus does not work. The border color still looks like the default color. Can someone point me in the right direction?
Your code is working, is just that the color you have is too light and similar to the default color. Check it out:
https://codesandbox.io/s/cranky-leakey-mtfutl
EDIT: Updated the sandbox to remove the outline from Chrome
To remove that outline that some browsers have you just have to do
outline: "none"
SECOND EDIT:
for showing the focus border while on hover, just change the order of the styles, with focus last:
"&:hover": {
border: `2px solid #FF0000`
},
"&:focus": {
border: `2px solid #0FF00F`,
outline: "none"
}
I updated the sandbox to reflect that

How can I stop my Header links to wrap when testing for window size?

The image above is how my header normally looks, the image below is what happens when I start to shrink the window size.
What CSS can I use to stop the Text navLinks to stop wrapping like that?
Here is the CSS I use:
const useStyles = makeStyles((theme) => ({
// appBar is the CSS for the material-UI component
appBar: {
borderBottom: `1px solid ${ theme.palette.divider }`,
flexGrow: 1,
"#media (max-width: 1000px)": {
paddingLeft: 0,
}
},
// toolBar is the CSS wrapper for all <divs> inside the appBar
toolBar: {
display: "flex",
justifyContent: "space-between",
alignItems: "center",
padding: "0.5rem 0.5rem 0.5rem 1rem",
},
// LOGO text
toolbarTitle: {
flexGrow: 1,
fontFamily: 'Track',
textAlign: "left",
margin: "0.5rem",
paddingLeft: "100px",
"#media (max-width: 1000px)": {
marginLeft: "20px",
paddingLeft: 0,
}
},
// Here are my navLinks that are wrapping and causing the problem.
navLinks: {
fontWeight: 700,
size: "18px",
marginLeft: "70px",
padding: "0 1rem",
float: "center",
whiteSpace: "nowrap",
overflow: "hidden",
display: "inline-block",
},
Thank you for the help!
for example
#media (max-width: 700px)": {
navlinks{margin-left: 30px,}
}
You can use media queries, size is % and inline blocks.

Customize Autocomplete CSS when value is present in the TextField in React Material UI

I'm using React Material Autocomplete fields in my project that has a nested TextField. I've currently applied standard styles to it (when no value is present and just the label is showing in the field), and also different styles on hover. However, I want the same hover styles to be applied to the whole Autocomplete box (not just the TextField element) if the TextField has a value in it, but I'm unable to figure out how to do this. My Autocomplete code and current CSS styles are below. Please could anybody help and let me know how I can do this?
Autocomplete Code
const renderComponentList = (componentList, isDisabled, name, label) => (
componentList &&
<Autocomplete
classes={{
root: classes.root,
}}
options={componentList}
disabled={isDisabled}
name={name}
getOptionLabel={(option) => option.name}
onChange={
(event, value, reason) => {
this.handleAutocompleteChange(name, value);
}
}
style={{width: '100%'}}
renderInput={
(params) =>
<TextField
{...params}
name={name}
label={label}
variant="outlined"
/>
}
/>
);
CSS Styles
export const styles = theme => ({
// Autocomplete option styles
root: {
color: '#FFFFFF',
backgroundColor: '#303039',
opacity: 0.6,
"&:hover": {
backgroundColor: '#1E1E24',
borderRadius: '5px',
opacity: 1,
},
"&:focus-within": {
backgroundColor: '#1E1E24',
borderRadius: '5px',
opacity: 1,
},
// Something like this to style the autocomplete when input has a value, but this only
// targets the input field (TextField) rather than the whole Autocomplete field
// "& input[value]:not([value=''])": {
// backgroundColor: '#1E1E24',
// borderRadius: '5px',
// opacity: 1,
// },
"& .MuiOutlinedInput-notchedOutline": {
border: '1px solid #484850',
},
"&:hover .MuiOutlinedInput-notchedOutline": {
border: '1px solid #484850',
},
"&.Mui-focused .MuiOutlinedInput-notchedOutline": {
border: '1px solid #484850',
borderRadius: '5px 5px 0 0',
},
"& .MuiInputLabel-outlined": {
color: '#FFFFFF',
},
"& .Mui-disabled": {
opacity: 0.6,
},
"& .Mui-disabled .MuiOutlinedInput-notchedOutline": {
border: '1px solid #484850',
},
},
});
I've managed to resolve the issue. I had to create a new class for the desired style when a value was present and conditionally render it in the Autcomplete element, based on the relevant state.
To conditionally render the class, I had to pass in stateVal as one of the props in my function and then change the root line in the Autocomplete classes property to root: stateVal ? classes.rootHasVal : classes.rootHasNoVal, instead.

Material UI ListItem Selected Styling in React.js

I am using material-ui ListItem to show my nav bar items.
I wrote the following CSS code to show styling when each item selected.
<List>
{routes.map(route => (
<Link to={route.path} key={route.name} style={{ textDecoration: "none" }}>
<ListItem button key={route.name} className={classes.listWrap}>
<ListItemText primary={route.name} className={classes.listItemText} />
</ListItem>
</Link>
))}
</List>;
CSS
listWrap: {
"&:hover": {
border: "1px solid #6c757d",
color: "black"
},
textAlign: "center",
"&:active": {
background: "#6c757d",
color: "black"
}
}
When I select one ListItem the styling doesn't work
how can we fix?
You can use focus instead of active.
listWrap: {
"&:hover": {
border: "1px solid #6c757d",
color: "black"
},
textAlign: "center",
"&:focus": {
background: "#6c757d",
color: "black"
}
}

Material-UI Input component underline color

I am trying to make an input component that has a white underline. Currently, when the user hovers over the component, the underline color changes to black. I would expect this be white. I believe this should be possible by overriding the underline class as in the demo and outlined below. Unfortunately, it doesn't seem to work, but if I inspect the styles manually in the browser and remove the below line it works as expected in the browser.
Example: https://stackblitz.com/edit/yjpf5s (View: https://yjpf5s.stackblitz.io)
Style removed manually in browser to obtain desired functionality:
.MuiInput-underline-365:hover:not(.MuiInput-disabled-364):not(.MuiInput-focused-363):not(.MuiInput-error-366):before {
border-bottom: 2px solid rgba(0, 0, 0, 0.87);
The overide class style I am using:
underline: {
color: palette.common.white,
borderBottom: palette.common.white,
'&:after': {
borderBottom: `2px solid ${palette.common.white}`,
},
'&:focused::after': {
borderBottom: `2px solid ${palette.common.white}`,
},
'&:error::after': {
borderBottom: `2px solid ${palette.common.white}`,
},
'&:before': {
borderBottom: `1px solid ${palette.common.white}`,
},
'&:hover:not($disabled):not($focused):not($error):before': {
borderBottom: `2px solid ${palette.common.white}`,
},
'&$disabled:before': {
borderBottom: `1px dotted ${palette.common.white}`,
},
},
Edit:
Here is the solution that ended up working:
'&:hover:not($disabled):not($focused):not($error):before': {
borderBottom: `2px solid ${palette.common.white} !important`,
},
I took a look at the source code and they are doing something like this
{
focused: {},
disabled: {},
error: {},
underline: {
'&:before': {
borderBottom: '1px solid rgba(255, 133, 51, 0.42)'
},
'&:after': {
borderBottom: `2px solid ${theme.palette.secondary.main}`
},
'&:hover:not($disabled):not($focused):not($error):before': {
borderBottom: `2px solid ${theme.palette.secondary.main}`
}
}
It works for me.
Inspired by Guillaume's answer, here is my working code, simplified if you don't care about error state:
const WhiteTextField = withStyles({
root: {
'& .MuiInputBase-input': {
color: '#fff', // Text color
},
'& .MuiInput-underline:before': {
borderBottomColor: '#fff8', // Semi-transparent underline
},
'& .MuiInput-underline:hover:before': {
borderBottomColor: '#fff', // Solid underline on hover
},
'& .MuiInput-underline:after': {
borderBottomColor: '#fff', // Solid underline on focus
},
},
})(TextField);
Use:
<WhiteTextField
fullWidth
onChange={this.handleNameChange}
value={this.props.name}
/>
At first, add your input like this
<Input {...props} className='myClass' />
Now in your CSS
.gc-input-bottom::after{
border-bottom: 2px solid $input-border-color-active!important;
:hover{
border-bottom: none!important;
}
}
.gc-input-bottom::before{
border-bottom: 1px solid $input-border-bottom-color!important;
}
Here before will give you the always visible underline access and after will give you the after click underline access. Now just do what you want
try like this
.MuiInput-underline-24:hover:not(.MuiInput-disabled-23):not(.MuiInput-focused-22):not(.MuiInput-error-25):before {
border-bottom: 2px solid rgb(255, 255, 255) !important;
}

Resources