@deephaven/grid 0.5.2-beta.0 → 0.6.1-demo.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/dist/CellInputField.js +40 -88
  2. package/dist/CellInputField.js.map +1 -1
  3. package/dist/Grid.js +1449 -1484
  4. package/dist/Grid.js.map +1 -1
  5. package/dist/GridColorUtils.js +18 -51
  6. package/dist/GridColorUtils.js.map +1 -1
  7. package/dist/GridMetricCalculator.d.ts +8 -1
  8. package/dist/GridMetricCalculator.d.ts.map +1 -1
  9. package/dist/GridMetricCalculator.js +1031 -994
  10. package/dist/GridMetricCalculator.js.map +1 -1
  11. package/dist/GridModel.d.ts +4 -1
  12. package/dist/GridModel.d.ts.map +1 -1
  13. package/dist/GridModel.js +175 -286
  14. package/dist/GridModel.js.map +1 -1
  15. package/dist/GridMouseHandler.js +39 -59
  16. package/dist/GridMouseHandler.js.map +1 -1
  17. package/dist/GridRange.js +572 -630
  18. package/dist/GridRange.js.map +1 -1
  19. package/dist/GridRenderer.js +1650 -1564
  20. package/dist/GridRenderer.js.map +1 -1
  21. package/dist/GridTestUtils.js +15 -29
  22. package/dist/GridTestUtils.js.map +1 -1
  23. package/dist/GridUtils.js +679 -717
  24. package/dist/GridUtils.js.map +1 -1
  25. package/dist/KeyHandler.js +6 -18
  26. package/dist/KeyHandler.js.map +1 -1
  27. package/dist/MockGridModel.js +105 -210
  28. package/dist/MockGridModel.js.map +1 -1
  29. package/dist/MockTreeGridModel.js +113 -183
  30. package/dist/MockTreeGridModel.js.map +1 -1
  31. package/dist/errors/PasteError.js +5 -44
  32. package/dist/errors/PasteError.js.map +1 -1
  33. package/dist/errors/index.js +1 -1
  34. package/dist/errors/index.js.map +1 -1
  35. package/dist/index.js +15 -15
  36. package/dist/index.js.map +1 -1
  37. package/dist/key-handlers/EditKeyHandler.js +42 -75
  38. package/dist/key-handlers/EditKeyHandler.js.map +1 -1
  39. package/dist/key-handlers/PasteKeyHandler.js +42 -78
  40. package/dist/key-handlers/PasteKeyHandler.js.map +1 -1
  41. package/dist/key-handlers/SelectionKeyHandler.d.ts.map +1 -1
  42. package/dist/key-handlers/SelectionKeyHandler.js +239 -229
  43. package/dist/key-handlers/SelectionKeyHandler.js.map +1 -1
  44. package/dist/key-handlers/TreeKeyHandler.js +42 -72
  45. package/dist/key-handlers/TreeKeyHandler.js.map +1 -1
  46. package/dist/key-handlers/index.js +4 -4
  47. package/dist/key-handlers/index.js.map +1 -1
  48. package/dist/memoizeClear.js +1 -1
  49. package/dist/memoizeClear.js.map +1 -1
  50. package/dist/mouse-handlers/EditMouseHandler.js +18 -50
  51. package/dist/mouse-handlers/EditMouseHandler.js.map +1 -1
  52. package/dist/mouse-handlers/GridColumnMoveMouseHandler.d.ts.map +1 -1
  53. package/dist/mouse-handlers/GridColumnMoveMouseHandler.js +141 -163
  54. package/dist/mouse-handlers/GridColumnMoveMouseHandler.js.map +1 -1
  55. package/dist/mouse-handlers/GridColumnSeparatorMouseHandler.js +47 -86
  56. package/dist/mouse-handlers/GridColumnSeparatorMouseHandler.js.map +1 -1
  57. package/dist/mouse-handlers/GridHorizontalScrollBarMouseHandler.js +145 -171
  58. package/dist/mouse-handlers/GridHorizontalScrollBarMouseHandler.js.map +1 -1
  59. package/dist/mouse-handlers/GridRowMoveMouseHandler.js +125 -147
  60. package/dist/mouse-handlers/GridRowMoveMouseHandler.js.map +1 -1
  61. package/dist/mouse-handlers/GridRowSeparatorMouseHandler.js +47 -86
  62. package/dist/mouse-handlers/GridRowSeparatorMouseHandler.js.map +1 -1
  63. package/dist/mouse-handlers/GridRowTreeMouseHandler.js +46 -76
  64. package/dist/mouse-handlers/GridRowTreeMouseHandler.js.map +1 -1
  65. package/dist/mouse-handlers/GridScrollBarCornerMouseHandler.js +31 -62
  66. package/dist/mouse-handlers/GridScrollBarCornerMouseHandler.js.map +1 -1
  67. package/dist/mouse-handlers/GridSelectionMouseHandler.js +200 -222
  68. package/dist/mouse-handlers/GridSelectionMouseHandler.js.map +1 -1
  69. package/dist/mouse-handlers/GridSeparatorMouseHandler.js +206 -253
  70. package/dist/mouse-handlers/GridSeparatorMouseHandler.js.map +1 -1
  71. package/dist/mouse-handlers/GridVerticalScrollBarMouseHandler.js +146 -172
  72. package/dist/mouse-handlers/GridVerticalScrollBarMouseHandler.js.map +1 -1
  73. package/dist/mouse-handlers/index.js +10 -10
  74. package/dist/mouse-handlers/index.js.map +1 -1
  75. package/dist/tsconfig.tsbuildinfo +1 -1
  76. package/package.json +6 -10
package/dist/Grid.js CHANGED
@@ -1,5 +1,3 @@
1
- function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
2
-
3
1
  function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
4
2
 
5
3
  function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
@@ -8,38 +6,6 @@ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (O
8
6
 
9
7
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
10
8
 
11
- function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
12
-
13
- function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
14
-
15
- function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
16
-
17
- function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); }
18
-
19
- function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
20
-
21
- function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
22
-
23
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
24
-
25
- function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
26
-
27
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
28
-
29
- function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
30
-
31
- function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
32
-
33
- function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
34
-
35
- function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
36
-
37
- function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
38
-
39
- function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
40
-
41
- function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
42
-
43
9
  function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
44
10
 
45
11
  /* eslint react/no-did-update-set-state: "off" */
@@ -48,19 +14,19 @@ import classNames from 'classnames';
48
14
  import memoize from 'memoize-one';
49
15
  import PropTypes from 'prop-types';
50
16
  import clamp from 'lodash.clamp';
51
- import GridMetricCalculator from './GridMetricCalculator';
52
- import GridModel from './GridModel';
53
- import GridMouseHandler from './GridMouseHandler';
54
- import GridTheme from './GridTheme';
55
- import GridRange from './GridRange';
56
- import GridRenderer from './GridRenderer';
57
- import GridUtils from './GridUtils';
58
- import { GridSelectionMouseHandler, GridColumnMoveMouseHandler, GridColumnSeparatorMouseHandler, GridHorizontalScrollBarMouseHandler, GridRowMoveMouseHandler, GridRowSeparatorMouseHandler, GridRowTreeMouseHandler, GridScrollBarCornerMouseHandler, GridVerticalScrollBarMouseHandler, EditMouseHandler } from './mouse-handlers';
17
+ import GridMetricCalculator from "./GridMetricCalculator.js";
18
+ import GridModel from "./GridModel.js";
19
+ import GridMouseHandler from "./GridMouseHandler.js";
20
+ import GridTheme from "./GridTheme.js";
21
+ import GridRange from "./GridRange.js";
22
+ import GridRenderer from "./GridRenderer.js";
23
+ import GridUtils from "./GridUtils.js";
24
+ import { GridSelectionMouseHandler, GridColumnMoveMouseHandler, GridColumnSeparatorMouseHandler, GridHorizontalScrollBarMouseHandler, GridRowMoveMouseHandler, GridRowSeparatorMouseHandler, GridRowTreeMouseHandler, GridScrollBarCornerMouseHandler, GridVerticalScrollBarMouseHandler, EditMouseHandler } from "./mouse-handlers/index.js";
59
25
  import "./Grid.css";
60
- import KeyHandler from './KeyHandler';
61
- import { EditKeyHandler, PasteKeyHandler, SelectionKeyHandler, TreeKeyHandler } from './key-handlers';
62
- import CellInputField from './CellInputField';
63
- import PasteError from './errors/PasteError';
26
+ import KeyHandler from "./KeyHandler.js";
27
+ import { EditKeyHandler, PasteKeyHandler, SelectionKeyHandler, TreeKeyHandler } from "./key-handlers/index.js";
28
+ import CellInputField from "./CellInputField.js";
29
+ import PasteError from "./errors/PasteError.js";
64
30
  /**
65
31
  * High performance, extendible, themeable grid component.
66
32
  * Architectured to be fast and handle billions of rows/columns by default.
@@ -76,67 +42,65 @@ import PasteError from './errors/PasteError';
76
42
  * Can also add onClick and onContextMenu handlers to add custom functionality and menus.
77
43
  */
78
44
 
