react position element

by Noah Sloan

HTML

<script src="http://fb.me/react-with-addons-0.9.0.js"></script>

<script src="http://fb.me/react-js-fiddle-integration.js"></script>
<script src="http://fb.me/JSXTransformer-0.9.0.js"></script>
<div id="foo"></div>
<div id="layer1"></div>

CSS

.container {
    background-color: #ccc;
    height: 30px;
    overflow: hidden;    
    position: relative;
}

.menu {    
    /*please forgive the asthetics*/
    border: 1px solid black;
    display: none;
    top: 100px; /*position below the container*/
    left: 5px;
    position: absolute;
}

.menu.open {
    display: block;
}

JavaScript 1.7

/**
* @jsx React.DOM
*/

/**
* @jsx React.DOM
*/

var Layer = React.createClass({
    componentDidMount: function() {
        // in practice, you would make a div to wrap it and calculate
        // the position here, but I've used CSS to keep it simple
        React.renderComponent(this.props.children, document.getElementById("layer1"));
    },
    componentDidUpdate: function() {
        React.renderComponent(this.props.children, document.getElementById("layer1"));
    },
    // TODO unmount
    render: function() {
        // don't need to render anything here
        return <text></text>;
    }
});

var Foo = React.createClass({
  getInitialState: function() {
      return {
          open: false,
          color: "white"
      };
  },
  render: function() {
    return (<div>    
      <p>Context: you need to position an element (like a dropdown menu) from the body element, because it's current container has overflow.</p>
      <div className="container">
          <button type="button" onClick={this.show}>Menu appears below me</button>
          <Layer>
          <div className={"menu" + (this.state.open ? " open" : "")} ref="menu" onClick={this.change}
                 style={{backgroundColor: this.state.color}}>
              Click to change color
          </div>
          </Layer>
      </div>
    </div>);
  },
   change: function() {
      // click handlers still work with the element moved... phew!
      function c() {
          return Math.floor(256 * Math.random());
      }
      this.setState({
          color: "rgb(" + c() + "," + c() + "," + c() + ")"
      });
  },
  show: function() {
      this.setState({
          open: !this.state.open
      });
  }
});

React.renderComponent(<Foo/>, document.getElementById("foo"));