Skip to content

Commit

Permalink
Merge pull request #51 from /issues/49
Browse files Browse the repository at this point in the history
Fallback to ResizeObserver; separate scaled and unscaled sizes
  • Loading branch information
bvaughn authored Apr 7, 2023
2 parents ba5a900 + ccb88dd commit 4f87fd5
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 27 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## 1.0.12
* Fix regression introduced in 1.0.8 with transformations; pass unscaled width and height as "default" params (and add additional `scaledHeight` and `scaledWidth` params to `children` function)
* Use `ResizeObserver` when possible; fallback to legacy resize polyfill logic otherwise

## 1.0.11
* Pre-transform static class property syntax (`defaultProps`) ([#46](https://github.com/bvaughn/react-virtualized-auto-sizer/issues/46))
* Fixed bad TypeScript definition for `onResize` prop ([#44](https://github.com/bvaughn/react-virtualized-auto-sizer/issues/44))
Expand Down
89 changes: 62 additions & 27 deletions src/AutoSizer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,13 @@ import {
import { createDetectElementResize } from "../vendor/detectElementResize";

export type Size = {
// Legacy width and height parameters (offsetWidth and offsetHeight)
height?: number;
width?: number;

// Take transform:scale into account (getBoundingClientRect)
scaledHeight?: number;
scaledWidth?: number;
};

export type Props = {
Expand All @@ -27,6 +32,8 @@ export type Props = {

type State = {
height: number;
scaledHeight: number;
scaledWidth: number;
width: number;
};

Expand All @@ -47,12 +54,15 @@ export class AutoSizer extends Component<Props, State> {

state = {
height: this.props.defaultHeight || 0,
scaledHeight: this.props.defaultHeight || 0,
scaledWidth: this.props.defaultWidth || 0,
width: this.props.defaultWidth || 0,
};

_parentNode: HTMLElement | null = null;
_autoSizer: HTMLElement | null = null;
_detectElementResize: DetectElementResize | null = null;
_parentNode: HTMLElement | null = null;
_resizeObserver: ResizeObserver | null = null;

componentDidMount() {
const { nonce } = this.props;
Expand All @@ -72,21 +82,38 @@ export class AutoSizer extends Component<Props, State> {

// Defer requiring resize handler in order to support server-side rendering.
// See issue #41
const detectElementResize = createDetectElementResize(nonce);
detectElementResize.addResizeListener(this._parentNode, this._onResize);

this._detectElementResize = detectElementResize;
if (this._parentNode != null) {
if (typeof ResizeObserver !== "undefined") {
this._resizeObserver = new ResizeObserver(this._onResize);
this._resizeObserver.observe(this._parentNode);
} else {
this._detectElementResize = createDetectElementResize(
nonce
) as DetectElementResize;
this._detectElementResize.addResizeListener(
this._parentNode,
this._onResize
);
}

this._onResize();
this._onResize();
}
}
}

componentWillUnmount() {
if (this._detectElementResize && this._parentNode) {
this._detectElementResize.removeResizeListener(
this._parentNode,
this._onResize
);
if (this._parentNode) {
if (this._detectElementResize) {
this._detectElementResize.removeResizeListener(
this._parentNode,
this._onResize
);
}

if (this._resizeObserver) {
this._resizeObserver.observe(this._parentNode);
this._resizeObserver.disconnect();
}
}
}

Expand All @@ -104,7 +131,7 @@ export class AutoSizer extends Component<Props, State> {
...rest
} = this.props;

const { height, width } = this.state;
const { height, scaledHeight, scaledWidth, width } = this.state;

// Outer div should not force width/height since that may prevent containers from shrinking.
// Inner component should overflow and use calculated width/height.
Expand All @@ -122,6 +149,7 @@ export class AutoSizer extends Component<Props, State> {
}
outerStyle.height = 0;
childParams.height = height;
childParams.scaledHeight = scaledHeight;
}

if (!disableWidth) {
Expand All @@ -130,6 +158,7 @@ export class AutoSizer extends Component<Props, State> {
}
outerStyle.width = 0;
childParams.width = width;
childParams.scaledWidth = scaledWidth;
}

return createElement(
Expand All @@ -154,30 +183,36 @@ export class AutoSizer extends Component<Props, State> {
// This can result in invalid style values which can result in NaN values if we don't handle them.
// See issue #150 for more context.

const rect = this._parentNode.getBoundingClientRect();
const height = rect.height || 0;
const width = rect.width || 0;

const style = window.getComputedStyle(this._parentNode) || {};
const paddingLeft = parseInt(style.paddingLeft, 10) || 0;
const paddingRight = parseInt(style.paddingRight, 10) || 0;
const paddingTop = parseInt(style.paddingTop, 10) || 0;
const paddingBottom = parseInt(style.paddingBottom, 10) || 0;
const paddingLeft = parseInt(style.paddingLeft ?? "0", 10);
const paddingRight = parseInt(style.paddingRight ?? "0", 10);
const paddingTop = parseInt(style.paddingTop ?? "0", 10);
const paddingBottom = parseInt(style.paddingBottom ?? "0", 10);

const rect = this._parentNode.getBoundingClientRect();
const scaledHeight = rect.height - paddingTop - paddingBottom;
const scaledWidth = rect.width - paddingLeft - paddingRight;

const newHeight = height - paddingTop - paddingBottom;
const newWidth = width - paddingLeft - paddingRight;
const height = this._parentNode.offsetHeight - paddingTop - paddingBottom;
const width = this._parentNode.offsetWidth - paddingLeft - paddingRight;

if (
(!disableHeight && this.state.height !== newHeight) ||
(!disableWidth && this.state.width !== newWidth)
(!disableHeight &&
(this.state.height !== height ||
this.state.scaledHeight !== scaledHeight)) ||
(!disableWidth &&
(this.state.width !== width ||
this.state.scaledWidth !== scaledWidth))
) {
this.setState({
height: height - paddingTop - paddingBottom,
width: width - paddingLeft - paddingRight,
height,
width,
scaledHeight,
scaledWidth,
});

if (typeof onResize === "function") {
onResize({ height, width });
onResize({ height, scaledHeight, scaledWidth, width });
}
}
}
Expand Down

0 comments on commit 4f87fd5

Please sign in to comment.