How to do CSS :hover function in JSX ? - reactjs

Hi and thanks for the great job here. I am using react.js for my project to build my components and I feel a little bit stuck in my project right now. I am trying to style a button with a hover function and I don't know how to apply this to react.
Here is the code :
let button = {
backgroundColor: colorPalette.white,
border: "1px solid rgb(12,106,145)",
color: colorPalette.brandCol1,
textAlign: 'center',
textDecoration: 'none',
fontSize : 'inherit',
fontWeight : 600,
padding : "5px 8px 5px 8px"
}
and I would like to add a hover style to it just like we do in css with
button:hover {
style here.......
}
What is the correct syntax ?

You can use:
const styles = {
myStyleClassName: {
padding: '16px 0px 16px 0px',
'& a': {
textDecoration: 'none',
color: '#0000ee',
},
'& a:hover': {
textDecoration: 'underline',
},
},
myButtonClass: {
'&:hover': {
textDecoration: 'underline',
},
},
};
....
render() {
<span className={myStyleClassName}><a tag><button><someDomObjct></span>
<button className={myButtonClass}>my label</button>
}
See: http://cssinjs.org/jss-nested/?v=v6.0.1
The repo isn't necessary for everything, the above should work out of the box.

You can use onMouseEnter onMouseLeave to adjust the state of the component
<button
onMouseEnter={() => setButtonHovered(true)}
onMouseLeave={() => setButtonHovered(false)}
className={buttonIsHovered ? 'hover' : null}
/>
see here for more info
or just use a css class?
import './style.css'
<button className="Button"/>
.Button:hover {
...
}

Using react to manage state for a hover animation is way overkill. You shouldn't need to use javascript for a simple CSS hover...You're in the browser, use the right tool for the right job, right?
So here I'll show a couple different ways to approach the same goal:
In my component I import glamor and my styles file:
import { style } from 'glamor';
import styles from '../styles';
And in my styles file, I have something like this:
import { style } from 'glamor';
const styles = {
redHoverbutton: style({
backgroundColor: "#aaaaaa",
fontSize: "1.1rem",
transition: "all ease .5s",
":hover": {
backgroundColor: "#ff0000",
color: "#ffffff"
}
})
};
export default styles;
And this makes the hover functionality work via css, like this:
<div {...styles.redHoverbutton}></div>
This is a css driven hover effect (with transition if you noticed) but this isn't inline css. None the less, your style can be crafted in the same file, like this:
let theStyle = style({ backgroundColor: "#aaaaaa",transition: "all ease .5s", ":hover": { cursor: "pointer", backgroundColor: "#ffff9b", color: "#fd0808" } });
return (<div {...theStyle}>Hover me!</div>);
Now, how to get the style and the spread operator onto the same line and inside of the JSX element?
<div {...style({ backgroundColor: "#aaaaaa", height: "30px", width: "100%", padding: "6px", fontsize: "16px", transition: "all ease .5s", ":hover": { cursor: "pointer", backgroundColor: "#ffff9b", color: "#fd0808" } })}>Hover Me!</div>
It may not be perfect but it works well and accomplished the same thing as a true inline style and in a similar manner.

Related

How to make an MUI 5 checkbox & label change color on hover?

I'd like to have a checkbox with a label in a wrapper. When the wrapper is hovered everything should change color. See the image:
Here is my code:
const styles = {formControlLabel:{
color:'#d7dae0',
border: '1px solid white',
span: {
color: '#d7dae0',
'&:hover':{border: '1px solid red'},
}
},
}}
export function MyCheckbox(){
return(
<FormControlLabel
control={<Checkbox />}
label={'test'}
sx={styles.formControlLabel}
/>
)
}
I've tried many different things, but this is the closest I've come. I can't seem to put a '&:hover' on the formControlLabel styles at the top level - it has to be imbedded in another element. Why is that?
Sandbox: https://codesandbox.io/s/magical-feynman-lzy1e2?file=/src/App.tsx
You need to change your :hover to your parent and set borderColor in the parent and having span inside the :hover parent, it will change to red at the same time
const styles = {
formControlLabel: {
border: "1px solid",
p: "8px",
m: "20px",
"&:hover": {
borderColor: "red",
span: {
color: "red"
},
}
}
};

is it possible to animate a strikethrough with React Spring?

I'm new to React Spring and I initially tried this
const strikeProps = useSpring({
textDecoration: "line-through",
from: { textDecoration: "none" },
});
But it's not working. I think there should be a way simulate the CSS solution for this.
The problem here is, that the original CSS solution is uses pseudo element for emulating the strike trough. We can only add react-spring properties for normal html elements. So the most compact way is to create a separate strike through component for this problem. For example:
const StrikeTroughtText = ({ children, weight = 1 }) => {
const props = useSpring({
from: { width: "0%" },
to: { width: "100%" }
});
return (
<div style={{ position: "relative", display: "inline-block" }}>
{children}
<animated.div
style={{
position: "absolute",
top: "50%",
left: 0,
width: props.width,
height: `${weight}px`,
background: "black"
}}
/>
</div>
);
};
We basically animate the width of the absolutely positioned div containing a black line over the text.
You can use it like a div component:
<StrikeTroughtText>text</StrikeTroughtText>
For bigger font size the default 1 px line weight is not enough, so I added a weight property also.
Here is my example: https://codesandbox.io/s/react-strike-trought-text-component-with-react-spring-animation-86cfd?file=/src/App.js

How do I add a hover selector to a style object?

