Skip to content

Commit 3170d8b

Browse files
authored
Merge pull request schrodinger#375 from pradeepnschrodinger/merge-11-PageUp-PageDown
Merge commits from '0a26dd1' (inclusive) till 'ff24111', from master into v1.0-beta
2 parents c385289 + 0f9552c commit 3170d8b

13 files changed

+280
-7
lines changed

examples/FixedRightColumnsExample.js

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/**
2+
* Copyright Schrodinger, LLC
3+
*/
4+
5+
"use strict";
6+
7+
const FakeObjectDataListStore = require('./helpers/FakeObjectDataListStore');
8+
const { DateCell, ImageCell, LinkCell, TextCell } = require('./helpers/cells');
9+
const { Table, Column, Cell } = require('fixed-data-table-2');
10+
const React = require('react');
11+
12+
class FixedRightColumnsExample extends React.Component {
13+
constructor(props) {
14+
super(props);
15+
16+
this.state = {
17+
dataList: new FakeObjectDataListStore(1000000),
18+
};
19+
}
20+
21+
render() {
22+
var {dataList} = this.state;
23+
return (
24+
<Table
25+
rowHeight={50}
26+
headerHeight={50}
27+
rowsCount={dataList.getSize()}
28+
width={1000}
29+
height={500}
30+
{...this.props}>
31+
<Column
32+
columnKey="avatar"
33+
cell={<ImageCell data={dataList} />}
34+
fixed={true}
35+
width={50}
36+
/>
37+
<Column
38+
columnKey="firstName"
39+
header={<Cell>First Name</Cell>}
40+
cell={<LinkCell data={dataList} />}
41+
fixedRight={true}
42+
width={100}
43+
/>
44+
<Column
45+
columnKey="lastName"
46+
header={<Cell>Last Name</Cell>}
47+
cell={<TextCell data={dataList} />}
48+
fixedRight={true}
49+
width={100}
50+
/>
51+
<Column
52+
columnKey="city"
53+
header={<Cell>City</Cell>}
54+
cell={<TextCell data={dataList} />}
55+
width={100}
56+
/>
57+
<Column
58+
columnKey="street"
59+
header={<Cell>Street</Cell>}
60+
cell={<TextCell data={dataList} />}
61+
width={200}
62+
/>
63+
<Column
64+
columnKey="zipCode"
65+
header={<Cell>Zip Code</Cell>}
66+
cell={<TextCell data={dataList} />}
67+
width={200}
68+
/>
69+
<Column
70+
columnKey="email"
71+
header={<Cell>Email</Cell>}
72+
cell={<LinkCell data={dataList} />}
73+
width={200}
74+
/>
75+
<Column
76+
columnKey="date"
77+
header={<Cell>DOB</Cell>}
78+
cell={<DateCell data={dataList} />}
79+
width={200}
80+
/>
81+
</Table>
82+
);
83+
}
84+
}
85+
86+
module.exports = FixedRightColumnsExample;

