Change scrollbar by hover. (React /css) - Material-UI - css

I have a scrollbar in multiple lists in the React app.
My global CSS within Material-UI is:
MuiCssBaseline: {
...theme.overrides?.MuiCssBaseline,
'#global': {
'#font-face': fontFace,
'*::-webkit-scrollbar': {
width: '1.3%',
maxWidth: '5px'
},
'*::-webkit-scrollbar-thumb': {
backgroundColor: 'white'
},
'*:focus': {
outline: 'none'
}
}
}
};
I am trying to add global state for hover.
When I hover on the box(!) not on the scroll itself, the scrollbar should be changed to gray.
Let's say I have box like:
<Box className={listStyle.root}>
<AutoSizer>
{({ height, width }) => (
<List dense ......
return (
<ListItem
/>
);
})}
</List>
)}
</AutoSizer>
I tried something like the following and it's not working:
.listStyle:{
'&:hover':{
'*::-webkit-scrollbar-thumb': {
backgroundColor: 'gray'
},
}
}
How can I achieve that?

The primary issue I see is that when nesting a rule (e.g. ::-webkit-scrollbar-thumb pseudo-element within :hover pseudo-class), you need to use & to refer to the parent rule instead of using *. So your listStyle should look like:
.listStyle:{
'&:hover':{
'&::-webkit-scrollbar-thumb': {
backgroundColor: 'gray'
},
}
}
It would also be equivalent to do the following:
.listStyle:{
'&:hover::-webkit-scrollbar-thumb': {
backgroundColor: 'gray'
}
}
If you want to apply this globally, you can do something like the following (I've changed the colors just to make the effects more easily distinguishable from browser defaults):
const theme = createMuiTheme({
overrides: {
MuiCssBaseline: {
"#global": {
"*::-webkit-scrollbar": {
width: "1.3%",
maxWidth: "5px"
},
"*::-webkit-scrollbar-thumb": {
backgroundColor: "purple"
},
"*:hover": {
"&::-webkit-scrollbar-thumb": {
backgroundColor: "green"
}
}
/* Equivalent alternative:
"*:hover::-webkit-scrollbar-thumb": {
backgroundColor: "green"
}
*/
}
}
}
});
Here is a full example showing both the global approach and overriding that using a class name at a lower level:
import React from "react";
import CssBaseline from "#material-ui/core/CssBaseline";
import {
ThemeProvider,
createMuiTheme,
makeStyles
} from "#material-ui/core/styles";
const theme = createMuiTheme({
overrides: {
MuiCssBaseline: {
"#global": {
"*::-webkit-scrollbar": {
width: "1.3%",
maxWidth: "5px"
},
"*::-webkit-scrollbar-thumb": {
backgroundColor: "purple"
},
"*:hover": {
"&::-webkit-scrollbar-thumb": {
backgroundColor: "green"
}
}
/* Equivalent alternative:
"*:hover::-webkit-scrollbar-thumb": {
backgroundColor: "green"
}
*/
}
}
}
});
const useStyles = makeStyles({
divStyle: {
"&:hover::-webkit-scrollbar-thumb": {
backgroundColor: "red"
}
}
});
export default function App() {
const classes = useStyles();
return (
<ThemeProvider theme={theme}>
<CssBaseline />
<div style={{ height: "200px", overflowY: "scroll" }}>
<h1>
Div with enough content to scroll. Globally controlled scrollbar hover
color
</h1>
<h2>1</h2>
<h2>2</h2>
<h2>3</h2>
<h2>4</h2>
<h2>5</h2>
<h2>6</h2>
</div>
<div
style={{ height: "200px", overflowY: "scroll" }}
className={classes.divStyle}
>
<h1>
Div with enough content to scroll. Scrollbar hover color controlled by
classes.divStyle.
</h1>
<h2>1</h2>
<h2>2</h2>
<h2>3</h2>
<h2>4</h2>
<h2>5</h2>
<h2>6</h2>
</div>
</ThemeProvider>
);
}

Related

How to change the hover effect color on the options of material ui select component in react js?

I was trying to change the hover effect of mui Auto Complete component options [inside the drop down]. But it seems I can not find the proper method to do so.
This is the hover effect I am trying to change : Image
I want to put my own color choice.
This is my code [sorry I am new to react. pretty bad codes] .
I tried many solution from stack overflow and other websites. They did not work for me [may be because I did not understand what they were saying].
I just want to change the hover effect color, when the mouse hovers over the options inside the select componenet. But I can not figure out how to do it.
This is my component Image
export default function SelectBox ( { ...props } ) {
return (
<Autocomplete
autoComplete={ true }
disablePortal
id="combo-box-demo"
options={ props.options }
ChipProps={ { backgroundColor: "green" } } // I have no idea what this does
sx={ {
width: { xs: 100, sm: 130, md: 150, lg: 170 },
// no idea what this does too
"& + .MuiAutocomplete-popper .MuiAutocomplete-option[aria-selected='true']" :
{
backgroundColor: "#FF8787",
},
} }
renderInput={ ( params ) => <TextField { ...params } label={ props.label } size='small' className='color-change'
sx={ {
width: "80%", backgroundColor: "#F1F1F1",
'.MuiOutlinedInput-notchedOutline': {
borderColor: '#C6DECD',
}, borderRadius: 2,
"&:hover .MuiOutlinedInput-notchedOutline": {
borderColor: "green"
}, "&:hover": {
"&& fieldset": {
border: "1px solid green"
}
}
} } /> }
/>
);
}
Assuming that the goal is to customize the background color of options when being hovered, it seems that posted code just need to add :hover to a selector for the sx prop of Autocomplete.
Simplified example tested here: stackblitz
Change the following selector:
"& + .MuiAutocomplete-popper .MuiAutocomplete-option[aria-selected='true']": {
backgroundColor: "#FF8787",
};
To add :hover so that it selects the hovered:
// 👇 Select the hover item here
'& + .MuiAutocomplete-popper .MuiAutocomplete-option:hover': {
// 👇 Customize the hover bg color here
backgroundColor: "#FF8787",
};
Full example for Autocomplete, the original selector is kept in here so it customizes the selected item to match the hover effect, but this an optional approach.
export default function SelectBox(props) {
return (
<Autocomplete
autoComplete={true}
disablePortal
id="combo-box-demo"
options={props.options}
ChipProps={{ backgroundColor: "green" }}
sx={{
width: { xs: 100, sm: 130, md: 150, lg: 170 },
// 👇 Select the hover item here
"& + .MuiAutocomplete-popper .MuiAutocomplete-option:hover": {
// 👇 Customize the hover bg color here
backgroundColor: "hotpink",
},
// 👇 Optional: keep this one to customize the selected item when hovered
"& + .MuiAutocomplete-popper .MuiAutocomplete-option[aria-selected='true']:hover":
{
backgroundColor: "hotpink",
},
}}
renderInput={(params) => (
<TextField
{...params}
label={props.label}
size="small"
className="color-change"
sx={{
width: "80%",
backgroundColor: "#F1F1F1",
".MuiOutlinedInput-notchedOutline": {
borderColor: "#C6DECD",
},
borderRadius: 2,
"&:hover .MuiOutlinedInput-notchedOutline": {
borderColor: "green",
},
"&:hover": {
"&& fieldset": {
border: "1px solid green",
},
},
}}
/>
)}
/>
);
}

React- Conditionally applying css in div but it does not work

Have looked at other examples and trying to do the same thing but not sure why my code is not working. I have code which loops through some keys and renders a div. I want to conditionally apply some styles based on whether the key is even or odd. Example:
<div className={parseInt(key) % 2 === 0 ? 'label1' : 'label2' }>
<span style={{ marginLeft: "10px" }}>{key}:00</span>
</div>
The styles are accessible in the same file and look something like:
# Material UI
const useStyles = makeStyles((theme) => ({
label1: {
width: "50px",
height: "16px",
top: "458px",
background: "yellow",
fontSize: "12px",
},
label2: {
width: "50px",
height: "16px",
top: "458px",
background: "red",
fontSize: "12px",
},
}));
What am I doing wrong? Currently no style is getting applied to the div
You need to use the classes from the material ui useStyles hook.
const classes = useStyles()
....
<div className={parseInt(key) % 2 === 0 ? classes.label1 : classes.label2 }>
<span style={{ marginLeft: "10px" }}>{key}:00</span>
</div>
Check the useStyles hook api: https://material-ui.com/styles/basics/
If you have a class component and you can use hooks then you can do it with the withStyles higher order component, like this example:
import { withStyles } from "#material-ui/core/styles"
const styles = theme => ({
label1: {
backgroundColor: "red",
},
label2: {
backgroundColor: "red",
},
})
class ClassComponent extends Component {
state = {
searchNodes: "",
}
render() {
const { classes } = this.props
return (
<div className={parseInt(key) % 2 === 0 ? classes.label1 : classes.label2}>
<span style={{ marginLeft: "10px" }}>{key}:00</span>
</div>
)
}
}
export default withStyles(styles, { withTheme: true })(ClassComponent)

How to style InputLabel & Select on an AppBar?

Still very new to Material-UI. Using the default theme/colors, I want to create an AppBar that has a FormControl/InputLabel/Select/MenuItem in it. With the defaults, I get a black input field on blue, which isn't great. I think probably having the input field and labels be theme.palette.primary.light would make more sense. I started to look in to how to do this and got in to setting FormLabelClasses to the InputLabel, setting inputProps to Select to set classes on the icon, and setting &:before and &:after to borders on the Select and so on... I feel like I'm doing this wrong since that seems to be quite a bit of work for something I think would be somewhat normal to do? To top it off, it's still not right (when you hover, the underline border goes black and I can't figure out how to fix that!)
Here's my code:
const styles = theme => ({
root: {
minWidth: 200,
marginTop: '-10px',
},
inputLabel: {
color: theme.palette.primary.light,
'&$inputLabelFocused': {
color: theme.palette.primary.light,
},
},
inputLabelFocused: {
},
icon: {
fill: theme.palette.primary.light,
},
select: {
color: theme.palette.primary.light,
'&:before': {
borderColor: theme.palette.primary.light,
},
'&:after': {
borderColor: theme.palette.primary.light,
},
},
})
class CustomSelector extends React.Component {
render() {
const { classes } = this.props;
return(
<div>
<FormControl className={classes.root}>
<InputLabel FormLabelClasses={{ root: classes.inputLabel, focused: classes.inputLabelFocused }}>Choose</InputLabel>
<Select value="" className={classes.select} inputProps={{ classes: { icon: classes.icon } }} autoWidth="true">
<MenuItem value=""><em>None</em></MenuItem>
<MenuItem value="Value 1">Value 1</MenuItem>
</Select>
</FormControl>
</div>
)
}
}