I created a style object in react that I will pass through a style prop:
const iconStyle = {
color: "#464545",
fontSize: "24px",
margin: "20px",
transitionProperty: "color",
transitionDuration: "1s",
}
Any idea on how I could add a hover selector inside of it, because I've looked around and I still have no clue.
probably this pseudo selector will help.
const iconStyle = {
color: "#464545",
fontSize: "24px",
margin: "20px",
transitionProperty: "color",
transitionDuration: "1s",
"&:hover": {
background: "#efefef"
},
}
In React.js there is no such way hover.
You can accomplish your goal with these two states.
onMouseEnter={() => this.setState({hover: true})}
onMouseLeave={() => this.setState({hover: false})}
And you can use "hover" state(for example) to specify styles like
style = this.state.hover ? style1 : style2
Hope this helps you to understand!

Component link hover style to use hover

I use the react-router-dom to create my routes because this has use component Link in my menu, but I want to custom that component. I have customing with const and Work, but my hover does't work.
My code:
<Link className="ui-link" style={styles.menuStyle} to={'/home'}>
<MdStore size={25} color="#5f5f5f" />
<Opt>Consumidores</Opt>
</Link>
My CSS, but my hover does't work:
const styles = {
menuStyle: {
textDecoration: 'none',
display: 'flex',
alignItems: 'center',
padding: '10px',
borderRadius: '8px',
margin: '5px 0px',
'&:hover': {
backgroundColor: '#171717',
},
},
};
why do not use the className="ui-link" and create a style to class?
For example:
a.ui-link:hover {
backgroundColor: '#171717';
}
I'm not really sure if you can do it like that, You can do one of the following:
Use styled components there you can simply style your Link tag with
whichever styles you want with pure css code
Use mouseEnter, mouseLeave events
Style it the regular way you would

How to change the styles of ListItem element with the "onclick" event?

My goal is when I click on a ListItem, it should change the background-color and text: "line-through". And then, if I click again, these changes should be canceled.
But it happens very strangely for me. I just can't understand why ListItem changes background-color only after I click to any place of the window? And why text into ListItem becomes crossed out only after I move pointer beyond the element
const styles = () => ({
listItem: {
borderRadius: "1em"
},
listItemDone: {
borderRadius: "1em",
backgroundColor: "#F6F6E8",
textDecoration: "line-through"
},
iconButton: {
padding: 5
},
important: {
color: "#00ACE9",
fontWeight: "bold"
}
});
class TodoListItem extends Component {
state = {
done: false
};
onClickItem = () => {
this.setState({
done: !this.state.done
});
};
render() {
const { label, important = false, classes } = this.props;
const { done } = this.state;
return (
<ListItem
onClick={this.onClickItem}
className={done ? classes.listItemDone : classes.listItem}
button
divider
>
<ListItemText
primary={label}
classes={{ primary: important ? classes.important : "" }}
/>
</ListItem>
);
}
}
Whenever you are trying to override Material-UI styles and it isn't working like you would expect, the best resource is the source code. Here is the URL for the ListItem source code: https://github.com/mui-org/material-ui/blob/master/packages/material-ui/src/ListItem/ListItem.js. For the most part, you only need to look at the styles variable near the top of the source file.
Below I've copied all of the portions of the styles variable that deal with backgroundColor and textDecoration:
export const styles = theme => ({
/* Styles applied to the (normally root) `component` element. May be wrapped by a `container`. */
root: {
textDecoration: 'none',
'&$selected, &$selected:hover, &$selected:focus': {
backgroundColor: theme.palette.action.selected,
},
},
/* Styles applied to the inner `component` element if `button={true}`. */
button: {
transition: theme.transitions.create('background-color', {
duration: theme.transitions.duration.shortest,
}),
'&:hover': {
textDecoration: 'none',
backgroundColor: theme.palette.action.hover,
// Reset on touch devices, it doesn't add specificity
'#media (hover: none)': {
backgroundColor: 'transparent',
},
},
'&:focus': {
backgroundColor: theme.palette.action.hover,
},
},
/* Styles applied to the root element if `selected={true}`. */
selected: {},
});
The main styles causing difficulty are the button hover and focus styles. In order to override these successfully without resorting to "!important", you need to have the appropriate CSS specificity.
The following seems to do the trick:
listItemDone: {
borderRadius: "1em",
"&,&:focus,&:hover": {
backgroundColor: "#F6F6E8",
textDecoration: "line-through"
}
},
However, the above prevents there from being any hover effect on "done" items, so you may instead want to do something more like:
listItemDone: {
borderRadius: "1em",
"&,&:focus": {
backgroundColor: "#F6F6E8",
textDecoration: "line-through"
},
"&:hover": {
textDecoration: "line-through"
}
},
This allows the hover background color of done items to still be theme.palette.action.hover. If you want the hover color to be different for done items, you can specify it explicitly along with the textDecoration.
There is one other detail to take care of. If you click a list item to put it in a "done" state and then click it again, it will not be in the "done" state anymore but it will have the button focus styles applied. In order to remove that focus styling, you also need the following:
listItem: {
borderRadius: "1em",
"&,&:focus": {
backgroundColor: theme.palette.background.paper // or whatever color you want this to be
}
},
Here is my modified version of your sandbox:
So I've tried to add !important to this styles and it started working as expected:
listItemDone: {
borderRadius: "1em",
backgroundColor: "#F6F6E8 !important",
textDecoration: "line-through !important"
},
demo.
It looks like this material-ui just overrides your styles (textDecoration and backgroundColor) when you hover over elements. Hope that helps.

Resources