Skip to content

Commit

Permalink
[Popover] Doesn't reposition with anchorEl
Browse files Browse the repository at this point in the history
Closes mui#5937
  • Loading branch information
quiaro committed Jul 19, 2017
1 parent 37cda13 commit 37db6d5
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 5 deletions.
37 changes: 32 additions & 5 deletions src/internal/Popover.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@

import React, { Component } from 'react';
import type { Element } from 'react';
import ReactDOM from 'react-dom';
import classNames from 'classnames';
import { createStyleSheet } from 'jss-theme-reactor';
import contains from 'dom-helpers/query/contains';
import debounce from 'lodash/debounce';
import EventListener from 'react-event-listener';
import withStyles from '../styles/withStyles';
import customPropTypes from '../utils/customPropTypes';
import Modal from './Modal';
Expand Down Expand Up @@ -211,7 +214,22 @@ class Popover extends Component<DefaultProps, Props, void> {
return `scale(${value}, ${value ** 2})`;
}

componentWillUnmount = () => {
this.handleResize.cancel();
};

autoTransitionDuration = undefined;
transitionEl = undefined;

setPositioningStyles = (element: HTMLElement) => {
if (element && element.style) {
const positioning = this.getPositioningStyle(element);

element.style.top = positioning.top;
element.style.left = positioning.left;
element.style.transformOrigin = positioning.transformOrigin;
}
};

handleEnter = (element: HTMLElement) => {
element.style.opacity = '0';
Expand All @@ -221,11 +239,7 @@ class Popover extends Component<DefaultProps, Props, void> {
this.props.onEnter(element);
}

const positioning = this.getPositioningStyle(element);

element.style.top = positioning.top;
element.style.left = positioning.left;
element.style.transformOrigin = positioning.transformOrigin;
this.setPositioningStyles(element);

let { transitionDuration } = this.props;
const { transitions } = this.context.styleManager.theme;
Expand Down Expand Up @@ -281,6 +295,17 @@ class Popover extends Component<DefaultProps, Props, void> {
}
};

handleResize = debounce(
() => {
const element: any = ReactDOM.findDOMNode(this.transitionEl);
this.setPositioningStyles(element);
},
166,
{
leading: true,
},
);

handleRequestTimeout = () => {
if (this.props.transitionDuration === 'auto') {
return (this.autoTransitionDuration || 0) + 20;
Expand Down Expand Up @@ -437,13 +462,15 @@ class Popover extends Component<DefaultProps, Props, void> {
role={role}
onRequestTimeout={this.handleRequestTimeout}
transitionAppear
ref={el => (this.transitionEl = el)}
>
<Paper
data-mui-test="Popover"
className={classNames(classes.paper, className)}
elevation={elevation}
{...other}
>
<EventListener target="window" onResize={this.handleResize} />
{children}
</Paper>
</Transition>
Expand Down
16 changes: 16 additions & 0 deletions src/internal/Popover.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,22 @@ describe('<Popover />', () => {
});
});

describe('on window resize', () => {
it('should recalculate position if the popover is open', () => {
const wrapper = shallow(<Popover open transitionDuration={0} />);
const instance = wrapper.instance();

stub(instance, 'setPositioningStyles');
wrapper.find('EventListener').at(0).simulate('resize');
assert.isTrue(instance.setPositioningStyles.called, 'position styles recalculated');
});

it('should not recalculate position if the popover is closed', () => {
const wrapper = mount(<Popover transitionDuration={0} />);
assert.isNotTrue(wrapper.contains('EventListener'), 'no component listening on resize');
});
});

describe('getPositioningStyle(element)', () => {
let instance;
let element;
Expand Down

0 comments on commit 37db6d5

Please sign in to comment.