diff --git a/src/popover/popover-animation-from-top.jsx b/src/popover/popover-animation-from-top.jsx index 339f2857d4364d..d9e338a455d397 100644 --- a/src/popover/popover-animation-from-top.jsx +++ b/src/popover/popover-animation-from-top.jsx @@ -23,7 +23,7 @@ function getStyles(props, state) { opacity: open ? 1 : 0, transform: open ? 'scaleY(1)' : 'scaleY(0)', transformOrigin: `${horizontal} ${targetOrigin.vertical}`, - position: 'fixed', + position: 'absolute', zIndex: zIndex.popover, transition: Transitions.easeOut('450ms', ['transform', 'opacity']), maxHeight: '100%', diff --git a/src/popover/popover-default-animation.jsx b/src/popover/popover-default-animation.jsx index 86a8bf325a0017..5d9b526dd1dcaf 100644 --- a/src/popover/popover-default-animation.jsx +++ b/src/popover/popover-default-animation.jsx @@ -23,7 +23,7 @@ function getStyles(props, state) { opacity: open ? 1 : 0, transform: open ? 'scale(1, 1)' : 'scale(0, 0)', transformOrigin: `${horizontal} ${targetOrigin.vertical}`, - position: 'fixed', + position: 'absolute', zIndex: zIndex.popover, transition: Transitions.easeOut('250ms', ['transform', 'opacity']), maxHeight: '100%', diff --git a/src/popover/popover.jsx b/src/popover/popover.jsx index 604f6223c5ed5e..9b40939ea24865 100644 --- a/src/popover/popover.jsx +++ b/src/popover/popover.jsx @@ -243,8 +243,8 @@ const Popover = React.createClass({ const a = { top: rect.top, left: rect.left, - width: el.offsetWidth, - height: el.offsetHeight, + width: rect.width, + height: rect.height, }; a.right = rect.right || a.left + a.width; diff --git a/src/render-to-layer.jsx b/src/render-to-layer.jsx index 460b5108fc863a..a532a3179d19e8 100644 --- a/src/render-to-layer.jsx +++ b/src/render-to-layer.jsx @@ -2,6 +2,8 @@ import React from 'react'; import ReactDOM from 'react-dom'; import Dom from './utils/dom'; import getMuiTheme from './styles/getMuiTheme'; +import WindowListenable from './mixins/window-listenable'; +import throttle from 'lodash.throttle'; // heavily inspired by https://github.com/Khan/react-components/blob/master/js/layered-component-mixin.jsx const RenderToLayer = React.createClass({ @@ -22,6 +24,10 @@ const RenderToLayer = React.createClass({ muiTheme: React.PropTypes.object, }, + mixins: [ + WindowListenable, + ], + getDefaultProps() { return { useLayerForClickAway: true, @@ -29,6 +35,7 @@ const RenderToLayer = React.createClass({ }, getInitialState() { + this._renderLayerThrottled = throttle(this._renderLayer, 100); return { muiTheme: this.context.muiTheme || getMuiTheme(), }; @@ -61,6 +68,11 @@ const RenderToLayer = React.createClass({ this._unrenderLayer(); }, + windowListeners: { + resize: '_renderLayerThrottled', + scroll: '_renderLayerThrottled', + }, + onClickAway(event) { if (event.defaultPrevented) { return; @@ -113,16 +125,12 @@ const RenderToLayer = React.createClass({ if (open) { if (!this._layer) { this._layer = document.createElement('div'); + this._layer.style.position = 'absolute'; document.body.appendChild(this._layer); if (this.props.useLayerForClickAway) { this._layer.addEventListener('touchstart', this.onClickAway); this._layer.addEventListener('click', this.onClickAway); - this._layer.style.position = 'fixed'; - this._layer.style.top = 0; - this._layer.style.bottom = 0; - this._layer.style.left = 0; - this._layer.style.right = 0; this._layer.style.zIndex = this.state.muiTheme.zIndex.layer; } else { setTimeout(() => { @@ -131,7 +139,15 @@ const RenderToLayer = React.createClass({ }, 0); } } - + const {documentElement, body} = document; + const top = window.pageYOffset || documentElement.scrollTop || body.scrollTop || 0; + const left = window.pageXOffset || documentElement.scrollLeft || body.scrollLeft || 0; + + this._layer.style.top = `${top}px`; + this._layer.style.height = `${body.clientHeight}px`; + this._layer.style.left = `${left}px`; + this._layer.style.width = `${body.clientWidth}px`; + // By calling this method in componentDidMount() and // componentDidUpdate(), you're effectively creating a "wormhole" that // funnels React's hierarchical updates through to a DOM node on an