Skip to content

Commit 81f4951

Browse files
committed
Merge pull request #161 from jquense/null-render
Clean up Grid to allow more complex ScrollSync
2 parents 6fd4f5a + c420bb0 commit 81f4951

4 files changed

Lines changed: 71 additions & 25 deletions

File tree

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
"prebuild": "npm run lint",
2626
"postpublish": "npm run deploy",
2727
"prepublish": "npm run build",
28-
"start": "webpack-dev-server --hot --inline --config webpack.config.dev.js",
28+
"start": "cross-env NODE_ENV=development webpack-dev-server --hot --inline --config webpack.config.dev.js",
2929
"test": "npm run lint && npm run test:unit",
3030
"test:unit": "cross-env NODE_ENV=test karma start",
3131
"watch": "watch 'clear && npm run lint -s && npm run test -s' source"
@@ -125,6 +125,7 @@
125125
},
126126
"dependencies": {
127127
"classnames": "^2.2.3",
128+
"dom-helpers": "^2.4.0",
128129
"raf": "^3.1.0",
129130
"react-pure-render": "^1.0.2"
130131
},

source/Grid/Grid.js

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
} from '../utils'
1111
import cn from 'classnames'
1212
import raf from 'raf'
13+
import getScrollbarSize from 'dom-helpers/util/scrollbarSize'
1314
import React, { Component, PropTypes } from 'react'
1415
import shouldPureComponentUpdate from 'react-pure-render/function'
1516

