Menu React

Starting point for creating JSFiddles with React.

by jpeter06

HTML

<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="container">
    <!-- This element's contents will be replaced with your component. -->
</div>

CSS

body{background: #20262e;}
ul.menu { padding:0; margin: 0px 0px 0px 20px ; list-style: none; position: relative; background:#444}
ul.menu li { display: inline-block;font-size: 14px; margin:10px 0px 0px 10px; padding: 0px 10px 4px 0px; text-decoration: none; text-transform: uppercase; color: #ccc;
cursor:pointer;}

ul.menu li.selected { color:red !important;}

ul.menu li:hover { color: white; }
#magic-line { position: absolute; bottom: -4px; transition:all 0.4s ease-in-out 0.12s; background:red;
     left: 0; width: 10px; height: 2px;  z-index:-1}

Babel + JSX

class Menu extends React.Component{
  constructor() {
    super();
    this.state = { selected: '' };
    this.referencias={};
  }
  
  addRef(input,obj){
   	this.referencias[obj.title]=input;
  }
  
  componentWillMount() {
    this.setState({selected:this.props.selected});
  }
  
  componentDidMount() {
    this.onMouseOut();
  }
  
	onClick(obj){ 
  	this.setState({selected:obj.title});
    this.props.onChange(obj.title);
  }
  
	onMouseOver(event){ 
  	let boundingUl=this.ul.getBoundingClientRect();
  	let bounding=event.target.getBoundingClientRect();
    this.magicLine.style.width=bounding.width-10+"px";
    this.magicLine.style.left=bounding.left-boundingUl.left-15+"px";
  }
  
	onMouseOut(event){ 
    let boundingUl=this.ul.getBoundingClientRect();
  	let bounding=this.referencias[this.state.selected].getBoundingClientRect();
    this.magicLine.style.width=bounding.width-10+"px";
    this.magicLine.style.left=bounding.left-boundingUl.left-15+"px";
  }
  
  render() {
    return (<div>
            <ul className="menu" ref={(input) => { this.ul = input; }}>
              {	this.props.fields.map((obj)=>{
                  return (
                    <li key={obj.title} 
                     ref={(input) => {this.addRef( input,obj) }}
                    className={(this.state.selected===obj.title ? 'selected' : '')}
                    onMouseOver={(event)=>{this.onMouseOver(event)}}
                    onMouseOut={(event)=>{this.onMouseOut(event)}}
                      onClick={(event)=>{this.onClick(obj)}}>
                    {obj.title} 
                    </li>
                  );
                })
              }
              <li id='magic-line' ref={(input) => { this.magicLine = input; }}></li>
            </ul>
      </div>
      );
  }
}


ReactDOM.render(
<div>
  <Menu  selected="B"  fields={[{title:"AA"},{title:"B"},{title:"CCCC"}]}/>
  <br></br>
  <Menu  selected="Report"...