From 7794ababea46e8aa3d9c356f0edb2771695caa23 Mon Sep 17 00:00:00 2001 From: Rowan Hill Date: Sat, 26 May 2018 15:55:26 +0100 Subject: [PATCH 1/5] Allow selection of ranges (with mouse & keyboard) Parent components of ReactDataGrid can subscribe to (start, update, end) events about selection ranges. An example page demonstrates this. --- .../example30-selection-range-events.js | 106 ++++++ packages/react-data-grid/src/Canvas.js | 6 + packages/react-data-grid/src/Cell.js | 16 + packages/react-data-grid/src/Grid.js | 6 + .../src/PropTypeShapes/CellMetaDataShape.js | 2 + packages/react-data-grid/src/ReactDataGrid.js | 34 ++ packages/react-data-grid/src/Viewport.js | 6 + .../src/constants/EventTypes.js | 3 + .../src/masks/InteractionMasks.js | 191 ++++++++-- .../src/masks/SelectionRangeMask.js | 30 ++ .../masks/__tests__/InteractionMasks.spec.js | 351 +++++++++++++++++- .../__tests__/SelectionRangeMask.spec.js | 43 +++ .../src/utils/SelectedCellUtils.js | 31 ++ themes/react-data-grid-cell.css | 5 + themes/react-data-grid-core.css | 6 + 15 files changed, 804 insertions(+), 32 deletions(-) create mode 100644 packages/react-data-grid-examples/src/scripts/example30-selection-range-events.js create mode 100644 packages/react-data-grid/src/masks/SelectionRangeMask.js create mode 100644 packages/react-data-grid/src/masks/__tests__/SelectionRangeMask.spec.js diff --git a/packages/react-data-grid-examples/src/scripts/example30-selection-range-events.js b/packages/react-data-grid-examples/src/scripts/example30-selection-range-events.js new file mode 100644 index 0000000000..84988027da --- /dev/null +++ b/packages/react-data-grid-examples/src/scripts/example30-selection-range-events.js @@ -0,0 +1,106 @@ +const ReactDataGrid = require('react-data-grid'); +const exampleWrapper = require('../components/exampleWrapper'); +const React = require('react'); + +class Example extends React.Component { + constructor(props, context) { + super(props, context); + this._columns = [ + { + key: 'id', + name: 'ID' + }, + { + key: 'title', + name: 'Title' + }, + { + key: 'count', + name: 'Count' + } + ]; + + this.state = { rows: this.createRows(1000) }; + } + + createRows = () => { + let rows = []; + for (let i = 1; i < 1000; i++) { + rows.push({ + id: i, + title: 'Title ' + i, + count: i * 1000, + isSelected: false + }); + } + + return rows; + }; + + rowGetter = (i) => { + return this.state.rows[i]; + }; + + onStart = (selectedRange) => { + this.textarea.value += 'START: ' + + `(${selectedRange.topLeft.idx}, ${selectedRange.topLeft.rowIdx}) -> ` + + `(${selectedRange.bottomRight.idx}, ${selectedRange.bottomRight.rowIdx})\n`; + this.textarea.scrollTop = this.textarea.scrollHeight; + }; + + onUpdate = (selectedRange) => { + this.textarea.value += 'UPDATE: ' + + `(${selectedRange.topLeft.idx}, ${selectedRange.topLeft.rowIdx}) -> ` + + `(${selectedRange.bottomRight.idx}, ${selectedRange.bottomRight.rowIdx})\n`; + this.textarea.scrollTop = this.textarea.scrollHeight; + }; + + onComplete = () => { + this.textarea.value += 'END\n'; + this.textarea.scrollTop = this.textarea.scrollHeight; + }; + + render() { + return ( +
+