@@ -208,6 +209,8 @@ export default class Grid extends Component {
208209
componentDidMount () {
209210
const { scrollLeft, scrollToColumn, scrollTop, scrollToRow } = this.props
210211

212+
this._scrollbarSize = getScrollbarSize()
213+
211214
if (scrollLeft >= 0 || scrollTop >= 0) {
212215
this.setScrollPosition({ scrollLeft, scrollTop })
213216
}
@@ -427,6 +430,13 @@ export default class Grid extends Component {
427430
let columnDatum = this._columnMetadata[columnIndex]
428431
let renderedCell = renderCell({ columnIndex, rowIndex })
429432
let key = `${rowIndex}-${columnIndex}`
433+
434+
// any other falsey value will be rendered
435+
// as a text node by React
436+
if (renderedCell == null || renderedCell === false) {
437+
continue
438+
}
439+
430440
let child = (
431441
<div
432442
key={key}
@@ -732,10 +742,11 @@ export default class Grid extends Component {
732742
// This causes a series of rapid renders that is slow for long lists.
733743
// We can avoid that by doing some simple bounds checking to ensure that scrollTop never exceeds the total height.
734744
const { height, width } = this.props
745+
const scrollbarSize = this._scrollbarSize
735746
const totalRowsHeight = this._getTotalRowsHeight()
736747
const totalColumnsWidth = this._getTotalColumnsWidth()
737-
const scrollLeft = Math.min(totalColumnsWidth - width, event.target.scrollLeft)
738-
const scrollTop = Math.min(totalRowsHeight - height, event.target.scrollTop)
748+
const scrollLeft = Math.min(totalColumnsWidth - width + scrollbarSize, event.target.scrollLeft)
749+
const scrollTop = Math.min(totalRowsHeight - height + scrollbarSize, event.target.scrollTop)
739750

740751
// Certain devices (like Apple touchpad) rapid-fire duplicate events.
741752
// Don't force a re-render if this is the case.

source/ScrollSync/ScrollSync.example.css

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
.GridRow {
2+
position: relative;
23
display: flex;
34
flex-direction: row;
45
}
@@ -9,6 +10,7 @@
910
}
1011
.LeftSideGridContainer {
1112
flex: 0 0 75px;
13+
z-index: 10;
1214
}
1315

1416
.LeftSideGrid {

source/ScrollSync/ScrollSync.example.js

Lines changed: 54 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ import { ContentBox, ContentBoxHeader, ContentBoxParagraph } from '../demo/Conte
55
import AutoSizer from '../AutoSizer'
66
import Grid from '../Grid'
77
import ScrollSync from './ScrollSync'
8-
import VirtualScroll from '../VirtualScroll'
98
import shouldPureComponentUpdate from 'react-pure-render/function'
109
import cn from 'classnames'
1110
import styles from './ScrollSync.example.css'
11+
import scrollbarSize from 'dom-helpers/util/scrollbarSize'
1212

1313
const LEFT_COLOR_FROM = hexToRgb('#471061')
1414
const LEFT_COLOR_TO = hexToRgb('#BC3959')
@@ -83,21 +83,47 @@ export default class GridExample extends Component {
8383
const middleColor = `#ffffff`
8484

8585
return (
86-
<div className={styles.GridRow}>
86+
<div className={styles.GridRow }>
8787
<div
8888
className={styles.LeftSideGridContainer}
8989
style={{
90-
backgroundColor: `rgb(${leftBackgroundColor.r},${leftBackgroundColor.g},${leftBackgroundColor.b})`,
90+
position: 'absolute',
91+
left: 0,
92+
top: 0,
9193
color: leftColor,
92-
marginTop: rowHeight
94+
backgroundColor: `rgb(${topBackgroundColor.r},${topBackgroundColor.g},${topBackgroundColor.b})`
9395
}}
9496
>
95-
<VirtualScroll
96-
className={styles.LeftSideGrid}
97-
height={height}
97+
<Grid
98+
renderCell={this._renderLeftHeaderCell}
99+
className={styles.HeaderGrid}
100+
width={columnWidth}
101+
height={rowHeight}
102+
rowHeight={rowHeight}
103+
columnWidth={columnWidth}
104+
rowsCount={1}
105+
columnsCount={1}
106+
/>
107+
</div>
108+
<div
109+
className={styles.LeftSideGridContainer}
110+
style={{
111+
position: 'absolute',
112+
left: 0,
113+
top: rowHeight,
114+
color: leftColor,
115+
backgroundColor: `rgb(${leftBackgroundColor.r},${leftBackgroundColor.g},${leftBackgroundColor.b})`
116+
}}
117+
>
118+
<Grid
119+
overscanColumnsCount={overscanColumnsCount}
98120
overscanRowsCount={overscanRowsCount}
121+
renderCell={this._renderLeftSideCell}
122+
columnWidth={columnWidth}
123+
columnsCount={1}
124+
className={styles.LeftSideGrid}
125+
height={height - scrollbarSize()}
99126
rowHeight={rowHeight}
100-
rowRenderer={this._renderLeftSideCell}
101127
rowsCount={rowsCount}
102128
scrollTop={scrollTop}
103129
width={columnWidth}
@@ -111,7 +137,7 @@ export default class GridExample extends Component {
111137
backgroundColor: `rgb(${topBackgroundColor.r},${topBackgroundColor.g},${topBackgroundColor.b})`,
112138
color: topColor,
113139
height: rowHeight,
114-
width
140+
width: width - scrollbarSize()
115141
}}>
116142
<Grid
117143
className={styles.HeaderGrid}
@@ -123,7 +149,7 @@ export default class GridExample extends Component {
123149
rowHeight={rowHeight}
124150
rowsCount={1}
125151
scrollLeft={scrollLeft}
126-
width={width}
152+
width={width - scrollbarSize()}
127153
/>
128154
</div>
129155
<div
@@ -161,32 +187,38 @@ export default class GridExample extends Component {
161187
}
162188

163189
_renderBodyCell ({ columnIndex, rowIndex }) {
164-
const rowClass = rowIndex % 2 === 0
165-
? columnIndex % 2 === 0 ? styles.evenRow : styles.oddRow
166-
: columnIndex % 2 !== 0 ? styles.evenRow : styles.oddRow
167-
const classNames = cn(rowClass, styles.cell)
190+
if (columnIndex < 1) {
191+
return
192+
}
168193

169-
return (
170-
<div className={classNames}>
171-
{`R${rowIndex}, C${columnIndex}`}
172-
</div>
173-
)
194+
return this._renderLeftSideCell({ columnIndex, rowIndex })
174195
}
175196

176197
_renderHeaderCell ({ columnIndex, rowIndex }) {
198+
if (columnIndex < 1) {
199+
return
200+
}
201+
202+
return this._renderLeftHeaderCell({ columnIndex, rowIndex })
203+
}
204+
205+
_renderLeftHeaderCell ({ columnIndex, rowIndex }) {
177206
return (
178207
<div className={styles.headerCell}>
179208
{`C${columnIndex}`}
180209
</div>
181210
)
182211
}
183212

184-
_renderLeftSideCell (rowIndex) {
185-
const classNames = cn(styles.cell, styles.leftCell)
213+
_renderLeftSideCell ({ columnIndex, rowIndex }) {
214+
const rowClass = rowIndex % 2 === 0
215+
? columnIndex % 2 === 0 ? styles.evenRow : styles.oddRow
216+
: columnIndex % 2 !== 0 ? styles.evenRow : styles.oddRow
217+
const classNames = cn(rowClass, styles.cell)
186218

187219
return (
188220
<div className={classNames}>
189-
{`R${rowIndex}`}
221+
{`R${rowIndex}, C${columnIndex}`}
190222
</div>
191223
)
192224
}

0 commit comments

Comments
 (0)