Skip to content

Commit d2060f1

Browse files
committed
Cover AutoSizer component and its example with types
1 parent 47fd3fa commit d2060f1

File tree

11 files changed

+109
-111
lines changed

11 files changed

+109
-111
lines changed

.flowconfig

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
[ignore]
22
.*/ArrowKeyStepper/.*
3-
.*/AutoSizer/.*
43
.*/Collection/.*
54
.*/ColumnSizer/.*
65
.*/InfiniteLoader/.*
@@ -9,7 +8,6 @@
98
.*/ScrollSync/.*
109
.*/Table/.*
1110
.*/WindowScroller/.*
12-
.*/demo/.*
1311

1412
.*/node_modules/babel-plugin-transform-react-remove-prop-types/.*
1513

source/AutoSizer/AutoSizer.example.js

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
/** @flow */
2-
import Immutable from "immutable";
2+
3+
import type { RowRendererParams } from '../types';
4+
5+
import { List as ImmutableList } from "immutable";
36
import PropTypes from "prop-types";
47
import React, { PureComponent } from "react";
58
import {
@@ -13,18 +16,12 @@ import styles from "./AutoSizer.example.css";
1316

1417
export default class AutoSizerExample extends PureComponent {
1518
static contextTypes = {
16-
list: PropTypes.instanceOf(Immutable.List).isRequired
19+
list: PropTypes.instanceOf(ImmutableList).isRequired
1720
};
1821

19-
constructor(props) {
20-
super(props);
21-
22-
this.state = {
23-
hideDescription: false
24-
};
25-
26-
this._rowRenderer = this._rowRenderer.bind(this);
27-
}
22+
state = {
23+
hideDescription: false
24+
};
2825

2926
render() {
3027
const { list } = this.context;
@@ -90,7 +87,7 @@ export default class AutoSizerExample extends PureComponent {
9087
);
9188
}
9289

93-
_rowRenderer({ index, key, style }) {
90+
_rowRenderer = ({ index, key, style }: RowRendererParams) => {
9491
const { list } = this.context;
9592
const row = list.get(index);
9693

source/AutoSizer/AutoSizer.js

Lines changed: 82 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,83 @@
11
/** @flow */
2-
import PropTypes from "prop-types";
3-
import React, { PureComponent } from "react";
2+
3+
import React from "react";
44
import createDetectElementResize from "../vendor/detectElementResize";
55

66
/**
77
* Decorator component that automatically adjusts the width and height of a single child.
88
* Child component should not be declared as a child but should rather be specified by a `ChildComponent` property.
99
* All other properties will be passed through to the child component.
1010
*/
11-
export default class AutoSizer extends PureComponent {
12-
static propTypes = {
13-
/**
14-
* Function responsible for rendering children.
15-
* This function should implement the following signature:
16-
* ({ height, width }) => PropTypes.element
17-
*/
18-
children: PropTypes.func.isRequired,
1911

20-
/** Disable dynamic :height property */
21-
disableHeight: PropTypes.bool,
12+
type Size = {
13+
height: number,
14+
width: number
15+
};
2216

23-
/** Disable dynamic :width property */
24-
disableWidth: PropTypes.bool,
17+
type Props = {
18+
/** Function responsible for rendering children.*/
19+
children: (warams: Size) => React.Element<*>,
2520

26-
/** Nonce of the inlined stylesheet for Content Security Policy */
27-
nonce: PropTypes.string,
21+
/** Disable dynamic :height property */
22+
disableHeight: boolean,
2823

29-
/** Callback to be invoked on-resize: ({ height, width }) */
30-
onResize: PropTypes.func.isRequired
31-
};
24+
/** Disable dynamic :width property */
25+
disableWidth: boolean,
26+
27+
/** Nonce of the inlined stylesheet for Content Security Policy */
28+
nonce?: string,
3229

30+
/** Callback to be invoked on-resize */
31+
onResize: (params: Size) => void
32+
};
33+
34+
type ResizeHandler = (element: HTMLElement, onResize: () => void) => void;
35+
36+
type DetectElementResize = {
37+
addResizeListener: ResizeHandler,
38+
removeResizeListener: ResizeHandler
39+
}
40+
41+
export default class AutoSizer extends React.PureComponent {
3342
static defaultProps = {
34-
onResize: () => {}
43+
onResize: () => {},
44+
disableHeight: false,
45+
disableWidth: false
3546
};
3647

37-
constructor(props) {
38-
super(props);
48+
props: Props;
3949

40-
this.state = {
41-
height: 0,
42-
width: 0
43-
};
50+
state = {
51+
height: 0,
52+
width: 0
53+
};
4454

45-
this._onResize = this._onResize.bind(this);
46-
this._setRef = this._setRef.bind(this);
47-
}
55+
_parentNode: ?HTMLElement;
56+
_autoSizer: ?HTMLElement;
57+
_detectElementResize: DetectElementResize;
4858

4959
componentDidMount() {
5060
const { nonce } = this.props;
61+
if (this._autoSizer && this._autoSizer.parentNode instanceof HTMLElement) {
62+
// Delay access of parentNode until mount.
63+
// This handles edge-cases where the component has already been unmounted before its ref has been set,
64+
// As well as libraries like react-lite which have a slightly different lifecycle.
65+
this._parentNode = this._autoSizer.parentNode;
66+
67+
// Defer requiring resize handler in order to support server-side rendering.
68+
// See issue #41
69+
this._detectElementResize = createDetectElementResize(nonce);
70+
this._detectElementResize.addResizeListener(
71+
this._parentNode,
72+
this._onResize
73+
);
5174

52-
// Delay access of parentNode until mount.
53-
// This handles edge-cases where the component has already been unmounted before its ref has been set,
54-
// As well as libraries like react-lite which have a slightly different lifecycle.
55-
this._parentNode = this._autoSizer.parentNode;
56-
57-
// Defer requiring resize handler in order to support server-side rendering.
58-
// See issue #41
59-
this._detectElementResize = createDetectElementResize(nonce);
60-
this._detectElementResize.addResizeListener(
61-
this._parentNode,
62-
this._onResize
63-
);
64-
65-
this._onResize();
75+
this._onResize();
76+
}
6677
}
6778

6879
componentWillUnmount() {
69-
if (this._detectElementResize) {
80+
if (this._detectElementResize && this._parentNode) {
7081
this._detectElementResize.removeResizeListener(
7182
this._parentNode,
7283
this._onResize
@@ -81,7 +92,7 @@ export default class AutoSizer extends PureComponent {
8192
// Outer div should not force width/height since that may prevent containers from shrinking.
8293
// Inner component should overflow and use calculated width/height.
8394
// See issue #68 for more information.
84-
const outerStyle = { overflow: "visible" };
95+
const outerStyle: Object = { overflow: "visible" };
8596

8697
if (!disableHeight) {
8798
outerStyle.height = 0;
@@ -110,39 +121,42 @@ export default class AutoSizer extends PureComponent {
110121
);
111122
}
112123

113-
_onResize() {
124+
_onResize = () => {
114125
const { disableHeight, disableWidth, onResize } = this.props;
115126

116-
// Guard against AutoSizer component being removed from the DOM immediately after being added.
117-
// This can result in invalid style values which can result in NaN values if we don't handle them.
118-
// See issue #150 for more context.
127+
if (this._parentNode) {
119128

120-
const height = this._parentNode.offsetHeight || 0;
121-
const width = this._parentNode.offsetWidth || 0;
129+
// Guard against AutoSizer component being removed from the DOM immediately after being added.
130+
// This can result in invalid style values which can result in NaN values if we don't handle them.
131+
// See issue #150 for more context.
122132

123-
const style = window.getComputedStyle(this._parentNode) || {};
124-
const paddingLeft = parseInt(style.paddingLeft, 10) || 0;
125-
const paddingRight = parseInt(style.paddingRight, 10) || 0;
126-
const paddingTop = parseInt(style.paddingTop, 10) || 0;
127-
const paddingBottom = parseInt(style.paddingBottom, 10) || 0;
133+
const height = this._parentNode.offsetHeight || 0;
134+
const width = this._parentNode.offsetWidth || 0;
128135

129-
const newHeight = height - paddingTop - paddingBottom;
130-
const newWidth = width - paddingLeft - paddingRight;
136+
const style = window.getComputedStyle(this._parentNode) || {};
137+
const paddingLeft = parseInt(style.paddingLeft, 10) || 0;
138+
const paddingRight = parseInt(style.paddingRight, 10) || 0;
139+
const paddingTop = parseInt(style.paddingTop, 10) || 0;
140+
const paddingBottom = parseInt(style.paddingBottom, 10) || 0;
131141

132-
if (
133-
(!disableHeight && this.state.height !== newHeight) ||
134-
(!disableWidth && this.state.width !== newWidth)
135-
) {
136-
this.setState({
137-
height: height - paddingTop - paddingBottom,
138-
width: width - paddingLeft - paddingRight
139-
});
142+
const newHeight = height - paddingTop - paddingBottom;
143+
const newWidth = width - paddingLeft - paddingRight;
144+
145+
if (
146+
!disableHeight && this.state.height !== newHeight ||
147+
!disableWidth && this.state.width !== newWidth
148+
) {
149+
this.setState({
150+
height: height - paddingTop - paddingBottom,
151+
width: width - paddingLeft - paddingRight
152+
});
140153

141-
onResize({ height, width });
154+
onResize({ height, width });
155+
}
142156
}
143157
}
144158

145-
_setRef(autoSizer) {
159+
_setRef = (autoSizer: HTMLElement | null) => {
146160
this._autoSizer = autoSizer;
147161
}
148162
}

source/AutoSizer/index.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
1-
export default from "./AutoSizer";
2-
export AutoSizer from "./AutoSizer";
1+
// @flow
2+
3+
export { default } from "./AutoSizer";
4+
export { default as AutoSizer } from "./AutoSizer";

source/Grid/accessibilityOverscanIndicesGetter.js

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// @flow
22

3-
import type { OverscanIndices } from "../types";
3+
import type { OverscanIndicesGetterParams, OverscanIndices } from "../types";
44

55
export const SCROLL_DIRECTION_BACKWARD = -1;
66
export const SCROLL_DIRECTION_FORWARD = 1;
@@ -13,33 +13,13 @@ export const SCROLL_DIRECTION_VERTICAL = "vertical";
1313
* This function ensures that overscanning doesn't exceed the available cells.
1414
*/
1515

16-
type Params = {
17-
// One of SCROLL_DIRECTION_HORIZONTAL or SCROLL_DIRECTION_VERTICAL
18-
direction: "horizontal" | "vertical",
19-
20-
// Number of rows or columns in the current axis
21-
cellCount: number,
22-
23-
// One of SCROLL_DIRECTION_BACKWARD or SCROLL_DIRECTION_FORWARD
24-
scrollDirection: -1 | 1,
25-
26-
// Maximum number of cells to over-render in either direction
27-
overscanCellsCount: number,
28-
29-
// Begin of range of visible cells
30-
startIndex: number,
31-
32-
// End of range of visible cells
33-
stopIndex: number
34-
};
35-
3616
export default function defaultOverscanIndicesGetter({
3717
cellCount,
3818
overscanCellsCount,
3919
scrollDirection,
4020
startIndex,
4121
stopIndex
42-
}: Params): OverscanIndices {
22+
}: OverscanIndicesGetterParams): OverscanIndices {
4323
// Make sure we render at least 1 cell extra before and after (except near boundaries)
4424
// This is necessary in order to support keyboard navigation (TAB/SHIFT+TAB) in some cases
4525
// For more info see issues #625

source/demo/Application.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
/** @flow */
21
import Immutable from "immutable";
32
import PropTypes from "prop-types";
43
import React, { PureComponent } from "react";

source/demo/ComponentLink.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
/** @flow */
21
import React from "react";
32
import { NavLink } from "react-router-dom";
43
import styles from "./ComponentLink.css";

source/demo/NavLink.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
/** @flow */
21
import React from "react";
32
import { NavLink as RRNavLink } from "react-router-dom";
43
import Icon from "./Icon";

source/demo/Wizard/Wizard.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
/* @flow */
21
import cn from "classnames";
32
import CodeMirror from "react-codemirror";
43
import React, { Component } from "react";

source/demo/Wizard/index.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
1-
/* @flow */
21
export default from "./Wizard";

0 commit comments

Comments
 (0)