Reputation: 3860
I want to create a button whose styling changes on a hover and stays that way until another hover occurs. Essentially, I want to create a button whose focus is changed by a hover, as seen here. I think I can do this with some functions changing the state between the parent and child, but is there a more simple way of doing this? Thanks.
class Button extends React.Component {
render() {
return (
<button>{this.props.title}</button>
);
}
}
class Parent extends React.Component {
render() {
return (
<div>
<Button title={"button 1"}/>
<Button title={"button 2"}/>
<Button title={"button 3"}/>
</div>
);
}
}
ReactDOM.render(<Parent />, app);
button:hover {
background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="app"></div>
Upvotes: 0
Views: 1636
Reputation: 191976
The Parent
is the only place that knows the buttons, and since the active
change needs to be persistent, you'll need to change the state:
class Button extends React.Component {
onHover = () => this.props.onHover(this.props.buttonId);
render() {
const { title, activeId, buttonId } = this.props;
return (
<button onMouseOver={this.onHover}
className={ activeId === buttonId ? 'active' : '' }>
{title}
</button>
);
}
}
class Parent extends React.Component {
constructor(props) {
super(props);
this.state = {
activeId: null
}
}
onButtonHover = (activeId) => this.setState({ activeId });
render() {
const { activeId } = this.state;
return (
<div>
<Button title={"button 1"}
onHover={this.onButtonHover}
buttonId={0}
activeId={ activeId } />
<Button title={"button 2"}
onHover={this.onButtonHover}
buttonId={1}
activeId={ activeId } />
<Button title={"button 3"}
onHover={this.onButtonHover}
buttonId={2}
activeId={ activeId } />
</div>
);
}
}
ReactDOM.render(<Parent />, app);
.active {
background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="app"></div>
Upvotes: 1
Reputation:
Here you have a possible CSS only solution: https://jsfiddle.net/ggcybu71/
.option:hover {
text-decoration: underline;
}
.option:hover:after {
content: "";
display: block;
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
z-index: -1;
}
It is way too "hacky", so I would only see it as a curiosity and I would probably not use it in production. I would implement a Javascript based mousemove event listening solution instead.
Upvotes: 0