Skip to content

Commit

Permalink
refactors from comments
Browse files Browse the repository at this point in the history
  • Loading branch information
priley86 committed Mar 27, 2019
1 parent 8994fe2 commit e8bce93
Show file tree
Hide file tree
Showing 10 changed files with 181 additions and 193 deletions.
1 change: 0 additions & 1 deletion packages/patternfly-4/react-docs/gatsby-browser.js
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
import '../react-core/dist/styles/base.css';
import './src/pages/styles/global.css';
36 changes: 0 additions & 36 deletions packages/patternfly-4/react-docs/src/pages/styles/global.css

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@ export { default as TableHeader, HeaderProps } from './Header';
export { default as TableBody, TableBodyProps } from './Body';
export { RowWrapper, RowWrapperRow } from './RowWrapper';
export { default as ExpandableRowContent } from './ExpandableRowContent';
export { sortable, headerCol, cellWidth, ISortable, expandable, isRowExpanded, mapOpenedRows } from './utils';
export { sortable, headerCol, cellWidth, ISortable, expandable, isRowExpanded } from './utils';
export { SortByDirection } from './SortColumn';
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ export { default as TableBody } from './Body';
export { default as BodyWrapper } from './BodyWrapper';
export { default as RowWrapper } from './RowWrapper';
export { default as ExpandableRowContent } from './ExpandableRowContent';
export { sortable, headerCol, cellWidth, expandable, isRowExpanded, mapOpenedRows } from './utils';
export { sortable, headerCol, cellWidth, expandable, isRowExpanded } from './utils';
export { SortByDirection } from './SortColumn';
2 changes: 2 additions & 0 deletions packages/patternfly-4/react-virtualized-extension/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# react-virtualized-extension

This package contains virtualization extensions for tables and lists.

This package is currently an extension. Extension components do not undergo the same rigorous design or coding review process as core PatternFly components. If enough members of the community find them useful, we will work to move them into our core PatternFly system by starting the design process for the idea.
Original file line number Diff line number Diff line change
Expand Up @@ -8,60 +8,127 @@ import calculateRows from './utils/calculateRows';
const initialContext = {
amountOfRowsToRender: 3, // First few rows for initial measurement
startIndex: 0, // Index where to start rendering

// Heights for extra rows to mimic scrolling
startHeight: 0,
startHeight: 0, // Heights for extra rows to mimic scrolling
endHeight: 0,

// Show extra row (even/odd issue)
showExtraRow: false
showExtraRow: false // Show extra row (even/odd issue)
};
export const VirtualizedBodyContext = React.createContext(initialContext);

