@ni/nimble-components 35.2.3 → 35.3.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.
- package/dist/all-components-bundle.js +171 -63
- package/dist/all-components-bundle.js.map +1 -1
- package/dist/all-components-bundle.min.js +6082 -6080
- package/dist/all-components-bundle.min.js.map +1 -1
- package/dist/esm/table/models/keyboard-navigation-manager.d.ts +6 -1
- package/dist/esm/table/models/keyboard-navigation-manager.js +90 -64
- package/dist/esm/table/models/keyboard-navigation-manager.js.map +1 -1
- package/dist/esm/theme-provider/design-token-comments.js +19 -1
- package/dist/esm/theme-provider/design-token-comments.js.map +1 -1
- package/dist/esm/theme-provider/design-token-names.js +19 -1
- package/dist/esm/theme-provider/design-token-names.js.map +1 -1
- package/dist/esm/theme-provider/design-token-values.d.ts +18 -0
- package/dist/esm/theme-provider/design-token-values.js +19 -1
- package/dist/esm/theme-provider/design-token-values.js.map +1 -1
- package/dist/esm/theme-provider/design-tokens.d.ts +18 -0
- package/dist/esm/theme-provider/design-tokens.js +18 -0
- package/dist/esm/theme-provider/design-tokens.js.map +1 -1
- package/dist/tokens-internal.scss +108 -0
- package/dist/tokens.scss +54 -0
- package/package.json +1 -1
|
@@ -16,6 +16,7 @@ export declare class KeyboardNavigationManager<TData extends TableRecord> implem
|
|
|
16
16
|
private columnIndex;
|
|
17
17
|
private focusWithinTable;
|
|
18
18
|
private isCurrentlyFocusingElement;
|
|
19
|
+
private focusedViaPointer;
|
|
19
20
|
private readonly tableNotifier;
|
|
20
21
|
private readonly virtualizerNotifier;
|
|
21
22
|
private visibleRowNotifiers;
|
|
@@ -30,6 +31,7 @@ export declare class KeyboardNavigationManager<TData extends TableRecord> implem
|
|
|
30
31
|
onRowBlur(event: FocusEvent): void;
|
|
31
32
|
onRowActionMenuToggle(event: CustomEvent<TableActionMenuToggleEventDetail>): void;
|
|
32
33
|
private readonly onTableFocusIn;
|
|
34
|
+
private focusSomethingOtherThanTheTable;
|
|
33
35
|
private readonly onTableFocusOut;
|
|
34
36
|
private readonly onCellActionMenuBlur;
|
|
35
37
|
private readonly onCellViewFocusIn;
|
|
@@ -37,6 +39,8 @@ export declare class KeyboardNavigationManager<TData extends TableRecord> implem
|
|
|
37
39
|
private readonly onCellBlur;
|
|
38
40
|
private readonly onCaptureKeyDown;
|
|
39
41
|
private readonly onKeyDown;
|
|
42
|
+
private readonly onPointerDown;
|
|
43
|
+
private readonly onPointerUpOrCancel;
|
|
40
44
|
private readonly onViewportKeyDown;
|
|
41
45
|
private onEnterPressed;
|
|
42
46
|
private onF2Pressed;
|
|
@@ -57,12 +61,13 @@ export declare class KeyboardNavigationManager<TData extends TableRecord> implem
|
|
|
57
61
|
private onMoveUp;
|
|
58
62
|
private onMoveDown;
|
|
59
63
|
private updateFocusStateFromActiveElement;
|
|
64
|
+
private getActiveElementCellAndRow;
|
|
60
65
|
private focusElement;
|
|
61
66
|
private setElementFocusable;
|
|
62
67
|
private setActionMenuButtonFocused;
|
|
63
|
-
private setFocusOnHeader;
|
|
64
68
|
private setDefaultFocus;
|
|
65
69
|
private scrollToAndFocusRow;
|
|
70
|
+
private rowIndexIsValid;
|
|
66
71
|
private focusCurrentRow;
|
|
67
72
|
private focusRowElement;
|
|
68
73
|
private focusHeaderElement;
|
|
@@ -26,25 +26,32 @@ export class KeyboardNavigationManager {
|
|
|
26
26
|
this.columnIndex = -1;
|
|
27
27
|
this.focusWithinTable = false;
|
|
28
28
|
this.isCurrentlyFocusingElement = false;
|
|
29
|
+
this.focusedViaPointer = false;
|
|
29
30
|
this.visibleRowNotifiers = [];
|
|
30
31
|
this.onTableFocusIn = (event) => {
|
|
31
32
|
this.focusWithinTable = true;
|
|
32
|
-
this.updateFocusStateFromActiveElement(
|
|
33
|
+
this.updateFocusStateFromActiveElement();
|
|
33
34
|
// Sets initial focus on the appropriate table content
|
|
34
35
|
const actionMenuOpen = this.table.openActionMenuRecordId !== undefined;
|
|
35
|
-
if (
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
let focusHeader = true;
|
|
39
|
-
if (this.hasRowOrCellFocusType()
|
|
40
|
-
&& this.scrollToAndFocusRow(this.rowIndex)) {
|
|
41
|
-
focusHeader = false;
|
|
36
|
+
if (!actionMenuOpen) {
|
|
37
|
+
if (this.focusType === TableFocusType.none) {
|
|
38
|
+
this.focusSomethingOtherThanTheTable();
|
|
42
39
|
}
|
|
43
|
-
if (
|
|
44
|
-
//
|
|
45
|
-
this.
|
|
40
|
+
else if (event.target === this.table) {
|
|
41
|
+
// restore focus to last focused element
|
|
42
|
+
if (this.hasRowOrCellFocusType() && this.rowIndexIsValid(this.rowIndex)) {
|
|
43
|
+
this.scrollToAndFocusRow(this.rowIndex);
|
|
44
|
+
}
|
|
45
|
+
else if (this.hasHeaderFocusType()) {
|
|
46
|
+
this.focusHeaderElement();
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
// should only get here if focusType was row/cell, but rowIndex was invalid
|
|
50
|
+
this.focusSomethingOtherThanTheTable();
|
|
51
|
+
}
|
|
46
52
|
}
|
|
47
53
|
}
|
|
54
|
+
this.focusedViaPointer = false;
|
|
48
55
|
};
|
|
49
56
|
this.onTableFocusOut = () => {
|
|
50
57
|
this.focusWithinTable = false;
|
|
@@ -59,12 +66,18 @@ export class KeyboardNavigationManager {
|
|
|
59
66
|
};
|
|
60
67
|
this.onCellViewFocusIn = (event) => {
|
|
61
68
|
event.stopPropagation();
|
|
62
|
-
this.updateFocusStateFromActiveElement(
|
|
69
|
+
this.updateFocusStateFromActiveElement();
|
|
63
70
|
};
|
|
64
71
|
this.onCellFocusIn = (event) => {
|
|
65
72
|
event.stopPropagation();
|
|
66
73
|
const cell = event.detail;
|
|
67
|
-
this.updateFocusStateFromActiveElement(
|
|
74
|
+
const row = this.updateFocusStateFromActiveElement();
|
|
75
|
+
if (row) {
|
|
76
|
+
if (this.hasRowOrCellFocusType()
|
|
77
|
+
&& this.rowIndex !== row.resolvedRowIndex) {
|
|
78
|
+
this.setRowFocusState(row.resolvedRowIndex);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
68
81
|
// Currently, clicking a non-interactive cell only updates the focus state to that row, it
|
|
69
82
|
// doesn't focus the cell. If we revisit this, we most likely need to set the cells to tabindex=-1
|
|
70
83
|
// upfront too, so their focusing behavior is consistent whether they've been previously keyboard
|
|
@@ -137,6 +150,12 @@ export class KeyboardNavigationManager {
|
|
|
137
150
|
}
|
|
138
151
|
}
|
|
139
152
|
};
|
|
153
|
+
this.onPointerDown = () => {
|
|
154
|
+
this.focusedViaPointer = true;
|
|
155
|
+
};
|
|
156
|
+
this.onPointerUpOrCancel = () => {
|
|
157
|
+
this.focusedViaPointer = false;
|
|
158
|
+
};
|
|
140
159
|
this.onViewportKeyDown = (event) => {
|
|
141
160
|
let handleEvent = !this.inNavigationMode
|
|
142
161
|
&& (event.key === keyArrowUp || event.key === keyArrowDown);
|
|
@@ -174,6 +193,9 @@ export class KeyboardNavigationManager {
|
|
|
174
193
|
connect() {
|
|
175
194
|
this.table.addEventListener('keydown', this.onCaptureKeyDown, { capture: true });
|
|
176
195
|
this.table.addEventListener('keydown', this.onKeyDown);
|
|
196
|
+
this.table.addEventListener('pointerdown', this.onPointerDown);
|
|
197
|
+
this.table.addEventListener('pointerup', this.onPointerUpOrCancel);
|
|
198
|
+
this.table.addEventListener('pointercancel', this.onPointerUpOrCancel);
|
|
177
199
|
this.table.addEventListener('focusin', this.onTableFocusIn);
|
|
178
200
|
this.table.addEventListener('focusout', this.onTableFocusOut);
|
|
179
201
|
this.table.viewport.addEventListener('keydown', this.onViewportKeyDown);
|
|
@@ -185,6 +207,9 @@ export class KeyboardNavigationManager {
|
|
|
185
207
|
disconnect() {
|
|
186
208
|
this.table.removeEventListener('keydown', this.onCaptureKeyDown, { capture: true });
|
|
187
209
|
this.table.removeEventListener('keydown', this.onKeyDown);
|
|
210
|
+
this.table.removeEventListener('pointerdown', this.onPointerDown);
|
|
211
|
+
this.table.removeEventListener('pointerup', this.onPointerUpOrCancel);
|
|
212
|
+
this.table.removeEventListener('pointercancel', this.onPointerUpOrCancel);
|
|
188
213
|
this.table.removeEventListener('focusin', this.onTableFocusIn);
|
|
189
214
|
this.table.removeEventListener('focusout', this.onTableFocusOut);
|
|
190
215
|
this.table.viewport.removeEventListener('keydown', this.onViewportKeyDown);
|
|
@@ -276,6 +301,13 @@ export class KeyboardNavigationManager {
|
|
|
276
301
|
this.setCellActionMenuFocusState(row.resolvedRowIndex, columnIndex, false);
|
|
277
302
|
}
|
|
278
303
|
}
|
|
304
|
+
focusSomethingOtherThanTheTable() {
|
|
305
|
+
this.setDefaultFocus();
|
|
306
|
+
if (this.focusType === TableFocusType.none) {
|
|
307
|
+
// nothing within the table to focus
|
|
308
|
+
this.table.blur();
|
|
309
|
+
}
|
|
310
|
+
}
|
|
279
311
|
onEnterPressed(ctrlKey) {
|
|
280
312
|
let row;
|
|
281
313
|
let rowElements;
|
|
@@ -451,7 +483,7 @@ export class KeyboardNavigationManager {
|
|
|
451
483
|
this.headerActionIndex = nextFocusState.headerActionIndex ?? this.headerActionIndex;
|
|
452
484
|
this.cellContentIndex = nextFocusState.cellContentIndex ?? this.cellContentIndex;
|
|
453
485
|
if (this.hasRowOrCellFocusType()) {
|
|
454
|
-
this.focusCurrentRow(
|
|
486
|
+
this.focusCurrentRow(!this.focusedViaPointer);
|
|
455
487
|
}
|
|
456
488
|
else {
|
|
457
489
|
this.focusHeaderElement();
|
|
@@ -627,35 +659,39 @@ export class KeyboardNavigationManager {
|
|
|
627
659
|
}
|
|
628
660
|
return false;
|
|
629
661
|
}
|
|
630
|
-
updateFocusStateFromActiveElement(
|
|
662
|
+
updateFocusStateFromActiveElement() {
|
|
631
663
|
// If the user is interacting with the table with non-keyboard methods (like mouse), we need to
|
|
632
664
|
// update our focus state based on the current active/focused element
|
|
633
|
-
const activeElement = this.
|
|
634
|
-
if (
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
const contentIndex = cell.cellView.tabbableChildren.indexOf(activeElement);
|
|
646
|
-
if (contentIndex > -1) {
|
|
647
|
-
this.setCellContentFocusState(contentIndex, row.resolvedRowIndex, columnIndex, false);
|
|
648
|
-
return;
|
|
649
|
-
}
|
|
650
|
-
}
|
|
651
|
-
}
|
|
652
|
-
if (setRowFocus
|
|
653
|
-
&& this.hasRowOrCellFocusType()
|
|
654
|
-
&& this.rowIndex !== row.resolvedRowIndex) {
|
|
655
|
-
this.setRowFocusState(row.resolvedRowIndex);
|
|
656
|
-
}
|
|
665
|
+
const { activeElement, row, cell } = this.getActiveElementCellAndRow();
|
|
666
|
+
if (!cell) {
|
|
667
|
+
return row;
|
|
668
|
+
}
|
|
669
|
+
const columnIndex = this.table.visibleColumns.indexOf(cell.column);
|
|
670
|
+
if (cell.actionMenuButton === activeElement) {
|
|
671
|
+
this.setCellActionMenuFocusState(row.resolvedRowIndex, columnIndex, false);
|
|
672
|
+
}
|
|
673
|
+
else {
|
|
674
|
+
const contentIndex = cell.cellView.tabbableChildren.indexOf(activeElement);
|
|
675
|
+
if (contentIndex > -1) {
|
|
676
|
+
this.setCellContentFocusState(contentIndex, row.resolvedRowIndex, columnIndex, false);
|
|
657
677
|
}
|
|
658
678
|
}
|
|
679
|
+
return row;
|
|
680
|
+
}
|
|
681
|
+
getActiveElementCellAndRow() {
|
|
682
|
+
const activeElement = this.getActiveElement();
|
|
683
|
+
if (!activeElement) {
|
|
684
|
+
return {};
|
|
685
|
+
}
|
|
686
|
+
const row = this.getContainingRow(activeElement);
|
|
687
|
+
if (!row) {
|
|
688
|
+
return { activeElement };
|
|
689
|
+
}
|
|
690
|
+
if (row instanceof TableGroupRow) {
|
|
691
|
+
return { activeElement, row };
|
|
692
|
+
}
|
|
693
|
+
const cell = this.getContainingCell(activeElement);
|
|
694
|
+
return { activeElement, row, cell };
|
|
659
695
|
}
|
|
660
696
|
focusElement(element, focusOptions) {
|
|
661
697
|
const previousActiveElement = this.getActiveElement();
|
|
@@ -686,13 +722,6 @@ export class KeyboardNavigationManager {
|
|
|
686
722
|
menuButton.classList.remove('cell-action-menu-focused');
|
|
687
723
|
}
|
|
688
724
|
}
|
|
689
|
-
setFocusOnHeader() {
|
|
690
|
-
if (this.hasHeaderFocusType()) {
|
|
691
|
-
return this.focusHeaderElement();
|
|
692
|
-
}
|
|
693
|
-
this.setDefaultFocus();
|
|
694
|
-
return this.focusType !== TableFocusType.none;
|
|
695
|
-
}
|
|
696
725
|
setDefaultFocus() {
|
|
697
726
|
const headerElements = this.getTableHeaderFocusableElements();
|
|
698
727
|
if (!this.trySetHeaderActionFocus(headerElements, 0)
|
|
@@ -702,22 +731,19 @@ export class KeyboardNavigationManager {
|
|
|
702
731
|
}
|
|
703
732
|
}
|
|
704
733
|
scrollToAndFocusRow(totalRowIndex, scrollOptions) {
|
|
705
|
-
if (
|
|
706
|
-
|
|
707
|
-
case TableFocusType.none:
|
|
708
|
-
case TableFocusType.headerActions:
|
|
709
|
-
case TableFocusType.columnHeader:
|
|
710
|
-
this.setRowFocusState(totalRowIndex);
|
|
711
|
-
break;
|
|
712
|
-
default:
|
|
713
|
-
break;
|
|
714
|
-
}
|
|
715
|
-
this.rowIndex = totalRowIndex;
|
|
716
|
-
this.virtualizer.scrollToIndex(totalRowIndex, scrollOptions);
|
|
717
|
-
this.focusCurrentRow(true);
|
|
718
|
-
return true;
|
|
734
|
+
if (!this.rowIndexIsValid(totalRowIndex)) {
|
|
735
|
+
return false;
|
|
719
736
|
}
|
|
720
|
-
|
|
737
|
+
if (!this.hasRowOrCellFocusType()) {
|
|
738
|
+
this.setRowFocusState();
|
|
739
|
+
}
|
|
740
|
+
this.rowIndex = totalRowIndex;
|
|
741
|
+
this.virtualizer.scrollToIndex(totalRowIndex, scrollOptions);
|
|
742
|
+
this.focusCurrentRow(!this.focusedViaPointer);
|
|
743
|
+
return true;
|
|
744
|
+
}
|
|
745
|
+
rowIndexIsValid(rowIndex) {
|
|
746
|
+
return rowIndex >= 0 && rowIndex < this.table.tableData.length;
|
|
721
747
|
}
|
|
722
748
|
focusCurrentRow(allowScroll) {
|
|
723
749
|
const visibleRowIndex = this.getCurrentRowVisibleIndex();
|
|
@@ -791,7 +817,7 @@ export class KeyboardNavigationManager {
|
|
|
791
817
|
break;
|
|
792
818
|
}
|
|
793
819
|
if (focusableElement) {
|
|
794
|
-
this.focusElement(focusableElement);
|
|
820
|
+
this.focusElement(focusableElement, { preventScroll: this.focusedViaPointer });
|
|
795
821
|
return true;
|
|
796
822
|
}
|
|
797
823
|
return false;
|
|
@@ -912,7 +938,7 @@ export class KeyboardNavigationManager {
|
|
|
912
938
|
trySetRowSelectionCheckboxFocus(rowElements) {
|
|
913
939
|
if (rowElements?.selectionCheckbox) {
|
|
914
940
|
this.focusType = TableFocusType.rowSelectionCheckbox;
|
|
915
|
-
this.focusCurrentRow(
|
|
941
|
+
this.focusCurrentRow(!this.focusedViaPointer);
|
|
916
942
|
return true;
|
|
917
943
|
}
|
|
918
944
|
return false;
|
|
@@ -1001,7 +1027,7 @@ export class KeyboardNavigationManager {
|
|
|
1001
1027
|
this.rowIndex = rowIndex;
|
|
1002
1028
|
this.columnIndex = columnIndex;
|
|
1003
1029
|
if (focusElement) {
|
|
1004
|
-
this.focusCurrentRow(
|
|
1030
|
+
this.focusCurrentRow(!this.focusedViaPointer);
|
|
1005
1031
|
}
|
|
1006
1032
|
}
|
|
1007
1033
|
isResolvedRowType(row) {
|