0

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>
Jimmy
  • 3,090
  • 12
  • 42
  • 99
  • *"Essentially, I want to create a button whose focus is changed by a hover"* - But do you actually want to set (keyboard) focus, or just style it? – nnnnnn Oct 22 '17 at 03:46
  • Jimmy my man you know how many times this has been asked here? Can we get a duplicate. – Darkrum Oct 22 '17 at 03:48
  • Possible duplicate of [How to use 'hover' in CSS](https://stackoverflow.com/questions/905033/how-to-use-hover-in-css) – Darkrum Oct 22 '17 at 03:51
  • Well, sorry Darkrum, but I've done plenty of searching and still can't find a more simple solution. nnnnnn, essentially I just want to duplicate the styling seen at the link provided. Thanks guys! – Jimmy Oct 22 '17 at 03:53
  • @Darkrum - This may be a duplicate, but not of the question you found, because in *this* question the OP doesn't want the style to be removed on mouseout, he wants it to stay until another button is hovered. – nnnnnn Oct 22 '17 at 03:53
  • This should help then https://stackoverflow.com/questions/17100235/make-css-hover-state-remain-after-unhovering – Darkrum Oct 22 '17 at 03:57
  • Thanks Darkrum but I have already reviewed that post, and the discussion seems to be more surrounded by styling staying permanent on hover, but not as much about the removal of styling when another hover event occurs, and having those hover events of duplicate elements communicate to each other. – Jimmy Oct 22 '17 at 04:01
  • @jimmy your right it doesn't completely answer your question which is by design in the hopes you might realize what you need to search. But here i will just tell you what to search for "add style on hover and remove from siblings". – Darkrum Oct 22 '17 at 04:08

2 Answers2

1

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>
Ori Drori
  • 183,571
  • 29
  • 224
  • 209
0

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.