class Body extends React.Component {
constructor(props) {
super(props);
state = initialContext;
measuredRows = {}; // row key -> measurement
ref = React.createRef(); //tbody ref used for gathering scroll position
initialMeasurement = true;
scrollTop = 0;
timeoutId = 0;

scrollTo = index => {
const { rows, rowKey } = this.props;
const startIndex = parseInt(index, 10);

if (startIndex >= 0) {
const startHeight =
calculateAverageHeight({
measuredRows: this.measuredRows,
rows,
rowKey
}) * startIndex;

this.scrollTop = startHeight;
this.ref.current.scrollTop = startHeight;

this.setState(this.calculateRows());
}
};

this.measuredRows = {}; // row key -> measurement
onScroll = e => {
const { onScroll, container } = this.props;
onScroll && onScroll(e);

this.ref = React.createRef();
const {
target: { scrollTop }
} = e;

this.scrollTo = index => {
const startIndex = parseInt(index, 10);
// Y didn't change, bail to avoid rendering rows
if (this.scrollTop === scrollTop) {
return;
}

if (startIndex >= 0) {
const startHeight =
calculateAverageHeight({
measuredRows: this.measuredRows,
rows: props.rows,
rowKey: props.rowKey
}) * startIndex;
this.scrollTop = container ? scrollTop - this.getBodyOffset() : scrollTop;

this.scrollTop = startHeight;
this.ref.current.scrollTop = startHeight;
this.setState(this.calculateRows());
};

this.setState(this.calculateRows(this.props));
checkMeasurements = prevProps => {
// If there are no valid measurements or the rows have changed,
// calculate some after waiting a while. Without this styling solutions
// like Radium won't work as you might expect given they can take a while to set container height.
if (this.initialMeasurement || (prevProps && prevProps.rows !== this.props.rows)) {
// If the rows have changed, but the user has not scrolled, maintain the existing
// scroll position
if (this.ref.current) {
this.ref.current.scrollTop = this.scrollTop;
}
};
this.timeoutId = setTimeout(() => {
const rows = this.calculateRows();

this.scrollTop = 0;
this.initialMeasurement = true;
this.timeoutId = 0;
if (!rows) {
// Refresh the rows to trigger measurement.
this.forceUpdate();

this.state = initialContext;
return;
}

this.checkMeasurements = this.checkMeasurements.bind(this);
this.onScroll = this.onScroll.bind(this);
}
componentDidMount() {
this.checkMeasurements();
this.props.container && this.registerContainer();
}
registerContainer() {
this.setState(rows, () => {
this.initialMeasurement = false;
});
}, 100);
}
};

getHeight = () => {
const { container, height, style } = this.props;
if (container) {
return container().clientHeight;
}
// If `props.height` is not defined, we use `props.style.maxHeight` instead.
return height || style.maxHeight;
};

// Attach information about measuring status. This way we can implement
// proper shouldComponentUpdate
rowsToRender = (rows, startIndex, amountOfRowsToRender, rowKey) => {
const renderedRows = rows.slice(startIndex, startIndex + amountOfRowsToRender).map((rowData, rowIndex) => ({
...rowData,
_measured: !!this.measuredRows[resolveRowKey({ rowData, rowIndex, rowKey })]
}));
return renderedRows;
};

getBodyOffset = () => this.ref.current.parentElement.offsetTop + this.ref.current.offsetTop;

registerContainer = () => {
setTimeout(() => {
this.props.container().addEventListener('scroll', this.onScroll);
}, 0);
};

calculateRows = () => {
const { rows, rowKey } = this.props;
return calculateRows({
scrollTop: this.scrollTop,
measuredRows: this.measuredRows,
height: this.getHeight(),
rowKey,
rows
});
};

componentDidMount() {
this.checkMeasurements();
this.props.container && this.registerContainer();
}

componentDidUpdate(prevProps) {
this.checkMeasurements(prevProps);
}
Expand All @@ -70,32 +137,12 @@ class Body extends React.Component {
clearTimeout(this.timeoutId);
}

getHeight(props) {
if (this.props.container) {
return this.props.container().clientHeight;
}
// If `props.height` is not defined, we use `props.style.maxHeight` instead.
return props.height || props.style.maxHeight;
}

render() {
const { onRow, rows, onScroll, container, ...props } = this.props;
const { onRow, rows, onScroll, container, rowKey, ...props } = this.props;
const { startIndex, amountOfRowsToRender, startHeight, endHeight, showExtraRow } = this.state;
const height = this.getHeight(this.props);

// Attach information about measuring status. This way we can implement
// proper shouldComponentUpdate
const rowsToRender = rows.slice(startIndex, startIndex + amountOfRowsToRender).map((rowData, rowIndex) => ({
...rowData,
_measured: !!this.measuredRows[
resolveRowKey({
rowData,
rowIndex,
rowKey: this.props.rowKey
})
]
}));
const height = this.getHeight();

const rowsToRender = this.rowsToRender(rows, startIndex, amountOfRowsToRender, rowKey);
if (process.env.NODE_ENV !== 'production' && typeof window !== 'undefined' && window.LOG_VIRTUALIZED) {
console.log(
// eslint-disable-line no-console
Expand All @@ -115,15 +162,11 @@ class Body extends React.Component {
const tableBodyProps = {
...props,
style: { height, display: 'block', overflow: 'auto' },
onRow: (row, extra) => {
const rowProps = onRow ? onRow(row, extra) : {};

return {
// Pass index so that row heights can be tracked properly
'data-rowkey': extra.rowKey,
...rowProps
};
},
onRow: (row, extra) => ({
// Pass index so that row heights can be tracked properly
'data-rowkey': extra.rowKey,
...(onRow ? onRow(row, extra) : {})
}),
rowsToRender,
onScroll: this.onScroll
};
Expand All @@ -135,8 +178,8 @@ class Body extends React.Component {
startHeight,
endHeight,
showExtraRow,
updateHeight: (rowKey, rowHeight) => {
this.measuredRows[rowKey] = rowHeight;
updateHeight: (oneRowKey, rowHeight) => {
this.measuredRows[oneRowKey] = rowHeight;
},
// Capture height data only during the initial measurement
initialMeasurement: this.initialMeasurement
Expand All @@ -146,64 +189,6 @@ class Body extends React.Component {
</VirtualizedBodyContext.Provider>
);
}

getBodyOffset() {
return this.ref.current.parentElement.offsetTop + this.ref.current.offsetTop;
}

onScroll(e) {
const { onScroll } = this.props;
onScroll && onScroll(e);

const {
target: { scrollTop }
} = e;

// Y didn't change, bail to avoid rendering rows
if (this.scrollTop === scrollTop) {
return;
}

this.scrollTop = this.props.container ? scrollTop - this.getBodyOffset() : scrollTop;

this.setState(this.calculateRows(this.props));
}

calculateRows(props) {
return calculateRows({
scrollTop: this.scrollTop,
measuredRows: this.measuredRows,
height: this.getHeight(props),
rowKey: props.rowKey,
rows: props.rows
});
}
checkMeasurements(prevProps) {
// If there are no valid measurements or the rows have changed,
// calculate some after waiting a while. Without this styling solutions
// like Radium won't work as you might expect given they can take a while to set container height.
if (this.initialMeasurement || (prevProps && prevProps.rows !== this.props.rows)) {
// If the rows have changed, but the user has not scrolled, maintain the existing
// scroll position
if (this.ref.current) {
this.ref.current.scrollTop = this.scrollTop;
}
this.timeoutId = setTimeout(() => {
const rows = this.calculateRows(this.props);

if (!rows) {
// Refresh the rows to trigger measurement.
this.forceUpdate();

return;
}

this.setState(rows, () => {
this.initialMeasurement = false;
});
}, 100);
}
}
}

const VirtualizedBody = ({ tableBody, ...props }) => (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ import React, { Component } from 'react';
import { VirtualizedBodyContext } from './Body';
import { bodyWrapperContextTypes, bodyWrapperTypes } from './types';

import { virtualizedCss } from './css/virtualized-css';

virtualizedCss.inject();

class BodyWrapper extends Component {
tr = props => React.createElement('tr', props);
render() {
Expand Down
Loading

0 comments on commit e8bce93

Please sign in to comment.