site/Constants.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@ exports.ExamplePages = {
3636
title: 'With JSON Data',
3737
description: 'A basic table example with two fixed columns, fed in some JSON data.',
3838
},
39+
FIXED_RIGHT_COLUMNS_EXAMPLE: {
40+
location: 'fixed-right-columns.html',
41+
fileName: 'FixedRightColumnsExample.js',
42+
title: 'Fixed Right Columns',
43+
description: 'A table example that has a columns fixed to the right side of the table.',
44+
},
3945
FLEXGROW_EXAMPLE: {
4046
location: 'example-flexgrow.html',
4147
fileName: 'FlexGrowExample.js',

site/examples/ExamplesPage.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ var EXAMPLE_COMPONENTS = {
4848
[ExamplePages.OWNER_HEIGHT_EXAMPLE.location]: require('../../examples/OwnerHeightExample'),
4949
[ExamplePages.LONG_CLICK_EXAMPLE.location]: require('../../examples/LongClickExample'),
5050
[ExamplePages.CONTEXT_EXAMPLE.location]: require('../../examples/ContextExample'),
51+
[ExamplePages.FIXED_RIGHT_COLUMNS_EXAMPLE.location]: require('../../examples/FixedRightColumnsExample'),
5152
};
5253

5354
class ExamplesPage extends React.Component {

src/FixedDataTable.js

Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ import joinClasses from 'joinClasses';
2929
import scrollbarsVisible from 'scrollbarsVisible';
3030
import tableHeightsSelector from 'tableHeights';
3131

32+
var ARROW_SCROLL_SPEED = 25;
33+
34+
3235
/**
3336
* Data grid component with fixed or scrollable header and columns.
3437
*
@@ -135,6 +138,12 @@ class FixedDataTable extends React.Component {
135138
touchScrollEnabled: PropTypes.bool,
136139

137140
// TODO (jordan) Remove propType of showScrollbarX & showScrollbarY without losing documentation (moved to scrollFlags)
141+
/**
142+
* Boolean flags to control if scrolling with keys is enabled
143+
*/
144+
keyboardScrollEnabled: PropTypes.bool,
145+
keyboardPageEnabled: PropTypes.bool,
146+
138147
/**
139148
* Hide the scrollbar but still enable scroll functionality
140149
*/
@@ -410,12 +419,15 @@ class FixedDataTable extends React.Component {
410419
groupHeaderHeight: 0,
411420
headerHeight: 0,
412421
},
422+
keyboardScrollEnabled: false,
423+
keyboardPageEnabled: false,
413424
touchScrollEnabled: false,
414425
stopScrollPropagation: false,
415426
}
416427

417428
componentWillMount() {
418429
this._didScrollStop = debounceCore(this._didScrollStopSync, 200, this);
430+
this._onKeyDown = this._onKeyDown.bind(this);
419431

420432
this._wheelHandler = new ReactWheelHandler(
421433
this._onScroll,
@@ -485,6 +497,53 @@ class FixedDataTable extends React.Component {
485497
);
486498
}
487499

500+
_onKeyDown(event) {
501+
const { scrollbarYHeight } = tableHeightsSelector(this.props);
502+
if (this.props.keyboardPageEnabled) {
503+
switch (event.key) {
504+
case 'PageDown':
505+
this._onScroll(0, scrollbarYHeight);
506+
event.preventDefault();
507+
break;
508+
509+
case 'PageUp':
510+
this._onScroll(0, scrollbarYHeight * -1);
511+
event.preventDefault();
512+
break;
513+
514+
default:
515+
break;
516+
}
517+
}
518+
if (this.props.keyboardScrollEnabled) {
519+
switch (event.key) {
520+
521+
case 'ArrowDown':
522+
this._onScroll(0, ARROW_SCROLL_SPEED);
523+
event.preventDefault();
524+
break;
525+
526+
case 'ArrowUp':
527+
this._onScroll(0, ARROW_SCROLL_SPEED * -1);
528+
event.preventDefault();
529+
break;
530+
531+
case 'ArrowRight':
532+
this._onScroll(ARROW_SCROLL_SPEED, 0);
533+
event.preventDefault();
534+
break;
535+
536+
case 'ArrowLeft':
537+
this._onScroll(ARROW_SCROLL_SPEED * -1, 0);
538+
event.preventDefault();
539+
break;
540+
541+
default:
542+
break;
543+
}
544+
}
545+
}
546+
488547
_reportContentHeight = () => {
489548
const { contentHeight } = tableHeightsSelector(this.props);
490549
const { onContentHeightChange } = this.props;
@@ -521,6 +580,8 @@ class FixedDataTable extends React.Component {
521580
const {
522581
fixedColumnGroups,
523582
fixedColumns,
583+
fixedRightColumnGroups,
584+
fixedRightColumns,
524585
scrollableColumnGroups,
525586
scrollableColumns,
526587
} = columnTemplatesSelector(this.props);
@@ -575,6 +636,7 @@ class FixedDataTable extends React.Component {
575636
offsetTop={0}
576637
scrollLeft={scrollX}
577638
fixedColumns={fixedColumnGroups}
639+
fixedRightColumns={fixedRightColumnGroups}
578640
scrollableColumns={scrollableColumnGroups}
579641
visible={true}
580642
onColumnResize={this._onColumnResize}
@@ -640,12 +702,13 @@ class FixedDataTable extends React.Component {
640702
offsetTop={footOffsetTop}
641703
visible={true}
642704
fixedColumns={fixedColumns.footer}
705+
fixedRightColumns={fixedRightColumns.footer}
643706
scrollableColumns={scrollableColumns.footer}
644707
scrollLeft={scrollX}
645708
/>;
646709
}
647710

648-
const rows = this._renderRows(bodyOffsetTop, fixedColumns.cell,
711+
const rows = this._renderRows(bodyOffsetTop, fixedColumns.cell, fixedRightColumns.cell,
649712
scrollableColumns.cell, bodyHeight);
650713

651714
const header =
@@ -665,6 +728,7 @@ class FixedDataTable extends React.Component {
665728
scrollLeft={scrollX}
666729
visible={true}
667730
fixedColumns={fixedColumns.header}
731+
fixedRightColumns={fixedRightColumns.header}
668732
scrollableColumns={scrollableColumns.header}
669733
touchEnabled={touchScrollEnabled}
670734
onColumnResize={this._onColumnResize}
@@ -710,6 +774,8 @@ class FixedDataTable extends React.Component {
710774
cx('fixedDataTableLayout/main'),
711775
cx('public/fixedDataTable/main'),
712776
)}
777+
tabIndex={0}
778+
onKeyDown={this._onKeyDown}
713779
onWheel={this._wheelHandler.onWheel}
714780
onTouchStart={this._touchHandler.onTouchStart}
715781
onTouchEnd={this._touchHandler.onTouchEnd}
@@ -739,13 +805,14 @@ class FixedDataTable extends React.Component {
739805
);
740806
}
741807

742-
_renderRows = (/*number*/ offsetTop, fixedCellTemplates, scrollableCellTemplates,
808+
_renderRows = (/*number*/ offsetTop, fixedCellTemplates, fixedRightCellTemplates, scrollableCellTemplates,
743809
bodyHeight) /*object*/ => {
744810
const props = this.props;
745811
return (
746812
<FixedDataTableBufferedRows
747813
isScrolling={this._isScrolling}
748814
fixedColumns={fixedCellTemplates}
815+
fixedRightColumns={fixedRightCellTemplates}
749816
height={bodyHeight}
750817
offsetTop={offsetTop}
751818
onRowClick={props.onRowClick}

src/FixedDataTableBufferedRows.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ class FixedDataTableBufferedRows extends React.Component {
2121
static propTypes = {
2222
isScrolling: PropTypes.bool,
2323
fixedColumns: PropTypes.array.isRequired,
24+
fixedRightColumns: PropTypes.array.isRequired,
2425
height: PropTypes.number.isRequired,
2526
offsetTop: PropTypes.number.isRequired,
2627
onRowClick: PropTypes.func,
@@ -118,6 +119,7 @@ class FixedDataTableBufferedRows extends React.Component {
118119
offsetTop={Math.round(rowOffsetTop)}
119120
visible={true}
120121
fixedColumns={props.fixedColumns}
122+
fixedRightColumns={props.fixedRightColumns}
121123
scrollableColumns={props.scrollableColumns}
122124
onClick={props.onRowClick}
123125
onDoubleClick={props.onRowDoubleClick}

src/FixedDataTableCellGroup.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ class FixedDataTableCellGroup extends React.Component {
201201
}
202202

203203
static defaultProps = /*object*/ {
204+
left: 0,
204205
offsetLeft: 0,
205206
}
206207

src/FixedDataTableColumn.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ class FixedDataTableColumn extends React.Component {
3131
*/
3232
fixed: PropTypes.bool,
3333

34+
/**
35+
* Controls if the column is fixed to the right side of the table when scrolling in the X axis.
36+
*/
37+
fixedRight: PropTypes.bool,
38+
3439
/**
3540
* The header cell for this column.
3641
* This can either be a string a React element, or a function that generates
@@ -181,6 +186,7 @@ class FixedDataTableColumn extends React.Component {
181186
static defaultProps = {
182187
allowCellsRecycling: false,
183188
fixed: false,
189+
fixedRight: false,
184190
};
185191

186192
render() {

src/FixedDataTableRow.js

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ class FixedDataTableRowImpl extends React.Component {
4444
*/
4545
fixedColumns: PropTypes.array.isRequired,
4646

47+
/**
48+
* Array of <FixedDataTableColumn /> for the fixed columns positioned at end of the table.
49+
*/
50+
fixedRightColumns: PropTypes.array.isRequired,
51+
4752
/**
4853
* Height of the row.
4954
*/
@@ -181,15 +186,39 @@ class FixedDataTableRowImpl extends React.Component {
181186
rowIndex={this.props.index}
182187
/>;
183188
var columnsLeftShadow = this._renderColumnsLeftShadow(fixedColumnsWidth);
189+
var fixedRightColumnsWidth = sumPropWidths(this.props.fixedRightColumns);
190+
var fixedRightColumns =
191+
<FixedDataTableCellGroup
192+
key="fixed_right_cells"
193+
isScrolling={this.props.isScrolling}
194+
height={this.props.height}
195+
cellGroupWrapperHeight={this.props.cellGroupWrapperHeight}
196+
offsetLeft={this.props.width - fixedRightColumnsWidth}
197+
width={fixedRightColumnsWidth}
198+
zIndex={2}
199+
columns={this.props.fixedRightColumns}
200+
touchEnabled={this.props.touchEnabled}
201+
onColumnResize={this.props.onColumnResize}
202+
onColumnReorder={this.props.onColumnReorder}
203+
onColumnReorderMove={this.props.onColumnReorderMove}
204+
onColumnReorderEnd={this.props.onColumnReorderEnd}
205+
isColumnReordering={this.props.isColumnReordering}
206+
columnReorderingData={this.props.columnReorderingData}
207+
rowHeight={this.props.height}
208+
rowIndex={this.props.index}
209+
/>;
210+
var fixedRightColumnsShdadow = fixedRightColumnsWidth ?
211+
this._renderFixedRightColumnsShadow(this.props.width - fixedRightColumnsWidth - 5) : null;
184212
var scrollableColumns =
185213
<FixedDataTableCellGroup
186214
key="scrollable_cells"
187215
isScrolling={this.props.isScrolling}
188216
height={this.props.height}
189217
cellGroupWrapperHeight={this.props.cellGroupWrapperHeight}
218+
align="right"
190219
left={this.props.scrollLeft}
191220
offsetLeft={fixedColumnsWidth}
192-
width={this.props.width - fixedColumnsWidth}
221+
width={this.props.width - fixedColumnsWidth - fixedRightColumnsWidth}
193222
zIndex={0}
194223
columns={this.props.scrollableColumns}
195224
touchEnabled={this.props.touchEnabled}
@@ -228,6 +257,8 @@ class FixedDataTableRowImpl extends React.Component {
228257
{fixedColumns}
229258
{scrollableColumns}
230259
{columnsLeftShadow}
260+
{fixedRightColumns}
261+
{fixedRightColumnsShdadow}
231262
</div>
232263
{rowExpanded && <div
233264
className={cx('fixedDataTableRowLayout/rowExpanded')}
@@ -274,6 +305,22 @@ class FixedDataTableRowImpl extends React.Component {
274305
return <div className={className} style={style} />;
275306
};
276307

308+
_renderFixedRightColumnsShadow = (/*number*/ left) => /*?object*/ {
309+
var className = cx(
310+
'fixedDataTableRowLayout/columnsShadow',
311+
'fixedDataTableRowLayout/columnsRightShadow',
312+
'fixedDataTableRowLayout/fixedColumnsDivider',
313+
'public/fixedDataTableRow/columnsShadow',
314+
'public/fixedDataTableRow/columnsRightShadow',
315+
'public/fixedDataTableRow/fixedColumnsDivider'
316+
);
317+
var style = {
318+
height: this.props.height,
319+
left: left
320+
};
321+
return <div className={className} style={style} />;
322+
};
323+
277324
_renderColumnsRightShadow = (/*number*/ totalWidth) => /*?object*/ {
278325
if (Math.ceil(this.props.scrollLeft + this.props.width) < Math.floor(totalWidth)) {
279326
var className = cx(

0 commit comments

Comments
 (0)