React dropdown

example with dropdown

by Allie Yu

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="root">
  <!-- This element's contents will be replaced with your component. -->
</div>
<div id="cnt">
  <!-- This element's contents will be replaced with your component. -->
</div>
<style id="drp-style">
  .dropdown-menu {
    display: none;
    border: 1px solid #c3c3c3;
    list-style: none;
    padding: 5px;
    margin: 0px;
    width: 150px;
    position: absolute;
    background: #fff;
  }
  
  .drp-cnt,
  .dropdown-menu.menu-open {
    display: inline-block;
  }
  
  .drp-cnt .drp-trigger {
    cursor: pointer;
    width: 150px;
    border: 1px solid #c3c3c3;
    padding: 5px;
    border-radius: 3px;
  }
  
  .app {
    height: 150px;
    position: relative;
    overflow: hidden;
    border: 1px solid grey;
    padding: 10px;
  }
  
  span.icon {
    float: right;
  }

</style>

Babel + JSX

class Dropdown extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      isOpen: false,
      selected: undefined
    }
  }

  componentDidMount() {
    this.offset = this.drp.getBoundingClientRect();
  }

  toggle() {
    this.setState({
      isOpen: !this.state.isOpen
    });
  }

  updateState(prop, value){
    console.log(prop, value);
    this.setState({
      [prop]: value
    });
  }

  render() {
  
    return <div>
      <button onClick={()=> this.updateState('isExternalWindow', !this.state.isExternalWindow)}>{this.state.isExternalWindow ? 'close' : 'open'} external window</button>
      <br/> <br/>
      <div  className="drp-cnt" ref={(el) => this.drp = el}>
        <div className="drp-trigger" onClick={() => this.toggle()}>{this.state.selected || 'select an item'} <span className="icon">&#9660;</span></div>

        <List isExternalWindow={this.state.isExternalWindow}
         onExternalWindowClose={()=> this.updateState('isExternalWindow', false) }
         selected={this.state.selected} 
         onClick={(val)=>this.updateState('selected', val)}
         items={this.props.items} 
         isOpen={this.state.isOpen} 
         offset={this.offset} />
      </div>
    </div>
  }
}


class List extends React.Component {
  constructor(props) {
    super(props);
    this.container = document.querySelector('#cnt');
    this.externalWindow = null;
  }

  componentWillReceiveProps(props) {
    if ('isExternalWindow' in props && props.isExternalWindow !== this.props.isExternalWindow) {
      props.isExternalWindow ? this.openInSeparateWindow() : this.attachToParentWindow();
    }
  }

  getListComponent() {
    const { isOpen, offset } = this.props;
    const isOpenClass = isOpen ? ' menu-open' : '';
    const style = offset ? {
      top: offset.top + offset.height,
      left: offset.left
    } : {};

    return <span>
    <ul onClick={(e) => this.props.onClick(e.target.textContent)} style={style}...