Customizing the Material UI 1.3.1 Expansion Panel

I have the background image on the header, but when I open it up the image continues to the body. Is there a way to have the expanded text not have the same background as the header? Thanks in advance!
const styles = theme => ({
expansion: {
backgroundImage: `url(${Tuesday})`,
width: "100%"
},
head: {
height: '84px'
},
text: {
color: 'white',
fontSize: '32px',
fontFamily: 'AvenirNext-Heavy'
},
body: {
backgroundImage: 'none'
}
});
const ExpandedMenu = (props) => {
const { classes } = props;
return(
<div>
<ExpansionPanel className={classes.expansion}>
<ExpansionPanelSummary className={classes.head} expandIcon={<ExpandMoreIcon />}>
<Typography className={classes.text}>TUESDAY</Typography>
</ExpansionPanelSummary>
<ExpansionPanelDetails className={classes.body}>
<Typography className={classes.body}>
<p>example text</p>
</Typography>
</ExpansionPanelDetails>
</ExpansionPanel>
</div>
)
}
just give the backGroundImage to your .head class:
this sandbox is the one that #SumanKundu built and I changed it to satisfy your need.
You can simply add inline styles but as #TFischer said withStyles will be a better option.
You can go to this sandbox for a working example and check if it works for you:
https://codesandbox.io/s/03x2r4lw2w

