-
Notifications
You must be signed in to change notification settings - Fork 350
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(VirtualTableGrid): Add a table grid styled component using react…
…-virtualized (#818) VirtualTableGrid uses react-virtualized to efficiently render large lists of data. resolves #773
- Loading branch information
1 parent
5c9a52f
commit f8cc152
Showing
11 changed files
with
3,504 additions
and
4 deletions.
There are no files selected for viewing
2 changes: 2 additions & 0 deletions
2
packages/patternfly-3/patternfly-react-extensions/less/table-grid.less
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
@import '~react-virtualized/styles.css'; | ||
|
||
.table-grid-pf { | ||
.row, | ||
[class*='col-'] { | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 2 additions & 0 deletions
2
...atternfly-3/patternfly-react-extensions/sass/patternfly-react-extensions/_table-grid.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
@import '~react-virtualized/styles.css'; | ||
|
||
.table-grid-pf { | ||
.row, | ||
[class*='col-'] { | ||
|
153 changes: 153 additions & 0 deletions
153
...ges/patternfly-3/patternfly-react-extensions/src/components/TableGrid/VirtualTableGrid.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
import React from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import classNames from 'classnames'; | ||
import { AutoSizer, List as VirtualList, WindowScroller, CellMeasurerCache, CellMeasurer } from 'react-virtualized'; | ||
|
||
import TableGridHead from './TableGridHead'; | ||
import TableGridColumnHeader from './TableGridColumnHeader'; | ||
import TableGridRow from './TableGridRow'; | ||
import TableGridCol from './TableGridCol'; | ||
import TableGrid from './TableGrid'; | ||
|
||
/** | ||
* VirtualTableGrid Component for PatternFly | ||
*/ | ||
|
||
const VirtualTableGrid = ({ | ||
className, | ||
bordered, | ||
selectType, | ||
scrollable, | ||
scrollableElementId, | ||
header, | ||
row, | ||
bodyClassName, | ||
empty, | ||
emptyComponent, | ||
measurementCache, | ||
data, | ||
tableData, | ||
...props | ||
}) => { | ||
const cellMeasurementCache = | ||
measurementCache || | ||
new CellMeasurerCache({ | ||
fixedWidth: true, | ||
minHeight: 44 | ||
}); | ||
|
||
const rowRenderer = rowProps => { | ||
const { index, style, key, parent } = rowProps; | ||
const obj = data[index]; | ||
|
||
return ( | ||
<CellMeasurer cache={cellMeasurementCache} columnIndex={0} key={key} rowIndex={index} parent={parent}> | ||
<div style={style}>{row({ obj, tableData, index })}</div> | ||
</CellMeasurer> | ||
); | ||
}; | ||
|
||
const classes = classNames( | ||
{ | ||
'table-grid-pf': true, | ||
'container-fluid': true, | ||
bordered, | ||
'row-select': selectType === 'row', | ||
'cell-select': selectType === 'cell', | ||
'checkbox-select': selectType === 'checkbox' | ||
}, | ||
className | ||
); | ||
|
||
const renderAutoSizer = sizerProps => { | ||
const { height, isScrolling, registerChild, onChildScroll, scrollTop } = sizerProps; | ||
|
||
return ( | ||
<AutoSizer disableHeight> | ||
{({ width }) => ( | ||
<div ref={registerChild}> | ||
<VirtualList | ||
autoHeight | ||
data={data} | ||
height={height || 0} | ||
deferredMeasurementCache={cellMeasurementCache} | ||
rowHeight={cellMeasurementCache.rowHeight} | ||
isScrolling={isScrolling} | ||
onScroll={onChildScroll} | ||
rowRenderer={rowRenderer} | ||
rowCount={data.length} | ||
scrollTop={scrollTop} | ||
width={width} | ||
tabIndex={null} | ||
/> | ||
</div> | ||
)} | ||
</AutoSizer> | ||
); | ||
}; | ||
|
||
const scrollElement = scrollable || document.getElementById(scrollableElementId) || window; | ||
|
||
const bodyComponent = empty ? ( | ||
emptyComponent | ||
) : ( | ||
<WindowScroller scrollElement={scrollElement}>{renderAutoSizer}</WindowScroller> | ||
); | ||
|
||
return ( | ||
<div className={classes} {...props}> | ||
{header(tableData)} | ||
<TableGrid.Body className={bodyClassName}>{bodyComponent}</TableGrid.Body> | ||
</div> | ||
); | ||
}; | ||
|
||
VirtualTableGrid.propTypes = { | ||
/** Additional css classes */ | ||
className: PropTypes.string, | ||
/** Flag to use a bordered grid */ | ||
bordered: PropTypes.bool, | ||
/** Type of selection for the grid */ | ||
selectType: PropTypes.oneOf(['row', 'cell', 'checkbox', 'none']), | ||
/** Scrollable element for the list (use scrollableElementId or scrollable or neither to default to window) */ | ||
scrollable: PropTypes.any, | ||
/** Id of the scrollable element for the list (use scrollableElementId or scrollable or neither to default to window) */ | ||
scrollableElementId: PropTypes.any, | ||
/** Function(tableData) to return the header for the grid */ | ||
header: PropTypes.func.isRequired, | ||
/** Function({obj, tableData, index}) to return a row */ | ||
row: PropTypes.func.isRequired, | ||
/** Classes to add to the body */ | ||
bodyClassName: PropTypes.string, | ||
/** Flag if there is no data */ | ||
empty: PropTypes.bool, | ||
/** Component to show if empty */ | ||
emptyComponent: PropTypes.node, | ||
/* react-virtualized: Cache to be shared between CellMeasurer and its parent Grid. */ | ||
measurementCache: PropTypes.object, | ||
/** Data to fill the table */ | ||
data: PropTypes.array, | ||
/** Global table data to be passed to each row (state values?) */ | ||
tableData: PropTypes.any | ||
}; | ||
|
||
VirtualTableGrid.defaultProps = { | ||
className: '', | ||
bordered: true, | ||
selectType: 'none', | ||
scrollable: null, | ||
scrollableElementId: '', | ||
bodyClassName: '', | ||
empty: false, | ||
emptyComponent: null, | ||
measurementCache: null, | ||
data: [], | ||
tableData: null | ||
}; | ||
|
||
VirtualTableGrid.Head = TableGridHead; | ||
VirtualTableGrid.ColumnHeader = TableGridColumnHeader; | ||
VirtualTableGrid.Row = TableGridRow; | ||
VirtualTableGrid.Col = TableGridCol; | ||
|
||
export default VirtualTableGrid; |
59 changes: 59 additions & 0 deletions
59
...ernfly-3/patternfly-react-extensions/src/components/TableGrid/VirtualTableGrid.stories.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import React from 'react'; | ||
import { storiesOf } from '@storybook/react'; | ||
import { withInfo } from '@storybook/addon-info/dist/index'; | ||
import { defaultTemplate } from 'storybook/decorators/storyTemplates'; | ||
import { storybookPackageName, STORYBOOK_CATEGORY } from 'storybook/constants/siteConstants'; | ||
import { MockVirtualTableGridExample, MockVirtualTableGridExampleSource } from './_mocks_/mockVirtualTableGridExample'; | ||
|
||
import { VirtualTableGrid, TableGridHead, TableGridColumnHeader, TableGridRow, TableGridCol } from './index'; | ||
|
||
import { name } from '../../../package.json'; | ||
import { boolean, select, withKnobs } from '@storybook/addon-knobs'; | ||
|
||
const stories = storiesOf(`${storybookPackageName(name)}/${STORYBOOK_CATEGORY.CONTENT_VIEWS}/VirtualTableGrid`, module); | ||
|
||
stories.addDecorator( | ||
defaultTemplate({ | ||
title: 'Virtual Table Grid', | ||
description: ( | ||
<div> | ||
The VirtualTableGrid is based on the Bootstrap Grid Layout and uses{' '} | ||
<a href="https://github.com/bvaughn/react-virtualized">react-virtualized</a> to efficiently render large lists | ||
of data. | ||
<br /> | ||
<br /> | ||
The <b>VirtualTableGrid.ColumnHeaders</b> should have the same bootstrap column classes as the children of the{' '} | ||
<b>VirtualTableGrid.Row</b> component in order to maintain equal widths. | ||
<br /> | ||
<br /> | ||
When using <i>cell</i> selection, the <b>VirtualTableGrid.Col</b> component should be used in place of the | ||
<b> Grid.Col</b> component for correct selection styling. | ||
</div> | ||
) | ||
}) | ||
); | ||
|
||
stories.addDecorator(withKnobs); | ||
stories.add( | ||
'VirtualTableGrid', | ||
withInfo({ | ||
source: false, | ||
propTables: [VirtualTableGrid, TableGridHead, TableGridColumnHeader, TableGridRow, TableGridCol], | ||
propTablesExclude: [MockVirtualTableGridExample], | ||
text: ( | ||
<div> | ||
<h1>Story Source</h1> | ||
<pre>{MockVirtualTableGridExampleSource}</pre> | ||
</div> | ||
) | ||
})(() => { | ||
const bordered = boolean('Bordered', true); | ||
const selectType = select( | ||
'Selection Type', | ||
{ none: 'None', row: 'Row', checkbox: 'Checkbox', cell: 'Cell' }, | ||
'none' | ||
); | ||
|
||
return <MockVirtualTableGridExample bordered={bordered} selectType={selectType} />; | ||
}) | ||
); |
Oops, something went wrong.