@brightspace-ui/core 3.30.0 → 3.30.1

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.
@@ -1,6 +1,6 @@
1
1
  import { css, html, LitElement } from 'lit';
2
- import { findComposedAncestor, getNextAncestorSibling, getPreviousAncestorSibling, isComposedAncestor } from '../../helpers/dom.js';
3
- import { getComposedActiveElement, getFirstFocusableDescendant, getLastFocusableDescendant, getNextFocusable, getPreviousFocusable, isFocusable } from '../../helpers/focus.js';
2
+ import { findComposedAncestor, isComposedAncestor } from '../../helpers/dom.js';
3
+ import { getComposedActiveElement, getFirstFocusableDescendant, getFocusableDescendants, getLastFocusableDescendant, getNextFocusable, getPreviousFocusable } from '../../helpers/focus.js';
4
4
  import { isInteractiveDescendant } from '../../mixins/interactive/interactive-mixin.js';
5
5
  import { RtlMixin } from '../../mixins/rtl/rtl-mixin.js';
6
6
 
@@ -220,7 +220,6 @@ class ListItemGenericLayout extends RtlMixin(LitElement) {
220
220
 
221
221
  firstUpdated() {
222
222
  this.addEventListener('keydown', this._onKeydown.bind(this));
223
- this.addEventListener('focusin', this._setFocusInfo.bind(this));
224
223
  }
225
224
 
226
225
  render() {
@@ -247,19 +246,18 @@ class ListItemGenericLayout extends RtlMixin(LitElement) {
247
246
  `;
248
247
  }
249
248
 
250
- _focusCellItem(num, itemNum) {
251
- const cell = this.shadowRoot && this.shadowRoot.querySelector(`[data-cell-num="${num}"]`);
249
+ _focusCellItem(focusInfo) {
250
+ const cell = this.shadowRoot?.querySelector(`[data-cell-num="${focusInfo.cellNum}"]`);
252
251
  if (!cell) return;
253
252
 
254
- const firstFocusable = getFirstFocusableDescendant(cell);
255
- if (!firstFocusable) return;
253
+ let focusable;
254
+ const focusables = getFocusableDescendants(cell, { deep: true, predicate: elem => !isInteractiveDescendant(elem) });
256
255
 
257
- if (itemNum === 1) {
258
- firstFocusable.focus();
259
- return firstFocusable;
260
- } else {
261
- return this._focusNextWithinCell(firstFocusable, itemNum);
262
- }
256
+ if (focusInfo.index <= focusables.length - 1) focusable = focusables[focusInfo.index];
257
+ else if (focusables.length > 0) focusable = focusables[focusables.length - 1];
258
+
259
+ if (focusable) focusable.focus();
260
+ return focusable;
263
261
  }
264
262
 
265
263
  _focusFirstCell() {
@@ -321,7 +319,7 @@ class ListItemGenericLayout extends RtlMixin(LitElement) {
321
319
  return focusable;
322
320
  }
323
321
 
324
- _focusNextRow(previous = false, num = 1) {
322
+ _focusNextRow(focusInfo, previous = false, num = 1) {
325
323
 
326
324
  const curListItem = findComposedAncestor(this, node => node.role === 'rowgroup');
327
325
  let listItem = curListItem;
@@ -335,7 +333,7 @@ class ListItemGenericLayout extends RtlMixin(LitElement) {
335
333
 
336
334
  if (!listItem) return;
337
335
  const listItemRow = listItem.shadowRoot.querySelector('[role="gridrow"]');
338
- const focusedCellItem = listItemRow._focusCellItem(this._cellNum, this._cellFocusedItem);
336
+ const focusedCellItem = listItemRow._focusCellItem(focusInfo);
339
337
 
340
338
  if (!focusedCellItem) {
341
339
  // could not focus on same cell in adjacent list-item so try general focus on item
@@ -351,51 +349,14 @@ class ListItemGenericLayout extends RtlMixin(LitElement) {
351
349
 
352
350
  }
353
351
 
354
- _focusNextWithinCell(node, num = 1) {
355
-
356
- if (!node || (node.assignedSlot && node.assignedSlot === this._getThisCell())) return null;
357
- let focusable = null;
358
- let siblingNum = 1;
359
- while (!focusable || siblingNum < num) {
360
- node = this._getNextSiblingInCell(node);
361
-
362
- if (!node) break;
363
- ++siblingNum;
364
-
365
- focusable = isFocusable(node, true) ? node : getFirstFocusableDescendant(node);
366
- if (isInteractiveDescendant(focusable)) focusable = null;
367
- }
368
-
369
- if (focusable) focusable.focus();
370
- return focusable;
352
+ _focusNextWithinRow(focusInfo, focusables) {
353
+ if (focusInfo.index === focusables.length - 1) this._focusNextCell(focusInfo.cellNum + 1);
354
+ else focusables[focusInfo.index + 1].focus();
371
355
  }
372
356
 
373
- _focusPreviousWithinCell(node) {
374
- if (!node || (node.assignedSlot && node.assignedSlot === this._getThisCell())) return null;
375
- let focusable = null;
376
- while (!focusable) {
377
- node = this._getPrevSiblingInCell(node);
378
- if (!node) break;
379
- focusable = isFocusable(node, true) ? node : getLastFocusableDescendant(node);
380
- }
381
- if (focusable) focusable.focus();
382
- return focusable;
383
- }
384
-
385
- _getFocusedItemPosition(node) {
386
- let position = 1;
387
- // walk the tree backwards until we hit the cell
388
- do {
389
- node = this._getPrevSiblingInCell(node);
390
- if (node) {
391
- const focusable = isFocusable(node, true) ? node : getLastFocusableDescendant(node);
392
- if (focusable) {
393
- ++position;
394
- node = focusable;
395
- }
396
- }
397
- } while (node);
398
- return position;
357
+ _focusPreviousWithinRow(focusInfo, focusables) {
358
+ if (focusInfo.index === 0) this._focusNextCell(focusInfo.cellNum - 1, false);
359
+ else focusables[focusInfo.index - 1].focus();
399
360
  }
400
361
 
401
362
  _getNextFlattenedListItem(listItem) {
@@ -430,15 +391,6 @@ class ListItemGenericLayout extends RtlMixin(LitElement) {
430
391
 
431
392
  }
432
393
 
433
- _getNextSiblingInCell(node) {
434
- const cell = findComposedAncestor(node, (parent) => parent.classList && parent.classList.contains('d2l-cell'));
435
- if (!cell || cell.name === node.slot) return null;
436
- if (node.nextElementSibling) return node.nextElementSibling;
437
-
438
- const sibling = getNextAncestorSibling(node);
439
- return isComposedAncestor(cell, sibling) ? sibling : null;
440
- }
441
-
442
394
  _getPreviousFlattenedListItem(listItem) {
443
395
 
444
396
  let previousElement = listItem.previousElementSibling;
@@ -476,72 +428,58 @@ class ListItemGenericLayout extends RtlMixin(LitElement) {
476
428
 
477
429
  }
478
430
 
479
- _getPrevSiblingInCell(node) {
480
- const cell = findComposedAncestor(node, (parent) => parent.classList && parent.classList.contains('d2l-cell'));
481
- if (!cell || cell.name === node.slot) return null;
482
- if (node.previousElementSibling) return node.previousElementSibling;
483
-
484
- const sibling = getPreviousAncestorSibling(node);
485
- return isComposedAncestor(cell, sibling) ? sibling : null;
486
- }
487
-
488
- _getThisCell() {
489
- return this.shadowRoot &&
490
- this.shadowRoot.querySelector(`.d2l-cell[data-cell-num="${this._cellNum}"]`);
491
- }
492
-
493
431
  _isContainedInSameRootList(item, node) {
494
432
  const rootList = item?.getRootList?.(item);
495
433
  return isComposedAncestor(rootList, node);
496
434
  }
497
435
 
498
- _onKeydown(event) {
436
+ _onKeydown(e) {
499
437
  if (!this.gridActive) return;
500
- let node = null;
501
438
  let preventDefault = true;
502
- switch (event.keyCode) {
439
+
440
+ const node = getComposedActiveElement();
441
+ const cell = findComposedAncestor(node, parent => parent.classList?.contains('d2l-cell'));
442
+ if (!cell) return;
443
+
444
+ const focusables = getFocusableDescendants(cell, { deep: true, predicate: elem => !isInteractiveDescendant(elem) });
445
+ const focusInfo = {
446
+ cellNum: parseInt(cell.getAttribute('data-cell-num')),
447
+ index: focusables.findIndex(elem => elem === node)
448
+ };
449
+
450
+ switch (e.keyCode) {
503
451
  case keyCodes.RIGHT:
504
- node = getComposedActiveElement();
505
452
  if (this.dir === 'rtl') {
506
- if (!this._focusPreviousWithinCell(node)) {
507
- this._focusNextCell(this._cellNum - 1, false);
508
- }
453
+ this._focusPreviousWithinRow(focusInfo, focusables);
509
454
  } else {
510
- if (!this._focusNextWithinCell(node)) {
511
- this._focusNextCell(this._cellNum + 1);
512
- }
455
+ this._focusNextWithinRow(focusInfo, focusables);
513
456
  }
514
457
  break;
515
458
  case keyCodes.LEFT:
516
- node = getComposedActiveElement();
517
459
  if (this.dir === 'rtl') {
518
- if (!this._focusNextWithinCell(node)) {
519
- this._focusNextCell(this._cellNum + 1);
520
- }
460
+ this._focusNextWithinRow(focusInfo, focusables);
521
461
  } else {
522
- if (!this._focusPreviousWithinCell(node)) {
523
- this._focusNextCell(this._cellNum - 1, false);
524
- }
462
+ this._focusPreviousWithinRow(focusInfo, focusables);
525
463
  }
526
464
  break;
527
465
  case keyCodes.UP:
528
466
  // move to above row, focus same item within the cell
529
- this._focusNextRow(true);
467
+ this._focusNextRow(focusInfo, true);
530
468
  break;
531
469
  case keyCodes.DOWN:
532
470
  // move to below row, focus same item within the cell
533
- this._focusNextRow();
471
+ this._focusNextRow(focusInfo);
534
472
  break;
535
473
  case keyCodes.HOME:
536
474
  if (this.dir === 'rtl') {
537
- if (event.ctrlKey) {
475
+ if (e.ctrlKey) {
538
476
  this._focusFirstRow();
539
477
  } else {
540
478
  // focus last cell
541
479
  this._focusLastCell();
542
480
  }
543
481
  } else {
544
- if (event.ctrlKey) {
482
+ if (e.ctrlKey) {
545
483
  // focus first item of first row
546
484
  this._focusFirstRow();
547
485
  } else {
@@ -552,7 +490,7 @@ class ListItemGenericLayout extends RtlMixin(LitElement) {
552
490
  break;
553
491
  case keyCodes.END:
554
492
  if (this.dir === 'rtl') {
555
- if (event.ctrlKey) {
493
+ if (e.ctrlKey) {
556
494
  // focus first item of last row
557
495
  this._focusLastRow();
558
496
  } else {
@@ -560,7 +498,7 @@ class ListItemGenericLayout extends RtlMixin(LitElement) {
560
498
  this._focusFirstCell();
561
499
  }
562
500
  } else {
563
- if (event.ctrlKey) {
501
+ if (e.ctrlKey) {
564
502
  // focus last item of last row
565
503
  this._focusLastRow();
566
504
  } else {
@@ -571,31 +509,21 @@ class ListItemGenericLayout extends RtlMixin(LitElement) {
571
509
  break;
572
510
  case keyCodes.PAGEUP:
573
511
  // focus five rows up
574
- this._focusNextRow(true, 5);
512
+ this._focusNextRow(focusInfo, true, 5);
575
513
  break;
576
514
  case keyCodes.PAGEDOWN:
577
515
  // focus five rows down
578
- this._focusNextRow(false, 5);
516
+ this._focusNextRow(focusInfo, false, 5);
579
517
  break;
580
518
  default:
581
519
  preventDefault = false;
582
520
  }
521
+
583
522
  if (preventDefault) {
584
- event.preventDefault();
585
- event.stopPropagation();
523
+ e.preventDefault();
524
+ e.stopPropagation();
586
525
  }
587
- }
588
-
589
- _setFocusInfo(e) {
590
- e.stopPropagation();
591
-
592
- if (!this.gridActive) return;
593
- const slot = (e.path || e.composedPath()).find(node =>
594
- node.nodeName === 'SLOT' && node.classList.contains('d2l-cell'));
595
- if (!slot) return;
596
-
597
- this._cellNum = parseInt(slot.getAttribute('data-cell-num'));
598
- this._cellFocusedItem = this._getFocusedItemPosition(e.target);
526
+ return;
599
527
  }
600
528
 
601
529
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brightspace-ui/core",
3
- "version": "3.30.0",
3
+ "version": "3.30.1",
4
4
  "description": "A collection of accessible, free, open-source web components for building Brightspace applications",
5
5
  "type": "module",
6
6
  "repository": "https://github.com/BrightspaceUI/core.git",