How to disable the hover effect of material-ui button inside of a styled component

I added the css hover property to disable the button's hover effect, but it seems not work for my case, how should I fix this?
import Button from 'material-ui/Button'
import styled from 'styled-components'
const StyledButton = styled(Button)`
&:hover {
background: none;
}
`
export const SubmitButton = ({ onClick }) => {
return (
<StyledButton
variant="raised"
onClick={onClick}>
login
</StyledButton>
)
}
You can solve this problem by adding an inline style
export const SubmitButton = ({ onClick }) => {
return (
<StyledButton
variant="raised"
onClick={onClick}
style={{ backgroundColor: 'transparent' }} >
login
</StyledButton>
)
}
Try setting it to the same color as the background:
root = {
backgroundColor: "#FFF"
"&:hover": {
//you want this to be the same as the backgroundColor above
backgroundColor: "#FFF"
}
}
this is solution for v5 if anyone needs it
<IconButton
disableElevation
disableRipple
size="small"
sx={{
ml: 1,
"&.MuiButtonBase-root:hover": {
bgcolor: "transparent"
}
}}
>
</IconButton>
You can try setting the background of the button as none
button: {
'&:hover': {
background: 'none',
},
}
If you used the origin Button component with className instead, you could have added disableRipple to the button like that.
<Button disableRipple>
You can just override it via a styled component:
const StyledButton = styled(Button)`
&:hover {
background-color: transparent;
}
`;
This should work
const StyledButton = styled(Button)`
&&.MuiButton-root {
&:hover {
background: none;
}
}
`

Resources