JSFiddle - React, Tailwind, and code Playground
by Sunify
HTML
<script src="https://fb.me/react-with-addons-15.1.0.js"></script>
<script src="https://fb.me/react-dom-15.1.0.js"></script>
<div id="app"></div>
Babel + JSX
const styles = {
app: {
overflow: 'hidden',
position: 'relative',
width: 100,
background: '#cf0',
},
dropdown: {
position: 'absolute',
width: 150,
height: 100,
background: '#FCC',
},
};
class RelativePortal extends React.Component {
static propTypes = {
top: React.PropTypes.number,
left: React.PropTypes.number,
};
static defaultProps = {
top: 0,
left: 0
};
constructor(props) {
super(props);
this.node = document.createElement('div');
document.body.appendChild(this.node);
this.state = {
top: 0,
left: 0
};
}
componentDidMount() {
this.handleResize = () => {
const rect = ReactDOM.findDOMNode(this).getBoundingClientRect();
const left = window.scrollX + rect.left;
const top = window.scrollY + rect.top;
if(top !== this.state.top || left !== this.state.left) {
this.setState({ left, top });
}
};
window.addEventListener('resize', this.handleResize);
this.handleResize();
}
render() {
return <div />;
}
componentDidUpdate() {
ReactDOM.render(
<div
{...this.props}
style={{
position: 'absolute',
top: this.state.top + this.props.top,
left: this.state.left + this.props.left,
}}
/>,
this.node
);
}
componentWillUnmout() {
document.body.removeChild(this.node);
}
}
class DropdownLink extends React.Component {
state = {
isOpen: false
};
render() {
const { isOpen } = this.state;
return (
<div>
<button onClick={() => this.setState({isOpen: !isOpen})}>
Toggle
</button>
<RelativePortal top={5} left={0}>
{isOpen &&
<Dropdown />
}
</RelativePortal>
</div>
);
}
}
class Dropdown extends React.Component {
render() {
return (
<div style={styles.dropdown} />
);
}
}
class App extends...