mirror of
https://github.com/elyby/accounts-frontend.git
synced 2025-05-31 14:11:58 +05:30
Create app namespace for all absolute requires of app modules. Move all packages under packages yarn workspace
This commit is contained in:
70
packages/app/components/MeasureHeight.tsx
Normal file
70
packages/app/components/MeasureHeight.tsx
Normal file
@@ -0,0 +1,70 @@
|
||||
import React from 'react';
|
||||
import { omit, debounce } from 'app/functions';
|
||||
|
||||
/**
|
||||
* MeasureHeight is a component that allows you to measure the height of elements wrapped.
|
||||
*
|
||||
* Each time the height changed, the `onMeasure` prop will be called.
|
||||
* On each component update the `shouldMeasure` prop is being called and depending of
|
||||
* the value returned will be decided whether to call `onMeasure`.
|
||||
* By default `shouldMeasure` will compare the old and new values of the `state` prop.
|
||||
* Both `shouldMeasure` and `state` can be used to reduce the amount of measures, which
|
||||
* will reduce the count of forced reflows in browser.
|
||||
*
|
||||
* Usage:
|
||||
* <MeasureHeight
|
||||
* state={theValueToInvalidateCurrentMeasure}
|
||||
* onMeasure={this.onUpdateContextHeight}
|
||||
* >
|
||||
* <div>some content here</div>
|
||||
* <div>which may be multiple children</div>
|
||||
* </MeasureHeight>
|
||||
*/
|
||||
|
||||
type ChildState = any;
|
||||
|
||||
export default class MeasureHeight extends React.PureComponent<
|
||||
{
|
||||
shouldMeasure: (prevState: ChildState, newState: ChildState) => boolean;
|
||||
onMeasure: (height: number) => void;
|
||||
state: ChildState;
|
||||
} & React.HTMLAttributes<HTMLDivElement>
|
||||
> {
|
||||
static defaultProps = {
|
||||
shouldMeasure: (prevState: ChildState, newState: ChildState) =>
|
||||
prevState !== newState,
|
||||
onMeasure: () => {},
|
||||
};
|
||||
|
||||
el: HTMLDivElement | null = null;
|
||||
|
||||
componentDidMount() {
|
||||
// we want to measure height immediately on first mount to avoid ui laggs
|
||||
this.measure();
|
||||
window.addEventListener('resize', this.enqueueMeasurement);
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps: typeof MeasureHeight.prototype.props) {
|
||||
if (this.props.shouldMeasure(prevProps.state, this.props.state)) {
|
||||
this.enqueueMeasurement();
|
||||
}
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
window.removeEventListener('resize', this.enqueueMeasurement);
|
||||
}
|
||||
|
||||
render() {
|
||||
const props = omit(this.props, ['shouldMeasure', 'onMeasure', 'state']);
|
||||
|
||||
return <div {...props} ref={(el: HTMLDivElement) => (this.el = el)} />;
|
||||
}
|
||||
|
||||
measure = () => {
|
||||
requestAnimationFrame(() => {
|
||||
this.el && this.props.onMeasure(this.el.offsetHeight);
|
||||
});
|
||||
};
|
||||
|
||||
enqueueMeasurement = debounce(this.measure);
|
||||
}
|
||||
Reference in New Issue
Block a user