Skip to content

Commit 95396e0

Browse files
amanmahajan7nstepien
authored andcommitted
Re-implement row selection (#1762)
* Re-implement row selection * Re-enable jsx-curly-brace-presence * onSelectedRowsChanged -> onSelectedRowsChange * Small cleanup in Canvas.tsx * small tweaks * Delete RowUtils tests * Fix Canvas tests * Get shift selection almost working * Simplify a few exports * Focus CellMask when clicking on a cell * Working shift selection * use a ref for lastSelectedRowIdx * Add class methods to avoid recomputation * Do it the react way * Simplify 1 type * Fix selection * tweaks * Remove references to `enableRowSelect` * More cleanup * fix some tests * fix tests * Remove @testing-library/react/cleanup-after-each * Fix some examples * Fix another example * optimize all-features example * Cleanup viewport events * Cleanup props, remove PureComponent * Fix draggable header example * Commit reordering fixes (not working) * Remove row-reordering components * Fix eslint errors * Remove re-ordering refrences * Remove tests for the deleted file * Fix types
1 parent a53db43 commit 95396e0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+344
-1151
lines changed

.eslintrc.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ const rules = {
357357
'react/jsx-no-undef': 0,
358358
'react/jsx-no-useless-fragment': 0,
359359
'react/jsx-one-expression-per-line': 0,
360-
'react/jsx-curly-brace-presence': 0,
360+
'react/jsx-curly-brace-presence': 1,
361361
'react/jsx-fragments': 1,
362362
'react/jsx-pascal-case': 1,
363363
'react/jsx-props-no-multi-spaces': 1,

examples/components/ExampleList.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ export default class ExampleList extends React.Component {
2929
<li><Link to="/examples/grouping">Grouping Example</Link></li>
3030
<li><Link to="/examples/custom-filters">Custom Filters Example</Link></li>
3131
<li><Link to="/examples/immutable-data-grouping">Immutable Data Grouping Example</Link></li>
32-
<li><Link to="/examples/row-reordering">Row Reordering Example</Link></li>
3332
<li><Link to="/examples/draggable-header">Draggable Header Example</Link></li>
3433
<li><Link to="/examples/tree-view">Tree View Example</Link></li>
3534
<li><Link to="/examples/tree-view-no-add-delete">Tree View No Add Delete Example</Link></li>

examples/components/Examples.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ import CellSelectionEvents from '../scripts/example21-cell-selection-events';
2828
import Grouping from '../scripts/example21-grouping';
2929
import CustomFilters from '../scripts/example22-custom-filters';
3030
import ImmutableDataGrouping from '../scripts/example23-immutable-data-grouping';
31-
import RowOrdering from '../scripts/example23-row-reordering';
3231
import DraggableHeader from '../scripts/example24-draggable-header';
3332
import TreeView from '../scripts/example25-tree-view';
3433
import TreeViewNoAddDelete from '../scripts/example26-tree-view-no-add-delete';
@@ -78,7 +77,6 @@ export default function Examples({ match }) {
7877
<Route path="/examples/grouping" component={Grouping} />
7978
<Route path="/examples/custom-filters" component={CustomFilters} />
8079
<Route path="/examples/immutable-data-grouping" component={ImmutableDataGrouping} />
81-
<Route path="/examples/row-reordering" component={RowOrdering} />
8280
<Route path="/examples/draggable-header" component={DraggableHeader} />
8381
<Route path="/examples/tree-view" component={TreeView} />
8482
<Route path="/examples/tree-view-no-add-delete" component={TreeViewNoAddDelete} />

examples/scripts/example13-all-features.js

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React from 'react';
2-
import ReactDataGrid from 'react-data-grid';
2+
import ReactDataGrid, { SelectColumn } from 'react-data-grid';
33
import { Editors, Toolbar, Formatters } from 'react-data-grid-addons';
44
import update from 'immutability-helper';
55
import faker from 'faker';
@@ -16,7 +16,8 @@ const titles = ['Dr.', 'Mr.', 'Mrs.', 'Miss', 'Ms.'];
1616
class Example extends React.Component {
1717
constructor(props, context) {
1818
super(props, context);
19-
this._columns = [
19+
this.columns = [
20+
SelectColumn,
2021
{
2122
key: 'id',
2223
name: 'ID',
@@ -38,8 +39,8 @@ class Example extends React.Component {
3839
width: 200,
3940
resizable: true,
4041
events: {
41-
onDoubleClick() {
42-
console.log('The user double clicked on title column');
42+
onClick: (ev, { idx, rowIdx }) => {
43+
this.grid.openCellEditor(rowIdx, idx);
4344
}
4445
}
4546
},
@@ -115,7 +116,10 @@ class Example extends React.Component {
115116
}
116117
];
117118

118-
this.state = { rows: this.createRows(2000) };
119+
this.state = {
120+
rows: this.createRows(2000),
121+
selectedRows: new Set()
122+
};
119123
}
120124

121125
createRows = (numberOfRows) => {
@@ -145,17 +149,6 @@ class Example extends React.Component {
145149
};
146150
};
147151

148-
getColumns = () => {
149-
const clonedColumns = this._columns.slice();
150-
clonedColumns[2].events = {
151-
onClick: (ev, { idx, rowIdx }) => {
152-
this.grid.openCellEditor(rowIdx, idx);
153-
}
154-
};
155-
156-
return clonedColumns;
157-
};
158-
159152
handleGridRowsUpdated = ({ fromRow, toRow, updated }) => {
160153
const rows = this.state.rows.slice();
161154

@@ -193,19 +186,24 @@ class Example extends React.Component {
193186
return this.state.rows.length;
194187
};
195188

189+
onSelectedRowsChange = (selectedRows) => {
190+
this.setState({ selectedRows });
191+
};
192+
196193
render() {
197194
return (
198195
<ReactDataGrid
199196
ref={node => this.grid = node}
200197
enableCellSelect
201-
columns={this.getColumns()}
198+
columns={this.columns}
202199
rowGetter={this.getRowAt}
203200
rowsCount={this.getSize()}
204201
onGridRowsUpdated={this.handleGridRowsUpdated}
205202
toolbar={<Toolbar onAddRow={this.handleAddRow} />}
206-
enableRowSelect
207203
rowHeight={50}
208204
minHeight={600}
205+
selectedRows={this.state.selectedRows}
206+
onSelectedRowsChange={this.onSelectedRowsChange}
209207
/>
210208
);
211209
}

examples/scripts/example16-row-select.js

Lines changed: 13 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import React from 'react';
2-
import ReactDataGrid from 'react-data-grid';
2+
import ReactDataGrid, { SelectColumn } from 'react-data-grid';
33

44
import exampleWrapper from '../components/exampleWrapper';
55

66
class Example extends React.Component {
77
constructor(props) {
88
super(props);
99
this._columns = [
10+
SelectColumn,
1011
{
1112
key: 'id',
1213
name: 'ID'
@@ -29,71 +30,41 @@ class Example extends React.Component {
2930
count: i * 1000
3031
});
3132
}
32-
this.state = { rows, selectedIndexes: [] };
33+
this.state = {
34+
rows,
35+
selectedRows: new Set()
36+
};
3337
}
3438

3539
rowGetter = (i) => {
3640
return this.state.rows[i];
3741
};
3842

39-
onRowsSelected = (rows) => {
40-
this.setState({ selectedIndexes: this.state.selectedIndexes.concat(rows.map(r => r.rowIdx)) });
41-
};
42-
43-
onRowsDeselected = (rows) => {
44-
const rowIndexes = rows.map(r => r.rowIdx);
45-
this.setState({ selectedIndexes: this.state.selectedIndexes.filter(i => rowIndexes.indexOf(i) === -1) });
43+
onSelectedRowsChange = (selectedRows) => {
44+
this.setState({ selectedRows });
4645
};
4746

4847
render() {
49-
const rowText = this.state.selectedIndexes.length === 1 ? 'row' : 'rows';
48+
const rowText = this.state.selectedRows.size === 1 ? 'row' : 'rows';
5049
return (
5150
<div>
52-
<span>{this.state.selectedIndexes.length} {rowText} selected</span>
51+
<span>{this.state.selectedRows.size} {rowText} selected</span>
5352
<ReactDataGrid
5453
rowKey="id"
5554
columns={this._columns}
5655
rowGetter={this.rowGetter}
5756
rowsCount={this.state.rows.length}
5857
minHeight={500}
59-
rowSelection={{
60-
showCheckbox: true,
61-
enableShiftSelect: true,
62-
onRowsSelected: this.onRowsSelected,
63-
onRowsDeselected: this.onRowsDeselected,
64-
selectBy: {
65-
indexes: this.state.selectedIndexes
66-
}
67-
}}
58+
selectedRows={this.state.selectedRows}
59+
onSelectedRowsChange={this.onSelectedRowsChange}
6860
/>
6961
</div>
7062
);
7163
}
7264
}
7365

7466
const exampleDescription = (
75-
<div>
76-
<p>Row selection is enabled via the <code>rowSelection</code> prop (object). The following keys control behaviour:</p>
77-
<h4>selectBy</h4>
78-
<p>
79-
This allows rows to be selected programatically. The options are:<br />
80-
indexes - <code dangerouslySetInnerHTML={{ __html: 'selectBy: {indexes: [0, 1, 2]}' }} /> to select rows by index.<br />
81-
keys - <code dangerouslySetInnerHTML={{ __html: "selectBy: {keys: {rowKey: 'title', values: ['Title1', 'Title2']}}" }} /> to select rows by specified key and values.<br />
82-
isSelectedKey - <code dangerouslySetInnerHTML={{ __html: "selectBy: {isSelectedKey: 'isSelected'}" }} /> to select rows by specified key (based on value being truthy or falsy).
83-
</p>
84-
<h4>onRowsSelected/onRowsDeselected</h4>
85-
<p>
86-
When rows are selected or de-selected, <code>onRowsSelected</code> or <code>onRowsDeselected</code> functions will be called (set as props) with an array of <code dangerouslySetInnerHTML={{ __html: '{rowIdx, row}' }} />.<br />
87-
This allows for single or multiple selection to be implemented as desired, by either appending to or replacing the list of selected items.
88-
</p>
89-
<h4>showCheckbox</h4>
90-
<p>Allows the row selection checkbox to be hidden (shown by default). Useful for selecting rows programatically and controlling selection via the<code>onRowClick</code> event.</p>
91-
<h4>enableShiftSelect</h4>
92-
<p>
93-
Allows a continuous range of rows to be selected by holding the shift key when clicking the row selection checkbox.
94-
</p>
95-
<p><b>Note:</b> These props supercede the existing <code>enableRowSelect</code> and <code>onRowUpdated</code> props which will be removed in a later release.</p>
96-
</div>
67+
<div />
9768
);
9869

9970
export default exampleWrapper({

examples/scripts/example17-grid-events.js

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@ class Example extends React.Component {
2121
}
2222
];
2323

24-
this.state = { rows: this.createRows(1000) };
24+
this.state = {
25+
rows: this.createRows(),
26+
selectedRows: new Set()
27+
};
2528
}
2629

2730
createRows = () => {
@@ -30,8 +33,7 @@ class Example extends React.Component {
3033
rows.push({
3134
id: i,
3235
title: `Title ${i}`,
33-
count: i * 1000,
34-
isSelected: false
36+
count: i * 1000
3537
});
3638
}
3739

@@ -43,24 +45,28 @@ class Example extends React.Component {
4345
};
4446

4547
onRowClick = (rowIdx, row) => {
46-
const rows = this.state.rows.slice();
47-
rows[rowIdx] = { ...row, isSelected: !row.isSelected };
48-
this.setState({ rows });
48+
const newSelectedRows = new Set(this.state.selectedRows);
49+
if (newSelectedRows.has(row.id)) {
50+
newSelectedRows.delete(row.id);
51+
} else {
52+
newSelectedRows.add(row.id);
53+
}
54+
this.onSelectedRowsChange(newSelectedRows);
4955
};
5056

5157
onKeyDown = (e) => {
5258
if (e.ctrlKey && e.keyCode === 65) {
5359
e.preventDefault();
54-
55-
const rows = [];
56-
this.state.rows.forEach((r) => {
57-
rows.push({ ...r, isSelected: true });
58-
});
59-
60-
this.setState({ rows });
60+
const newSelectedRows = new Set(this.state.selectedRows);
61+
this.state.rows.forEach(row => newSelectedRows.add(row.id));
62+
this.onSelectedRowsChange(newSelectedRows);
6163
}
6264
};
6365

66+
onSelectedRowsChange = (selectedRows) => {
67+
this.setState({ selectedRows });
68+
};
69+
6470
render() {
6571
return (
6672
<ReactDataGrid
@@ -69,14 +75,10 @@ class Example extends React.Component {
6975
rowGetter={this.rowGetter}
7076
rowsCount={this.state.rows.length}
7177
minHeight={500}
72-
rowSelection={{
73-
showCheckbox: false,
74-
selectBy: {
75-
isSelectedKey: 'isSelected'
76-
}
77-
}}
7878
onRowClick={this.onRowClick}
7979
onGridKeyDown={this.onKeyDown}
80+
selectedRows={this.state.selectedRows}
81+
onSelectedRowsChange={this.onSelectedRowsChange}
8082
/>
8183
);
8284
}

examples/scripts/example21-cell-selection-events.js

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,6 @@ class Example extends React.Component {
3131
return this._rows[index];
3232
};
3333

34-
onRowSelect = (rows) => {
35-
this.setState({ selectedRows: rows });
36-
};
37-
3834
onCellSelected = ({ rowIdx, idx }) => {
3935
this.grid.openCellEditor(rowIdx, idx);
4036
};
@@ -55,9 +51,7 @@ class Example extends React.Component {
5551
columns={this._columns}
5652
rowGetter={this.rowGetter}
5753
rowsCount={this._rows.length}
58-
enableRowSelect="multi"
5954
minHeight={500}
60-
onRowSelect={this.onRowSelect}
6155
enableCellSelect
6256
onCellSelected={this.onCellSelected}
6357
onCellDeSelected={this.onCellDeSelected}

0 commit comments

Comments
 (0)