Skip to content

Commit

Permalink
fix(minHeight): issues/403 resize events reset height (#447)
Browse files Browse the repository at this point in the history
  • Loading branch information
cdcabrera committed Oct 26, 2020
1 parent 4194200 commit 74f0e7f
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 4 deletions.
50 changes: 49 additions & 1 deletion src/components/minHeight/__tests__/minHeight.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { shallow } from 'enzyme';
import { mount, shallow } from 'enzyme';
import { MinHeight } from '../minHeight';

describe('MinHeight Component', () => {
Expand Down Expand Up @@ -32,4 +32,52 @@ describe('MinHeight Component', () => {
component.setProps({ autoUpdate: false, minHeight: 300 });
expect(component.instance().updatedMinHeight).toEqual(200);
});

it('should set minHeight on resize', () => {
const props = {};
const component = shallow(<MinHeight {...props}>lorem ipsum</MinHeight>);

expect(component.instance().onResizeContainer).toBeDefined();

// initial height and width should be zero
expect(component.instance().updatedMinHeight).toEqual(0);
expect(component.instance().updatedContainerWidth).toEqual(0);

// set the container size arbitrarily and force handleResize to fire
component.instance().containerRef.current = { clientHeight: 100, clientWidth: 200 };
global.dispatchEvent(new Event('resize'));
expect(component.instance().updatedMinHeight).toEqual(100);
expect(component.instance().updatedContainerWidth).toEqual(200);

// set the container size arbitrarily and force handleResize to fire
component.instance().containerRef.current = { clientHeight: 1000, clientWidth: 1337 };
global.dispatchEvent(new Event('resize'));
expect(component.instance().updatedMinHeight).toEqual(1000);
expect(component.instance().updatedContainerWidth).toEqual(1337);
});

it('should attempt to handle a ResizeObserver', () => {
const observe = jest.fn();
const unobserve = jest.fn();

window.ResizeObserver = jest.fn().mockImplementation(() => ({
observe,
unobserve
}));

const props = {};
const component = mount(<MinHeight {...props}>lorem ipsum</MinHeight>);
expect(observe).toHaveBeenCalledTimes(1);

component.unmount();
expect(unobserve).toHaveBeenCalledTimes(1);
});

it('should run componentWillUnmount method successfully', () => {
const props = {};
const component = mount(<MinHeight {...props}>lorem ipsum</MinHeight>);
const componentWillUnmount = jest.spyOn(component.instance(), 'componentWillUnmount');
component.unmount();
expect(componentWillUnmount).toHaveBeenCalled();
});
});
56 changes: 53 additions & 3 deletions src/components/minHeight/minHeight.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,25 @@
import React from 'react';
import PropTypes from 'prop-types';
import { helpers } from '../../common';

/**
* Set a min-height to prevent page jump component.
*
* @augments React.Component
* @fires onResizeContainer
*/
class MinHeight extends React.Component {
containerRef = React.createRef();

updatedMinHeight = 0;

updatedContainerWidth = 0;

resizeObserver = helpers.noop;

componentDidMount() {
this.setMinHeight();
this.setResizeObserver();
}

componentDidUpdate() {
Expand All @@ -23,14 +30,40 @@ class MinHeight extends React.Component {
}
}

componentWillUnmount() {
this.resizeObserver();
}

/**
* On resize adjust graph display.
*
* @event onResizeContainer
*/
onResizeContainer = () => {
const { updatedContainerWidth } = this;
const clientWidth = this.containerRef?.current?.clientWidth || 0;

if (clientWidth !== updatedContainerWidth) {
this.updatedContainerWidth = clientWidth;
this.setMinHeight(true);
}
};

/**
* Set minHeight on mount or update.
*
* @param {boolean} resetMinHeight
*/
setMinHeight() {
setMinHeight(resetMinHeight) {
const { updatedMinHeight } = this;
const { minHeight: overrideMinHeight } = this.props;
// const { clientHeight = 0 } = this.containerRef.current || {};
const clientHeight = this.containerRef?.current?.clientHeight || 0;
const { current: domElement = {} } = this.containerRef;

if (resetMinHeight && domElement.style) {
domElement.style.minHeight = 0;
}

const clientHeight = domElement?.clientHeight || 0;

if (clientHeight !== updatedMinHeight) {
this.updatedMinHeight = clientHeight;
Expand All @@ -41,6 +74,23 @@ class MinHeight extends React.Component {
}
}

/**
* Set ResizeObserver for scenarios when min-height needs to be updated.
*/
setResizeObserver() {
const containerElement = this.containerRef.current;
const { ResizeObserver } = window;

if (containerElement && ResizeObserver) {
const resizeObserver = new ResizeObserver(this.onResizeContainer);
resizeObserver.observe(containerElement);
this.resizeObserver = () => resizeObserver.unobserve(containerElement);
} else {
window.addEventListener('resize', this.onResizeContainer);
this.resizeObserver = () => window.removeEventListener('resize', this.onResizeContainer);
}
}

/**
* Render a min-height div with children.
*
Expand Down

0 comments on commit 74f0e7f

Please sign in to comment.