79
- var Grid = /*#__PURE__*/function (_PureComponent) {
80
- _inherits(Grid, _PureComponent);
81
-
82
- var _super = _createSuper(Grid);
83
-
84
- function Grid(props) {
85
- var _this;
86
-
87
- _classCallCheck(this, Grid);
88
-
89
- _this = _super.call(this, props);
90
-
91
- _defineProperty(_assertThisInitialized(_this), "getCachedKeyHandlers", memoize(function (keyHandlers) {
92
- return [].concat(_toConsumableArray(keyHandlers), _toConsumableArray(_this.keyHandlers)).sort(function (a, b) {
93
- return a.order - b.order;
94
- });
95
- }));
45
+ class Grid extends PureComponent {
46
+ // use same constant as chrome source for windows
47
+ // https://github.com/chromium/chromium/blob/973af9d461b6b5dc60208c8d3d66adc27e53da78/ui/events/blink/web_input_event_builders_win.cc#L285
48
+ static getScale(context) {
49
+ var devicePixelRatio = window.devicePixelRatio || 1;
50
+ var backingStorePixelRatio = context.webkitBackingStorePixelRatio || context.mozBackingStorePixelRatio || context.msBackingStorePixelRatio || context.oBackingStorePixelRatio || context.backingStorePixelRatio || 1;
51
+ return devicePixelRatio / backingStorePixelRatio;
52
+ }
96
53
 
97
- _defineProperty(_assertThisInitialized(_this), "getCachedMouseHandlers", memoize(function (mouseHandlers) {
98
- return [].concat(_toConsumableArray(mouseHandlers), _toConsumableArray(_this.mouseHandlers)).sort(function (a, b) {
99
- return a.order - b.order;
100
- });
101
- }));
54
+ static getCursorClassName(cursor) {
55
+ return cursor ? "grid-cursor-".concat(cursor) : null;
56
+ }
102
57
 
103
- _this.handleClick = _this.handleClick.bind(_assertThisInitialized(_this));
104
- _this.handleContextMenu = _this.handleContextMenu.bind(_assertThisInitialized(_this));
105
- _this.handleEditCellCancel = _this.handleEditCellCancel.bind(_assertThisInitialized(_this));
106
- _this.handleEditCellChange = _this.handleEditCellChange.bind(_assertThisInitialized(_this));
107
- _this.handleEditCellCommit = _this.handleEditCellCommit.bind(_assertThisInitialized(_this));
108
- _this.handleDoubleClick = _this.handleDoubleClick.bind(_assertThisInitialized(_this));
109
- _this.handleKeyDown = _this.handleKeyDown.bind(_assertThisInitialized(_this));
110
- _this.handleMouseDown = _this.handleMouseDown.bind(_assertThisInitialized(_this));
111
- _this.handleMouseDrag = _this.handleMouseDrag.bind(_assertThisInitialized(_this));
112
- _this.handleMouseMove = _this.handleMouseMove.bind(_assertThisInitialized(_this));
113
- _this.handleMouseLeave = _this.handleMouseLeave.bind(_assertThisInitialized(_this));
114
- _this.handleMouseUp = _this.handleMouseUp.bind(_assertThisInitialized(_this));
115
- _this.handleResize = _this.handleResize.bind(_assertThisInitialized(_this));
116
- _this.handleWheel = _this.handleWheel.bind(_assertThisInitialized(_this));
117
- var metricCalculator = props.metricCalculator,
118
- movedColumns = props.movedColumns,
119
- movedRows = props.movedRows,
120
- renderer = props.renderer;
121
- _this.renderer = renderer || new GridRenderer();
122
- _this.metricCalculator = metricCalculator || new GridMetricCalculator();
123
- _this.canvas = null;
124
- _this.canvasContext = null;
125
- _this.animationFrame = null;
126
- _this.prevMetrics = null;
127
- _this.metrics = null;
128
- _this.isStuckToBottom = false;
129
- _this.isStuckToRight = false; // Track the cursor that is currently added to the document
58
+ constructor(props) {
59
+ super(props);
60
+
61
+ _defineProperty(this, "getCachedKeyHandlers", memoize(keyHandlers => [...keyHandlers, ...this.keyHandlers].sort((a, b) => a.order - b.order)));
62
+
63
+ _defineProperty(this, "getCachedMouseHandlers", memoize(mouseHandlers => [...mouseHandlers, ...this.mouseHandlers].sort((a, b) => a.order - b.order)));
64
+
65
+ this.handleClick = this.handleClick.bind(this);
66
+ this.handleContextMenu = this.handleContextMenu.bind(this);
67
+ this.handleEditCellCancel = this.handleEditCellCancel.bind(this);
68
+ this.handleEditCellChange = this.handleEditCellChange.bind(this);
69
+ this.handleEditCellCommit = this.handleEditCellCommit.bind(this);
70
+ this.handleDoubleClick = this.handleDoubleClick.bind(this);
71
+ this.handleKeyDown = this.handleKeyDown.bind(this);
72
+ this.handleMouseDown = this.handleMouseDown.bind(this);
73
+ this.handleMouseDrag = this.handleMouseDrag.bind(this);
74
+ this.handleMouseMove = this.handleMouseMove.bind(this);
75
+ this.handleMouseLeave = this.handleMouseLeave.bind(this);
76
+ this.handleMouseUp = this.handleMouseUp.bind(this);
77
+ this.handleResize = this.handleResize.bind(this);
78
+ this.handleWheel = this.handleWheel.bind(this);
79
+ var {
80
+ metricCalculator,
81
+ movedColumns,
82
+ movedRows,
83
+ renderer
84
+ } = props;
85
+ this.renderer = renderer || new GridRenderer();
86
+ this.metricCalculator = metricCalculator || new GridMetricCalculator();
87
+ this.canvas = null;
88
+ this.canvasContext = null;
89
+ this.animationFrame = null;
90
+ this.prevMetrics = null;
91
+ this.metrics = null;
92
+ this.isStuckToBottom = false;
93
+ this.isStuckToRight = false; // Track the cursor that is currently added to the document
130
94
  // Add to document so that when dragging the cursor stays, even if mouse leaves the canvas
131
95
  // Note: on document, not body so that cursor styling can be combined with
132
96
  // blocked pointer events that would otherwise prevent cursor styling from showing
133
97
 
134
- _this.documentCursor = null;
135
- _this.dragTimer = null; // specify handler ordering, such that any extensions can insert handlers in between
98
+ this.documentCursor = null;
99
+ this.dragTimer = null; // specify handler ordering, such that any extensions can insert handlers in between
136
100
 
137
- _this.keyHandlers = [new EditKeyHandler(400), new PasteKeyHandler(450), new SelectionKeyHandler(500), new TreeKeyHandler(900)];
138
- _this.mouseHandlers = [new GridRowSeparatorMouseHandler(100), new GridColumnSeparatorMouseHandler(200), new GridRowMoveMouseHandler(300), new GridColumnMoveMouseHandler(400), new EditMouseHandler(450), new GridVerticalScrollBarMouseHandler(500), new GridHorizontalScrollBarMouseHandler(600), new GridScrollBarCornerMouseHandler(700), new GridRowTreeMouseHandler(800), new GridSelectionMouseHandler(900)];
139
- _this.state = {
101
+ this.keyHandlers = [new EditKeyHandler(400), new PasteKeyHandler(450), new SelectionKeyHandler(500), new TreeKeyHandler(900)];
102
+ this.mouseHandlers = [new GridRowSeparatorMouseHandler(100), new GridColumnSeparatorMouseHandler(200), new GridRowMoveMouseHandler(300), new GridColumnMoveMouseHandler(400), new EditMouseHandler(450), new GridVerticalScrollBarMouseHandler(500), new GridHorizontalScrollBarMouseHandler(600), new GridScrollBarCornerMouseHandler(700), new GridRowTreeMouseHandler(800), new GridSelectionMouseHandler(900)];
103
+ this.state = {
140
104
  // Top/left visible cell in the grid. Note that it's visible row/column index, not the model index (ie. if columns are re-ordered)
141
105
  top: 0,
142
106
  left: 0,
@@ -161,8 +125,8 @@ var Grid = /*#__PURE__*/function (_PureComponent) {
161
125
  mouseX: null,
162
126
  mouseY: null,
163
127
  // Move operations the user has performed on this grids columns/rows
164
- movedColumns: movedColumns,
165
- movedRows: movedRows,
128
+ movedColumns,
129
+ movedRows,
166
130
  // Cursor (highlighted cell) location and active selected range
167
131
  cursorRow: null,
168
132
  cursorColumn: null,
@@ -181,1552 +145,1553 @@ var Grid = /*#__PURE__*/function (_PureComponent) {
181
145
  // The cell that is currently being edited
182
146
  editingCell: null
183
147
  };
184
- return _this;
185
148
  }
186
149
 
187
- _createClass(Grid, [{
188
- key: "componentDidMount",
189
- value: function componentDidMount() {
190
- this.initContext(); // Need to explicitly add wheel event to canvas so we can preventDefault/avoid passive listener issue
191
- // Otherwise React attaches listener at doc level and you can't prevent default
192
- // https://github.com/facebook/react/issues/14856
150
+ componentDidMount() {
151
+ this.initContext(); // Need to explicitly add wheel event to canvas so we can preventDefault/avoid passive listener issue
152
+ // Otherwise React attaches listener at doc level and you can't prevent default
153
+ // https://github.com/facebook/react/issues/14856
154
+
155
+ this.canvas.addEventListener('wheel', this.handleWheel, {
156
+ passive: false
157
+ });
158
+ window.addEventListener('resize', this.handleResize);
159
+ this.updateCanvasScale();
160
+ this.updateCanvas();
161
+ }
162
+
163
+ componentDidUpdate(prevProps, prevState) {
164
+ var {
165
+ isStickyBottom,
166
+ isStickyRight,
167
+ movedColumns,
168
+ movedRows,
169
+ onMovedColumnsChanged,
170
+ onMoveColumnComplete
171
+ } = this.props;
172
+ var {
173
+ isStickyBottom: prevIsStickyBottom,
174
+ isStickyRight: prevIsStickyRight,
175
+ movedColumns: prevPropMovedColumns,
176
+ movedRows: prevMovedRows
177
+ } = prevProps;
178
+ var {
179
+ movedColumns: prevStateMovedColumns
180
+ } = prevState;
181
+ var {
182
+ draggingColumn,
183
+ movedColumns: currentStateMovedColumns
184
+ } = this.state;
185
+
186
+ if (prevPropMovedColumns !== movedColumns) {
187
+ this.setState({
188
+ movedColumns
189
+ });
190
+ }
193
191
 
194
- this.canvas.addEventListener('wheel', this.handleWheel, {
195
- passive: false
192
+ if (prevMovedRows !== movedRows) {
193
+ this.setState({
194
+ movedRows
196
195
  });
197
- window.addEventListener('resize', this.handleResize);
198
- this.updateCanvasScale();
199
- this.updateCanvas();
200
196
  }
201
- }, {
202
- key: "componentDidUpdate",
203
- value: function componentDidUpdate(prevProps, prevState) {
204
- var _this$props = this.props,
205
- isStickyBottom = _this$props.isStickyBottom,
206
- isStickyRight = _this$props.isStickyRight,
207
- movedColumns = _this$props.movedColumns,
208
- movedRows = _this$props.movedRows,
209
- onMovedColumnsChanged = _this$props.onMovedColumnsChanged,
210
- onMoveColumnComplete = _this$props.onMoveColumnComplete;
211
- var prevIsStickyBottom = prevProps.isStickyBottom,
212
- prevIsStickyRight = prevProps.isStickyRight,
213
- prevPropMovedColumns = prevProps.movedColumns,
214
- prevMovedRows = prevProps.movedRows;
215
- var prevStateMovedColumns = prevState.movedColumns;
216
- var _this$state = this.state,
217
- draggingColumn = _this$state.draggingColumn,
218
- currentStateMovedColumns = _this$state.movedColumns;
219
-
220
- if (prevPropMovedColumns !== movedColumns) {
197
+
198
+ if (prevStateMovedColumns !== currentStateMovedColumns) {
199
+ onMovedColumnsChanged(currentStateMovedColumns);
200
+ }
201
+
202
+ if (prevState.draggingColumn != null && draggingColumn == null) {
203
+ onMoveColumnComplete(currentStateMovedColumns);
204
+ }
205
+
206
+ if (isStickyBottom !== prevIsStickyBottom) {
207
+ this.isStuckToBottom = false;
208
+ }
209
+
210
+ if (isStickyRight !== prevIsStickyRight) {
211
+ this.isStuckToRight = false;
212
+ }
213
+
214
+ this.updateMetrics();
215
+ this.requestUpdateCanvas();
216
+
217
+ if (!this.metrics || !this.prevMetrics) {
218
+ return;
219
+ }
220
+
221
+ var {
222
+ bottomVisible,
223
+ rightVisible,
224
+ rowCount,
225
+ columnCount,
226
+ top,
227
+ left,
228
+ height,
229
+ width
230
+ } = this.metrics;
231
+ var {
232
+ rowCount: prevRowCount,
233
+ columnCount: prevColumnCount,
234
+ height: prevHeight,
235
+ width: prevWidth
236
+ } = this.prevMetrics;
237
+ var metricState = this.getMetricState();
238
+
239
+ if (prevRowCount !== rowCount || height !== prevHeight) {
240
+ var lastTop = this.metricCalculator.getLastTop(metricState);
241
+
242
+ if (this.isStuckToBottom && bottomVisible < rowCount - 1 && bottomVisible > 0 && top > 0 || top > lastTop) {
221
243
  this.setState({
222
- movedColumns: movedColumns
244
+ top: lastTop
223
245
  });
224
246
  }
247
+ }
225
248
 
226
- if (prevMovedRows !== movedRows) {
249
+ if (prevColumnCount !== columnCount || width !== prevWidth) {
250
+ var lastLeft = this.metricCalculator.getLastLeft(metricState);
251
+
252
+ if (this.isStuckToRight && rightVisible < columnCount - 1 && rightVisible > 0 && left > 0 || left > lastLeft) {
227
253
  this.setState({
228
- movedRows: movedRows
254
+ left: lastLeft
229
255
  });
230
256
  }
257
+ }
231
258
 
232
- if (prevStateMovedColumns !== currentStateMovedColumns) {
233
- onMovedColumnsChanged(currentStateMovedColumns);
234
- }
259
+ if (this.validateSelection()) {
260
+ this.checkSelectionChange(prevState);
261
+ }
262
+ }
235
263
 
236
- if (prevState.draggingColumn != null && draggingColumn == null) {
237
- onMoveColumnComplete(currentStateMovedColumns);
238
- }
264
+ componentWillUnmount() {
265
+ if (this.animationFrame != null) {
266
+ cancelAnimationFrame(this.animationFrame);
267
+ }
239
268
 
240
- if (isStickyBottom !== prevIsStickyBottom) {
241
- this.isStuckToBottom = false;
242
- }
269
+ this.canvas.removeEventListener('wheel', this.handleWheel, {
270
+ passive: false
271
+ });
272
+ window.removeEventListener('mousemove', this.handleMouseDrag, true);
273
+ window.removeEventListener('mouseup', this.handleMouseUp, true);
274
+ window.removeEventListener('resize', this.handleResize);
275
+ this.stopDragTimer();
276
+ }
243
277
 
244
- if (isStickyRight !== prevIsStickyRight) {
245
- this.isStuckToRight = false;
246
- }
278
+ getTheme() {
279
+ var {
280
+ theme
281
+ } = this.props;
282
+ return Grid.getTheme(theme);
283
+ }
247
284
 
248
- this.updateMetrics();
249
- this.requestUpdateCanvas();
285
+ getGridPointFromEvent(event) {
286
+ var rect = this.canvas.getBoundingClientRect();
287
+ var x = event.clientX - rect.left;
288
+ var y = event.clientY - rect.top;
289
+ return this.getGridPointFromXY(x, y);
290
+ }
250
291
 
251
- if (!this.metrics || !this.prevMetrics) {
252
- return;
253
- }
292
+ getGridPointFromXY(x, y) {
293
+ return GridUtils.getGridPointFromXY(x, y, this.metrics);
294
+ }
254
295
 
255
- var _this$metrics = this.metrics,
256
- bottomVisible = _this$metrics.bottomVisible,
257
- rightVisible = _this$metrics.rightVisible,
258
- rowCount = _this$metrics.rowCount,
259
- columnCount = _this$metrics.columnCount,
260
- top = _this$metrics.top,
261
- left = _this$metrics.left,
262
- height = _this$metrics.height,
263
- width = _this$metrics.width;
264
- var _this$prevMetrics = this.prevMetrics,
265
- prevRowCount = _this$prevMetrics.rowCount,
266
- prevColumnCount = _this$prevMetrics.columnCount,
267
- prevHeight = _this$prevMetrics.height,
268
- prevWidth = _this$prevMetrics.width;
269
- var metricState = this.getMetricState();
270
-
271
- if (prevRowCount !== rowCount || height !== prevHeight) {
272
- var lastTop = this.metricCalculator.getLastTop(metricState);
273
-
274
- if (this.isStuckToBottom && bottomVisible < rowCount - 1 && bottomVisible > 0 && top > 0 || top > lastTop) {
275
- this.setState({
276
- top: lastTop
277
- });
278
- }
279
- }
296
+ getMetricState() {
297
+ var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.state;
298
+ var theme = this.getTheme();
299
+ var {
300
+ model,
301
+ stateOverride
302
+ } = this.props;
303
+ var context = this.canvasContext;
304
+ var width = this.canvas.clientWidth;
305
+ var height = this.canvas.clientHeight;
306
+ var {
307
+ left,
308
+ top,
309
+ leftOffset,
310
+ topOffset,
311
+ movedColumns,
312
+ movedRows,
313
+ isDraggingHorizontalScrollBar,
314
+ isDraggingVerticalScrollBar
315
+ } = state;
316
+ return _objectSpread({
317
+ left,
318
+ top,
319
+ leftOffset,
320
+ topOffset,
321
+ width,
322
+ height,
323
+ context,
324
+ theme,
325
+ model,
326
+ movedColumns,
327
+ movedRows,
328
+ isDraggingHorizontalScrollBar,
329
+ isDraggingVerticalScrollBar
330
+ }, stateOverride);
331
+ }
280
332
 
281
- if (prevColumnCount !== columnCount || width !== prevWidth) {
282
- var lastLeft = this.metricCalculator.getLastLeft(metricState);
333
+ getKeyHandlers() {
334
+ var {
335
+ keyHandlers
336
+ } = this.props;
337
+ return this.getCachedKeyHandlers(keyHandlers);
338
+ }
283
339
 
284
- if (this.isStuckToRight && rightVisible < columnCount - 1 && rightVisible > 0 && left > 0 || left > lastLeft) {
285
- this.setState({
286
- left: lastLeft
287
- });
288
- }
289
- }
340
+ getMouseHandlers() {
341
+ var {
342
+ mouseHandlers
343
+ } = this.props;
344
+ return this.getCachedMouseHandlers(mouseHandlers);
345
+ }
290
346
 
291
- if (this.validateSelection()) {
292
- this.checkSelectionChange(prevState);
293
- }
347
+ getModelColumn(columnIndex) {
348
+ var _this$metrics, _this$metrics$modelCo;
349
+
350
+ return (_this$metrics = this.metrics) === null || _this$metrics === void 0 ? void 0 : (_this$metrics$modelCo = _this$metrics.modelColumns) === null || _this$metrics$modelCo === void 0 ? void 0 : _this$metrics$modelCo.get(columnIndex);
351
+ }
352
+
353
+ getModelRow(rowIndex) {
354
+ var _this$metrics2, _this$metrics2$modelR;
355
+
356
+ return (_this$metrics2 = this.metrics) === null || _this$metrics2 === void 0 ? void 0 : (_this$metrics2$modelR = _this$metrics2.modelRows) === null || _this$metrics2$modelR === void 0 ? void 0 : _this$metrics2$modelR.get(rowIndex);
357
+ }
358
+
359
+ toggleRowExpanded(row) {
360
+ var {
361
+ metrics
362
+ } = this;
363
+ var {
364
+ modelRows
365
+ } = metrics;
366
+ var modelRow = modelRows.get(row);
367
+ var {
368
+ model
369
+ } = this.props; // We only want to set expansion if the row is expandable
370
+ // If it's not, still move the cursor to that position, as it may be outside of the current viewport and we don't know if it's expandable yet
371
+
372
+ if (model.isRowExpandable(modelRow)) {
373
+ model.setRowExpanded(modelRow, !model.isRowExpanded(modelRow));
294
374
  }
295
- }, {
296
- key: "componentWillUnmount",
297
- value: function componentWillUnmount() {
298
- if (this.animationFrame != null) {
299
- cancelAnimationFrame(this.animationFrame);
375
+
376
+ this.clearSelectedRanges();
377
+ this.commitSelection(); // Need to commit before moving in case we're selecting same row again
378
+
379
+ this.moveCursorToPosition(0, row);
380
+ this.commitSelection();
381
+ this.isStuckToBottom = false;
382
+ }
383
+ /** Allows the selected range to be set programatically */
384
+
385
+
386
+ setSelectedRanges(gridRanges) {
387
+ var {
388
+ model
389
+ } = this.props;
390
+ var {
391
+ columnCount,
392
+ rowCount
393
+ } = model;
394
+ var {
395
+ cursorRow,
396
+ cursorColumn,
397
+ selectedRanges
398
+ } = this.state;
399
+ this.setState({
400
+ selectedRanges: gridRanges,
401
+ lastSelectedRanges: selectedRanges
402
+ });
403
+
404
+ if (gridRanges.length > 0) {
405
+ var range = GridRange.boundedRange(gridRanges[0], columnCount, rowCount);
406
+ var newCursorRow = cursorRow;
407
+ var newCursorColumn = cursorColumn;
408
+
409
+ if (!range.containsCell(cursorColumn, cursorRow)) {
410
+ ({
411
+ row: newCursorRow,
412
+ column: newCursorColumn
413
+ } = range.startCell());
300
414
  }
301
415
 
302
- this.canvas.removeEventListener('wheel', this.handleWheel, {
303
- passive: false
416
+ this.setState({
417
+ selectionStartColumn: range.startColumn,
418
+ selectionStartRow: range.startRow,
419
+ selectionEndColumn: range.endColumn,
420
+ selectionEndRow: range.endRow,
421
+ cursorColumn: newCursorColumn,
422
+ cursorRow: newCursorRow
304
423
  });
305
- window.removeEventListener('mousemove', this.handleMouseDrag, true);
306
- window.removeEventListener('mouseup', this.handleMouseUp, true);
307
- window.removeEventListener('resize', this.handleResize);
308
- this.stopDragTimer();
309
- }
310
- }, {
311
- key: "getTheme",
312
- value: function getTheme() {
313
- var theme = this.props.theme;
314
- return Grid.getTheme(theme);
315
- }
316
- }, {
317
- key: "getGridPointFromEvent",
318
- value: function getGridPointFromEvent(event) {
319
- var rect = this.canvas.getBoundingClientRect();
320
- var x = event.clientX - rect.left;
321
- var y = event.clientY - rect.top;
322
- return this.getGridPointFromXY(x, y);
323
424
  }
324
- }, {
325
- key: "getGridPointFromXY",
326
- value: function getGridPointFromXY(x, y) {
327
- return GridUtils.getGridPointFromXY(x, y, this.metrics);
328
- }
329
- }, {
330
- key: "getMetricState",
331
- value: function getMetricState() {
332
- var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.state;
333
- var theme = this.getTheme();
334
- var _this$props2 = this.props,
335
- model = _this$props2.model,
336
- stateOverride = _this$props2.stateOverride;
337
- var context = this.canvasContext;
338
- var width = this.canvas.clientWidth;
339
- var height = this.canvas.clientHeight;
340
- var left = state.left,
341
- top = state.top,
342
- leftOffset = state.leftOffset,
343
- topOffset = state.topOffset,
344
- movedColumns = state.movedColumns,
345
- movedRows = state.movedRows,
346
- isDraggingHorizontalScrollBar = state.isDraggingHorizontalScrollBar,
347
- isDraggingVerticalScrollBar = state.isDraggingVerticalScrollBar;
348
- return _objectSpread({
349
- left: left,
350
- top: top,
351
- leftOffset: leftOffset,
352
- topOffset: topOffset,
353
- width: width,
354
- height: height,
355
- context: context,
356
- theme: theme,
357
- model: model,
358
- movedColumns: movedColumns,
359
- movedRows: movedRows,
360
- isDraggingHorizontalScrollBar: isDraggingHorizontalScrollBar,
361
- isDraggingVerticalScrollBar: isDraggingVerticalScrollBar
362
- }, stateOverride);
363
- }
364
- }, {
365
- key: "getKeyHandlers",
366
- value: function getKeyHandlers() {
367
- var keyHandlers = this.props.keyHandlers;
368
- return this.getCachedKeyHandlers(keyHandlers);
369
- }
370
- }, {
371
- key: "getMouseHandlers",
372
- value: function getMouseHandlers() {
373
- var mouseHandlers = this.props.mouseHandlers;
374
- return this.getCachedMouseHandlers(mouseHandlers);
375
- }
376
- }, {
377
- key: "getModelColumn",
378
- value: function getModelColumn(columnIndex) {
379
- var _this$metrics2, _this$metrics2$modelC;
425
+ }
380
426
 
381
- return (_this$metrics2 = this.metrics) === null || _this$metrics2 === void 0 ? void 0 : (_this$metrics2$modelC = _this$metrics2.modelColumns) === null || _this$metrics2$modelC === void 0 ? void 0 : _this$metrics2$modelC.get(columnIndex);
382
- }
383
- }, {
384
- key: "getModelRow",
385
- value: function getModelRow(rowIndex) {
386
- var _this$metrics3, _this$metrics3$modelR;
427
+ initContext() {
428
+ var {
429
+ canvas
430
+ } = this;
431
+ var {
432
+ canvasOptions
433
+ } = this.props;
434
+ this.canvasContext = canvas.getContext('2d', canvasOptions);
435
+ }
387
436
 
388
- return (_this$metrics3 = this.metrics) === null || _this$metrics3 === void 0 ? void 0 : (_this$metrics3$modelR = _this$metrics3.modelRows) === null || _this$metrics3$modelR === void 0 ? void 0 : _this$metrics3$modelR.get(rowIndex);
437
+ requestUpdateCanvas() {
438
+ if (this.animationFrame != null) {
439
+ return;
389
440
  }
390
- }, {
391
- key: "toggleRowExpanded",
392
- value: function toggleRowExpanded(row) {
393
- var metrics = this.metrics;
394
- var modelRows = metrics.modelRows;
395
- var modelRow = modelRows.get(row);
396
- var model = this.props.model; // We only want to set expansion if the row is expandable
397
- // If it's not, still move the cursor to that position, as it may be outside of the current viewport and we don't know if it's expandable yet
398
-
399
- if (model.isRowExpandable(modelRow)) {
400
- model.setRowExpanded(modelRow, !model.isRowExpanded(modelRow));
401
- }
402
441
 
403
- this.clearSelectedRanges();
404
- this.commitSelection(); // Need to commit before moving in case we're selecting same row again
442
+ this.animationFrame = requestAnimationFrame(() => {
443
+ this.animationFrame = null;
444
+ this.updateCanvas(this.metrics);
445
+ });
446
+ }
405
447
 
406
- this.moveCursorToPosition(0, row);
407
- this.commitSelection();
408
- this.isStuckToBottom = false;
409
- }
410
- /** Allows the selected range to be set programatically */
411
-
412
- }, {
413
- key: "setSelectedRanges",
414
- value: function setSelectedRanges(gridRanges) {
415
- var model = this.props.model;
416
- var columnCount = model.columnCount,
417
- rowCount = model.rowCount;
418
- var _this$state2 = this.state,
419
- cursorRow = _this$state2.cursorRow,
420
- cursorColumn = _this$state2.cursorColumn,
421
- selectedRanges = _this$state2.selectedRanges;
422
- this.setState({
423
- selectedRanges: gridRanges,
424
- lastSelectedRanges: selectedRanges
425
- });
448
+ updateCanvas() {
449
+ var metrics = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.updateMetrics();
450
+ this.updateCanvasScale();
451
+ var {
452
+ onViewChanged
453
+ } = this.props;
454
+ onViewChanged(metrics);
455
+ this.drawCanvas(metrics);
456
+ }
426
457
 
427
- if (gridRanges.length > 0) {
428
- var range = GridRange.boundedRange(gridRanges[0], columnCount, rowCount);
429
- var newCursorRow = cursorRow;
430
- var newCursorColumn = cursorColumn;
458
+ updateCanvasScale() {
459
+ var {
460
+ canvas,
461
+ canvasContext
462
+ } = this;
463
+ var scale = Grid.getScale(canvasContext); // the parent wrapper has 100% width/height, and is used for determining size
464
+ // we don't want to stretch the canvas to 100%, to avoid fractional pixels.
465
+ // A wrapper element must be used for sizing, and canvas size must be
466
+ // set manually to a floored value in css and a scaled value in width/height
467
+
468
+ var {
469
+ width,
470
+ height
471
+ } = canvas.parentElement.getBoundingClientRect();
472
+ canvas.style.width = "".concat(Math.floor(width), "px");
473
+ canvas.style.height = "".concat(Math.floor(height), "px");
474
+ canvas.width = Math.floor(width) * scale;
475
+ canvas.height = Math.floor(height) * scale;
476
+ canvasContext.scale(scale, scale);
477
+ }
431
478
 
432
- if (!range.containsCell(cursorColumn, cursorRow)) {
433
- var _range$startCell = range.startCell();
479
+ updateMetrics() {
480
+ var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.state;
481
+ this.prevMetrics = this.metrics;
482
+ var {
483
+ metricCalculator
484
+ } = this;
485
+ var metricState = this.getMetricState(state);
486
+ this.metrics = metricCalculator.getMetrics(metricState);
487
+ return this.metrics;
488
+ }
434
489
 
435
- newCursorRow = _range$startCell.row;
436
- newCursorColumn = _range$startCell.column;
437
- }
490
+ checkSelectionChange(prevState) {
491
+ var {
492
+ selectedRanges: oldSelectedRanges
493
+ } = prevState;
494
+ var {
495
+ selectedRanges
496
+ } = this.state;
497
+
498
+ if (selectedRanges !== oldSelectedRanges) {
499
+ var {
500
+ onSelectionChanged
501
+ } = this.props;
502
+ onSelectionChanged(selectedRanges);
503
+ }
504
+ }
438
505
 
506
+ validateSelection() {
507
+ var {
508
+ model
509
+ } = this.props;
510
+ var {
511
+ selectedRanges
512
+ } = this.state;
513
+ var {
514
+ columnCount,
515
+ rowCount
516
+ } = model;
517
+
518
+ for (var i = 0; i < selectedRanges.length; i += 1) {
519
+ var range = selectedRanges[i];
520
+
521
+ if (range.endColumn != null && range.endColumn >= columnCount || range.endRow != null && range.endRow >= rowCount) {
522
+ // Just clear the selection rather than trying to trim it.
439
523
  this.setState({
440
- selectionStartColumn: range.startColumn,
441
- selectionStartRow: range.startRow,
442
- selectionEndColumn: range.endColumn,
443
- selectionEndRow: range.endRow,
444
- cursorColumn: newCursorColumn,
445
- cursorRow: newCursorRow
524
+ selectedRanges: [],
525
+ lastSelectedRanges: []
446
526
  });
527
+ return false;
447
528
  }
448
529
  }
449
- }, {
450
- key: "initContext",
451
- value: function initContext() {
452
- var canvas = this.canvas;
453
- var canvasOptions = this.props.canvasOptions;
454
- this.canvasContext = canvas.getContext('2d', canvasOptions);
455
- }
456
- }, {
457
- key: "requestUpdateCanvas",
458
- value: function requestUpdateCanvas() {
459
- var _this2 = this;
460
530
 
461
- if (this.animationFrame != null) {
462
- return;
463
- }
464
-
465
- this.animationFrame = requestAnimationFrame(function () {
466
- _this2.animationFrame = null;
531
+ return true;
532
+ }
467
533
 
468
- _this2.updateCanvas(_this2.metrics);
469
- });
470
- }
471
- }, {
472
- key: "updateCanvas",
473
- value: function updateCanvas() {
474
- var metrics = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.updateMetrics();
475
- this.updateCanvasScale();
476
- var onViewChanged = this.props.onViewChanged;
477
- onViewChanged(metrics);
478
- this.drawCanvas(metrics);
479
- }
480
- }, {
481
- key: "updateCanvasScale",
482
- value: function updateCanvasScale() {
483
- var canvas = this.canvas,
484
- canvasContext = this.canvasContext;
485
- var scale = Grid.getScale(canvasContext); // the parent wrapper has 100% width/height, and is used for determining size
486
- // we don't want to stretch the canvas to 100%, to avoid fractional pixels.
487
- // A wrapper element must be used for sizing, and canvas size must be
488
- // set manually to a floored value in css and a scaled value in width/height
489
-
490
- var _canvas$parentElement = canvas.parentElement.getBoundingClientRect(),
491
- width = _canvas$parentElement.width,
492
- height = _canvas$parentElement.height;
493
-
494
- canvas.style.width = "".concat(Math.floor(width), "px");
495
- canvas.style.height = "".concat(Math.floor(height), "px");
496
- canvas.width = Math.floor(width) * scale;
497
- canvas.height = Math.floor(height) * scale;
498
- canvasContext.scale(scale, scale);
499
- }
500
- }, {
501
- key: "updateMetrics",
502
- value: function updateMetrics() {
503
- var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.state;
504
- this.prevMetrics = this.metrics;
505
- var metricCalculator = this.metricCalculator;
506
- var metricState = this.getMetricState(state);
507
- this.metrics = metricCalculator.getMetrics(metricState);
508
- return this.metrics;
509
- }
510
- }, {
511
- key: "checkSelectionChange",
512
- value: function checkSelectionChange(prevState) {
513
- var oldSelectedRanges = prevState.selectedRanges;
514
- var selectedRanges = this.state.selectedRanges;
515
-
516
- if (selectedRanges !== oldSelectedRanges) {
517
- var onSelectionChanged = this.props.onSelectionChanged;
518
- onSelectionChanged(selectedRanges);
519
- }
520
- }
521
- }, {
522
- key: "validateSelection",
523
- value: function validateSelection() {
524
- var model = this.props.model;
525
- var selectedRanges = this.state.selectedRanges;
526
- var columnCount = model.columnCount,
527
- rowCount = model.rowCount;
528
-
529
- for (var i = 0; i < selectedRanges.length; i += 1) {
530
- var range = selectedRanges[i];
531
-
532
- if (range.endColumn != null && range.endColumn >= columnCount || range.endRow != null && range.endRow >= rowCount) {
533
- // Just clear the selection rather than trying to trim it.
534
- this.setState({
535
- selectedRanges: [],
536
- lastSelectedRanges: []
537
- });
538
- return false;
539
- }
540
- }
534
+ clearSelectedRanges() {
535
+ var {
536
+ selectedRanges
537
+ } = this.state;
538
+ this.setState({
539
+ selectedRanges: [],
540
+ lastSelectedRanges: selectedRanges
541
+ });
542
+ }
543
+ /** Clears all but the last selected range */
541
544
 
542
- return true;
543
- }
544
- }, {
545
- key: "clearSelectedRanges",
546
- value: function clearSelectedRanges() {
547
- var selectedRanges = this.state.selectedRanges;
548
- this.setState({
549
- selectedRanges: [],
550
- lastSelectedRanges: selectedRanges
551
- });
552
- }
553
- /** Clears all but the last selected range */
554
545
 
555
- }, {
556
- key: "trimSelectedRanges",
557
- value: function trimSelectedRanges() {
558
- var selectedRanges = this.state.selectedRanges;
546
+ trimSelectedRanges() {
547
+ var {
548
+ selectedRanges
549
+ } = this.state;
559
550
 
560
- if (selectedRanges.length > 0) {
561
- this.setState({
562
- selectedRanges: selectedRanges.slice(selectedRanges.length - 1)
563
- });
564
- }
565
- }
566
- }, {
567
- key: "beginSelection",
568
- value: function beginSelection(column, row) {
551
+ if (selectedRanges.length > 0) {
569
552
  this.setState({
570
- selectionStartColumn: column,
571
- selectionStartRow: row,
572
- selectionEndColumn: column,
573
- selectionEndRow: row,
574
- cursorColumn: column,
575
- cursorRow: row
553
+ selectedRanges: selectedRanges.slice(selectedRanges.length - 1)
576
554
  });
577
555
  }
578
- /**
579
- * Moves the selection to the cell specified
580
- * @param {number} column The column index to move the cursor to
581
- * @param {number} row The row index to move the cursor to
582
- * @param {boolean} extendSelection Whether to extend the current selection (eg. holding Shift)
583
- * @param {boolean} maximizePreviousRange When true, maximize/add to the previous range only, ignoring where the selection was started.
584
- */
556
+ }
585
557
 
586
- }, {
587
- key: "moveSelection",
588
- value: function moveSelection(column, row) {
589
- var _this3 = this;
590
-
591
- var extendSelection = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
592
- var maximizePreviousRange = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
593
- this.setState(function (state) {
594
- var selectedRanges = state.selectedRanges,
595
- selectionStartRow = state.selectionStartRow,
596
- selectionStartColumn = state.selectionStartColumn;
597
- var theme = _this3.props.theme;
598
- var autoSelectRow = theme.autoSelectRow,
599
- autoSelectColumn = theme.autoSelectColumn;
600
-
601
- if (extendSelection && selectedRanges.length > 0) {
602
- var lastSelectedRange = selectedRanges[selectedRanges.length - 1];
603
- var left = null;
604
- var top = null;
605
- var right = null;
606
- var bottom = null;
607
-
608
- if (maximizePreviousRange) {
609
- left = autoSelectRow ? null : Math.min(column, lastSelectedRange.startColumn);
610
- top = autoSelectColumn ? null : Math.min(row, lastSelectedRange.startRow);
611
- right = autoSelectRow ? null : Math.max(column, lastSelectedRange.endColumn);
612
- bottom = autoSelectColumn ? null : Math.max(row, lastSelectedRange.endRow);
613
- } else {
614
- left = lastSelectedRange.startColumn;
615
- top = lastSelectedRange.startRow;
616
-
617
- if (selectionStartColumn != null || selectionStartRow != null) {
618
- if (!autoSelectRow) {
619
- left = selectionStartColumn;
620
- }
621
-
622
- if (!autoSelectColumn) {
623
- top = selectionStartRow;
624
- }
558
+ beginSelection(column, row) {
559
+ this.setState({
560
+ selectionStartColumn: column,
561
+ selectionStartRow: row,
562
+ selectionEndColumn: column,
563
+ selectionEndRow: row,
564
+ cursorColumn: column,
565
+ cursorRow: row
566
+ });
567
+ }
568
+ /**
569
+ * Moves the selection to the cell specified
570
+ * @param {number} column The column index to move the cursor to
571
+ * @param {number} row The row index to move the cursor to
572
+ * @param {boolean} extendSelection Whether to extend the current selection (eg. holding Shift)
573
+ * @param {boolean} maximizePreviousRange When true, maximize/add to the previous range only, ignoring where the selection was started.
574
+ */
575
+
576
+
577
+ moveSelection(column, row) {
578
+ var extendSelection = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
579
+ var maximizePreviousRange = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
580
+ this.setState(state => {
581
+ var {
582
+ selectedRanges,
583
+ selectionStartRow,
584
+ selectionStartColumn
585
+ } = state;
586
+ var {
587
+ theme
588
+ } = this.props;
589
+ var {
590
+ autoSelectRow,
591
+ autoSelectColumn
592
+ } = theme;
593
+
594
+ if (extendSelection && selectedRanges.length > 0) {
595
+ var lastSelectedRange = selectedRanges[selectedRanges.length - 1];
596
+ var left = null;
597
+ var top = null;
598
+ var right = null;
599
+ var bottom = null;
600
+
601
+ if (maximizePreviousRange) {
602
+ left = autoSelectRow ? null : Math.min(column, lastSelectedRange.startColumn);
603
+ top = autoSelectColumn ? null : Math.min(row, lastSelectedRange.startRow);
604
+ right = autoSelectRow ? null : Math.max(column, lastSelectedRange.endColumn);
605
+ bottom = autoSelectColumn ? null : Math.max(row, lastSelectedRange.endRow);
606
+ } else {
607
+ left = lastSelectedRange.startColumn;
608
+ top = lastSelectedRange.startRow;
609
+
610
+ if (selectionStartColumn != null || selectionStartRow != null) {
611
+ if (!autoSelectRow) {
612
+ left = selectionStartColumn;
625
613
  }
626
614
 
627
- right = autoSelectRow ? null : column;
628
- bottom = autoSelectColumn ? null : row;
615
+ if (!autoSelectColumn) {
616
+ top = selectionStartRow;
617
+ }
629
618
  }
630
619
 
631
- var selectedRange = GridRange.makeNormalized(left, top, right, bottom);
632
-
633
- if (lastSelectedRange.equals(selectedRange)) {
634
- return null;
635
- }
620
+ right = autoSelectRow ? null : column;
621
+ bottom = autoSelectColumn ? null : row;
622
+ }
636
623
 
637
- var _newRanges = [].concat(selectedRanges);
624
+ var selectedRange = GridRange.makeNormalized(left, top, right, bottom);
638
625
 
639
- _newRanges[_newRanges.length - 1] = selectedRange;
640
- return {
641
- selectedRanges: _newRanges,
642
- selectionEndColumn: column,
643
- selectionEndRow: row
644
- };
626
+ if (lastSelectedRange.equals(selectedRange)) {
627
+ return null;
645
628
  }
646
629
 
647
- var newRanges = [].concat(selectedRanges);
648
- var selectedColumn = autoSelectRow ? null : column;
649
- var selectedRow = autoSelectColumn ? null : row;
650
- newRanges.push(GridRange.makeNormalized(selectedColumn, selectedRow, selectedColumn, selectedRow));
630
+ var _newRanges = [].concat(selectedRanges);
631
+
632
+ _newRanges[_newRanges.length - 1] = selectedRange;
651
633
  return {
652
- selectedRanges: newRanges,
634
+ selectedRanges: _newRanges,
653
635
  selectionEndColumn: column,
654
636
  selectionEndRow: row
655
637
  };
656
- });
657
- }
658
- /**
659
- * Commits the last selected range to the selected ranges.
660
- * First checks if the last range is completely contained within another range, and if it
661
- * is then it blows those ranges apart.
662
- * Then it consolidates all the selected ranges, reducing them.
663
- */
638
+ }
664
639
 
665
- }, {
666
- key: "commitSelection",
667
- value: function commitSelection() {
668
- var _this4 = this;
669
-
670
- this.setState(function (state) {
671
- var theme = _this4.props.theme;
672
- var autoSelectRow = theme.autoSelectRow;
673
- var selectedRanges = state.selectedRanges,
674
- lastSelectedRanges = state.lastSelectedRanges,
675
- cursorRow = state.cursorRow,
676
- cursorColumn = state.cursorColumn;
677
-
678
- if (selectedRanges.length === 1 && (autoSelectRow ? GridRange.rowCount(selectedRanges) === 1 : GridRange.cellCount(selectedRanges) === 1) && GridRange.rangeArraysEqual(selectedRanges, lastSelectedRanges)) {
679
- // If it's the exact same single selection, then deselect.
680
- // For if we click on one cell multiple times.
681
- return {
682
- selectedRanges: [],
683
- lastSelectedRanges: []
684
- };
685
- }
640
+ var newRanges = [].concat(selectedRanges);
641
+ var selectedColumn = autoSelectRow ? null : column;
642
+ var selectedRow = autoSelectColumn ? null : row;
643
+ newRanges.push(GridRange.makeNormalized(selectedColumn, selectedRow, selectedColumn, selectedRow));
644
+ return {
645
+ selectedRanges: newRanges,
646
+ selectionEndColumn: column,
647
+ selectionEndRow: row
648
+ };
649
+ });
650
+ }
651
+ /**
652
+ * Commits the last selected range to the selected ranges.
653
+ * First checks if the last range is completely contained within another range, and if it
654
+ * is then it blows those ranges apart.
655
+ * Then it consolidates all the selected ranges, reducing them.
656
+ */
657
+
658
+
659
+ commitSelection() {
660
+ this.setState(state => {
661
+ var {
662
+ theme
663
+ } = this.props;
664
+ var {
665
+ autoSelectRow
666
+ } = theme;
667
+ var {
668
+ selectedRanges,
669
+ lastSelectedRanges,
670
+ cursorRow,
671
+ cursorColumn
672
+ } = state;
673
+
674
+ if (selectedRanges.length === 1 && (autoSelectRow ? GridRange.rowCount(selectedRanges) === 1 : GridRange.cellCount(selectedRanges) === 1) && GridRange.rangeArraysEqual(selectedRanges, lastSelectedRanges)) {
675
+ // If it's the exact same single selection, then deselect.
676
+ // For if we click on one cell multiple times.
677
+ return {
678
+ selectedRanges: [],
679
+ lastSelectedRanges: []
680
+ };
681
+ }
686
682
 
687
- var newSelectedRanges = selectedRanges.slice();
683
+ var newSelectedRanges = selectedRanges.slice();
688
684
 
689
- if (newSelectedRanges.length > 1) {
690
- // Check if the latest selection is entirely within a previously selected range
691
- // If that's the case, then deselect that section instead
692
- var lastRange = newSelectedRanges[newSelectedRanges.length - 1];
685
+ if (newSelectedRanges.length > 1) {
686
+ // Check if the latest selection is entirely within a previously selected range
687
+ // If that's the case, then deselect that section instead
688
+ var lastRange = newSelectedRanges[newSelectedRanges.length - 1];
693
689
 
694
- for (var i = 0; i < newSelectedRanges.length - 1; i += 1) {
695
- var selectedRange = newSelectedRanges[i];
690
+ for (var i = 0; i < newSelectedRanges.length - 1; i += 1) {
691
+ var selectedRange = newSelectedRanges[i];
696
692
 
697
- if (selectedRange.contains(lastRange)) {
698
- // We found a match, now remove the two matching ranges, and add back
699
- // the remainder of the two
700
- var remainder = selectedRange.subtract(lastRange);
701
- newSelectedRanges.pop();
702
- newSelectedRanges.splice(i, 1);
703
- newSelectedRanges = newSelectedRanges.concat(remainder);
704
- break;
705
- }
693
+ if (selectedRange.contains(lastRange)) {
694
+ // We found a match, now remove the two matching ranges, and add back
695
+ // the remainder of the two
696
+ var remainder = selectedRange.subtract(lastRange);
697
+ newSelectedRanges.pop();
698
+ newSelectedRanges.splice(i, 1);
699
+ newSelectedRanges = newSelectedRanges.concat(remainder);
700
+ break;
706
701
  }
707
-
708
- newSelectedRanges = GridRange.consolidate(newSelectedRanges);
709
702
  }
710
703
 
711
- var newCursorColumn = cursorColumn;
712
- var newCursorRow = cursorRow;
713
-
714
- if (!GridRange.containsCell(newSelectedRanges, cursorColumn, cursorRow)) {
715
- var model = _this4.props.model;
716
- var columnCount = model.columnCount,
717
- rowCount = model.rowCount;
718
- var nextCursor = GridRange.nextCell(GridRange.boundedRanges(selectedRanges, columnCount, rowCount));
719
-
720
- if (nextCursor != null) {
721
- newCursorColumn = nextCursor.column;
722
- newCursorRow = nextCursor.row;
723
- } else {
724
- newCursorColumn = null;
725
- newCursorRow = null;
726
- }
704
+ newSelectedRanges = GridRange.consolidate(newSelectedRanges);
705
+ }
706
+
707
+ var newCursorColumn = cursorColumn;
708
+ var newCursorRow = cursorRow;
709
+
710
+ if (!GridRange.containsCell(newSelectedRanges, cursorColumn, cursorRow)) {
711
+ var {
712
+ model
713
+ } = this.props;
714
+ var {
715
+ columnCount,
716
+ rowCount
717
+ } = model;
718
+ var nextCursor = GridRange.nextCell(GridRange.boundedRanges(selectedRanges, columnCount, rowCount));
719
+
720
+ if (nextCursor != null) {
721
+ ({
722
+ column: newCursorColumn,
723
+ row: newCursorRow
724
+ } = nextCursor);
725
+ } else {
726
+ newCursorColumn = null;
727
+ newCursorRow = null;
727
728
  }
729
+ }
728
730
 
729
- return {
730
- cursorRow: newCursorRow,
731
- cursorColumn: newCursorColumn,
732
- selectedRanges: newSelectedRanges,
733
- lastSelectedRanges: selectedRanges
734
- };
735
- });
736
- }
737
- }, {
738
- key: "selectAll",
739
- value: function selectAll() {
740
- var _this$props3 = this.props,
741
- model = _this$props3.model,
742
- theme = _this$props3.theme;
743
- var autoSelectRow = theme.autoSelectRow,
744
- autoSelectColumn = theme.autoSelectColumn;
745
- var top = autoSelectColumn ? null : 0;
746
- var bottom = autoSelectColumn ? null : model.rowCount - 1;
747
- var left = autoSelectRow ? null : 0;
748
- var right = autoSelectRow ? null : model.columnCount - 1;
749
- this.setSelectedRanges([new GridRange(left, top, right, bottom)]);
731
+ return {
732
+ cursorRow: newCursorRow,
733
+ cursorColumn: newCursorColumn,
734
+ selectedRanges: newSelectedRanges,
735
+ lastSelectedRanges: selectedRanges
736
+ };
737
+ });
738
+ }
739
+
740
+ selectAll() {
741
+ var {
742
+ model,
743
+ theme
744
+ } = this.props;
745
+ var {
746
+ autoSelectRow,
747
+ autoSelectColumn
748
+ } = theme;
749
+ var top = autoSelectColumn ? null : 0;
750
+ var bottom = autoSelectColumn ? null : model.rowCount - 1;
751
+ var left = autoSelectRow ? null : 0;
752
+ var right = autoSelectRow ? null : model.columnCount - 1;
753
+ this.setSelectedRanges([new GridRange(left, top, right, bottom)]);
754
+ }
755
+
756
+ moveCursor(deltaColumn, deltaRow, extendSelection) {
757
+ var {
758
+ cursorRow,
759
+ cursorColumn,
760
+ selectionEndColumn,
761
+ selectionEndRow
762
+ } = this.state;
763
+ var column = extendSelection ? selectionEndColumn : cursorColumn;
764
+ var row = extendSelection ? selectionEndRow : cursorRow;
765
+
766
+ if (row === null || column === null) {
767
+ var {
768
+ left,
769
+ top
770
+ } = this.state;
771
+ this.moveCursorToPosition(left, top, extendSelection);
772
+ } else {
773
+ var {
774
+ model
775
+ } = this.props;
776
+ var {
777
+ columnCount,
778
+ rowCount
779
+ } = model;
780
+
781
+ var _left = clamp(column + deltaColumn, 0, columnCount - 1);
782
+
783
+ var _top = clamp(row + deltaRow, 0, rowCount - 1);
784
+
785
+ this.moveCursorToPosition(_left, _top, extendSelection);
750
786
  }
751
- }, {
752
- key: "moveCursor",
753
- value: function moveCursor(deltaColumn, deltaRow, extendSelection) {
754
- var _this$state3 = this.state,
755
- cursorRow = _this$state3.cursorRow,
756
- cursorColumn = _this$state3.cursorColumn,
757
- selectionEndColumn = _this$state3.selectionEndColumn,
758
- selectionEndRow = _this$state3.selectionEndRow;
759
- var column = extendSelection ? selectionEndColumn : cursorColumn;
760
- var row = extendSelection ? selectionEndRow : cursorRow;
761
-
762
- if (row === null || column === null) {
763
- var _this$state4 = this.state,
764
- left = _this$state4.left,
765
- top = _this$state4.top;
766
- this.moveCursorToPosition(left, top, extendSelection);
767
- } else {
768
- var model = this.props.model;
769
- var columnCount = model.columnCount,
770
- rowCount = model.rowCount;
771
-
772
- var _left = clamp(column + deltaColumn, 0, columnCount - 1);
773
-
774
- var _top = clamp(row + deltaRow, 0, rowCount - 1);
775
-
776
- this.moveCursorToPosition(_left, _top, extendSelection);
777
- }
787
+ }
788
+ /**
789
+ * Move the cursor in the provided selection direction
790
+ * @param {string} direction The direction to move the cursor in
791
+ */
792
+
793
+
794
+ moveCursorInDirection() {
795
+ var direction = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : GridRange.SELECTION_DIRECTION.DOWN;
796
+ var {
797
+ model
798
+ } = this.props;
799
+ var {
800
+ columnCount,
801
+ rowCount
802
+ } = model;
803
+ var {
804
+ cursorRow,
805
+ cursorColumn,
806
+ selectedRanges
807
+ } = this.state;
808
+ var ranges = selectedRanges.length > 0 ? selectedRanges : [GridRange.makeCell(cursorColumn, cursorRow)];
809
+ var nextCursor = null;
810
+
811
+ if (ranges.length === 1 && GridRange.cellCount(ranges) === 1) {
812
+ var _gridRange$nextCell;
813
+
814
+ // If we only have one cell selected, we want to update the cursor and we want to update the selected cells
815
+ var gridRange = new GridRange(0, 0, columnCount - 1, rowCount - 1);
816
+ nextCursor = (_gridRange$nextCell = gridRange.nextCell(cursorColumn, cursorRow, direction)) !== null && _gridRange$nextCell !== void 0 ? _gridRange$nextCell : gridRange.startCell(direction);
817
+ } else {
818
+ nextCursor = GridRange.nextCell(GridRange.boundedRanges(ranges, columnCount, rowCount), cursorColumn, cursorRow, direction);
778
819
  }
779
- /**
780
- * Move the cursor in the provided selection direction
781
- * @param {string} direction The direction to move the cursor in
782
- */
783
820
 
784
- }, {
785
- key: "moveCursorInDirection",
786
- value: function moveCursorInDirection() {
787
- var direction = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : GridRange.SELECTION_DIRECTION.DOWN;
788
- var model = this.props.model;
789
- var columnCount = model.columnCount,
790
- rowCount = model.rowCount;
791
- var _this$state5 = this.state,
792
- cursorRow = _this$state5.cursorRow,
793
- cursorColumn = _this$state5.cursorColumn,
794
- selectedRanges = _this$state5.selectedRanges;
795
- var ranges = selectedRanges.length > 0 ? selectedRanges : [GridRange.makeCell(cursorColumn, cursorRow)];
796
- var nextCursor = null;
797
-
798
- if (ranges.length === 1 && GridRange.cellCount(ranges) === 1) {
799
- var _gridRange$nextCell;
800
-
801
- // If we only have one cell selected, we want to update the cursor and we want to update the selected cells
802
- var gridRange = new GridRange(0, 0, columnCount - 1, rowCount - 1);
803
- nextCursor = (_gridRange$nextCell = gridRange.nextCell(cursorColumn, cursorRow, direction)) !== null && _gridRange$nextCell !== void 0 ? _gridRange$nextCell : gridRange.startCell(direction);
804
- } else {
805
- nextCursor = GridRange.nextCell(GridRange.boundedRanges(ranges, columnCount, rowCount), cursorColumn, cursorRow, direction);
806
- }
821
+ if (nextCursor != null) {
822
+ var {
823
+ column,
824
+ row
825
+ } = nextCursor;
826
+ this.setState({
827
+ cursorColumn: column,
828
+ cursorRow: row
829
+ });
807
830
 
808
- if (nextCursor != null) {
809
- var _nextCursor = nextCursor,
810
- column = _nextCursor.column,
811
- row = _nextCursor.row;
831
+ if (!GridRange.containsCell(selectedRanges, column, row)) {
812
832
  this.setState({
813
- cursorColumn: column,
814
- cursorRow: row
833
+ selectedRanges: [GridRange.makeCell(column, row)],
834
+ selectionStartColumn: column,
835
+ selectionStartRow: row,
836
+ selectionEndColumn: column,
837
+ selectionEndRow: row
815
838
  });
839
+ }
816
840
 
817
- if (!GridRange.containsCell(selectedRanges, column, row)) {
818
- this.setState({
819
- selectedRanges: [GridRange.makeCell(column, row)],
820
- selectionStartColumn: column,
821
- selectionStartRow: row,
822
- selectionEndColumn: column,
823
- selectionEndRow: row
824
- });
825
- }
841
+ this.moveViewToCell(nextCursor.column, nextCursor.row);
842
+ }
843
+ }
844
+ /**
845
+ * Move a cursor to the specified position in the grid.
846
+ * @param {number|null} column The column index to move the cursor to
847
+ * @param {number|null} row The row index to move the cursor to
848
+ * @param {boolean} extendSelection Whether to extend the current selection (eg. holding Shift)
849
+ * @param {boolean} keepCursorInView Whether to move the viewport so that the cursor is in view
850
+ * @param {boolean} maximizePreviousRange With this and `extendSelection` true, it will maximize/add to the previous range only, ignoring where the selection was started
851
+ */
852
+
853
+
854
+ moveCursorToPosition(column, row) {
855
+ var extendSelection = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
856
+ var keepCursorInView = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
857
+ var maximizePreviousRange = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
858
+
859
+ if (!extendSelection) {
860
+ this.beginSelection(column, row);
861
+ }
826
862
 
827
- this.moveViewToCell(nextCursor.column, nextCursor.row);
863
+ this.moveSelection(column, row, extendSelection, maximizePreviousRange);
864
+
865
+ if (keepCursorInView) {
866
+ this.moveViewToCell(column, row);
867
+ }
868
+ }
869
+ /**
870
+ * Moves the view to make the specified cell visible
871
+ *
872
+ * @param {number|null} column The column index to bring into view
873
+ * @param {number|null} row The row index to bring into view
874
+ */
875
+
876
+
877
+ moveViewToCell(column, row) {
878
+ var {
879
+ metricCalculator
880
+ } = this;
881
+ var {
882
+ bottomVisible,
883
+ rightVisible,
884
+ topVisible,
885
+ leftVisible
886
+ } = this.metrics;
887
+ var metricState = this.getMetricState(this.state);
888
+ var {
889
+ top,
890
+ left,
891
+ topOffset,
892
+ leftOffset
893
+ } = this.state;
894
+
895
+ if (row != null && !GridUtils.isFloatingRow(row, this.metrics)) {
896
+ if (row < topVisible) {
897
+ top = metricCalculator.getTopForTopVisible(metricState, row);
898
+ topOffset = 0;
899
+ } else if (row > bottomVisible) {
900
+ top = metricCalculator.getTopForBottomVisible(metricState, row);
901
+ topOffset = 0;
828
902
  }
829
903
  }
830
- /**
831
- * Move a cursor to the specified position in the grid.
832
- * @param {number|null} column The column index to move the cursor to
833
- * @param {number|null} row The row index to move the cursor to
834
- * @param {boolean} extendSelection Whether to extend the current selection (eg. holding Shift)
835
- * @param {boolean} keepCursorInView Whether to move the viewport so that the cursor is in view
836
- * @param {boolean} maximizePreviousRange With this and `extendSelection` true, it will maximize/add to the previous range only, ignoring where the selection was started
837
- */
838
-
839
- }, {
840
- key: "moveCursorToPosition",
841
- value: function moveCursorToPosition(column, row) {
842
- var extendSelection = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
843
- var keepCursorInView = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
844
- var maximizePreviousRange = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;
845
904
 
846
- if (!extendSelection) {
847
- this.beginSelection(column, row);
905
+ if (column != null && !GridUtils.isFloatingColumn(column, this.metrics)) {
906
+ if (column < leftVisible) {
907
+ left = metricCalculator.getLeftForLeftVisible(metricState, column);
908
+ leftOffset = 0;
909
+ } else if (column > rightVisible) {
910
+ left = metricCalculator.getLeftForRightVisible(metricState, column);
911
+ leftOffset = 0;
848
912
  }
913
+ }
849
914
 
850
- this.moveSelection(column, row, extendSelection, maximizePreviousRange);
915
+ this.setViewState({
916
+ top,
917
+ left,
918
+ topOffset,
919
+ leftOffset
920
+ });
921
+ }
922
+ /**
923
+ * Checks the `top` and `left` properties that are set and updates the isStuckToBottom/Right properties
924
+ * Should be called when user interaction occurs
925
+ * @param {object} viewState New state properties to set.
926
+ * @param {boolean} forceUpdate Whether to force an update.
927
+ */
928
+
929
+
930
+ setViewState(viewState) {
931
+ var forceUpdate = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
932
+ var {
933
+ isStickyBottom,
934
+ isStickyRight
935
+ } = this.props;
936
+ var {
937
+ top,
938
+ left
939
+ } = viewState;
940
+ var {
941
+ lastTop,
942
+ lastLeft
943
+ } = this.metrics;
944
+
945
+ if (top != null) {
946
+ this.isStuckToBottom = isStickyBottom && top >= lastTop;
947
+ }
851
948
 
852
- if (keepCursorInView) {
853
- this.moveViewToCell(column, row);
854
- }
949
+ if (left != null) {
950
+ this.isStuckToRight = isStickyRight && left >= lastLeft;
855
951
  }
856
- /**
857
- * Moves the view to make the specified cell visible
858
- *
859
- * @param {number|null} column The column index to bring into view
860
- * @param {number|null} row The row index to bring into view
861
- */
862
952
 
863
- }, {
864
- key: "moveViewToCell",
865
- value: function moveViewToCell(column, row) {
866
- var metricCalculator = this.metricCalculator;
867
- var _this$metrics4 = this.metrics,
868
- bottomVisible = _this$metrics4.bottomVisible,
869
- rightVisible = _this$metrics4.rightVisible,
870
- topVisible = _this$metrics4.topVisible,
871
- leftVisible = _this$metrics4.leftVisible;
872
- var metricState = this.getMetricState(this.state);
873
- var _this$state6 = this.state,
874
- top = _this$state6.top,
875
- left = _this$state6.left,
876
- topOffset = _this$state6.topOffset,
877
- leftOffset = _this$state6.leftOffset;
878
-
879
- if (row != null && !GridUtils.isFloatingRow(row, this.metrics)) {
880
- if (row < topVisible) {
881
- top = metricCalculator.getTopForTopVisible(metricState, row);
882
- topOffset = 0;
883
- } else if (row > bottomVisible) {
884
- top = metricCalculator.getTopForBottomVisible(metricState, row);
885
- topOffset = 0;
953
+ this.setState(viewState);
954
+
955
+ if (forceUpdate) {
956
+ this.forceUpdate();
957
+ }
958
+ }
959
+ /**
960
+ * Start editing the data at the given index
961
+ *
962
+ * @param {number} column The visible column index to start editing
963
+ * @param {number} row The visible row index to start editing
964
+ * @param {boolean} isQuickEdit If this is a quick edit (the arrow keys can commit)
965
+ * @param {number[]|null} selectionRange The tuple [start,end] text selection range of the value to select when editing
966
+ * @param {string?} value The value to start with in the edit field. Leave undefined to use the current value.
967
+ */
968
+
969
+
970
+ startEditing(column, row) {
971
+ var isQuickEdit = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
972
+ var selectionRange = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
973
+ var value = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : undefined;
974
+ var {
975
+ model
976
+ } = this.props;
977
+ var modelColumn = this.getModelColumn(column);
978
+ var modelRow = this.getModelRow(row);
979
+ var cell = {
980
+ column,
981
+ row,
982
+ selectionRange,
983
+ value: value !== undefined ? value : model.editValueForCell(modelColumn, modelRow),
984
+ isQuickEdit
985
+ };
986
+ this.setState({
987
+ editingCell: cell,
988
+ cursorColumn: column,
989
+ cursorRow: row
990
+ });
991
+ this.moveViewToCell(column, row);
992
+ }
993
+
994
+ isValidForCell(column, row, value) {
995
+ var {
996
+ model
997
+ } = this.props;
998
+ var modelColumn = this.getModelColumn(column);
999
+ var modelRow = this.getModelRow(row);
1000
+ return model.isValidForCell(modelColumn, modelRow, value);
1001
+ }
1002
+ /**
1003
+ * Paste a value with the current selection
1004
+ * It first needs to validate that the pasted table is valid for the given selection.
1005
+ * Also may update selection if single cells are selected and a table is pasted.
1006
+ * @param {string[][] | string} value Table or a string that is being pasted
1007
+ */
1008
+
1009
+
1010
+ pasteValue(value) {
1011
+ var _this = this;
1012
+
1013
+ return _asyncToGenerator(function* () {
1014
+ var {
1015
+ model
1016
+ } = _this.props;
1017
+ var {
1018
+ movedColumns,
1019
+ movedRows,
1020
+ selectedRanges
1021
+ } = _this.state;
1022
+
1023
+ try {
1024
+ if (!model.isEditable || !selectedRanges.every(range => model.isEditableRange(range))) {
1025
+ throw new PasteError("Can't paste in to read-only area.");
886
1026
  }
887
- }
888
1027
 
889
- if (column != null && !GridUtils.isFloatingColumn(column, this.metrics)) {
890
- if (column < leftVisible) {
891
- left = metricCalculator.getLeftForLeftVisible(metricState, column);
892
- leftOffset = 0;
893
- } else if (column > rightVisible) {
894
- left = metricCalculator.getLeftForRightVisible(metricState, column);
895
- leftOffset = 0;
1028
+ if (selectedRanges.length <= 0) {
1029
+ throw new PasteError('Select an area to paste to.');
896
1030
  }
897
- }
898
1031
 
899
- this.setViewState({
900
- top: top,
901
- left: left,
902
- topOffset: topOffset,
903
- leftOffset: leftOffset
904
- });
905
- }
906
- /**
907
- * Checks the `top` and `left` properties that are set and updates the isStuckToBottom/Right properties
908
- * Should be called when user interaction occurs
909
- * @param {object} viewState New state properties to set.
910
- * @param {boolean} forceUpdate Whether to force an update.
911
- */
1032
+ if (typeof value === 'string') {
1033
+ // Just paste the value into all the selected cells
1034
+ var _edits = [];
1035
+ var modelRanges = GridUtils.getModelRanges(selectedRanges, movedColumns, movedRows);
1036
+ GridRange.forEachCell(modelRanges, (x, y) => {
1037
+ _edits.push({
1038
+ x,
1039
+ y,
1040
+ text: value
1041
+ });
1042
+ });
1043
+ yield model.setValues(_edits);
1044
+ return;
1045
+ } // Otherwise it's a table of data
912
1046
 
913
- }, {
914
- key: "setViewState",
915
- value: function setViewState(viewState) {
916
- var forceUpdate = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
917
- var _this$props4 = this.props,
918
- isStickyBottom = _this$props4.isStickyBottom,
919
- isStickyRight = _this$props4.isStickyRight;
920
- var top = viewState.top,
921
- left = viewState.left;
922
- var _this$metrics5 = this.metrics,
923
- lastTop = _this$metrics5.lastTop,
924
- lastLeft = _this$metrics5.lastLeft;
925
-
926
- if (top != null) {
927
- this.isStuckToBottom = isStickyBottom && top >= lastTop;
928
- }
929
1047
 
930
- if (left != null) {
931
- this.isStuckToRight = isStickyRight && left >= lastLeft;
932
- }
1048
+ var tableHeight = value.length;
1049
+ var tableWidth = value[0].length;
1050
+ var {
1051
+ columnCount,
1052
+ rowCount
1053
+ } = model;
1054
+ var ranges = selectedRanges; // If each cell is a single selection, we need to update the selection to map to the newly pasted data
933
1055
 
934
- this.setState(viewState);
1056
+ if (ranges.every(range => GridRange.cellCount([range]) === 1 && range.startColumn + tableWidth <= columnCount && range.startRow + tableHeight <= rowCount)) {
1057
+ // Remap the selected ranges
1058
+ ranges = ranges.map(range => new GridRange(range.startColumn, range.startRow, range.startColumn + tableWidth - 1, range.startRow + tableHeight - 1));
935
1059
 
936
- if (forceUpdate) {
937
- this.forceUpdate();
938
- }
939
- }
940
- /**
941
- * Start editing the data at the given index
942
- *
943
- * @param {number} column The visible column index to start editing
944
- * @param {number} row The visible row index to start editing
945
- * @param {boolean} isQuickEdit If this is a quick edit (the arrow keys can commit)
946
- * @param {number[]|null} selectionRange The tuple [start,end] text selection range of the value to select when editing
947
- * @param {string?} value The value to start with in the edit field. Leave undefined to use the current value.
948
- */
1060
+ _this.setSelectedRanges(ranges);
1061
+ }
949
1062
 
950
- }, {
951
- key: "startEditing",
952
- value: function startEditing(column, row) {
953
- var isQuickEdit = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
954
- var selectionRange = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
955
- var value = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : undefined;
956
- var model = this.props.model;
957
- var modelColumn = this.getModelColumn(column);
958
- var modelRow = this.getModelRow(row);
959
- var cell = {
960
- column: column,
961
- row: row,
962
- selectionRange: selectionRange,
963
- value: value !== undefined ? value : model.editValueForCell(modelColumn, modelRow),
964
- isQuickEdit: isQuickEdit
965
- };
966
- this.setState({
967
- editingCell: cell,
968
- cursorColumn: column,
969
- cursorRow: row
970
- });
971
- this.moveViewToCell(column, row);
972
- }
973
- }, {
974
- key: "isValidForCell",
975
- value: function isValidForCell(column, row, value) {
976
- var model = this.props.model;
977
- var modelColumn = this.getModelColumn(column);
978
- var modelRow = this.getModelRow(row);
979
- return model.isValidForCell(modelColumn, modelRow, value);
980
- }
981
- /**
982
- * Paste a value with the current selection
983
- * It first needs to validate that the pasted table is valid for the given selection.
984
- * Also may update selection if single cells are selected and a table is pasted.
985
- * @param {string[][] | string} value Table or a string that is being pasted
986
- */
1063
+ if (!ranges.every(range => GridRange.rowCount([range]) === tableHeight && GridRange.columnCount([range]) === tableWidth)) {
1064
+ throw new PasteError('Copy and paste area are not same size.');
1065
+ }
987
1066
 
988
- }, {
989
- key: "pasteValue",
990
- value: function () {
991
- var _pasteValue = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(value) {
992
- var model, _this$state7, movedColumns, movedRows, selectedRanges, _edits, modelRanges, tableHeight, tableWidth, columnCount, rowCount, ranges, edits, onError;
993
-
994
- return regeneratorRuntime.wrap(function _callee$(_context) {
995
- while (1) {
996
- switch (_context.prev = _context.next) {
997
- case 0:
998
- model = this.props.model;
999
- _this$state7 = this.state, movedColumns = _this$state7.movedColumns, movedRows = _this$state7.movedRows, selectedRanges = _this$state7.selectedRanges;
1000
- _context.prev = 2;
1001
-
1002
- if (!(!model.isEditable || !selectedRanges.every(function (range) {
1003
- return model.isEditableRange(range);
1004
- }))) {
1005
- _context.next = 5;
1006
- break;
1007
- }
1008
-
1009
- throw new PasteError("Can't paste in to read-only area.");
1010
-
1011
- case 5:
1012
- if (!(selectedRanges.length <= 0)) {
1013
- _context.next = 7;
1014
- break;
1015
- }
1016
-
1017
- throw new PasteError('Select an area to paste to.');
1018
-
1019
- case 7:
1020
- if (!(typeof value === 'string')) {
1021
- _context.next = 14;
1022
- break;
1023
- }
1024
-
1025
- // Just paste the value into all the selected cells
1026
- _edits = [];
1027
- modelRanges = GridUtils.getModelRanges(selectedRanges, movedColumns, movedRows);
1028
- GridRange.forEachCell(modelRanges, function (x, y) {
1029
- _edits.push({
1030
- x: x,
1031
- y: y,
1032
- text: value
1033
- });
1034
- });
1035
- _context.next = 13;
1036
- return model.setValues(_edits);
1037
-
1038
- case 13:
1039
- return _context.abrupt("return");
1040
-
1041
- case 14:
1042
- // Otherwise it's a table of data
1043
- tableHeight = value.length;
1044
- tableWidth = value[0].length;
1045
- columnCount = model.columnCount, rowCount = model.rowCount;
1046
- ranges = selectedRanges; // If each cell is a single selection, we need to update the selection to map to the newly pasted data
1047
-
1048
- if (ranges.every(function (range) {
1049
- return GridRange.cellCount([range]) === 1 && range.startColumn + tableWidth <= columnCount && range.startRow + tableHeight <= rowCount;
1050
- })) {
1051
- // Remap the selected ranges
1052
- ranges = ranges.map(function (range) {
1053
- return new GridRange(range.startColumn, range.startRow, range.startColumn + tableWidth - 1, range.startRow + tableHeight - 1);
1054
- });
1055
- this.setSelectedRanges(ranges);
1056
- }
1057
-
1058
- if (ranges.every(function (range) {
1059
- return GridRange.rowCount([range]) === tableHeight && GridRange.columnCount([range]) === tableWidth;
1060
- })) {
1061
- _context.next = 21;
1062
- break;
1063
- }
1064
-
1065
- throw new PasteError('Copy and paste area are not same size.');
1066
-
1067
- case 21:
1068
- edits = [];
1069
- ranges.forEach(function (range) {
1070
- for (var x = 0; x < tableWidth; x += 1) {
1071
- for (var y = 0; y < tableHeight; y += 1) {
1072
- edits.push({
1073
- x: range.startColumn + x,
1074
- y: range.startRow + y,
1075
- text: value[y][x]
1076
- });
1077
- }
1078
- }
1079
- });
1080
- _context.next = 25;
1081
- return model.setValues(edits);
1082
-
1083
- case 25:
1084
- _context.next = 31;
1085
- break;
1086
-
1087
- case 27:
1088
- _context.prev = 27;
1089
- _context.t0 = _context["catch"](2);
1090
- onError = this.props.onError;
1091
- onError(_context.t0);
1092
-
1093
- case 31:
1094
- case "end":
1095
- return _context.stop();
1067
+ var edits = [];
1068
+ ranges.forEach(range => {
1069
+ for (var x = 0; x < tableWidth; x += 1) {
1070
+ for (var y = 0; y < tableHeight; y += 1) {
1071
+ edits.push({
1072
+ x: range.startColumn + x,
1073
+ y: range.startRow + y,
1074
+ text: value[y][x]
1075
+ });
1096
1076
  }
1097
1077
  }
1098
- }, _callee, this, [[2, 27]]);
1099
- }));
1100
-
1101
- function pasteValue(_x) {
1102
- return _pasteValue.apply(this, arguments);
1078
+ });
1079
+ yield model.setValues(edits);
1080
+ } catch (e) {
1081
+ var {
1082
+ onError
1083
+ } = _this.props;
1084
+ onError(e);
1103
1085
  }
1086
+ })();
1087
+ }
1104
1088
 
1105
- return pasteValue;
1106
- }()
1107
- }, {
1108
- key: "setValueForCell",
1109
- value: function setValueForCell(column, row, value) {
1110
- var model = this.props.model;
1111
- var modelColumn = this.getModelColumn(column);
1112
- var modelRow = this.getModelRow(row);
1113
-
1114
- if (model.isValidForCell(modelColumn, modelRow, value)) {
1115
- model.setValueForCell(modelColumn, modelRow, value);
1116
- }
1117
- }
1118
- }, {
1119
- key: "setValueForRanges",
1120
- value: function setValueForRanges(ranges, value) {
1121
- var model = this.props.model;
1122
- var _this$state8 = this.state,
1123
- movedColumns = _this$state8.movedColumns,
1124
- movedRows = _this$state8.movedRows;
1125
- var modelRanges = GridUtils.getModelRanges(ranges, movedColumns, movedRows);
1126
- model.setValueForRanges(modelRanges, value);
1127
- }
1128
- }, {
1129
- key: "isSelected",
1130
- value: function isSelected(row, column) {
1131
- var selectedRanges = this.state.selectedRanges;
1132
-
1133
- for (var i = 0; i < selectedRanges.length; i += 1) {
1134
- var selectedRange = selectedRanges[i];
1135
- var rowSelected = selectedRange.startRow === null || selectedRange.startRow <= row && row <= selectedRange.endRow;
1136
- var columnSelected = selectedRange.startColumn === null || selectedRange.startColumn <= column && column <= selectedRange.endColumn;
1137
-
1138
- if (rowSelected && columnSelected) {
1139
- return true;
1140
- }
1141
- }
1089
+ setValueForCell(column, row, value) {
1090
+ var {
1091
+ model
1092
+ } = this.props;
1093
+ var modelColumn = this.getModelColumn(column);
1094
+ var modelRow = this.getModelRow(row);
1142
1095
 
1143
- return false;
1144
- }
1145
- }, {
1146
- key: "addDocumentCursor",
1147
- value: function addDocumentCursor() {
1148
- var cursor = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
1149
- if (this.documentCursor === Grid.getCursorClassName(cursor)) return;
1150
- document.documentElement.classList.remove(this.documentCursor);
1151
- this.documentCursor = Grid.getCursorClassName(cursor);
1152
- document.documentElement.classList.add(this.documentCursor);
1153
- document.documentElement.classList.add('grid-block-events');
1154
- }
1155
- }, {
1156
- key: "removeDocumentCursor",
1157
- value: function removeDocumentCursor() {
1158
- if (this.documentCursor) {
1159
- document.documentElement.classList.remove(this.documentCursor);
1160
- document.documentElement.classList.remove('grid-block-events');
1161
- this.documentCursor = null;
1162
- }
1096
+ if (model.isValidForCell(modelColumn, modelRow, value)) {
1097
+ model.setValueForCell(modelColumn, modelRow, value);
1163
1098
  }
1164
- }, {
1165
- key: "startDragTimer",
1166
- value: function startDragTimer(event) {
1167
- var _this5 = this;
1168
-
1169
- this.stopDragTimer();
1170
- var mouseEvent = new MouseEvent('custom', event);
1171
- this.dragTimer = setTimeout(function () {
1172
- _this5.handleMouseDrag(mouseEvent);
1173
- }, Grid.dragTimeout);
1174
- }
1175
- }, {
1176
- key: "stopDragTimer",
1177
- value: function stopDragTimer() {
1178
- if (this.dragTimer) {
1179
- clearTimeout(this.dragTimer);
1180
- this.dragTimer = null;
1099
+ }
1100
+
1101
+ setValueForRanges(ranges, value) {
1102
+ var {
1103
+ model
1104
+ } = this.props;
1105
+ var {
1106
+ movedColumns,
1107
+ movedRows
1108
+ } = this.state;
1109
+ var modelRanges = GridUtils.getModelRanges(ranges, movedColumns, movedRows);
1110
+ model.setValueForRanges(modelRanges, value);
1111
+ }
1112
+
1113
+ isSelected(row, column) {
1114
+ var {
1115
+ selectedRanges
1116
+ } = this.state;
1117
+
1118
+ for (var i = 0; i < selectedRanges.length; i += 1) {
1119
+ var selectedRange = selectedRanges[i];
1120
+ var rowSelected = selectedRange.startRow === null || selectedRange.startRow <= row && row <= selectedRange.endRow;
1121
+ var columnSelected = selectedRange.startColumn === null || selectedRange.startColumn <= column && column <= selectedRange.endColumn;
1122
+
1123
+ if (rowSelected && columnSelected) {
1124
+ return true;
1181
1125
  }
1182
1126
  }
1183
- /**
1184
- * When scrolling you've have to re-draw the whole canvas. As a consequence, all these drawing methods
1185
- * must be very quick.
1186
- */
1187
1127
 
1188
- }, {
1189
- key: "drawCanvas",
1190
- value: function drawCanvas() {
1191
- var metrics = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.updateMetrics();
1192
- var _this$state9 = this.state,
1193
- left = _this$state9.left,
1194
- top = _this$state9.top,
1195
- cursorColumn = _this$state9.cursorColumn,
1196
- cursorRow = _this$state9.cursorRow,
1197
- draggingColumn = _this$state9.draggingColumn,
1198
- draggingColumnOffset = _this$state9.draggingColumnOffset,
1199
- draggingColumnSeparator = _this$state9.draggingColumnSeparator,
1200
- draggingRow = _this$state9.draggingRow,
1201
- draggingRowOffset = _this$state9.draggingRowOffset,
1202
- draggingRowSeparator = _this$state9.draggingRowSeparator,
1203
- editingCell = _this$state9.editingCell,
1204
- isDraggingHorizontalScrollBar = _this$state9.isDraggingHorizontalScrollBar,
1205
- isDraggingVerticalScrollBar = _this$state9.isDraggingVerticalScrollBar,
1206
- isDragging = _this$state9.isDragging,
1207
- mouseX = _this$state9.mouseX,
1208
- mouseY = _this$state9.mouseY,
1209
- selectedRanges = _this$state9.selectedRanges;
1210
- var _this$props5 = this.props,
1211
- model = _this$props5.model,
1212
- stateOverride = _this$props5.stateOverride;
1213
- var renderer = this.renderer;
1214
- var context = this.canvasContext;
1215
- var theme = this.getTheme();
1216
- var width = this.canvas.clientWidth;
1217
- var height = this.canvas.clientHeight;
1218
-
1219
- var renderState = _objectSpread({
1220
- left: left,
1221
- top: top,
1222
- width: width,
1223
- height: height,
1224
- context: context,
1225
- theme: theme,
1226
- model: model,
1227
- metrics: metrics,
1228
- mouseX: mouseX,
1229
- mouseY: mouseY,
1230
- selectedRanges: selectedRanges,
1231
- draggingColumn: draggingColumn,
1232
- draggingColumnOffset: draggingColumnOffset,
1233
- draggingColumnSeparator: draggingColumnSeparator,
1234
- draggingRow: draggingRow,
1235
- draggingRowOffset: draggingRowOffset,
1236
- draggingRowSeparator: draggingRowSeparator,
1237
- editingCell: editingCell,
1238
- isDraggingHorizontalScrollBar: isDraggingHorizontalScrollBar,
1239
- isDraggingVerticalScrollBar: isDraggingVerticalScrollBar,
1240
- isDragging: isDragging,
1241
- cursorColumn: cursorColumn,
1242
- cursorRow: cursorRow
1243
- }, stateOverride);
1244
-
1245
- context.save();
1246
- renderer.drawCanvas(renderState);
1247
- context.restore();
1248
- }
1249
- }, {
1250
- key: "focus",
1251
- value: function focus() {
1252
- this.canvas.focus();
1253
- }
1254
- }, {
1255
- key: "isFocused",
1256
- value: function isFocused() {
1257
- return document.activeElement === this.canvas;
1258
- }
1259
- }, {
1260
- key: "handleClick",
1261
- value: function handleClick(event) {
1262
- var gridPoint = this.getGridPointFromEvent(event);
1263
- var mouseHandlers = this.getMouseHandlers();
1264
-
1265
- for (var i = 0; i < mouseHandlers.length; i += 1) {
1266
- var mouseHandler = mouseHandlers[i];
1267
-
1268
- if (mouseHandler.onClick(gridPoint, this, event)) {
1269
- event.stopPropagation();
1270
- event.preventDefault();
1271
- break;
1272
- }
1273
- }
1128
+ return false;
1129
+ }
1274
1130
 
1275
- this.canvas.focus();
1131
+ addDocumentCursor() {
1132
+ var cursor = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
1133
+ if (this.documentCursor === Grid.getCursorClassName(cursor)) return;
1134
+ document.documentElement.classList.remove(this.documentCursor);
1135
+ this.documentCursor = Grid.getCursorClassName(cursor);
1136
+ document.documentElement.classList.add(this.documentCursor);
1137
+ document.documentElement.classList.add('grid-block-events');
1138
+ }
1139
+
1140
+ removeDocumentCursor() {
1141
+ if (this.documentCursor) {
1142
+ document.documentElement.classList.remove(this.documentCursor);
1143
+ document.documentElement.classList.remove('grid-block-events');
1144
+ this.documentCursor = null;
1276
1145
  }
1277
- }, {
1278
- key: "handleContextMenu",
1279
- value: function handleContextMenu(event) {
1280
- var gridPoint = this.getGridPointFromEvent(event);
1281
- var mouseHandlers = this.getMouseHandlers();
1282
-
1283
- for (var i = 0; i < mouseHandlers.length; i += 1) {
1284
- var mouseHandler = mouseHandlers[i];
1285
-
1286
- if (mouseHandler.onContextMenu(gridPoint, this, event)) {
1287
- event.stopPropagation();
1288
- event.preventDefault();
1289
- break;
1290
- }
1291
- }
1146
+ }
1147
+
1148
+ startDragTimer(event) {
1149
+ this.stopDragTimer();
1150
+ var mouseEvent = new MouseEvent('custom', event);
1151
+ this.dragTimer = setTimeout(() => {
1152
+ this.handleMouseDrag(mouseEvent);
1153
+ }, Grid.dragTimeout);
1154
+ }
1155
+
1156
+ stopDragTimer() {
1157
+ if (this.dragTimer) {
1158
+ clearTimeout(this.dragTimer);
1159
+ this.dragTimer = null;
1292
1160
  }
1293
- }, {
1294
- key: "handleKeyDown",
1295
- value: function handleKeyDown(e) {
1296
- var keyHandlers = this.getKeyHandlers();
1161
+ }
1162
+ /**
1163
+ * When scrolling you've have to re-draw the whole canvas. As a consequence, all these drawing methods
1164
+ * must be very quick.
1165
+ */
1166
+
1167
+
1168
+ drawCanvas() {
1169
+ var metrics = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.updateMetrics();
1170
+ var {
1171
+ left,
1172
+ top,
1173
+ cursorColumn,
1174
+ cursorRow,
1175
+ draggingColumn,
1176
+ draggingColumnOffset,
1177
+ draggingColumnSeparator,
1178
+ draggingRow,
1179
+ draggingRowOffset,
1180
+ draggingRowSeparator,
1181
+ editingCell,
1182
+ isDraggingHorizontalScrollBar,
1183
+ isDraggingVerticalScrollBar,
1184
+ isDragging,
1185
+ mouseX,
1186
+ mouseY,
1187
+ selectedRanges
1188
+ } = this.state;
1189
+ var {
1190
+ model,
1191
+ stateOverride
1192
+ } = this.props;
1193
+ var {
1194
+ renderer
1195
+ } = this;
1196
+ var context = this.canvasContext;
1197
+ var theme = this.getTheme();
1198
+ var width = this.canvas.clientWidth;
1199
+ var height = this.canvas.clientHeight;
1200
+
1201
+ var renderState = _objectSpread({
1202
+ left,
1203
+ top,
1204
+ width,
1205
+ height,
1206
+ context,
1207
+ theme,
1208
+ model,
1209
+ metrics,
1210
+ mouseX,
1211
+ mouseY,
1212
+ selectedRanges,
1213
+ draggingColumn,
1214
+ draggingColumnOffset,
1215
+ draggingColumnSeparator,
1216
+ draggingRow,
1217
+ draggingRowOffset,
1218
+ draggingRowSeparator,
1219
+ editingCell,
1220
+ isDraggingHorizontalScrollBar,
1221
+ isDraggingVerticalScrollBar,
1222
+ isDragging,
1223
+ cursorColumn,
1224
+ cursorRow
1225
+ }, stateOverride);
1226
+
1227
+ context.save();
1228
+ renderer.drawCanvas(renderState);
1229
+ context.restore();
1230
+ }
1297
1231
 
1298
- for (var i = 0; i < keyHandlers.length; i += 1) {
1299
- var keyHandler = keyHandlers[i];
1300
- var result = keyHandler.onDown(e, this);
1232
+ focus() {
1233
+ this.canvas.focus();
1234
+ }
1301
1235
 
1302
- if (result) {
1303
- var _result$stopPropagati, _result$preventDefaul;
1236
+ isFocused() {
1237
+ return document.activeElement === this.canvas;
1238
+ }
1304
1239
 
1305
- if ((_result$stopPropagati = result === null || result === void 0 ? void 0 : result.stopPropagation) !== null && _result$stopPropagati !== void 0 ? _result$stopPropagati : true) e.stopPropagation();
1306
- if ((_result$preventDefaul = result === null || result === void 0 ? void 0 : result.preventDefault) !== null && _result$preventDefaul !== void 0 ? _result$preventDefaul : true) e.preventDefault();
1307
- break;
1308
- }
1240
+ handleClick(event) {
1241
+ var gridPoint = this.getGridPointFromEvent(event);
1242
+ var mouseHandlers = this.getMouseHandlers();
1243
+
1244
+ for (var i = 0; i < mouseHandlers.length; i += 1) {
1245
+ var mouseHandler = mouseHandlers[i];
1246
+
1247
+ if (mouseHandler.onClick(gridPoint, this, event)) {
1248
+ event.stopPropagation();
1249
+ event.preventDefault();
1250
+ break;
1309
1251
  }
1310
1252
  }
1311
- /**
1312
- * Notify all of the mouse handlers for this grid of a mouse event.
1313
- * @param {String} functionName The name of the function in the mouse handler to call
1314
- * @param {MouseEvent} event The mouse event to notify
1315
- * @param {Boolean} updateCoordinates Whether to update the mouse coordinates
1316
- * @param {Boolean} addCursorToDocument Whether to add a cursor overlay or not (for dragging)
1317
- */
1318
1253
 
1319
- }, {
1320
- key: "notifyMouseHandlers",
1321
- value: function notifyMouseHandlers(functionName, event) {
1322
- var updateCoordinates = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
1323
- var addCursorToDocument = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
1324
- var gridPoint = this.getGridPointFromEvent(event);
1325
- var mouseHandlers = this.getMouseHandlers();
1326
- var cursor = null;
1254
+ this.canvas.focus();
1255
+ }
1327
1256
 
1328
- for (var i = 0; i < mouseHandlers.length; i += 1) {
1329
- var mouseHandler = mouseHandlers[i];
1330
- var result = mouseHandler[functionName] && mouseHandler[functionName](gridPoint, this, event);
1257
+ handleContextMenu(event) {
1258
+ var gridPoint = this.getGridPointFromEvent(event);
1259
+ var mouseHandlers = this.getMouseHandlers();
1331
1260
 
1332
- if (result) {
1333
- var _result$stopPropagati2, _result$preventDefaul2;
1261
+ for (var i = 0; i < mouseHandlers.length; i += 1) {
1262
+ var mouseHandler = mouseHandlers[i];
1334
1263
 
1335
- if (mouseHandler.cursor != null) {
1336
- cursor = mouseHandler.cursor;
1264
+ if (mouseHandler.onContextMenu(gridPoint, this, event)) {
1265
+ event.stopPropagation();
1266
+ event.preventDefault();
1267
+ break;
1268
+ }
1269
+ }
1270
+ }
1337
1271
 
1338
- if (addCursorToDocument) {
1339
- this.addDocumentCursor(cursor);
1340
- }
1341
- } // result is bool or object, events are stopped by default
1272
+ handleKeyDown(e) {
1273
+ var keyHandlers = this.getKeyHandlers();
1342
1274
 
1275
+ for (var i = 0; i < keyHandlers.length; i += 1) {
1276
+ var keyHandler = keyHandlers[i];
1277
+ var result = keyHandler.onDown(e, this);
1343
1278
 
1344
- if ((_result$stopPropagati2 = result === null || result === void 0 ? void 0 : result.stopPropagation) !== null && _result$stopPropagati2 !== void 0 ? _result$stopPropagati2 : true) event.stopPropagation();
1345
- if ((_result$preventDefaul2 = result === null || result === void 0 ? void 0 : result.preventDefault) !== null && _result$preventDefaul2 !== void 0 ? _result$preventDefaul2 : true) event.preventDefault();
1346
- break;
1347
- }
1279
+ if (result) {
1280
+ var _result$stopPropagati, _result$preventDefaul;
1281
+
1282
+ if ((_result$stopPropagati = result === null || result === void 0 ? void 0 : result.stopPropagation) !== null && _result$stopPropagati !== void 0 ? _result$stopPropagati : true) e.stopPropagation();
1283
+ if ((_result$preventDefaul = result === null || result === void 0 ? void 0 : result.preventDefault) !== null && _result$preventDefaul !== void 0 ? _result$preventDefaul : true) e.preventDefault();
1284
+ break;
1348
1285
  }
1286
+ }
1287
+ }
1288
+ /**
1289
+ * Notify all of the mouse handlers for this grid of a mouse event.
1290
+ * @param {String} functionName The name of the function in the mouse handler to call
1291
+ * @param {MouseEvent} event The mouse event to notify
1292
+ * @param {Boolean} updateCoordinates Whether to update the mouse coordinates
1293
+ * @param {Boolean} addCursorToDocument Whether to add a cursor overlay or not (for dragging)
1294
+ */
1295
+
1296
+
1297
+ notifyMouseHandlers(functionName, event) {
1298
+ var updateCoordinates = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
1299
+ var addCursorToDocument = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
1300
+ var gridPoint = this.getGridPointFromEvent(event);
1301
+ var mouseHandlers = this.getMouseHandlers();
1302
+ var cursor = null;
1303
+
1304
+ for (var i = 0; i < mouseHandlers.length; i += 1) {
1305
+ var mouseHandler = mouseHandlers[i];
1306
+ var result = mouseHandler[functionName] && mouseHandler[functionName](gridPoint, this, event);
1307
+
1308
+ if (result) {
1309
+ var _result$stopPropagati2, _result$preventDefaul2;
1310
+
1311
+ if (mouseHandler.cursor != null) {
1312
+ ({
1313
+ cursor
1314
+ } = mouseHandler);
1315
+
1316
+ if (addCursorToDocument) {
1317
+ this.addDocumentCursor(cursor);
1318
+ }
1319
+ } // result is bool or object, events are stopped by default
1349
1320
 
1350
- this.setState({
1351
- cursor: cursor
1352
- });
1353
1321
 
1354
- if (updateCoordinates) {
1355
- var x = gridPoint.x,
1356
- y = gridPoint.y;
1357
- this.setState({
1358
- mouseX: x,
1359
- mouseY: y
1360
- });
1322
+ if ((_result$stopPropagati2 = result === null || result === void 0 ? void 0 : result.stopPropagation) !== null && _result$stopPropagati2 !== void 0 ? _result$stopPropagati2 : true) event.stopPropagation();
1323
+ if ((_result$preventDefaul2 = result === null || result === void 0 ? void 0 : result.preventDefault) !== null && _result$preventDefaul2 !== void 0 ? _result$preventDefaul2 : true) event.preventDefault();
1324
+ break;
1361
1325
  }
1362
1326
  }
1363
- }, {
1364
- key: "handleMouseDown",
1365
- value: function handleMouseDown(event) {
1366
- window.addEventListener('mousemove', this.handleMouseDrag, true);
1367
- window.addEventListener('mouseup', this.handleMouseUp, true);
1368
-
1369
- if (event.button != null && event.button !== 0) {
1370
- return;
1371
- }
1372
1327
 
1373
- this.notifyMouseHandlers(GridMouseHandler.FUNCTION_NAMES.DOWN, event);
1374
- this.startDragTimer(event);
1375
- }
1376
- }, {
1377
- key: "handleDoubleClick",
1378
- value: function handleDoubleClick(event) {
1379
- this.notifyMouseHandlers(GridMouseHandler.FUNCTION_NAMES.DOUBLE_CLICK, event);
1380
- }
1381
- }, {
1382
- key: "handleMouseMove",
1383
- value: function handleMouseMove(event) {
1384
- this.notifyMouseHandlers(GridMouseHandler.FUNCTION_NAMES.MOVE, event);
1385
- }
1386
- }, {
1387
- key: "handleMouseLeave",
1388
- value: function handleMouseLeave(event) {
1389
- this.notifyMouseHandlers(GridMouseHandler.FUNCTION_NAMES.LEAVE, event, false);
1328
+ this.setState({
1329
+ cursor
1330
+ });
1331
+
1332
+ if (updateCoordinates) {
1333
+ var {
1334
+ x,
1335
+ y
1336
+ } = gridPoint;
1390
1337
  this.setState({
1391
- mouseX: null,
1392
- mouseY: null
1338
+ mouseX: x,
1339
+ mouseY: y
1393
1340
  });
1394
1341
  }
1395
- }, {
1396
- key: "handleMouseDrag",
1397
- value: function handleMouseDrag(event) {
1398
- this.setState({
1399
- isDragging: true
1400
- });
1401
- this.notifyMouseHandlers(GridMouseHandler.FUNCTION_NAMES.DRAG, event, true, true);
1402
- this.stopDragTimer();
1342
+ }
1343
+
1344
+ handleMouseDown(event) {
1345
+ window.addEventListener('mousemove', this.handleMouseDrag, true);
1346
+ window.addEventListener('mouseup', this.handleMouseUp, true);
1347
+
1348
+ if (event.button != null && event.button !== 0) {
1349
+ return;
1403
1350
  }
1404
- }, {
1405
- key: "handleMouseUp",
1406
- value: function handleMouseUp(event) {
1407
- window.removeEventListener('mousemove', this.handleMouseDrag, true);
1408
- window.removeEventListener('mouseup', this.handleMouseUp, true);
1409
-
1410
- if (event.button != null && event.button !== 0) {
1411
- return;
1412
- }
1413
1351
 
1414
- this.notifyMouseHandlers(GridMouseHandler.FUNCTION_NAMES.UP, event, false);
1415
- this.stopDragTimer();
1416
- this.removeDocumentCursor();
1352
+ this.notifyMouseHandlers(GridMouseHandler.FUNCTION_NAMES.DOWN, event);
1353
+ this.startDragTimer(event);
1354
+ }
1355
+
1356
+ handleDoubleClick(event) {
1357
+ this.notifyMouseHandlers(GridMouseHandler.FUNCTION_NAMES.DOUBLE_CLICK, event);
1358
+ }
1359
+
1360
+ handleMouseMove(event) {
1361
+ this.notifyMouseHandlers(GridMouseHandler.FUNCTION_NAMES.MOVE, event);
1362
+ }
1363
+
1364
+ handleMouseLeave(event) {
1365
+ this.notifyMouseHandlers(GridMouseHandler.FUNCTION_NAMES.LEAVE, event, false);
1366
+ this.setState({
1367
+ mouseX: null,
1368
+ mouseY: null
1369
+ });
1370
+ }
1371
+
1372
+ handleMouseDrag(event) {
1373
+ this.setState({
1374
+ isDragging: true
1375
+ });
1376
+ this.notifyMouseHandlers(GridMouseHandler.FUNCTION_NAMES.DRAG, event, true, true);
1377
+ this.stopDragTimer();
1378
+ }
1379
+
1380
+ handleMouseUp(event) {
1381
+ window.removeEventListener('mousemove', this.handleMouseDrag, true);
1382
+ window.removeEventListener('mouseup', this.handleMouseUp, true);
1383
+
1384
+ if (event.button != null && event.button !== 0) {
1385
+ return;
1417
1386
  }
1418
- }, {
1419
- key: "handleResize",
1420
- value: function handleResize() {
1421
- /**
1422
- * We need to always redraw the canvas in the same frame as the updateCanvasScale
1423
- * because it clears the canvas by nature of direct dom manipulation. However,
1424
- * We also need to verify the state/metrics, which we currently have no way
1425
- * of doing outside of a full componentDidUpdate() call, so we force the update.
1426
- * Ideally, we could verify state/metrics without the forced update.
1427
- */
1428
- this.updateCanvasScale();
1429
- this.updateCanvas();
1430
- this.forceUpdate();
1387
+
1388
+ this.notifyMouseHandlers(GridMouseHandler.FUNCTION_NAMES.UP, event, false);
1389
+ this.stopDragTimer();
1390
+ this.removeDocumentCursor();
1391
+ }
1392
+
1393
+ handleResize() {
1394
+ /**
1395
+ * We need to always redraw the canvas in the same frame as the updateCanvasScale
1396
+ * because it clears the canvas by nature of direct dom manipulation. However,
1397
+ * We also need to verify the state/metrics, which we currently have no way
1398
+ * of doing outside of a full componentDidUpdate() call, so we force the update.
1399
+ * Ideally, we could verify state/metrics without the forced update.
1400
+ */
1401
+ this.updateCanvasScale();
1402
+ this.updateCanvas();
1403
+ this.forceUpdate();
1404
+ }
1405
+
1406
+ handleWheel(e) {
1407
+ this.notifyMouseHandlers(GridMouseHandler.FUNCTION_NAMES.WHEEL, e);
1408
+
1409
+ if (e.defaultPrevented) {
1410
+ return;
1431
1411
  }
1432
- }, {
1433
- key: "handleWheel",
1434
- value: function handleWheel(e) {
1435
- this.notifyMouseHandlers(GridMouseHandler.FUNCTION_NAMES.WHEEL, e);
1436
1412
 
1437
- if (e.defaultPrevented) {
1438
- return;
1413
+ var {
1414
+ metricCalculator,
1415
+ metrics
1416
+ } = this;
1417
+ var metricState = this.getMetricState();
1418
+ var {
1419
+ lastTop,
1420
+ lastLeft
1421
+ } = metrics;
1422
+ var {
1423
+ top,
1424
+ left,
1425
+ topOffset,
1426
+ leftOffset
1427
+ } = metrics;
1428
+ var theme = this.getTheme();
1429
+ var {
1430
+ deltaX,
1431
+ deltaY
1432
+ } = GridUtils.getScrollDelta(e, metrics.barWidth, metrics.barHeight, metrics.rowHeight, metrics.rowHeight); // iterate through each column to determine column width and figure out how far to scroll
1433
+ // get column width of next column to scroll to, and subract it from the remaining distance to travel
1434
+
1435
+ while (deltaX !== 0) {
1436
+ leftOffset += deltaX;
1437
+ deltaX = 0; // no scrolling needed, at directional edge
1438
+
1439
+ if (leftOffset > 0 && left >= lastLeft || leftOffset < 0 && left <= 0) {
1440
+ leftOffset = 0;
1441
+ break;
1439
1442
  }
1440
1443
 
1441
- var metricCalculator = this.metricCalculator,
1442
- metrics = this.metrics;
1443
- var metricState = this.getMetricState();
1444
- var lastTop = metrics.lastTop,
1445
- lastLeft = metrics.lastLeft;
1446
- var top = metrics.top,
1447
- left = metrics.left,
1448
- topOffset = metrics.topOffset,
1449
- leftOffset = metrics.leftOffset;
1450
- var theme = this.getTheme();
1444
+ if (leftOffset > 0) {
1445
+ var _metrics$visibleColum;
1451
1446
 
1452
- var _GridUtils$getScrollD = GridUtils.getScrollDelta(e, metrics.barWidth, metrics.barHeight, metrics.rowHeight, metrics.rowHeight),
1453
- deltaX = _GridUtils$getScrollD.deltaX,
1454
- deltaY = _GridUtils$getScrollD.deltaY; // iterate through each column to determine column width and figure out how far to scroll
1455
- // get column width of next column to scroll to, and subract it from the remaining distance to travel
1447
+ // scroll right
1448
+ // get width of next column
1449
+ var columnWidth = (_metrics$visibleColum = metrics.visibleColumnWidths.get(left)) !== null && _metrics$visibleColum !== void 0 ? _metrics$visibleColum : metricCalculator.getVisibleColumnWidth(left, metricState);
1456
1450
 
1451
+ if (leftOffset >= columnWidth) {
1452
+ // remove width from balance and advance by 1 column
1453
+ deltaX = leftOffset - columnWidth;
1454
+ leftOffset = 0;
1455
+ left += 1;
1456
+ } else if (theme.scrollSnapToColumn) {
1457
+ // if there's still a balance to travel but its less then a column and snapping is on
1458
+ leftOffset = 0;
1459
+ left += 1;
1460
+ }
1461
+ } else if (leftOffset < 0) {
1462
+ var _metrics$visibleColum2;
1457
1463
 
1458
- while (deltaX !== 0) {
1459
- leftOffset += deltaX;
1460
- deltaX = 0; // no scrolling needed, at directional edge
1464
+ // scroll left
1465
+ // get width of next column
1466
+ var _columnWidth = (_metrics$visibleColum2 = metrics.visibleColumnWidths.get(left - 1)) !== null && _metrics$visibleColum2 !== void 0 ? _metrics$visibleColum2 : metricCalculator.getVisibleColumnWidth(left - 1, metricState);
1461
1467
 
1462
- if (leftOffset > 0 && left >= lastLeft || leftOffset < 0 && left <= 0) {
1468
+ if (Math.abs(leftOffset) <= _columnWidth && theme.scrollSnapToColumn) {
1469
+ // if there's still a balance to travel but its less then a column and snapping is on
1470
+ leftOffset = 0;
1471
+ left -= 1;
1472
+ } else {
1473
+ // remove width from balance and advance by 1 column
1474
+ deltaX = leftOffset + _columnWidth;
1463
1475
  leftOffset = 0;
1464
- break;
1476
+ left -= 1;
1465
1477
  }
1478
+ }
1479
+ } // iterate through each row to determine row height and figure out how far to scroll
1480
+ // get row height of next row to scroll to, and subract it from the remaining distance to travel
1466
1481
 
1467
- if (leftOffset > 0) {
1468
- var _metrics$visibleColum;
1469
-
1470
- // scroll right
1471
- // get width of next column
1472
- var columnWidth = (_metrics$visibleColum = metrics.visibleColumnWidths.get(left)) !== null && _metrics$visibleColum !== void 0 ? _metrics$visibleColum : metricCalculator.getVisibleColumnWidth(left, metricState);
1473
-
1474
- if (leftOffset >= columnWidth) {
1475
- // remove width from balance and advance by 1 column
1476
- deltaX = leftOffset - columnWidth;
1477
- leftOffset = 0;
1478
- left += 1;
1479
- } else if (theme.scrollSnapToColumn) {
1480
- // if there's still a balance to travel but its less then a column and snapping is on
1481
- leftOffset = 0;
1482
- left += 1;
1483
- }
1484
- } else if (leftOffset < 0) {
1485
- var _metrics$visibleColum2;
1486
-
1487
- // scroll left
1488
- // get width of next column
1489
- var _columnWidth = (_metrics$visibleColum2 = metrics.visibleColumnWidths.get(left - 1)) !== null && _metrics$visibleColum2 !== void 0 ? _metrics$visibleColum2 : metricCalculator.getVisibleColumnWidth(left - 1, metricState);
1490
-
1491
- if (Math.abs(leftOffset) <= _columnWidth && theme.scrollSnapToColumn) {
1492
- // if there's still a balance to travel but its less then a column and snapping is on
1493
- leftOffset = 0;
1494
- left -= 1;
1495
- } else {
1496
- // remove width from balance and advance by 1 column
1497
- deltaX = leftOffset + _columnWidth;
1498
- leftOffset = 0;
1499
- left -= 1;
1500
- }
1501
- }
1502
- } // iterate through each row to determine row height and figure out how far to scroll
1503
- // get row height of next row to scroll to, and subract it from the remaining distance to travel
1504
1482
 
1483
+ while (deltaY !== 0) {
1484
+ topOffset += deltaY;
1485
+ deltaY = 0; // no scrolling needed, at directional edge
1486
+
1487
+ if (topOffset > 0 && top >= lastTop || topOffset < 0 && top <= 0) {
1488
+ topOffset = 0;
1489
+ break;
1490
+ }
1491
+
1492
+ if (topOffset > 0) {
1493
+ var _metrics$visibleRowHe;
1505
1494
 
1506
- while (deltaY !== 0) {
1507
- topOffset += deltaY;
1508
- deltaY = 0; // no scrolling needed, at directional edge
1495
+ // scroll direction down
1496
+ // get height of next row
1497
+ var rowHeight = (_metrics$visibleRowHe = metrics.visibleRowHeights.get(top)) !== null && _metrics$visibleRowHe !== void 0 ? _metrics$visibleRowHe : metricCalculator.getVisibleRowHeight(top, metricState);
1509
1498
 
1510
- if (topOffset > 0 && top >= lastTop || topOffset < 0 && top <= 0) {
1499
+ if (topOffset >= rowHeight) {
1500
+ // remove height from balance and advance by 1 row
1501
+ deltaY = topOffset - rowHeight;
1502
+ topOffset = 0;
1503
+ top += 1;
1504
+ } else if (theme.scrollSnapToRow) {
1505
+ // if there's still a balance to travel but its less then a row and snapping is on
1511
1506
  topOffset = 0;
1512
- break;
1507
+ top += 1;
1513
1508
  }
1509
+ } else if (topOffset < 0) {
1510
+ var _metrics$visibleRowHe2;
1514
1511
 
1515
- if (topOffset > 0) {
1516
- var _metrics$visibleRowHe;
1517
-
1518
- // scroll direction down
1519
- // get height of next row
1520
- var rowHeight = (_metrics$visibleRowHe = metrics.visibleRowHeights.get(top)) !== null && _metrics$visibleRowHe !== void 0 ? _metrics$visibleRowHe : metricCalculator.getVisibleRowHeight(top, metricState);
1521
-
1522
- if (topOffset >= rowHeight) {
1523
- // remove height from balance and advance by 1 row
1524
- deltaY = topOffset - rowHeight;
1525
- topOffset = 0;
1526
- top += 1;
1527
- } else if (theme.scrollSnapToRow) {
1528
- // if there's still a balance to travel but its less then a row and snapping is on
1529
- topOffset = 0;
1530
- top += 1;
1531
- }
1532
- } else if (topOffset < 0) {
1533
- var _metrics$visibleRowHe2;
1534
-
1535
- // scroll direction up
1536
- // get height of next row
1537
- var _rowHeight = (_metrics$visibleRowHe2 = metrics.visibleRowHeights.get(top - 1)) !== null && _metrics$visibleRowHe2 !== void 0 ? _metrics$visibleRowHe2 : metricCalculator.getVisibleRowHeight(top - 1, metricState);
1538
-
1539
- if (Math.abs(topOffset) <= _rowHeight && theme.scrollSnapToRow) {
1540
- // if there's still a balance to travel but its less then a row and snapping is on
1541
- topOffset = 0;
1542
- top -= 1;
1543
- } else {
1544
- // remove height from balance and advance by 1 row
1545
- deltaY = topOffset + _rowHeight;
1546
- topOffset = 0;
1547
- top -= 1;
1548
- }
1512
+ // scroll direction up
1513
+ // get height of next row
1514
+ var _rowHeight = (_metrics$visibleRowHe2 = metrics.visibleRowHeights.get(top - 1)) !== null && _metrics$visibleRowHe2 !== void 0 ? _metrics$visibleRowHe2 : metricCalculator.getVisibleRowHeight(top - 1, metricState);
1515
+
1516
+ if (Math.abs(topOffset) <= _rowHeight && theme.scrollSnapToRow) {
1517
+ // if there's still a balance to travel but its less then a row and snapping is on
1518
+ topOffset = 0;
1519
+ top -= 1;
1520
+ } else {
1521
+ // remove height from balance and advance by 1 row
1522
+ deltaY = topOffset + _rowHeight;
1523
+ topOffset = 0;
1524
+ top -= 1;
1549
1525
  }
1550
1526
  }
1551
-
1552
- this.setViewState({
1553
- top: top,
1554
- left: left,
1555
- leftOffset: leftOffset,
1556
- topOffset: topOffset
1557
- });
1558
- e.stopPropagation();
1559
- e.preventDefault();
1560
1527
  }
1561
- }, {
1562
- key: "handleEditCellCancel",
1563
- value: function handleEditCellCancel() {
1564
- this.setState({
1565
- editingCell: null
1566
- });
1567
- this.focus();
1568
- }
1569
- }, {
1570
- key: "handleEditCellChange",
1571
- value: function handleEditCellChange(value) {
1572
- this.setState(function (_ref) {
1573
- var editingCell = _ref.editingCell;
1574
- return {
1575
- editingCell: _objectSpread(_objectSpread({}, editingCell), {}, {
1576
- value: value
1577
- })
1578
- };
1579
- });
1580
- }
1581
- }, {
1582
- key: "handleEditCellCommit",
1583
- value: function handleEditCellCommit(value) {
1584
- var _ref2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
1585
- _ref2$direction = _ref2.direction,
1586
- direction = _ref2$direction === void 0 ? GridRange.SELECTION_DIRECTION.DOWN : _ref2$direction,
1587
- _ref2$fillRange = _ref2.fillRange,
1588
- fillRange = _ref2$fillRange === void 0 ? false : _ref2$fillRange;
1589
-
1590
- var _this$state10 = this.state,
1591
- column = _this$state10.cursorColumn,
1592
- row = _this$state10.cursorRow,
1593
- selectedRanges = _this$state10.selectedRanges;
1594
-
1595
- if (!this.isValidForCell(column, row, value)) {
1596
- // Don't allow an invalid value to be commited, the editing cell should show an error
1597
- if (direction == null) {
1598
- // If they clicked off of the editing cell, just remove focus
1599
- this.setState({
1600
- editingCell: null
1601
- });
1602
- }
1603
1528
 
1604
- return;
1605
- }
1529
+ this.setViewState({
1530
+ top,
1531
+ left,
1532
+ leftOffset,
1533
+ topOffset
1534
+ });
1535
+ e.stopPropagation();
1536
+ e.preventDefault();
1537
+ }
1606
1538
 
1607
- if (fillRange) {
1608
- this.setValueForRanges(selectedRanges, value);
1609
- } else {
1610
- this.setValueForCell(column, row, value);
1611
- }
1539
+ handleEditCellCancel() {
1540
+ this.setState({
1541
+ editingCell: null
1542
+ });
1543
+ this.focus();
1544
+ }
1612
1545
 
1613
- if (direction != null) {
1614
- this.moveCursorInDirection(direction);
1615
- }
1546
+ handleEditCellChange(value) {
1547
+ this.setState((_ref) => {
1548
+ var {
1549
+ editingCell
1550
+ } = _ref;
1551
+ return {
1552
+ editingCell: _objectSpread(_objectSpread({}, editingCell), {}, {
1553
+ value
1554
+ })
1555
+ };
1556
+ });
1557
+ }
1616
1558
 
1617
- this.setState({
1618
- editingCell: null
1619
- });
1620
- this.focus();
1621
- }
1622
- }, {
1623
- key: "renderInputField",
1624
- value: function renderInputField() {
1625
- var model = this.props.model;
1626
- var editingCell = this.state.editingCell;
1627
- var metrics = this.metrics;
1628
-
1629
- if (editingCell == null || metrics == null) {
1630
- return null;
1559
+ handleEditCellCommit(value) {
1560
+ var {
1561
+ direction = GridRange.SELECTION_DIRECTION.DOWN,
1562
+ fillRange = false
1563
+ } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
1564
+ var {
1565
+ cursorColumn: column,
1566
+ cursorRow: row,
1567
+ selectedRanges
1568
+ } = this.state;
1569
+
1570
+ if (!this.isValidForCell(column, row, value)) {
1571
+ // Don't allow an invalid value to be commited, the editing cell should show an error
1572
+ if (direction == null) {
1573
+ // If they clicked off of the editing cell, just remove focus
1574
+ this.setState({
1575
+ editingCell: null
1576
+ });
1631
1577
  }
1632
1578
 
1633
- var _editingCell$selectio = editingCell.selectionRange,
1634
- selectionRange = _editingCell$selectio === void 0 ? null : _editingCell$selectio,
1635
- value = editingCell.value,
1636
- isQuickEdit = editingCell.isQuickEdit;
1637
- var _this$state11 = this.state,
1638
- row = _this$state11.cursorRow,
1639
- column = _this$state11.cursorColumn;
1640
- var gridX = metrics.gridX,
1641
- gridY = metrics.gridY,
1642
- visibleColumnXs = metrics.visibleColumnXs,
1643
- visibleRowYs = metrics.visibleRowYs,
1644
- visibleColumnWidths = metrics.visibleColumnWidths,
1645
- visibleRowHeights = metrics.visibleRowHeights;
1646
- var x = visibleColumnXs.get(column);
1647
- var y = visibleRowYs.get(row);
1648
- var w = visibleColumnWidths.get(column);
1649
- var h = visibleRowHeights.get(row);
1650
- var isVisible = x != null && y != null && w != null && h != null; // If the cell isn't visible, we still need to display an invisible cell for focus purposes
1651
-
1652
- var wrapperStyle = isVisible ? {
1653
- position: 'absolute',
1654
- left: gridX + x,
1655
- top: gridY + y,
1656
- width: w,
1657
- height: h
1658
- } : {
1659
- opacity: 0
1660
- };
1661
- var modelColumn = this.getModelColumn(column);
1662
- var modelRow = this.getModelRow(row);
1663
- var inputStyle = modelColumn != null && modelRow != null ? {
1664
- textAlign: model.textAlignForCell(modelColumn, modelRow)
1665
- } : null;
1666
- var isValid = model.isValidForCell(modelColumn, modelRow, value);
1667
- return /*#__PURE__*/React.createElement("div", {
1668
- style: wrapperStyle
1669
- }, /*#__PURE__*/React.createElement(CellInputField, {
1670
- key: "".concat(column, ",").concat(row),
1671
- selectionRange: selectionRange,
1672
- className: classNames({
1673
- error: !isValid
1674
- }),
1675
- onCancel: this.handleEditCellCancel,
1676
- onChange: this.handleEditCellChange,
1677
- onDone: this.handleEditCellCommit,
1678
- isQuickEdit: isQuickEdit,
1679
- style: inputStyle,
1680
- value: value
1681
- }));
1579
+ return;
1682
1580
  }
1683
- }, {
1684
- key: "render",
1685
- value: function render() {
1686
- var _this6 = this;
1687
-
1688
- var cursor = this.state.cursor;
1689
- return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("canvas", {
1690
- className: classNames('grid-canvas', Grid.getCursorClassName(cursor)),
1691
- ref: function ref(canvas) {
1692
- _this6.canvas = canvas;
1693
- },
1694
- onClick: this.handleClick,
1695
- onContextMenu: this.handleContextMenu,
1696
- onDoubleClick: this.handleDoubleClick,
1697
- onKeyDown: this.handleKeyDown,
1698
- onMouseDown: this.handleMouseDown,
1699
- onMouseMove: this.handleMouseMove,
1700
- onMouseLeave: this.handleMouseLeave,
1701
- tabIndex: 0
1702
- }, "Your browser does not support HTML canvas. Update your browser?"), this.renderInputField());
1581
+
1582
+ if (fillRange) {
1583
+ this.setValueForRanges(selectedRanges, value);
1584
+ } else {
1585
+ this.setValueForCell(column, row, value);
1703
1586
  }
1704
- }], [{
1705
- key: "getScale",
1706
- value: // use same constant as chrome source for windows
1707
- // https://github.com/chromium/chromium/blob/973af9d461b6b5dc60208c8d3d66adc27e53da78/ui/events/blink/web_input_event_builders_win.cc#L285
1708
- function getScale(context) {
1709
- var devicePixelRatio = window.devicePixelRatio || 1;
1710
- var backingStorePixelRatio = context.webkitBackingStorePixelRatio || context.mozBackingStorePixelRatio || context.msBackingStorePixelRatio || context.oBackingStorePixelRatio || context.backingStorePixelRatio || 1;
1711
- return devicePixelRatio / backingStorePixelRatio;
1587
+
1588
+ if (direction != null) {
1589
+ this.moveCursorInDirection(direction);
1712
1590
  }
1713
- }, {
1714
- key: "getCursorClassName",
1715
- value: function getCursorClassName(cursor) {
1716
- return cursor ? "grid-cursor-".concat(cursor) : null;
1591
+
1592
+ this.setState({
1593
+ editingCell: null
1594
+ });
1595
+ this.focus();
1596
+ }
1597
+
1598
+ renderInputField() {
1599
+ var {
1600
+ model
1601
+ } = this.props;
1602
+ var {
1603
+ editingCell
1604
+ } = this.state;
1605
+ var {
1606
+ metrics
1607
+ } = this;
1608
+
1609
+ if (editingCell == null || metrics == null) {
1610
+ return null;
1717
1611
  }
1718
- }]);
1719
1612
 
1720
- return Grid;
1721
- }(PureComponent);
1613
+ var {
1614
+ selectionRange = null,
1615
+ value,
1616
+ isQuickEdit
1617
+ } = editingCell;
1618
+ var {
1619
+ cursorRow: row,
1620
+ cursorColumn: column
1621
+ } = this.state;
1622
+ var {
1623
+ gridX,
1624
+ gridY,
1625
+ visibleColumnXs,
1626
+ visibleRowYs,
1627
+ visibleColumnWidths,
1628
+ visibleRowHeights
1629
+ } = metrics;
1630
+ var x = visibleColumnXs.get(column);
1631
+ var y = visibleRowYs.get(row);
1632
+ var w = visibleColumnWidths.get(column);
1633
+ var h = visibleRowHeights.get(row);
1634
+ var isVisible = x != null && y != null && w != null && h != null; // If the cell isn't visible, we still need to display an invisible cell for focus purposes
1635
+
1636
+ var wrapperStyle = isVisible ? {
1637
+ position: 'absolute',
1638
+ left: gridX + x,
1639
+ top: gridY + y,
1640
+ width: w,
1641
+ height: h
1642
+ } : {
1643
+ opacity: 0
1644
+ };
1645
+ var modelColumn = this.getModelColumn(column);
1646
+ var modelRow = this.getModelRow(row);
1647
+ var inputStyle = modelColumn != null && modelRow != null ? {
1648
+ textAlign: model.textAlignForCell(modelColumn, modelRow)
1649
+ } : null;
1650
+ var isValid = model.isValidForCell(modelColumn, modelRow, value);
1651
+ return /*#__PURE__*/React.createElement("div", {
1652
+ style: wrapperStyle
1653
+ }, /*#__PURE__*/React.createElement(CellInputField, {
1654
+ key: "".concat(column, ",").concat(row),
1655
+ selectionRange: selectionRange,
1656
+ className: classNames({
1657
+ error: !isValid
1658
+ }),
1659
+ onCancel: this.handleEditCellCancel,
1660
+ onChange: this.handleEditCellChange,
1661
+ onDone: this.handleEditCellCommit,
1662
+ isQuickEdit: isQuickEdit,
1663
+ style: inputStyle,
1664
+ value: value
1665
+ }));
1666
+ }
1667
+
1668
+ render() {
1669
+ var {
1670
+ cursor
1671
+ } = this.state;
1672
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("canvas", {
1673
+ className: classNames('grid-canvas', Grid.getCursorClassName(cursor)),
1674
+ ref: canvas => {
1675
+ this.canvas = canvas;
1676
+ },
1677
+ onClick: this.handleClick,
1678
+ onContextMenu: this.handleContextMenu,
1679
+ onDoubleClick: this.handleDoubleClick,
1680
+ onKeyDown: this.handleKeyDown,
1681
+ onMouseDown: this.handleMouseDown,
1682
+ onMouseMove: this.handleMouseMove,
1683
+ onMouseLeave: this.handleMouseLeave,
1684
+ tabIndex: 0
1685
+ }, "Your browser does not support HTML canvas. Update your browser?"), this.renderInputField());
1686
+ }
1687
+
1688
+ }
1722
1689
 
1723
1690
  _defineProperty(Grid, "pixelsPerLine", 100 / 3);
1724
1691
 
1725
1692
  _defineProperty(Grid, "dragTimeout", 1000);
1726
1693
 
1727
- _defineProperty(Grid, "getTheme", memoize(function (userTheme) {
1728
- return _objectSpread(_objectSpread({}, GridTheme), userTheme);
1729
- }));
1694
+ _defineProperty(Grid, "getTheme", memoize(userTheme => _objectSpread(_objectSpread({}, GridTheme), userTheme)));
1730
1695
 
1731
1696
  Grid.propTypes = {
1732
1697
  canvasOptions: PropTypes.shape({}),
@@ -1767,11 +1732,11 @@ Grid.defaultProps = {
1767
1732
  mouseHandlers: [],
1768
1733
  movedColumns: [],
1769
1734
  movedRows: [],
1770
- onError: function onError() {},
1771
- onSelectionChanged: function onSelectionChanged() {},
1772
- onMovedColumnsChanged: function onMovedColumnsChanged() {},
1773
- onMoveColumnComplete: function onMoveColumnComplete() {},
1774
- onViewChanged: function onViewChanged() {},
1735
+ onError: () => {},
1736
+ onSelectionChanged: () => {},
1737
+ onMovedColumnsChanged: () => {},
1738
+ onMoveColumnComplete: () => {},
1739
+ onViewChanged: () => {},
1775
1740
  renderer: null,
1776
1741
  stateOverride: {},
1777
1742
  theme: {