@refinitiv-ui/efx-grid 6.0.107 → 6.0.109

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.
@@ -321,7 +321,7 @@ let Grid = function(placeholder, config) {
321
321
  t._snapshotFillerDataChanged = t._snapshotFillerDataChanged.bind(t);
322
322
  t._onPollingInterval = t._onPollingInterval.bind(t);
323
323
 
324
- t._onKeyDown = t._onKeyDown.bind(t);
324
+ t._onTabNavigation = t._onTabNavigation.bind(t);
325
325
  t._requestScroll = t._requestScroll.bind(t);
326
326
  t._onVScroll = t._onVScroll.bind(t);
327
327
  t._selfScrollToRow = t._selfScrollToRow.bind(t);
@@ -404,10 +404,9 @@ let Grid = function(placeholder, config) {
404
404
  t._grid.listen("postSectionDataBinding", t._onPostSectionDataBinding);
405
405
  t._grid.listen("firstRendered", t._dispatch.bind(t, "firstRendered"));
406
406
  t._grid.listen("afterContentBinding", t._dispatch.bind(t, "afterContentBinding"));
407
- t._grid.listen("keydown", t._onKeyDown);
407
+ t._grid.listen("tabNavigation", t._onTabNavigation);
408
408
 
409
409
  t._grid.getVScrollbar().listen("scroll", t._onVScroll);
410
- t._hiddenInput = t._grid.getHiddenInput();
411
410
 
412
411
  t._grid.enableRowHighlighting(true);
413
412
 
@@ -634,8 +633,10 @@ Grid.prototype.dispose = function() {
634
633
  this._subs = null;
635
634
  }
636
635
 
637
- if(this._focusingArgs && this._focusingArgs.id) {
638
- clearTimeout(this._focusingArgs.id);
636
+ if(this._focusingArgs) {
637
+ if(this._focusingArgs.id) {
638
+ clearTimeout(this._focusingArgs.id);
639
+ }
639
640
  this._focusingArgs = null;
640
641
  }
641
642
  };
@@ -4123,16 +4124,11 @@ Grid.prototype.getVScrollView = function () {
4123
4124
  * @param {Element} el
4124
4125
  * @return {boolean}
4125
4126
  */
4126
- function isValidInput(el) {
4127
- return el && el.tagName !== "SPAN" && !el.disabled;
4128
- }
4129
- /** @private
4130
- * @param {Element} el
4131
- * @param {Element} hiddenInput
4132
- * @return {boolean}
4133
- */
4134
- function isValidTarget(el, hiddenInput) {
4135
- return !el.classList.contains("valigner") && el !== hiddenInput;
4127
+ function isFocusableContent(el) {
4128
+ if(el) {
4129
+ return (el.tagName !== "SPAN" && !el.disabled);
4130
+ }
4131
+ return false;
4136
4132
  }
4137
4133
  /** @private
4138
4134
  * @param {Object} cell
@@ -4141,7 +4137,7 @@ function isValidTarget(el, hiddenInput) {
4141
4137
  function focusCell(cell) {
4142
4138
  if(cell) {
4143
4139
  let cellContent = cell.getContent();
4144
- if(cellContent && isValidInput(cellContent)) {
4140
+ if(cellContent && isFocusableContent(cellContent)) {
4145
4141
  cellContent.focus();
4146
4142
  return true;
4147
4143
  }
@@ -4152,18 +4148,15 @@ function focusCell(cell) {
4152
4148
  */
4153
4149
  Grid.prototype._onVScroll = function() {
4154
4150
  let args = this._focusingArgs;
4155
- if(!args) { return; }
4156
-
4157
- this._focusingArgs = null;
4158
- let event = args.event;
4159
- let cell = args.section.getCell(args.colIndex, args.rowIndex);
4160
- if(focusCell(cell)) {
4161
- event.preventDefault();
4162
- } else {
4163
- if(event.shiftKey) {
4164
- this._findPrevFocusableCell(event, args.colIndex, args.rowIndex, args.focusableColIndices);
4165
- } else {
4166
- this._findNextFocusableCell(event, args.colIndex, args.rowIndex, args.focusableColIndices);
4151
+ if(args) {
4152
+ this._focusingArgs = null;
4153
+ let cell = this._grid.getCell("content", args.colIndex, args.rowIndex);
4154
+ if(!focusCell(cell)) {
4155
+ if(args.shiftKey) {
4156
+ this._focusPrevCellContent(args);
4157
+ } else {
4158
+ this._focusNextCellContent(args);
4159
+ }
4167
4160
  }
4168
4161
  }
4169
4162
  };
@@ -4171,89 +4164,108 @@ Grid.prototype._onVScroll = function() {
4171
4164
  */
4172
4165
  Grid.prototype._selfScrollToRow = function() {
4173
4166
  let args = this._focusingArgs;
4174
- if(!args) { return; }
4175
- args.id = 0;
4176
- this.scrollToRow(args.rowIndex);
4167
+ if(args) {
4168
+ args.id = 0;
4169
+ this.scrollToRow(args.rowIndex);
4170
+ }
4177
4171
  };
4178
4172
  /** @private
4179
- * @param {Object} e
4173
+ * @param {Object} args
4180
4174
  * @param {number} colIndex
4181
4175
  * @param {number} rowIndex
4182
- * @param {Array} focusableColIndices
4183
- * @param {Object} section
4184
4176
  */
4185
- Grid.prototype._requestScroll = function(e, colIndex, rowIndex, focusableColIndices, section) {
4186
- let args = this._focusingArgs;
4187
- if(args) { return; }
4188
- if(this._scrolledRow === rowIndex) { return; } // Avoid infinite loop
4189
-
4190
- this._scrolledRow = rowIndex;
4191
- args = this._focusingArgs = {
4192
- event: e,
4193
- colIndex: colIndex,
4194
- rowIndex: rowIndex,
4195
- focusableColIndices: focusableColIndices,
4196
- section: section
4197
- };
4177
+ Grid.prototype._requestScroll = function(args, colIndex, rowIndex) {
4178
+ if(this._focusingArgs || this._scrolledRow === args.rowIndex) {
4179
+ return; // Avoid infinite loop
4180
+ }
4198
4181
 
4182
+ this._scrolledRow = args.rowIndex;
4183
+ this._focusingArgs = args;
4184
+ args.colIndex = colIndex;
4185
+ args.rowIndex = rowIndex;
4186
+ args.event = null; // The event is invalid after the scroll
4199
4187
  args.id = setTimeout(this._selfScrollToRow); // Avoid event loop protection
4200
4188
  };
4201
4189
  /** @private
4202
- * @param {Object} e
4203
- * @param {number} colIndex
4204
- * @param {number} rowIndex
4205
- * @param {Array} focusableColIndices
4206
- * @param {Element=} content
4190
+ * @param {Object} args
4207
4191
  */
4208
- Grid.prototype._findNextFocusableCell = function(e, colIndex, rowIndex, focusableColIndices, content) {
4209
- let startIdx = focusableColIndices.indexOf(colIndex);
4192
+ Grid.prototype._focusNextCellContent = function(args) {
4193
+ let colIndex = args.colIndex;
4194
+ let rowIndex = args.rowIndex;
4195
+ if(rowIndex < 0 || rowIndex == null) {
4196
+ return;
4197
+ }
4210
4198
 
4211
- // Calculate starting row and column index
4212
- if(!isValidTarget(e.target, this._hiddenInput) || startIdx < 0) {
4213
- rowIndex = 0;
4214
- startIdx = 0;
4215
- } else if(isValidInput(content) && startIdx >= 0) {
4199
+ let focusableColIndices = args.focusableColIndices;
4200
+ let len = focusableColIndices.length;
4201
+ let startIdx = 0;
4202
+ let i;
4203
+ if(colIndex >= 0) {
4204
+ for(i = 1; i < len; i++) {
4205
+ if(colIndex < focusableColIndices[i]) {
4206
+ break;
4207
+ }
4208
+ startIdx = i;
4209
+ }
4210
+ }
4211
+ // If the current focus is on a valid content, starts on the next cell
4212
+ if(args.event && args.validContent) {
4216
4213
  startIdx++;
4217
4214
  }
4215
+
4218
4216
  let grid = this._grid;
4219
4217
  let section = grid.getSection("content");
4220
4218
  let viewInfo = grid.getVerticalViewInfo();
4221
4219
  let bottomRowIndex = viewInfo.bottomRowIndex;
4222
4220
  let rowCount = this.getRowCount();
4223
4221
  for(let r = rowIndex; r < rowCount; r++) {
4224
- for(let i = startIdx; i < focusableColIndices.length; i++) {
4222
+ for(i = startIdx; i < len; i++) {
4225
4223
  let c = focusableColIndices[i];
4226
4224
  if(r > bottomRowIndex) {
4227
- this._requestScroll(e, c, r, focusableColIndices, section);
4225
+ this._requestScroll(args, c, r);
4228
4226
  return;
4229
4227
  } else {
4230
4228
  let cell = section.getCell(c, r);
4231
4229
  if(focusCell(cell)) {
4232
- e.preventDefault();
4230
+ if(args.event) {
4231
+ args.event.preventDefault();
4232
+ }
4233
4233
  return;
4234
4234
  }
4235
4235
  }
4236
4236
  }
4237
4237
  startIdx = 0;
4238
4238
  }
4239
+
4240
+ if(args.validContent) { // The current focus on the last focusable content
4241
+ this._grid.getHiddenInput().focus();
4242
+ }
4239
4243
  };
4240
4244
  /** @private
4241
- * @param {Object} e
4242
- * @param {number} colIndex
4243
- * @param {number} rowIndex
4244
- * @param {Array} focusableColIndices
4245
- * @param {Element=} content
4245
+ * @param {Object} args
4246
4246
  */
4247
- Grid.prototype._findPrevFocusableCell = function(e, colIndex, rowIndex, focusableColIndices, content) {
4248
- let startIdx = focusableColIndices.indexOf(colIndex);
4249
- let len = focusableColIndices.length;
4247
+ Grid.prototype._focusPrevCellContent = function(args) {
4248
+ let colIndex = args.colIndex;
4249
+ let rowIndex = args.rowIndex;
4250
+ if(rowIndex < 0 || rowIndex == null) {
4251
+ return;
4252
+ }
4250
4253
 
4251
- // Calculate starting row and column index
4252
- if(!isValidTarget(e.target, this._hiddenInput) || startIdx < 0) {
4253
- rowIndex = 0;
4254
- startIdx = 0;
4255
- } else if(isValidInput(content) && startIdx >= 0) {
4256
- startIdx--;
4254
+ let focusableColIndices = args.focusableColIndices;
4255
+ let len = focusableColIndices.length;
4256
+ let startIdx = len - 1;
4257
+ let i;
4258
+ if(colIndex >= 0) {
4259
+ for(i = len - 1; --i >= 0;) {
4260
+ if(colIndex > focusableColIndices[i]) {
4261
+ break;
4262
+ }
4263
+ startIdx = i;
4264
+ }
4265
+ }
4266
+ // If the current focus is on a valid content, starts on the next cell
4267
+ if(args.event && args.validContent) {
4268
+ --startIdx;
4257
4269
  }
4258
4270
 
4259
4271
  let grid = this._grid;
@@ -4261,32 +4273,33 @@ Grid.prototype._findPrevFocusableCell = function(e, colIndex, rowIndex, focusabl
4261
4273
  let viewInfo = grid.getVerticalViewInfo();
4262
4274
  let topRowIndex = viewInfo.topRowIndex;
4263
4275
  for(let r = rowIndex; r >= 0; r--) {
4264
- for(let i = startIdx; i >= 0; i--) {
4276
+ for(i = startIdx; i >= 0; i--) {
4265
4277
  let c = focusableColIndices[i];
4266
4278
  if(r < topRowIndex) {
4267
- this._requestScroll(e, c, r, focusableColIndices, section);
4279
+ this._requestScroll(args, c, r);
4268
4280
  return;
4269
4281
  } else {
4270
4282
  let cell = section.getCell(c, r);
4271
4283
  if(focusCell(cell)) {
4272
- e.preventDefault();
4284
+ if(args.event) {
4285
+ args.event.preventDefault();
4286
+ }
4273
4287
  return;
4274
4288
  }
4275
4289
  }
4276
4290
  }
4277
4291
  startIdx = len - 1;
4278
4292
  }
4293
+
4294
+ if(args.validContent) { // The current focus on the last focusable content
4295
+ this._grid.getHiddenInput(true).focus();
4296
+ }
4279
4297
  };
4280
4298
 
4281
4299
  /** @private
4282
4300
  * @param {Object} e
4283
4301
  */
4284
- Grid.prototype._onKeyDown = function(e) {
4285
- if (e.keyCode !== 9 || e.ctrlKey || e.altKey || e.metaKey) {
4286
- return;
4287
- }
4288
-
4289
- // Find next focusable cell
4302
+ Grid.prototype._onTabNavigation = function(e) {
4290
4303
  let colDefs = this.getColumnDefinitions();
4291
4304
  let colCount = colDefs.length;
4292
4305
 
@@ -4302,13 +4315,36 @@ Grid.prototype._onKeyDown = function(e) {
4302
4315
  }
4303
4316
 
4304
4317
  this._scrolledRow = -1; // Reset the scroll loop protector
4305
- let pos = this.getRelativePosition(e);
4306
- let content = pos["cell"] ? pos["cell"].getContent() : null;
4318
+ let keyEvt = e.event;
4319
+ let pos = this.getRelativePosition(keyEvt);
4320
+ let validContent = true;
4321
+ let activeElement = e.activeElement;
4322
+ if(activeElement) {
4323
+ validContent = !activeElement.classList.contains("valigner");
4324
+ }
4325
+
4326
+ if(validContent) {
4327
+ let content = pos["cell"] ? pos["cell"].getContent() : null;
4328
+ validContent = isFocusableContent(content);
4329
+ }
4330
+ let startingRowIndex = pos["rowIndex"];
4331
+ if(e.onTheEdge) {
4332
+ let viewInfo = this._grid.getVScrollView();
4333
+ startingRowIndex = keyEvt.shiftKey ? viewInfo.lastFullRow : viewInfo.firstFullRow;
4334
+ }
4335
+ let args = {
4336
+ event: keyEvt,
4337
+ shiftKey: keyEvt.shiftKey,
4338
+ colIndex: pos["colIndex"],
4339
+ rowIndex: startingRowIndex,
4340
+ focusableColIndices: focusableColIndices,
4341
+ validContent: validContent
4342
+ };
4307
4343
 
4308
- if(e.shiftKey) {
4309
- this._findPrevFocusableCell(e, pos["colIndex"], pos["rowIndex"], focusableColIndices, content);
4344
+ if(keyEvt.shiftKey) {
4345
+ this._focusPrevCellContent(args);
4310
4346
  } else {
4311
- this._findNextFocusableCell(e, pos["colIndex"], pos["rowIndex"], focusableColIndices, content);
4347
+ this._focusNextCellContent(args);
4312
4348
  }
4313
4349
  };
4314
4350