@ni/nimble-components 29.6.0 → 29.7.0
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 +1302 -41
- package/dist/all-components-bundle.js.map +1 -1
- package/dist/all-components-bundle.min.js +4053 -3810
- package/dist/all-components-bundle.min.js.map +1 -1
- package/dist/esm/table/components/cell/index.d.ts +9 -0
- package/dist/esm/table/components/cell/index.js +20 -0
- package/dist/esm/table/components/cell/index.js.map +1 -1
- package/dist/esm/table/components/cell/styles.js +17 -1
- package/dist/esm/table/components/cell/styles.js.map +1 -1
- package/dist/esm/table/components/cell/template.js +10 -2
- package/dist/esm/table/components/cell/template.js.map +1 -1
- package/dist/esm/table/components/group-row/index.d.ts +11 -3
- package/dist/esm/table/components/group-row/index.js +13 -1
- package/dist/esm/table/components/group-row/index.js.map +1 -1
- package/dist/esm/table/components/group-row/styles.js +7 -1
- package/dist/esm/table/components/group-row/styles.js.map +1 -1
- package/dist/esm/table/components/group-row/template.js +1 -1
- package/dist/esm/table/components/group-row/template.js.map +1 -1
- package/dist/esm/table/components/header/styles.js +7 -1
- package/dist/esm/table/components/header/styles.js.map +1 -1
- package/dist/esm/table/components/row/index.d.ts +16 -4
- package/dist/esm/table/components/row/index.js +34 -6
- package/dist/esm/table/components/row/index.js.map +1 -1
- package/dist/esm/table/components/row/styles.js +39 -1
- package/dist/esm/table/components/row/styles.js.map +1 -1
- package/dist/esm/table/components/row/template.js +4 -2
- package/dist/esm/table/components/row/template.js.map +1 -1
- package/dist/esm/table/index.d.ts +22 -2
- package/dist/esm/table/index.js +58 -1
- package/dist/esm/table/index.js.map +1 -1
- package/dist/esm/table/models/keyboard-navigation-manager.d.ts +96 -0
- package/dist/esm/table/models/keyboard-navigation-manager.js +1015 -0
- package/dist/esm/table/models/keyboard-navigation-manager.js.map +1 -0
- package/dist/esm/table/models/table-update-tracker.d.ts +2 -1
- package/dist/esm/table/models/table-update-tracker.js +20 -3
- package/dist/esm/table/models/table-update-tracker.js.map +1 -1
- package/dist/esm/table/models/virtualizer.d.ts +6 -2
- package/dist/esm/table/models/virtualizer.js +16 -22
- package/dist/esm/table/models/virtualizer.js.map +1 -1
- package/dist/esm/table/styles.js +21 -0
- package/dist/esm/table/styles.js.map +1 -1
- package/dist/esm/table/template.js +21 -3
- package/dist/esm/table/template.js.map +1 -1
- package/dist/esm/table/testing/table.pageobject.d.ts +7 -2
- package/dist/esm/table/testing/table.pageobject.js +16 -9
- package/dist/esm/table/testing/table.pageobject.js.map +1 -1
- package/dist/esm/table/types.d.ts +38 -0
- package/dist/esm/table/types.js +14 -0
- package/dist/esm/table/types.js.map +1 -1
- package/dist/esm/table-column/anchor/cell-view/index.d.ts +3 -0
- package/dist/esm/table-column/anchor/cell-view/index.js +13 -0
- package/dist/esm/table-column/anchor/cell-view/index.js.map +1 -1
- package/dist/esm/table-column/anchor/cell-view/template.js +4 -2
- package/dist/esm/table-column/anchor/cell-view/template.js.map +1 -1
- package/dist/esm/table-column/base/cell-view/index.d.ts +5 -0
- package/dist/esm/table-column/base/cell-view/index.js +7 -0
- package/dist/esm/table-column/base/cell-view/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -16280,7 +16280,7 @@
|
|
|
16280
16280
|
|
|
16281
16281
|
/**
|
|
16282
16282
|
* Do not edit directly
|
|
16283
|
-
* Generated on
|
|
16283
|
+
* Generated on Tue, 25 Jun 2024 18:25:46 GMT
|
|
16284
16284
|
*/
|
|
16285
16285
|
|
|
16286
16286
|
const Information100DarkUi = "#a46eff";
|
|
@@ -16699,6 +16699,9 @@
|
|
|
16699
16699
|
const keyEnter = "Enter";
|
|
16700
16700
|
const keyEscape = "Escape";
|
|
16701
16701
|
const keyHome = "Home";
|
|
16702
|
+
const keyFunction2 = "F2";
|
|
16703
|
+
const keyPageDown = "PageDown";
|
|
16704
|
+
const keyPageUp = "PageUp";
|
|
16702
16705
|
const keyShift = "Shift";
|
|
16703
16706
|
const keySpace = " ";
|
|
16704
16707
|
const keyTab = "Tab";
|
|
@@ -64433,6 +64436,20 @@ img.ProseMirror-separator {
|
|
|
64433
64436
|
selected: 'selected',
|
|
64434
64437
|
partiallySelected: 'partially-selected'
|
|
64435
64438
|
};
|
|
64439
|
+
/**
|
|
64440
|
+
* @internal
|
|
64441
|
+
* Table keyboard focus types
|
|
64442
|
+
*/
|
|
64443
|
+
const TableFocusType = {
|
|
64444
|
+
none: 'none',
|
|
64445
|
+
columnHeader: 'columnHeader',
|
|
64446
|
+
headerActions: 'headerActions',
|
|
64447
|
+
row: 'row',
|
|
64448
|
+
rowSelectionCheckbox: 'rowSelectionCheckbox',
|
|
64449
|
+
cell: 'cell',
|
|
64450
|
+
cellActionMenu: 'cellActionMenu',
|
|
64451
|
+
cellContent: 'cellContent'
|
|
64452
|
+
};
|
|
64436
64453
|
|
|
64437
64454
|
/**
|
|
64438
64455
|
* The possible operations to use when sorting a table column.
|
|
@@ -64514,6 +64531,13 @@ img.ProseMirror-separator {
|
|
|
64514
64531
|
this.delegatedEvents = [];
|
|
64515
64532
|
this.delegatedEventHandler = () => { };
|
|
64516
64533
|
}
|
|
64534
|
+
/**
|
|
64535
|
+
* Gets the child elements in this cell view that should be able to be reached via Tab/ Shift-Tab,
|
|
64536
|
+
* if any.
|
|
64537
|
+
*/
|
|
64538
|
+
get tabbableChildren() {
|
|
64539
|
+
return [];
|
|
64540
|
+
}
|
|
64517
64541
|
/**
|
|
64518
64542
|
* Called if an element inside this cell view has focus, and this row/cell is being recycled.
|
|
64519
64543
|
* Expected implementation is to commit changes as needed, and blur the focusable element (or close
|
|
@@ -64897,6 +64921,15 @@ img.ProseMirror-separator {
|
|
|
64897
64921
|
--ni-private-column-divider-padding: 3px;
|
|
64898
64922
|
}
|
|
64899
64923
|
|
|
64924
|
+
:host(${focusVisible}) {
|
|
64925
|
+
${
|
|
64926
|
+
/* The table can briefly be focused in some keyboard nav cases (e.g. regaining focus and we
|
|
64927
|
+
need to scroll to the previously focused row first). Ensure that we don't get the browser-default
|
|
64928
|
+
focus outline in that case.
|
|
64929
|
+
) */ ''}
|
|
64930
|
+
outline: none;
|
|
64931
|
+
}
|
|
64932
|
+
|
|
64900
64933
|
.disable-select {
|
|
64901
64934
|
${userSelectNone}
|
|
64902
64935
|
}
|
|
@@ -65027,6 +65060,10 @@ img.ProseMirror-separator {
|
|
|
65027
65060
|
position: relative;
|
|
65028
65061
|
}
|
|
65029
65062
|
|
|
65063
|
+
.table-viewport${focusVisible} {
|
|
65064
|
+
outline: none;
|
|
65065
|
+
}
|
|
65066
|
+
|
|
65030
65067
|
.table-scroll {
|
|
65031
65068
|
pointer-events: none;
|
|
65032
65069
|
position: absolute;
|
|
@@ -65053,10 +65090,17 @@ img.ProseMirror-separator {
|
|
|
65053
65090
|
|
|
65054
65091
|
.group-row {
|
|
65055
65092
|
position: relative;
|
|
65093
|
+
--ni-private-table-cell-focus-offset-multiplier: 0;
|
|
65056
65094
|
}
|
|
65057
65095
|
|
|
65058
65096
|
.row {
|
|
65059
65097
|
position: relative;
|
|
65098
|
+
--ni-private-table-cell-focus-offset-multiplier: 0;
|
|
65099
|
+
}
|
|
65100
|
+
|
|
65101
|
+
.collapse-all-visible .row,
|
|
65102
|
+
.collapse-all-visible .group-row {
|
|
65103
|
+
--ni-private-table-cell-focus-offset-multiplier: 1;
|
|
65060
65104
|
}
|
|
65061
65105
|
|
|
65062
65106
|
.accessibly-hidden {
|
|
@@ -65087,6 +65131,11 @@ img.ProseMirror-separator {
|
|
|
65087
65131
|
cursor: default;
|
|
65088
65132
|
}
|
|
65089
65133
|
|
|
65134
|
+
:host(${focusVisible}) {
|
|
65135
|
+
outline: calc(2 * ${borderWidth}) solid ${borderHoverColor};
|
|
65136
|
+
outline-offset: calc(-2 * ${borderWidth});
|
|
65137
|
+
}
|
|
65138
|
+
|
|
65090
65139
|
.sort-indicator,
|
|
65091
65140
|
.grouped-indicator {
|
|
65092
65141
|
flex: 0 0 auto;
|
|
@@ -65240,6 +65289,11 @@ img.ProseMirror-separator {
|
|
|
65240
65289
|
background-color: ${fillHoverSelectedColor};
|
|
65241
65290
|
}
|
|
65242
65291
|
|
|
65292
|
+
:host(${focusVisible}) {
|
|
65293
|
+
outline: calc(2 * ${borderWidth}) solid ${borderHoverColor};
|
|
65294
|
+
outline-offset: calc(-2 * ${borderWidth});
|
|
65295
|
+
}
|
|
65296
|
+
|
|
65243
65297
|
.expand-collapse-button {
|
|
65244
65298
|
flex: 0 0 auto;
|
|
65245
65299
|
margin-left: max(
|
|
@@ -65314,6 +65368,34 @@ img.ProseMirror-separator {
|
|
|
65314
65368
|
--ni-private-table-cell-action-menu-display: block;
|
|
65315
65369
|
}
|
|
65316
65370
|
|
|
65371
|
+
nimble-table-cell${focusVisible} {
|
|
65372
|
+
--ni-private-table-cell-action-menu-display: block;
|
|
65373
|
+
}
|
|
65374
|
+
|
|
65375
|
+
nimble-table-cell:first-of-type${focusVisible} {
|
|
65376
|
+
margin-left: calc(
|
|
65377
|
+
-1 * (${controlHeight} - ${smallPadding}) * var(--ni-private-table-cell-focus-offset-multiplier)
|
|
65378
|
+
);
|
|
65379
|
+
padding-left: calc(
|
|
65380
|
+
(${controlHeight} - ${mediumPadding}) *
|
|
65381
|
+
var(--ni-private-table-cell-focus-offset-multiplier) +
|
|
65382
|
+
${mediumPadding}
|
|
65383
|
+
);
|
|
65384
|
+
}
|
|
65385
|
+
|
|
65386
|
+
nimble-table-cell:first-of-type${focusVisible}::before {
|
|
65387
|
+
content: '';
|
|
65388
|
+
display: block;
|
|
65389
|
+
width: calc(
|
|
65390
|
+
(
|
|
65391
|
+
${controlHeight} *
|
|
65392
|
+
var(--ni-private-table-cell-nesting-level) +
|
|
65393
|
+
${smallPadding}
|
|
65394
|
+
) * var(--ni-private-table-cell-focus-offset-multiplier)
|
|
65395
|
+
);
|
|
65396
|
+
height: ${controlHeight};
|
|
65397
|
+
}
|
|
65398
|
+
|
|
65317
65399
|
:host(:hover) nimble-table-cell {
|
|
65318
65400
|
--ni-private-table-cell-action-menu-display: block;
|
|
65319
65401
|
}
|
|
@@ -65321,6 +65403,10 @@ img.ProseMirror-separator {
|
|
|
65321
65403
|
:host([selected]) nimble-table-cell {
|
|
65322
65404
|
--ni-private-table-cell-action-menu-display: block;
|
|
65323
65405
|
}
|
|
65406
|
+
|
|
65407
|
+
:host(${focusVisible}) nimble-table-cell {
|
|
65408
|
+
--ni-private-table-cell-action-menu-display: block;
|
|
65409
|
+
}
|
|
65324
65410
|
`.withBehaviors(themeBehavior(Theme.color, css `
|
|
65325
65411
|
:host([selectable]:not([selected]):hover)::before {
|
|
65326
65412
|
background-color: ${hexToRgbaCssColor(White, 0.05)};
|
|
@@ -65351,6 +65437,15 @@ img.ProseMirror-separator {
|
|
|
65351
65437
|
--ni-private-table-cell-action-menu-display: block;
|
|
65352
65438
|
}
|
|
65353
65439
|
|
|
65440
|
+
:host(${focusVisible}) {
|
|
65441
|
+
outline: calc(2 * ${borderWidth}) solid ${borderHoverColor};
|
|
65442
|
+
outline-offset: -2px;
|
|
65443
|
+
}
|
|
65444
|
+
|
|
65445
|
+
.cell-view-container {
|
|
65446
|
+
display: contents;
|
|
65447
|
+
}
|
|
65448
|
+
|
|
65354
65449
|
.cell-view {
|
|
65355
65450
|
overflow: hidden;
|
|
65356
65451
|
}
|
|
@@ -65363,19 +65458,33 @@ img.ProseMirror-separator {
|
|
|
65363
65458
|
height: ${controlSlimHeight};
|
|
65364
65459
|
align-self: center;
|
|
65365
65460
|
}
|
|
65461
|
+
|
|
65462
|
+
${
|
|
65463
|
+
/* This CSS class is applied dynamically by KeyboardNavigationManager */ ''}
|
|
65464
|
+
.action-menu.cell-action-menu-focused {
|
|
65465
|
+
display: block;
|
|
65466
|
+
}
|
|
65366
65467
|
`;
|
|
65367
65468
|
|
|
65368
65469
|
// prettier-ignore
|
|
65369
65470
|
const template$h = html `
|
|
65370
|
-
<template role="cell" style="--ni-private-table-cell-nesting-level: ${x => x.nestingLevel}"
|
|
65371
|
-
${x => x.
|
|
65471
|
+
<template role="cell" style="--ni-private-table-cell-nesting-level: ${x => x.nestingLevel}"
|
|
65472
|
+
@focusin="${x => x.onCellFocusIn()}"
|
|
65473
|
+
@blur="${x => x.onCellBlur()}"
|
|
65474
|
+
>
|
|
65475
|
+
<div ${ref('cellViewContainer')} class="cell-view-container" @focusin="${x => x.onCellViewFocusIn()}">
|
|
65476
|
+
${x => x.cellViewTemplate}
|
|
65477
|
+
</div>
|
|
65372
65478
|
${when(x => x.hasActionMenu, html `
|
|
65373
65479
|
<${menuButtonTag} ${ref('actionMenuButton')}
|
|
65374
65480
|
content-hidden
|
|
65375
65481
|
appearance="${ButtonAppearance.ghost}"
|
|
65482
|
+
${'' /* tabindex managed dynamically by KeyboardNavigationManager */}
|
|
65483
|
+
tabindex="-1"
|
|
65376
65484
|
@beforetoggle="${(x, c) => x.onActionMenuBeforeToggle(c.event)}"
|
|
65377
65485
|
@toggle="${(x, c) => x.onActionMenuToggle(c.event)}"
|
|
65378
65486
|
@click="${(_, c) => c.event.stopPropagation()}"
|
|
65487
|
+
@blur="${x => x.onActionMenuBlur()}"
|
|
65379
65488
|
class="action-menu"
|
|
65380
65489
|
title="${x => (x.actionMenuLabel ? x.actionMenuLabel : tableCellActionMenuLabel.getValueFor(x))}"
|
|
65381
65490
|
>
|
|
@@ -65398,6 +65507,11 @@ img.ProseMirror-separator {
|
|
|
65398
65507
|
this.menuOpen = false;
|
|
65399
65508
|
this.nestingLevel = 0;
|
|
65400
65509
|
}
|
|
65510
|
+
/** @internal */
|
|
65511
|
+
get cellView() {
|
|
65512
|
+
return this.cellViewContainer
|
|
65513
|
+
.firstElementChild;
|
|
65514
|
+
}
|
|
65401
65515
|
onActionMenuBeforeToggle(event) {
|
|
65402
65516
|
this.$emit('cell-action-menu-beforetoggle', event.detail);
|
|
65403
65517
|
}
|
|
@@ -65405,6 +65519,18 @@ img.ProseMirror-separator {
|
|
|
65405
65519
|
this.menuOpen = event.detail.newState;
|
|
65406
65520
|
this.$emit('cell-action-menu-toggle', event.detail);
|
|
65407
65521
|
}
|
|
65522
|
+
onActionMenuBlur() {
|
|
65523
|
+
this.$emit('cell-action-menu-blur', this);
|
|
65524
|
+
}
|
|
65525
|
+
onCellViewFocusIn() {
|
|
65526
|
+
this.$emit('cell-view-focus-in', this);
|
|
65527
|
+
}
|
|
65528
|
+
onCellFocusIn() {
|
|
65529
|
+
this.$emit('cell-focus-in', this);
|
|
65530
|
+
}
|
|
65531
|
+
onCellBlur() {
|
|
65532
|
+
this.$emit('cell-blur', this);
|
|
65533
|
+
}
|
|
65408
65534
|
}
|
|
65409
65535
|
__decorate$1([
|
|
65410
65536
|
observable
|
|
@@ -65430,6 +65556,9 @@ img.ProseMirror-separator {
|
|
|
65430
65556
|
__decorate$1([
|
|
65431
65557
|
observable
|
|
65432
65558
|
], TableCell.prototype, "cellViewTemplate", void 0);
|
|
65559
|
+
__decorate$1([
|
|
65560
|
+
observable
|
|
65561
|
+
], TableCell.prototype, "cellViewContainer", void 0);
|
|
65433
65562
|
__decorate$1([
|
|
65434
65563
|
observable
|
|
65435
65564
|
], TableCell.prototype, "nestingLevel", void 0);
|
|
@@ -65451,11 +65580,13 @@ img.ProseMirror-separator {
|
|
|
65451
65580
|
>
|
|
65452
65581
|
${when(x => !x.rowOperationGridCellHidden, html `
|
|
65453
65582
|
<span role="gridcell" class="row-operations-container">
|
|
65454
|
-
${when(x => x.
|
|
65583
|
+
${when(x => x.showSelectionCheckbox, html `
|
|
65455
65584
|
<${checkboxTag}
|
|
65456
65585
|
${ref('selectionCheckbox')}
|
|
65457
65586
|
class="selection-checkbox"
|
|
65458
|
-
|
|
65587
|
+
${'' /* tabindex managed dynamically by KeyboardNavigationManager */}
|
|
65588
|
+
tabindex="-1"
|
|
65589
|
+
@change="${(x, c) => x.onSelectionCheckboxChange(c.event)}"
|
|
65459
65590
|
@click="${(_, c) => c.event.stopPropagation()}"
|
|
65460
65591
|
title="${x => tableRowSelectLabel.getValueFor(x)}"
|
|
65461
65592
|
aria-label="${x => tableRowSelectLabel.getValueFor(x)}"
|
|
@@ -65576,6 +65707,10 @@ img.ProseMirror-separator {
|
|
|
65576
65707
|
get isNestedParent() {
|
|
65577
65708
|
return this.isParentRow && this.nestingLevel > 0;
|
|
65578
65709
|
}
|
|
65710
|
+
/** @internal */
|
|
65711
|
+
get showSelectionCheckbox() {
|
|
65712
|
+
return this.selectable && !this.hideSelection;
|
|
65713
|
+
}
|
|
65579
65714
|
get ariaSelected() {
|
|
65580
65715
|
if (this.selectable) {
|
|
65581
65716
|
return this.selected ? 'true' : 'false';
|
|
@@ -65583,16 +65718,20 @@ img.ProseMirror-separator {
|
|
|
65583
65718
|
return null;
|
|
65584
65719
|
}
|
|
65585
65720
|
/** @internal */
|
|
65586
|
-
|
|
65721
|
+
onSelectionCheckboxChange(event) {
|
|
65587
65722
|
if (this.ignoreSelectionChangeEvents) {
|
|
65588
65723
|
return;
|
|
65589
65724
|
}
|
|
65590
65725
|
const checkbox = event.target;
|
|
65591
65726
|
const checked = checkbox.checked;
|
|
65592
|
-
this.
|
|
65727
|
+
this.onSelectionChange(!checked, checked);
|
|
65728
|
+
}
|
|
65729
|
+
/** @internal */
|
|
65730
|
+
onSelectionChange(oldState, newState) {
|
|
65731
|
+
this.selected = newState;
|
|
65593
65732
|
const detail = {
|
|
65594
|
-
oldState
|
|
65595
|
-
newState
|
|
65733
|
+
oldState,
|
|
65734
|
+
newState
|
|
65596
65735
|
};
|
|
65597
65736
|
this.$emit('row-selection-toggle', detail);
|
|
65598
65737
|
}
|
|
@@ -65623,6 +65762,20 @@ img.ProseMirror-separator {
|
|
|
65623
65762
|
this.updateCellStates();
|
|
65624
65763
|
}
|
|
65625
65764
|
}
|
|
65765
|
+
/** @internal */
|
|
65766
|
+
getFocusableElements() {
|
|
65767
|
+
return {
|
|
65768
|
+
selectionCheckbox: this.showSelectionCheckbox
|
|
65769
|
+
? this.selectionCheckbox
|
|
65770
|
+
: undefined,
|
|
65771
|
+
cells: Array.from(this.cellContainer.querySelectorAll(tableCellTag)).map(cell => ({
|
|
65772
|
+
cell,
|
|
65773
|
+
actionMenuButton: cell.hasActionMenu
|
|
65774
|
+
? cell.actionMenuButton
|
|
65775
|
+
: undefined
|
|
65776
|
+
}))
|
|
65777
|
+
};
|
|
65778
|
+
}
|
|
65626
65779
|
onRowExpandToggle(event) {
|
|
65627
65780
|
const expandEventDetail = {
|
|
65628
65781
|
oldState: this.expanded,
|
|
@@ -65630,7 +65783,7 @@ img.ProseMirror-separator {
|
|
|
65630
65783
|
recordId: this.recordId
|
|
65631
65784
|
};
|
|
65632
65785
|
this.$emit('row-expand-toggle', expandEventDetail);
|
|
65633
|
-
event
|
|
65786
|
+
event?.stopImmediatePropagation();
|
|
65634
65787
|
// To avoid a visual glitch with improper expand/collapse icons performing an
|
|
65635
65788
|
// animation (due to visual re-use apparently), we apply a class to the
|
|
65636
65789
|
// contained expand-collapse button temporarily. We use the 'transitionend' event
|
|
@@ -65742,6 +65895,9 @@ img.ProseMirror-separator {
|
|
|
65742
65895
|
__decorate$1([
|
|
65743
65896
|
observable
|
|
65744
65897
|
], TableRow.prototype, "nestingLevel", void 0);
|
|
65898
|
+
__decorate$1([
|
|
65899
|
+
observable
|
|
65900
|
+
], TableRow.prototype, "resolvedRowIndex", void 0);
|
|
65745
65901
|
__decorate$1([
|
|
65746
65902
|
attr({ attribute: 'is-parent-row', mode: 'boolean' })
|
|
65747
65903
|
], TableRow.prototype, "isParentRow", void 0);
|
|
@@ -65772,6 +65928,9 @@ img.ProseMirror-separator {
|
|
|
65772
65928
|
__decorate$1([
|
|
65773
65929
|
volatile
|
|
65774
65930
|
], TableRow.prototype, "isNestedParent", null);
|
|
65931
|
+
__decorate$1([
|
|
65932
|
+
volatile
|
|
65933
|
+
], TableRow.prototype, "showSelectionCheckbox", null);
|
|
65775
65934
|
__decorate$1([
|
|
65776
65935
|
volatile
|
|
65777
65936
|
], TableRow.prototype, "ariaSelected", null);
|
|
@@ -65822,6 +65981,11 @@ img.ProseMirror-separator {
|
|
|
65822
65981
|
background-color: ${fillHoverColor};
|
|
65823
65982
|
}
|
|
65824
65983
|
|
|
65984
|
+
:host(${focusVisible}) {
|
|
65985
|
+
outline: calc(2 * ${borderWidth}) solid ${borderHoverColor};
|
|
65986
|
+
outline-offset: calc(-2 * ${borderWidth});
|
|
65987
|
+
}
|
|
65988
|
+
|
|
65825
65989
|
.expand-collapse-button {
|
|
65826
65990
|
margin-left: calc(
|
|
65827
65991
|
${mediumPadding} + ${standardPadding} * 2 *
|
|
@@ -65882,7 +66046,7 @@ img.ProseMirror-separator {
|
|
|
65882
66046
|
<${checkboxTag}
|
|
65883
66047
|
${ref('selectionCheckbox')}
|
|
65884
66048
|
class="selection-checkbox"
|
|
65885
|
-
@change="${(x, c) => x.
|
|
66049
|
+
@change="${(x, c) => x.onSelectionCheckboxChange(c.event)}"
|
|
65886
66050
|
@click="${(_, c) => c.event.stopPropagation()}"
|
|
65887
66051
|
title="${x => tableGroupSelectAllLabel.getValueFor(x)}"
|
|
65888
66052
|
aria-label="${x => tableGroupSelectAllLabel.getValueFor(x)}"
|
|
@@ -65948,7 +66112,7 @@ img.ProseMirror-separator {
|
|
|
65948
66112
|
this.expandIcon.addEventListener('transitionend', this.removeAnimatingClass);
|
|
65949
66113
|
}
|
|
65950
66114
|
/** @internal */
|
|
65951
|
-
|
|
66115
|
+
onSelectionCheckboxChange(event) {
|
|
65952
66116
|
if (this.ignoreSelectionChangeEvents) {
|
|
65953
66117
|
return;
|
|
65954
66118
|
}
|
|
@@ -65963,6 +66127,15 @@ img.ProseMirror-separator {
|
|
|
65963
66127
|
};
|
|
65964
66128
|
this.$emit('group-selection-toggle', detail);
|
|
65965
66129
|
}
|
|
66130
|
+
/** @internal */
|
|
66131
|
+
getFocusableElements() {
|
|
66132
|
+
return {
|
|
66133
|
+
selectionCheckbox: this.selectable
|
|
66134
|
+
? this.selectionCheckbox
|
|
66135
|
+
: undefined,
|
|
66136
|
+
cells: []
|
|
66137
|
+
};
|
|
66138
|
+
}
|
|
65966
66139
|
selectionStateChanged() {
|
|
65967
66140
|
this.setSelectionCheckboxState();
|
|
65968
66141
|
}
|
|
@@ -65985,6 +66158,9 @@ img.ProseMirror-separator {
|
|
|
65985
66158
|
__decorate$1([
|
|
65986
66159
|
observable
|
|
65987
66160
|
], TableGroupRow.prototype, "nestingLevel", void 0);
|
|
66161
|
+
__decorate$1([
|
|
66162
|
+
observable
|
|
66163
|
+
], TableGroupRow.prototype, "resolvedRowIndex", void 0);
|
|
65988
66164
|
__decorate$1([
|
|
65989
66165
|
observable
|
|
65990
66166
|
], TableGroupRow.prototype, "immediateChildCount", void 0);
|
|
@@ -66018,6 +66194,8 @@ img.ProseMirror-separator {
|
|
|
66018
66194
|
const template$e = html `
|
|
66019
66195
|
<template
|
|
66020
66196
|
role="treegrid"
|
|
66197
|
+
${'' /* tabindex managed dynamically by KeyboardNavigationManager */}
|
|
66198
|
+
tabindex="0"
|
|
66021
66199
|
aria-multiselectable="${x => x.ariaMultiSelectable}"
|
|
66022
66200
|
${children$1({ property: 'childItems', filter: elements() })}
|
|
66023
66201
|
>
|
|
@@ -66045,6 +66223,8 @@ img.ProseMirror-separator {
|
|
|
66045
66223
|
<span class="checkbox-container">
|
|
66046
66224
|
<${checkboxTag}
|
|
66047
66225
|
${ref('selectionCheckbox')}
|
|
66226
|
+
${'' /* tabindex managed dynamically by KeyboardNavigationManager */}
|
|
66227
|
+
tabindex="-1"
|
|
66048
66228
|
class="${x => `selection-checkbox ${x.selectionMode ? x.selectionMode : ''}`}"
|
|
66049
66229
|
@change="${(x, c) => x.onAllRowsSelectionChange(c.event)}"
|
|
66050
66230
|
title="${x => tableSelectAllLabel.getValueFor(x)}"
|
|
@@ -66054,6 +66234,9 @@ img.ProseMirror-separator {
|
|
|
66054
66234
|
</span>
|
|
66055
66235
|
`)}
|
|
66056
66236
|
<${buttonTag}
|
|
66237
|
+
${ref('collapseAllButton')}
|
|
66238
|
+
${'' /* tabindex managed dynamically by KeyboardNavigationManager */}
|
|
66239
|
+
tabindex="-1"
|
|
66057
66240
|
class="collapse-all-button ${x => `${x.showCollapseAll ? 'visible' : ''}`}"
|
|
66058
66241
|
content-hidden
|
|
66059
66242
|
appearance="${ButtonAppearance.ghost}"
|
|
@@ -66081,9 +66264,11 @@ img.ProseMirror-separator {
|
|
|
66081
66264
|
`)}
|
|
66082
66265
|
<${tableHeaderTag}
|
|
66083
66266
|
class="header"
|
|
66267
|
+
${'' /* tabindex managed dynamically by KeyboardNavigationManager (if column sorting not disabled) */}
|
|
66084
66268
|
sort-direction="${x => (typeof x.columnInternals.currentSortIndex === 'number' ? x.columnInternals.currentSortDirection : TableColumnSortDirection.none)}"
|
|
66085
66269
|
?first-sorted-column="${(x, c) => x === c.parent.firstSortedColumn}"
|
|
66086
66270
|
?indicators-hidden="${x => x.columnInternals.hideHeaderIndicators}"
|
|
66271
|
+
@keydown="${(x, c) => c.parent.onHeaderKeyDown(x, c.event)}"
|
|
66087
66272
|
@click="${(x, c) => c.parent.toggleColumnSort(x, c.event.shiftKey)}"
|
|
66088
66273
|
:isGrouped=${x => (typeof x.columnInternals.groupIndex === 'number' && !x.columnInternals.groupingDisabled)}
|
|
66089
66274
|
>
|
|
@@ -66107,15 +66292,17 @@ img.ProseMirror-separator {
|
|
|
66107
66292
|
</span>
|
|
66108
66293
|
</div>
|
|
66109
66294
|
</div>
|
|
66110
|
-
<div class="table-viewport" ${ref('viewport')}>
|
|
66295
|
+
<div class="table-viewport" tabindex="-1" ${ref('viewport')}>
|
|
66111
66296
|
<div class="table-scroll"></div>
|
|
66112
|
-
<div class="table-row-container" ${children$1({ property: 'rowElements', filter: elements(tableRowTag) })}
|
|
66297
|
+
<div class="table-row-container ${x => `${x.showCollapseAll ? 'collapse-all-visible' : ''}`}" ${children$1({ property: 'rowElements', filter: elements(`${tableRowTag}, ${tableGroupRowTag}`) })}
|
|
66113
66298
|
role="rowgroup">
|
|
66114
66299
|
${when(x => x.columns.length > 0 && x.canRenderRows, html `
|
|
66115
66300
|
${repeat(x => x.virtualizer.visibleItems, html `
|
|
66116
66301
|
${when((x, c) => c.parent.tableData[x.index]?.isGroupRow, html `
|
|
66117
66302
|
<${tableGroupRowTag}
|
|
66118
66303
|
class="group-row"
|
|
66304
|
+
${'' /* tabindex managed dynamically by KeyboardNavigationManager */}
|
|
66305
|
+
tabindex="-1"
|
|
66119
66306
|
:groupRowValue="${(x, c) => c.parent.tableData[x.index]?.groupRowValue}"
|
|
66120
66307
|
?expanded="${(x, c) => c.parent.tableData[x.index]?.isExpanded}"
|
|
66121
66308
|
:nestingLevel="${(x, c) => c.parent.tableData[x.index]?.nestingLevel}"
|
|
@@ -66123,6 +66310,9 @@ img.ProseMirror-separator {
|
|
|
66123
66310
|
:groupColumn="${(x, c) => c.parent.tableData[x.index]?.groupColumn}"
|
|
66124
66311
|
?selectable="${(_, c) => c.parent.selectionMode === TableRowSelectionMode.multiple}"
|
|
66125
66312
|
selection-state="${(x, c) => c.parent.tableData[x.index]?.selectionState}"
|
|
66313
|
+
:resolvedRowIndex="${x => x.index}"
|
|
66314
|
+
@focusin="${(_, c) => c.parent.onRowFocusIn(c.event)}"
|
|
66315
|
+
@blur="${(_, c) => c.parent.onRowBlur(c.event)}"
|
|
66126
66316
|
@group-selection-toggle="${(x, c) => c.parent.onRowSelectionToggle(x.index, c.event)}"
|
|
66127
66317
|
@group-expand-toggle="${(x, c) => c.parent.handleGroupRowExpanded(x.index, c.event)}"
|
|
66128
66318
|
>
|
|
@@ -66131,6 +66321,8 @@ img.ProseMirror-separator {
|
|
|
66131
66321
|
${when((x, c) => !c.parent.tableData[x.index]?.isGroupRow, html `
|
|
66132
66322
|
<${tableRowTag}
|
|
66133
66323
|
class="row"
|
|
66324
|
+
${'' /* tabindex managed dynamically by KeyboardNavigationManager */}
|
|
66325
|
+
tabindex="-1"
|
|
66134
66326
|
record-id="${(x, c) => c.parent.tableData[x.index]?.id}"
|
|
66135
66327
|
?selectable="${(_, c) => c.parent.selectionMode !== TableRowSelectionMode.none}"
|
|
66136
66328
|
?selected="${(x, c) => c.parent.tableData[x.index]?.selectionState === TableRowSelectionState.selected}"
|
|
@@ -66142,12 +66334,14 @@ img.ProseMirror-separator {
|
|
|
66142
66334
|
:nestingLevel="${(x, c) => c.parent.tableData[x.index]?.nestingLevel}"
|
|
66143
66335
|
?row-operation-grid-cell-hidden="${(_, c) => !c.parent.showRowOperationColumn}"
|
|
66144
66336
|
?loading="${(x, c) => c.parent.tableData[x.index]?.isLoadingChildren}"
|
|
66337
|
+
:resolvedRowIndex="${x => x.index}"
|
|
66145
66338
|
@click="${(x, c) => c.parent.onRowClick(x.index, c.event)}"
|
|
66339
|
+
@focusin="${(_, c) => c.parent.onRowFocusIn(c.event)}"
|
|
66340
|
+
@blur="${(_, c) => c.parent.onRowBlur(c.event)}"
|
|
66146
66341
|
@row-selection-toggle="${(x, c) => c.parent.onRowSelectionToggle(x.index, c.event)}"
|
|
66147
66342
|
@row-action-menu-beforetoggle="${(x, c) => c.parent.onRowActionMenuBeforeToggle(x.index, c.event)}"
|
|
66148
66343
|
@row-action-menu-toggle="${(_, c) => c.parent.onRowActionMenuToggle(c.event)}"
|
|
66149
66344
|
@row-expand-toggle="${(x, c) => c.parent.handleRowExpanded(x.index)}"
|
|
66150
|
-
:dataIndex="${x => x.index}"
|
|
66151
66345
|
>
|
|
66152
66346
|
${when((x, c) => c.parent.openActionMenuRecordId === c.parent.tableData[x.index]?.id, html `
|
|
66153
66347
|
${repeat((_, c) => c.parent.actionMenuSlots, html `
|
|
@@ -66812,16 +67006,25 @@ img.ProseMirror-separator {
|
|
|
66812
67006
|
* @internal
|
|
66813
67007
|
*/
|
|
66814
67008
|
class Virtualizer {
|
|
67009
|
+
get pageSize() {
|
|
67010
|
+
return this._pageSize;
|
|
67011
|
+
}
|
|
67012
|
+
get rowHeight() {
|
|
67013
|
+
return (parseFloat(controlHeight.getValueFor(this.table))
|
|
67014
|
+
+ 2 * parseFloat(borderWidth.getValueFor(this.table)));
|
|
67015
|
+
}
|
|
66815
67016
|
constructor(table, tanStackTable) {
|
|
66816
67017
|
this.visibleItems = [];
|
|
66817
67018
|
this.scrollHeight = 0;
|
|
66818
67019
|
this.headerContainerMarginRight = 0;
|
|
66819
67020
|
this.rowContainerYOffset = 0;
|
|
67021
|
+
this._pageSize = 0;
|
|
66820
67022
|
this.table = table;
|
|
66821
67023
|
this.tanStackTable = tanStackTable;
|
|
66822
67024
|
this.viewportResizeObserver = new ResizeObserver(entries => {
|
|
66823
67025
|
const borderBoxSize = entries[0]?.borderBoxSize[0];
|
|
66824
67026
|
if (borderBoxSize) {
|
|
67027
|
+
this.updatePageSize();
|
|
66825
67028
|
// If we have enough rows that a vertical scrollbar is shown, we need to offset the header widths
|
|
66826
67029
|
// by the same margin so the column headers align with the corresponding rendered cells
|
|
66827
67030
|
const viewportBoundingWidth = borderBoxSize.inlineSize;
|
|
@@ -66842,6 +67045,9 @@ img.ProseMirror-separator {
|
|
|
66842
67045
|
this.updateVirtualizer();
|
|
66843
67046
|
}
|
|
66844
67047
|
}
|
|
67048
|
+
scrollToIndex(index, options) {
|
|
67049
|
+
this.virtualizer?.scrollToIndex(index, options);
|
|
67050
|
+
}
|
|
66845
67051
|
updateVirtualizer() {
|
|
66846
67052
|
const options = this.createVirtualizerOptions();
|
|
66847
67053
|
if (this.virtualizer) {
|
|
@@ -66854,8 +67060,7 @@ img.ProseMirror-separator {
|
|
|
66854
67060
|
this.handleVirtualizerChange();
|
|
66855
67061
|
}
|
|
66856
67062
|
createVirtualizerOptions() {
|
|
66857
|
-
const rowHeight =
|
|
66858
|
-
+ 2 * parseFloat(borderWidth.getValueFor(this.table));
|
|
67063
|
+
const rowHeight = this.rowHeight;
|
|
66859
67064
|
return {
|
|
66860
67065
|
count: this.tanStackTable.getRowModel().rows.length,
|
|
66861
67066
|
getScrollElement: () => {
|
|
@@ -66872,7 +67077,7 @@ img.ProseMirror-separator {
|
|
|
66872
67077
|
};
|
|
66873
67078
|
}
|
|
66874
67079
|
handleVirtualizerChange() {
|
|
66875
|
-
this.
|
|
67080
|
+
this.table.handleFocusedCellRecycling();
|
|
66876
67081
|
const virtualizer = this.virtualizer;
|
|
66877
67082
|
this.visibleItems = virtualizer.getVirtualItems();
|
|
66878
67083
|
this.scrollHeight = virtualizer.getTotalSize();
|
|
@@ -66887,24 +67092,8 @@ img.ProseMirror-separator {
|
|
|
66887
67092
|
}
|
|
66888
67093
|
this.rowContainerYOffset = rowContainerYOffset;
|
|
66889
67094
|
}
|
|
66890
|
-
|
|
66891
|
-
|
|
66892
|
-
while (tableFocusedElement !== null
|
|
66893
|
-
&& !(tableFocusedElement instanceof TableCellView)) {
|
|
66894
|
-
if (tableFocusedElement.shadowRoot) {
|
|
66895
|
-
tableFocusedElement = tableFocusedElement.shadowRoot.activeElement;
|
|
66896
|
-
}
|
|
66897
|
-
else {
|
|
66898
|
-
break;
|
|
66899
|
-
}
|
|
66900
|
-
}
|
|
66901
|
-
if (tableFocusedElement instanceof TableCellView) {
|
|
66902
|
-
tableFocusedElement.focusedRecycleCallback();
|
|
66903
|
-
}
|
|
66904
|
-
if (this.table.openActionMenuRecordId !== undefined) {
|
|
66905
|
-
const activeRow = this.table.rowElements.find(row => row.recordId === this.table.openActionMenuRecordId);
|
|
66906
|
-
activeRow?.closeOpenActionMenus();
|
|
66907
|
-
}
|
|
67095
|
+
updatePageSize() {
|
|
67096
|
+
this._pageSize = Math.round(this.table.viewport.clientHeight / this.rowHeight);
|
|
66908
67097
|
}
|
|
66909
67098
|
}
|
|
66910
67099
|
__decorate$1([
|
|
@@ -67264,7 +67453,9 @@ img.ProseMirror-separator {
|
|
|
67264
67453
|
'rowParentIds',
|
|
67265
67454
|
'groupRows',
|
|
67266
67455
|
'columnIds',
|
|
67456
|
+
'columnHidden',
|
|
67267
67457
|
'columnSort',
|
|
67458
|
+
'columnSortDisabled',
|
|
67268
67459
|
'columnWidths',
|
|
67269
67460
|
'columnDefinition',
|
|
67270
67461
|
'actionMenuSlots',
|
|
@@ -67320,6 +67511,13 @@ img.ProseMirror-separator {
|
|
|
67320
67511
|
|| this.isTracked('columnDefinition')
|
|
67321
67512
|
|| this.isTracked('rowParentIds'));
|
|
67322
67513
|
}
|
|
67514
|
+
get requiresKeyboardFocusReset() {
|
|
67515
|
+
return (this.isTracked('columnSortDisabled')
|
|
67516
|
+
|| this.isTracked('columnDefinition')
|
|
67517
|
+
|| this.isTracked('columnHidden')
|
|
67518
|
+
|| this.isTracked('selectionMode')
|
|
67519
|
+
|| this.isTracked('actionMenuSlots'));
|
|
67520
|
+
}
|
|
67323
67521
|
trackAllStateChanged() {
|
|
67324
67522
|
this.trackAll();
|
|
67325
67523
|
this.queueUpdate();
|
|
@@ -67334,13 +67532,20 @@ img.ProseMirror-separator {
|
|
|
67334
67532
|
else if (isColumnInternalsProperty(changedColumnProperty, 'operandDataRecordFieldName', 'sortOperation')) {
|
|
67335
67533
|
this.track('columnDefinition');
|
|
67336
67534
|
}
|
|
67337
|
-
else if (isColumnInternalsProperty(changedColumnProperty, 'sortingDisabled'
|
|
67535
|
+
else if (isColumnInternalsProperty(changedColumnProperty, 'sortingDisabled')) {
|
|
67536
|
+
this.track('columnSort');
|
|
67537
|
+
this.track('columnSortDisabled');
|
|
67538
|
+
}
|
|
67539
|
+
else if (isColumnInternalsProperty(changedColumnProperty, 'currentSortDirection', 'currentSortIndex')) {
|
|
67338
67540
|
this.track('columnSort');
|
|
67339
67541
|
}
|
|
67340
|
-
else if (
|
|
67341
|
-
|| isColumnInternalsProperty(changedColumnProperty, 'currentFractionalWidth', 'currentPixelWidth', 'minPixelWidth', 'resizingDisabled')) {
|
|
67542
|
+
else if (isColumnInternalsProperty(changedColumnProperty, 'currentFractionalWidth', 'currentPixelWidth', 'minPixelWidth', 'resizingDisabled')) {
|
|
67342
67543
|
this.track('columnWidths');
|
|
67343
67544
|
}
|
|
67545
|
+
else if (isColumnProperty(changedColumnProperty, 'columnHidden')) {
|
|
67546
|
+
this.track('columnWidths');
|
|
67547
|
+
this.track('columnHidden');
|
|
67548
|
+
}
|
|
67344
67549
|
else if (isColumnProperty(changedColumnProperty, 'actionMenuSlot')) {
|
|
67345
67550
|
this.track('actionMenuSlots');
|
|
67346
67551
|
}
|
|
@@ -67353,6 +67558,7 @@ img.ProseMirror-separator {
|
|
|
67353
67558
|
this.track('columnIds');
|
|
67354
67559
|
this.track('columnDefinition');
|
|
67355
67560
|
this.track('columnSort');
|
|
67561
|
+
this.track('columnSortDisabled');
|
|
67356
67562
|
this.track('columnWidths');
|
|
67357
67563
|
this.track('actionMenuSlots');
|
|
67358
67564
|
this.track('groupRows');
|
|
@@ -67982,6 +68188,992 @@ img.ProseMirror-separator {
|
|
|
67982
68188
|
observable
|
|
67983
68189
|
], ColumnValidator.prototype, "isColumnValid", void 0);
|
|
67984
68190
|
|
|
68191
|
+
/**
|
|
68192
|
+
* Manages the keyboard navigation and focus within the table.
|
|
68193
|
+
* @internal
|
|
68194
|
+
*/
|
|
68195
|
+
class KeyboardNavigationManager {
|
|
68196
|
+
get inNavigationMode() {
|
|
68197
|
+
return (this.focusType !== TableFocusType.cellActionMenu
|
|
68198
|
+
&& this.focusType !== TableFocusType.cellContent);
|
|
68199
|
+
}
|
|
68200
|
+
constructor(table, virtualizer) {
|
|
68201
|
+
this.table = table;
|
|
68202
|
+
this.virtualizer = virtualizer;
|
|
68203
|
+
this.focusType = TableFocusType.none;
|
|
68204
|
+
this.headerActionIndex = -1;
|
|
68205
|
+
this.rowIndex = -1;
|
|
68206
|
+
this.cellContentIndex = -1;
|
|
68207
|
+
this.columnIndex = -1;
|
|
68208
|
+
this.focusWithinTable = false;
|
|
68209
|
+
this.isCurrentlyFocusingElement = false;
|
|
68210
|
+
this.visibleRowNotifiers = [];
|
|
68211
|
+
this.onTableFocusIn = (event) => {
|
|
68212
|
+
this.focusWithinTable = true;
|
|
68213
|
+
this.updateFocusStateFromActiveElement(false);
|
|
68214
|
+
// Sets initial focus on the appropriate table content
|
|
68215
|
+
const actionMenuOpen = this.table.openActionMenuRecordId !== undefined;
|
|
68216
|
+
if ((event.target === this.table
|
|
68217
|
+
|| this.focusType === TableFocusType.none)
|
|
68218
|
+
&& !actionMenuOpen) {
|
|
68219
|
+
let focusHeader = true;
|
|
68220
|
+
if (this.hasRowOrCellFocusType()
|
|
68221
|
+
&& this.scrollToAndFocusRow(this.rowIndex)) {
|
|
68222
|
+
focusHeader = false;
|
|
68223
|
+
}
|
|
68224
|
+
if (focusHeader && !this.setFocusOnHeader()) {
|
|
68225
|
+
// nothing to focus
|
|
68226
|
+
this.table.blur();
|
|
68227
|
+
}
|
|
68228
|
+
}
|
|
68229
|
+
};
|
|
68230
|
+
this.onTableFocusOut = () => {
|
|
68231
|
+
this.focusWithinTable = false;
|
|
68232
|
+
};
|
|
68233
|
+
this.onCellActionMenuBlur = (event) => {
|
|
68234
|
+
event.stopPropagation();
|
|
68235
|
+
const cell = event.detail;
|
|
68236
|
+
if (cell.actionMenuButton) {
|
|
68237
|
+
// Ensure that action menu buttons get hidden when no longer focused
|
|
68238
|
+
this.setActionMenuButtonFocused(cell.actionMenuButton, false);
|
|
68239
|
+
}
|
|
68240
|
+
};
|
|
68241
|
+
this.onCellViewFocusIn = (event) => {
|
|
68242
|
+
event.stopPropagation();
|
|
68243
|
+
this.updateFocusStateFromActiveElement(false);
|
|
68244
|
+
};
|
|
68245
|
+
this.onCellFocusIn = (event) => {
|
|
68246
|
+
event.stopPropagation();
|
|
68247
|
+
const cell = event.detail;
|
|
68248
|
+
this.updateFocusStateFromActiveElement(true);
|
|
68249
|
+
// Currently, clicking a non-interactive cell only updates the focus state to that row, it
|
|
68250
|
+
// doesn't focus the cell. If we revisit this, we most likely need to set the cells to tabindex=-1
|
|
68251
|
+
// upfront too, so their focusing behavior is consistent whether they've been previously keyboard
|
|
68252
|
+
// focused or not.
|
|
68253
|
+
if (this.focusType === TableFocusType.row
|
|
68254
|
+
&& this.getActiveElement() === cell) {
|
|
68255
|
+
this.focusCurrentRow(false);
|
|
68256
|
+
}
|
|
68257
|
+
};
|
|
68258
|
+
this.onCellBlur = (event) => {
|
|
68259
|
+
event.stopPropagation();
|
|
68260
|
+
const cell = event.detail;
|
|
68261
|
+
this.setElementFocusable(cell, false);
|
|
68262
|
+
};
|
|
68263
|
+
this.onCaptureKeyDown = (event) => {
|
|
68264
|
+
let handled = false;
|
|
68265
|
+
if (event.key === keyTab) {
|
|
68266
|
+
handled = this.onTabPressed(event.shiftKey);
|
|
68267
|
+
}
|
|
68268
|
+
else if (this.inNavigationMode) {
|
|
68269
|
+
switch (event.key) {
|
|
68270
|
+
case keyArrowLeft:
|
|
68271
|
+
handled = this.onLeftArrowPressed();
|
|
68272
|
+
break;
|
|
68273
|
+
case keyArrowRight:
|
|
68274
|
+
handled = this.onRightArrowPressed();
|
|
68275
|
+
break;
|
|
68276
|
+
case keyArrowUp:
|
|
68277
|
+
handled = this.onUpArrowPressed();
|
|
68278
|
+
break;
|
|
68279
|
+
case keyArrowDown:
|
|
68280
|
+
handled = this.onDownArrowPressed();
|
|
68281
|
+
break;
|
|
68282
|
+
case keyPageUp:
|
|
68283
|
+
handled = this.onPageUpPressed();
|
|
68284
|
+
break;
|
|
68285
|
+
case keyPageDown:
|
|
68286
|
+
handled = this.onPageDownPressed();
|
|
68287
|
+
break;
|
|
68288
|
+
case keyHome:
|
|
68289
|
+
handled = this.onHomePressed(event.ctrlKey);
|
|
68290
|
+
break;
|
|
68291
|
+
case keyEnd:
|
|
68292
|
+
handled = this.onEndPressed(event.ctrlKey);
|
|
68293
|
+
break;
|
|
68294
|
+
case keyEnter:
|
|
68295
|
+
handled = this.onEnterPressed(event.ctrlKey);
|
|
68296
|
+
break;
|
|
68297
|
+
case keySpace:
|
|
68298
|
+
handled = this.onSpacePressed(event.shiftKey);
|
|
68299
|
+
break;
|
|
68300
|
+
case keyFunction2:
|
|
68301
|
+
handled = this.onF2Pressed();
|
|
68302
|
+
break;
|
|
68303
|
+
}
|
|
68304
|
+
}
|
|
68305
|
+
if (handled) {
|
|
68306
|
+
event.preventDefault();
|
|
68307
|
+
}
|
|
68308
|
+
};
|
|
68309
|
+
this.onKeyDown = (event) => {
|
|
68310
|
+
if (!this.inNavigationMode && !event.defaultPrevented) {
|
|
68311
|
+
if (event.key === keyEscape || event.key === keyFunction2) {
|
|
68312
|
+
const row = this.getCurrentRow();
|
|
68313
|
+
if (row) {
|
|
68314
|
+
this.trySetCellFocus(row.getFocusableElements());
|
|
68315
|
+
}
|
|
68316
|
+
}
|
|
68317
|
+
}
|
|
68318
|
+
};
|
|
68319
|
+
this.onViewportKeyDown = (event) => {
|
|
68320
|
+
let handleEvent = !this.inNavigationMode
|
|
68321
|
+
&& (event.key === keyArrowUp || event.key === keyArrowDown);
|
|
68322
|
+
switch (event.key) {
|
|
68323
|
+
case keyPageUp:
|
|
68324
|
+
case keyPageDown:
|
|
68325
|
+
case keyHome:
|
|
68326
|
+
case keyEnd:
|
|
68327
|
+
handleEvent = true;
|
|
68328
|
+
break;
|
|
68329
|
+
}
|
|
68330
|
+
if (handleEvent) {
|
|
68331
|
+
// Swallow key presses that would cause table scrolling, independently of keyboard navigation
|
|
68332
|
+
event.preventDefault();
|
|
68333
|
+
event.stopImmediatePropagation();
|
|
68334
|
+
}
|
|
68335
|
+
};
|
|
68336
|
+
this.tableNotifier = Observable.getNotifier(this.table);
|
|
68337
|
+
this.tableNotifier.subscribe(this, 'rowElements');
|
|
68338
|
+
this.virtualizerNotifier = Observable.getNotifier(this.virtualizer);
|
|
68339
|
+
this.virtualizerNotifier.subscribe(this, 'visibleItems');
|
|
68340
|
+
}
|
|
68341
|
+
resetFocusState() {
|
|
68342
|
+
this.focusType = TableFocusType.none;
|
|
68343
|
+
const activeElement = this.getActiveElement();
|
|
68344
|
+
if (activeElement && this.isInTable(activeElement)) {
|
|
68345
|
+
this.setDefaultFocus();
|
|
68346
|
+
}
|
|
68347
|
+
}
|
|
68348
|
+
get hasActiveRowOrCellFocus() {
|
|
68349
|
+
return this.focusWithinTable && this.hasRowOrCellFocusType();
|
|
68350
|
+
}
|
|
68351
|
+
connect() {
|
|
68352
|
+
this.table.addEventListener('keydown', this.onCaptureKeyDown, { capture: true });
|
|
68353
|
+
this.table.addEventListener('keydown', this.onKeyDown);
|
|
68354
|
+
this.table.addEventListener('focusin', this.onTableFocusIn);
|
|
68355
|
+
this.table.addEventListener('focusout', this.onTableFocusOut);
|
|
68356
|
+
this.table.viewport.addEventListener('keydown', this.onViewportKeyDown);
|
|
68357
|
+
this.table.viewport.addEventListener('cell-action-menu-blur', this.onCellActionMenuBlur);
|
|
68358
|
+
this.table.viewport.addEventListener('cell-view-focus-in', this.onCellViewFocusIn);
|
|
68359
|
+
this.table.viewport.addEventListener('cell-focus-in', this.onCellFocusIn);
|
|
68360
|
+
this.table.viewport.addEventListener('cell-blur', this.onCellBlur);
|
|
68361
|
+
}
|
|
68362
|
+
disconnect() {
|
|
68363
|
+
this.table.removeEventListener('keydown', this.onCaptureKeyDown, { capture: true });
|
|
68364
|
+
this.table.removeEventListener('keydown', this.onKeyDown);
|
|
68365
|
+
this.table.removeEventListener('focusin', this.onTableFocusIn);
|
|
68366
|
+
this.table.removeEventListener('focusout', this.onTableFocusOut);
|
|
68367
|
+
this.table.viewport.removeEventListener('keydown', this.onViewportKeyDown);
|
|
68368
|
+
this.table.viewport.removeEventListener('cell-action-menu-blur', this.onCellActionMenuBlur);
|
|
68369
|
+
this.table.viewport.removeEventListener('cell-view-focus-in', this.onCellViewFocusIn);
|
|
68370
|
+
this.table.viewport.removeEventListener('cell-focus-in', this.onCellFocusIn);
|
|
68371
|
+
this.table.viewport.removeEventListener('cell-blur', this.onCellBlur);
|
|
68372
|
+
}
|
|
68373
|
+
handleChange(source, args) {
|
|
68374
|
+
let focusRowAndCell = false;
|
|
68375
|
+
if (source === this.virtualizer && args === 'visibleItems') {
|
|
68376
|
+
focusRowAndCell = true;
|
|
68377
|
+
}
|
|
68378
|
+
else if (source === this.table && args === 'rowElements') {
|
|
68379
|
+
for (const notifier of this.visibleRowNotifiers) {
|
|
68380
|
+
notifier.unsubscribe(this);
|
|
68381
|
+
}
|
|
68382
|
+
this.visibleRowNotifiers = [];
|
|
68383
|
+
for (const visibleRow of this.table.rowElements) {
|
|
68384
|
+
const rowNotifier = Observable.getNotifier(visibleRow);
|
|
68385
|
+
rowNotifier.subscribe(this, 'resolvedRowIndex');
|
|
68386
|
+
if (visibleRow.resolvedRowIndex === this.rowIndex) {
|
|
68387
|
+
focusRowAndCell = true;
|
|
68388
|
+
}
|
|
68389
|
+
}
|
|
68390
|
+
}
|
|
68391
|
+
else if (args === 'resolvedRowIndex'
|
|
68392
|
+
&& this.isResolvedRowType(source)) {
|
|
68393
|
+
if (source.resolvedRowIndex === this.rowIndex) {
|
|
68394
|
+
focusRowAndCell = true;
|
|
68395
|
+
}
|
|
68396
|
+
}
|
|
68397
|
+
if (focusRowAndCell) {
|
|
68398
|
+
// Focusable elements in cells, and action menus, are both blurred on scroll. To maintain our row/cell focus state,
|
|
68399
|
+
// we focus the cell instead here. (We also don't want to refocus the cell content when the focusedRecycleCallback just
|
|
68400
|
+
// blurred it.)
|
|
68401
|
+
if (this.focusType === TableFocusType.cellActionMenu
|
|
68402
|
+
|| this.focusType === TableFocusType.cellContent) {
|
|
68403
|
+
this.setCellFocusState(this.columnIndex, this.rowIndex, false);
|
|
68404
|
+
}
|
|
68405
|
+
if (this.inNavigationMode && this.hasRowOrCellFocusType()) {
|
|
68406
|
+
if (this.rowIndex > this.table.tableData.length - 1) {
|
|
68407
|
+
// Focused row index no longer valid, coerce to 1st row if possible
|
|
68408
|
+
if (this.table.tableData.length > 0) {
|
|
68409
|
+
this.rowIndex = 0;
|
|
68410
|
+
}
|
|
68411
|
+
else {
|
|
68412
|
+
if (this.focusWithinTable) {
|
|
68413
|
+
this.setDefaultFocus();
|
|
68414
|
+
}
|
|
68415
|
+
else {
|
|
68416
|
+
this.focusType = TableFocusType.none;
|
|
68417
|
+
}
|
|
68418
|
+
return;
|
|
68419
|
+
}
|
|
68420
|
+
}
|
|
68421
|
+
if (this.focusWithinTable) {
|
|
68422
|
+
this.focusCurrentRow(false);
|
|
68423
|
+
}
|
|
68424
|
+
}
|
|
68425
|
+
}
|
|
68426
|
+
}
|
|
68427
|
+
handleFocusedCellRecycling(hadRowOrCellFocus) {
|
|
68428
|
+
if (hadRowOrCellFocus && !this.focusWithinTable) {
|
|
68429
|
+
this.focusCurrentRow(false);
|
|
68430
|
+
}
|
|
68431
|
+
}
|
|
68432
|
+
onRowFocusIn(event) {
|
|
68433
|
+
if (this.isCurrentlyFocusingElement) {
|
|
68434
|
+
return;
|
|
68435
|
+
}
|
|
68436
|
+
const row = event.target;
|
|
68437
|
+
if (this.isResolvedRowType(row)) {
|
|
68438
|
+
if (this.rowIndex !== row.resolvedRowIndex) {
|
|
68439
|
+
// If user focuses a row some other way (e.g. mouse), update our focus state so future keyboard nav
|
|
68440
|
+
// will start from that row
|
|
68441
|
+
this.setRowFocusState(row.resolvedRowIndex);
|
|
68442
|
+
}
|
|
68443
|
+
}
|
|
68444
|
+
}
|
|
68445
|
+
onRowBlur(event) {
|
|
68446
|
+
const row = event.target;
|
|
68447
|
+
if (this.isResolvedRowType(row)) {
|
|
68448
|
+
this.setElementFocusable(row, false);
|
|
68449
|
+
}
|
|
68450
|
+
}
|
|
68451
|
+
onRowActionMenuToggle(event) {
|
|
68452
|
+
const isOpen = event.detail.newState;
|
|
68453
|
+
if (isOpen) {
|
|
68454
|
+
const row = event.target;
|
|
68455
|
+
const columnIndex = this.table.visibleColumns.findIndex(column => column.columnId === event.detail.columnId);
|
|
68456
|
+
this.setCellActionMenuFocusState(row.resolvedRowIndex, columnIndex, false);
|
|
68457
|
+
}
|
|
68458
|
+
}
|
|
68459
|
+
onEnterPressed(ctrlKey) {
|
|
68460
|
+
let row;
|
|
68461
|
+
let rowElements;
|
|
68462
|
+
if (this.hasRowOrCellFocusType()) {
|
|
68463
|
+
row = this.getCurrentRow();
|
|
68464
|
+
rowElements = row?.getFocusableElements();
|
|
68465
|
+
}
|
|
68466
|
+
if (this.focusType === TableFocusType.row) {
|
|
68467
|
+
if (row instanceof TableGroupRow) {
|
|
68468
|
+
this.toggleRowExpanded(row);
|
|
68469
|
+
return true;
|
|
68470
|
+
}
|
|
68471
|
+
}
|
|
68472
|
+
if (this.focusType === TableFocusType.cell) {
|
|
68473
|
+
if (ctrlKey) {
|
|
68474
|
+
const cell = rowElements?.cells[this.columnIndex];
|
|
68475
|
+
if (cell?.actionMenuButton && !cell.actionMenuButton.open) {
|
|
68476
|
+
cell.actionMenuButton.toggleButton.control.click();
|
|
68477
|
+
return true;
|
|
68478
|
+
}
|
|
68479
|
+
}
|
|
68480
|
+
return this.focusFirstInteractiveElementInCurrentCell(rowElements);
|
|
68481
|
+
}
|
|
68482
|
+
return false;
|
|
68483
|
+
}
|
|
68484
|
+
onF2Pressed() {
|
|
68485
|
+
if (this.focusType === TableFocusType.cell) {
|
|
68486
|
+
const row = this.getCurrentRow();
|
|
68487
|
+
const rowElements = row?.getFocusableElements();
|
|
68488
|
+
return this.focusFirstInteractiveElementInCurrentCell(rowElements);
|
|
68489
|
+
}
|
|
68490
|
+
return false;
|
|
68491
|
+
}
|
|
68492
|
+
onSpacePressed(shiftKey) {
|
|
68493
|
+
if (this.focusType === TableFocusType.row
|
|
68494
|
+
|| this.focusType === TableFocusType.cell) {
|
|
68495
|
+
if (this.focusType === TableFocusType.row || shiftKey) {
|
|
68496
|
+
const row = this.getCurrentRow();
|
|
68497
|
+
if (row instanceof TableRow && row.selectable) {
|
|
68498
|
+
row.onSelectionChange(row.selected, !row.selected);
|
|
68499
|
+
}
|
|
68500
|
+
else if (row instanceof TableGroupRow) {
|
|
68501
|
+
this.toggleRowExpanded(row);
|
|
68502
|
+
}
|
|
68503
|
+
}
|
|
68504
|
+
// Default Space behavior scrolls down, which is redundant given the rest of our keyboard nav code, and we'd still try to focus a
|
|
68505
|
+
// row that you scrolled away from. So suppress default Space behavior if a row or cell is selected, regardless of if we're
|
|
68506
|
+
// toggling selection or not.
|
|
68507
|
+
return true;
|
|
68508
|
+
}
|
|
68509
|
+
return false;
|
|
68510
|
+
}
|
|
68511
|
+
onLeftArrowPressed() {
|
|
68512
|
+
let row;
|
|
68513
|
+
let rowElements;
|
|
68514
|
+
let headerElements;
|
|
68515
|
+
if (this.hasRowOrCellFocusType()) {
|
|
68516
|
+
row = this.getCurrentRow();
|
|
68517
|
+
rowElements = row?.getFocusableElements();
|
|
68518
|
+
}
|
|
68519
|
+
else if (this.hasHeaderFocusType()) {
|
|
68520
|
+
headerElements = this.getTableHeaderFocusableElements();
|
|
68521
|
+
}
|
|
68522
|
+
switch (this.focusType) {
|
|
68523
|
+
case TableFocusType.headerActions:
|
|
68524
|
+
return this.trySetHeaderActionFocus(headerElements, this.headerActionIndex - 1);
|
|
68525
|
+
case TableFocusType.columnHeader:
|
|
68526
|
+
return (this.trySetColumnHeaderFocus(headerElements, this.columnIndex - 1)
|
|
68527
|
+
|| this.trySetHeaderActionFocus(headerElements, headerElements.headerActions.length - 1));
|
|
68528
|
+
case TableFocusType.row:
|
|
68529
|
+
if (this.isRowExpanded(row) === true) {
|
|
68530
|
+
this.toggleRowExpanded(row);
|
|
68531
|
+
return true;
|
|
68532
|
+
}
|
|
68533
|
+
return false;
|
|
68534
|
+
case TableFocusType.rowSelectionCheckbox:
|
|
68535
|
+
this.setRowFocusState();
|
|
68536
|
+
return this.focusCurrentRow(true);
|
|
68537
|
+
case TableFocusType.cell:
|
|
68538
|
+
if (!this.trySetCellFocus(rowElements, this.columnIndex - 1)
|
|
68539
|
+
&& !this.trySetRowSelectionCheckboxFocus(rowElements)) {
|
|
68540
|
+
this.setRowFocusState();
|
|
68541
|
+
this.focusCurrentRow(true);
|
|
68542
|
+
}
|
|
68543
|
+
return true;
|
|
68544
|
+
}
|
|
68545
|
+
return false;
|
|
68546
|
+
}
|
|
68547
|
+
onRightArrowPressed() {
|
|
68548
|
+
let row;
|
|
68549
|
+
let rowElements;
|
|
68550
|
+
let headerElements;
|
|
68551
|
+
if (this.hasRowOrCellFocusType()) {
|
|
68552
|
+
row = this.getCurrentRow();
|
|
68553
|
+
rowElements = row?.getFocusableElements();
|
|
68554
|
+
}
|
|
68555
|
+
else if (this.hasHeaderFocusType()) {
|
|
68556
|
+
headerElements = this.getTableHeaderFocusableElements();
|
|
68557
|
+
}
|
|
68558
|
+
switch (this.focusType) {
|
|
68559
|
+
case TableFocusType.headerActions:
|
|
68560
|
+
return (this.trySetHeaderActionFocus(headerElements, this.headerActionIndex + 1) || this.trySetColumnHeaderFocus(headerElements, 0));
|
|
68561
|
+
case TableFocusType.columnHeader:
|
|
68562
|
+
return this.trySetColumnHeaderFocus(headerElements, this.columnIndex + 1);
|
|
68563
|
+
case TableFocusType.row:
|
|
68564
|
+
if (this.isRowExpanded(row) === false) {
|
|
68565
|
+
this.toggleRowExpanded(row);
|
|
68566
|
+
return true;
|
|
68567
|
+
}
|
|
68568
|
+
return (this.trySetRowSelectionCheckboxFocus(rowElements)
|
|
68569
|
+
|| this.trySetCellFocus(rowElements, 0));
|
|
68570
|
+
case TableFocusType.rowSelectionCheckbox:
|
|
68571
|
+
return this.trySetCellFocus(rowElements, 0);
|
|
68572
|
+
case TableFocusType.cell:
|
|
68573
|
+
return this.trySetCellFocus(rowElements, this.columnIndex + 1);
|
|
68574
|
+
}
|
|
68575
|
+
return false;
|
|
68576
|
+
}
|
|
68577
|
+
onUpArrowPressed() {
|
|
68578
|
+
this.onMoveUp(1);
|
|
68579
|
+
// Always prevent default - prevents page scroll, and FireFox changing focus if focus is at table extents
|
|
68580
|
+
return true;
|
|
68581
|
+
}
|
|
68582
|
+
onPageUpPressed() {
|
|
68583
|
+
return this.onMoveUp(this.virtualizer.pageSize);
|
|
68584
|
+
}
|
|
68585
|
+
onHomePressed(ctrlKey) {
|
|
68586
|
+
if (this.handleHomeEndWithinRow(ctrlKey)) {
|
|
68587
|
+
const row = this.getCurrentRow();
|
|
68588
|
+
const rowElements = row?.getFocusableElements();
|
|
68589
|
+
return (this.trySetRowSelectionCheckboxFocus(rowElements)
|
|
68590
|
+
|| this.trySetCellFocus(rowElements, 0));
|
|
68591
|
+
}
|
|
68592
|
+
return this.onMoveUp(0, 0);
|
|
68593
|
+
}
|
|
68594
|
+
onDownArrowPressed() {
|
|
68595
|
+
this.onMoveDown(1);
|
|
68596
|
+
// Always prevent default - prevents page scroll, and FireFox changing focus if focus is at table extents
|
|
68597
|
+
return true;
|
|
68598
|
+
}
|
|
68599
|
+
onPageDownPressed() {
|
|
68600
|
+
return this.onMoveDown(this.virtualizer.pageSize);
|
|
68601
|
+
}
|
|
68602
|
+
onEndPressed(ctrlKey) {
|
|
68603
|
+
if (this.handleHomeEndWithinRow(ctrlKey)) {
|
|
68604
|
+
const row = this.getCurrentRow();
|
|
68605
|
+
const rowElements = row?.getFocusableElements();
|
|
68606
|
+
return this.trySetCellFocus(rowElements, this.table.visibleColumns.length - 1);
|
|
68607
|
+
}
|
|
68608
|
+
return this.onMoveDown(0, this.table.tableData.length - 1);
|
|
68609
|
+
}
|
|
68610
|
+
handleHomeEndWithinRow(ctrlKey) {
|
|
68611
|
+
return ((this.focusType === TableFocusType.cell
|
|
68612
|
+
|| this.focusType === TableFocusType.rowSelectionCheckbox)
|
|
68613
|
+
&& !ctrlKey);
|
|
68614
|
+
}
|
|
68615
|
+
onTabPressed(shiftKeyPressed) {
|
|
68616
|
+
const activeElement = this.getActiveElement();
|
|
68617
|
+
if (activeElement === null || activeElement === this.table) {
|
|
68618
|
+
return false;
|
|
68619
|
+
}
|
|
68620
|
+
const nextFocusState = this.hasRowOrCellFocusType()
|
|
68621
|
+
? this.getNextRowTabStop(shiftKeyPressed)
|
|
68622
|
+
: this.getNextHeaderTabStop(shiftKeyPressed);
|
|
68623
|
+
if (nextFocusState) {
|
|
68624
|
+
this.focusType = nextFocusState.focusType;
|
|
68625
|
+
this.rowIndex = nextFocusState.rowIndex ?? this.rowIndex;
|
|
68626
|
+
this.columnIndex = nextFocusState.columnIndex ?? this.columnIndex;
|
|
68627
|
+
this.headerActionIndex = nextFocusState.headerActionIndex ?? this.headerActionIndex;
|
|
68628
|
+
this.cellContentIndex = nextFocusState.cellContentIndex ?? this.cellContentIndex;
|
|
68629
|
+
if (this.hasRowOrCellFocusType()) {
|
|
68630
|
+
this.focusCurrentRow(false);
|
|
68631
|
+
}
|
|
68632
|
+
else {
|
|
68633
|
+
this.focusHeaderElement();
|
|
68634
|
+
}
|
|
68635
|
+
return true;
|
|
68636
|
+
}
|
|
68637
|
+
this.blurAfterLastTab(activeElement);
|
|
68638
|
+
return false;
|
|
68639
|
+
}
|
|
68640
|
+
getNextRowTabStop(shiftKeyPressed) {
|
|
68641
|
+
const row = this.getCurrentRow();
|
|
68642
|
+
if (row === undefined) {
|
|
68643
|
+
return undefined;
|
|
68644
|
+
}
|
|
68645
|
+
let startIndex = -1;
|
|
68646
|
+
const focusStates = [];
|
|
68647
|
+
const rowElements = row.getFocusableElements();
|
|
68648
|
+
if (rowElements.selectionCheckbox) {
|
|
68649
|
+
focusStates.push({
|
|
68650
|
+
focusType: TableFocusType.rowSelectionCheckbox
|
|
68651
|
+
});
|
|
68652
|
+
if (this.focusType === TableFocusType.rowSelectionCheckbox) {
|
|
68653
|
+
startIndex = 0;
|
|
68654
|
+
}
|
|
68655
|
+
}
|
|
68656
|
+
let cellIndex = 0;
|
|
68657
|
+
while (cellIndex < rowElements.cells.length) {
|
|
68658
|
+
const firstCellTabbableIndex = focusStates.length;
|
|
68659
|
+
const cellInfo = rowElements.cells[cellIndex];
|
|
68660
|
+
const cellViewTabbableChildren = cellInfo.cell.cellView.tabbableChildren;
|
|
68661
|
+
for (let i = 0; i < cellViewTabbableChildren.length; i++) {
|
|
68662
|
+
focusStates.push({
|
|
68663
|
+
focusType: TableFocusType.cellContent,
|
|
68664
|
+
columnIndex: cellIndex,
|
|
68665
|
+
cellContentIndex: i
|
|
68666
|
+
});
|
|
68667
|
+
if (this.focusType === TableFocusType.cellContent
|
|
68668
|
+
&& this.columnIndex === cellIndex
|
|
68669
|
+
&& this.cellContentIndex === i) {
|
|
68670
|
+
startIndex = focusStates.length - 1;
|
|
68671
|
+
}
|
|
68672
|
+
}
|
|
68673
|
+
if (cellInfo.actionMenuButton) {
|
|
68674
|
+
focusStates.push({
|
|
68675
|
+
focusType: TableFocusType.cellActionMenu,
|
|
68676
|
+
columnIndex: cellIndex
|
|
68677
|
+
});
|
|
68678
|
+
if (this.focusType === TableFocusType.cellActionMenu
|
|
68679
|
+
&& this.columnIndex === cellIndex) {
|
|
68680
|
+
startIndex = focusStates.length - 1;
|
|
68681
|
+
}
|
|
68682
|
+
}
|
|
68683
|
+
const lastCellTabbableIndex = focusStates.length - 1;
|
|
68684
|
+
if (this.focusType === TableFocusType.cell
|
|
68685
|
+
&& this.columnIndex === cellIndex) {
|
|
68686
|
+
startIndex = shiftKeyPressed
|
|
68687
|
+
? lastCellTabbableIndex + 1
|
|
68688
|
+
: firstCellTabbableIndex - 1;
|
|
68689
|
+
}
|
|
68690
|
+
cellIndex += 1;
|
|
68691
|
+
}
|
|
68692
|
+
if (this.focusType === TableFocusType.row) {
|
|
68693
|
+
startIndex = shiftKeyPressed ? focusStates.length : -1;
|
|
68694
|
+
}
|
|
68695
|
+
const direction = shiftKeyPressed ? -1 : 1;
|
|
68696
|
+
return focusStates[startIndex + direction];
|
|
68697
|
+
}
|
|
68698
|
+
getNextHeaderTabStop(shiftKeyPressed) {
|
|
68699
|
+
let startIndex = -1;
|
|
68700
|
+
const focusStates = [];
|
|
68701
|
+
const headerTabbableElements = this.getTableHeaderFocusableElements().headerActions;
|
|
68702
|
+
for (let i = 0; i < headerTabbableElements.length; i++) {
|
|
68703
|
+
focusStates.push({
|
|
68704
|
+
focusType: TableFocusType.headerActions,
|
|
68705
|
+
headerActionIndex: i
|
|
68706
|
+
});
|
|
68707
|
+
}
|
|
68708
|
+
if (this.focusType === TableFocusType.headerActions) {
|
|
68709
|
+
startIndex = this.headerActionIndex;
|
|
68710
|
+
}
|
|
68711
|
+
else {
|
|
68712
|
+
// TableFocusType.columnHeader
|
|
68713
|
+
startIndex = focusStates.length;
|
|
68714
|
+
}
|
|
68715
|
+
const direction = shiftKeyPressed ? -1 : 1;
|
|
68716
|
+
return focusStates[startIndex + direction];
|
|
68717
|
+
}
|
|
68718
|
+
blurAfterLastTab(activeElement) {
|
|
68719
|
+
// In order to get the desired browser-provided Tab/Shift-Tab behavior of focusing the
|
|
68720
|
+
// element before/after the table, the table shouldn't have tabIndex=0 when this event
|
|
68721
|
+
// handling ends. However it needs to be tabIndex=0 so we can re-focus the table the next time
|
|
68722
|
+
// it's tabbed to, so set tabIndex back to 0 after a rAF.
|
|
68723
|
+
// Note: In Chrome this is only needed for Shift-Tab, but in Firefox both Tab and Shift-Tab need this
|
|
68724
|
+
// to work as expected.
|
|
68725
|
+
this.table.tabIndex = -1;
|
|
68726
|
+
window.requestAnimationFrame(() => {
|
|
68727
|
+
this.table.tabIndex = 0;
|
|
68728
|
+
});
|
|
68729
|
+
// Don't explicitly call blur() on activeElement (causes unexpected behavior on Safari / Mac Firefox)
|
|
68730
|
+
this.setElementFocusable(activeElement, false);
|
|
68731
|
+
}
|
|
68732
|
+
onMoveUp(rowDelta, newRowIndex) {
|
|
68733
|
+
const coerceRowIndex = rowDelta > 1;
|
|
68734
|
+
switch (this.focusType) {
|
|
68735
|
+
case TableFocusType.row:
|
|
68736
|
+
case TableFocusType.rowSelectionCheckbox:
|
|
68737
|
+
case TableFocusType.cell: {
|
|
68738
|
+
const scrollOptions = {};
|
|
68739
|
+
let rowIndex = this.rowIndex;
|
|
68740
|
+
if (newRowIndex !== undefined) {
|
|
68741
|
+
rowIndex = newRowIndex;
|
|
68742
|
+
}
|
|
68743
|
+
rowIndex -= rowDelta;
|
|
68744
|
+
if (coerceRowIndex && rowIndex < 0) {
|
|
68745
|
+
rowIndex = 0;
|
|
68746
|
+
}
|
|
68747
|
+
if (rowDelta > 1) {
|
|
68748
|
+
scrollOptions.align = 'start';
|
|
68749
|
+
}
|
|
68750
|
+
if (rowIndex < this.rowIndex && rowIndex >= 0) {
|
|
68751
|
+
return this.scrollToAndFocusRow(rowIndex, scrollOptions);
|
|
68752
|
+
}
|
|
68753
|
+
if (rowIndex === -1) {
|
|
68754
|
+
const headerElements = this.getTableHeaderFocusableElements();
|
|
68755
|
+
if (this.focusType === TableFocusType.row
|
|
68756
|
+
|| this.focusType === TableFocusType.rowSelectionCheckbox) {
|
|
68757
|
+
return (this.trySetHeaderActionFocus(headerElements, 0)
|
|
68758
|
+
|| this.trySetColumnHeaderFocus(headerElements, 0));
|
|
68759
|
+
}
|
|
68760
|
+
return this.trySetColumnHeaderFocus(headerElements, this.columnIndex);
|
|
68761
|
+
}
|
|
68762
|
+
return false;
|
|
68763
|
+
}
|
|
68764
|
+
}
|
|
68765
|
+
return false;
|
|
68766
|
+
}
|
|
68767
|
+
onMoveDown(rowDelta, newRowIndex) {
|
|
68768
|
+
const coerceRowIndex = rowDelta > 1;
|
|
68769
|
+
switch (this.focusType) {
|
|
68770
|
+
case TableFocusType.headerActions: {
|
|
68771
|
+
this.setRowFocusState(0);
|
|
68772
|
+
return this.scrollToAndFocusRow(0);
|
|
68773
|
+
}
|
|
68774
|
+
case TableFocusType.columnHeader: {
|
|
68775
|
+
this.setCellFocusState(this.columnIndex, 0, false);
|
|
68776
|
+
return this.scrollToAndFocusRow(0);
|
|
68777
|
+
}
|
|
68778
|
+
case TableFocusType.row:
|
|
68779
|
+
case TableFocusType.rowSelectionCheckbox:
|
|
68780
|
+
case TableFocusType.cell: {
|
|
68781
|
+
const scrollOptions = {};
|
|
68782
|
+
let rowIndex = this.rowIndex;
|
|
68783
|
+
if (newRowIndex !== undefined) {
|
|
68784
|
+
rowIndex = newRowIndex;
|
|
68785
|
+
}
|
|
68786
|
+
rowIndex += rowDelta;
|
|
68787
|
+
if (coerceRowIndex && rowIndex >= this.table.tableData.length) {
|
|
68788
|
+
rowIndex = this.table.tableData.length - 1;
|
|
68789
|
+
}
|
|
68790
|
+
if (rowDelta > 1) {
|
|
68791
|
+
scrollOptions.align = 'end';
|
|
68792
|
+
}
|
|
68793
|
+
if (rowIndex > this.rowIndex
|
|
68794
|
+
&& rowIndex < this.table.tableData.length) {
|
|
68795
|
+
return this.scrollToAndFocusRow(rowIndex, scrollOptions);
|
|
68796
|
+
}
|
|
68797
|
+
return false;
|
|
68798
|
+
}
|
|
68799
|
+
}
|
|
68800
|
+
return false;
|
|
68801
|
+
}
|
|
68802
|
+
updateFocusStateFromActiveElement(setRowFocus) {
|
|
68803
|
+
// If the user is interacting with the table with non-keyboard methods (like mouse), we need to
|
|
68804
|
+
// update our focus state based on the current active/focused element
|
|
68805
|
+
const activeElement = this.getActiveElement();
|
|
68806
|
+
if (activeElement) {
|
|
68807
|
+
const row = this.getContainingRow(activeElement);
|
|
68808
|
+
if (row) {
|
|
68809
|
+
if (!(row instanceof TableGroupRow)) {
|
|
68810
|
+
const cell = this.getContainingCell(activeElement);
|
|
68811
|
+
if (cell) {
|
|
68812
|
+
const columnIndex = this.table.visibleColumns.indexOf(cell.column);
|
|
68813
|
+
if (cell.actionMenuButton === activeElement) {
|
|
68814
|
+
this.setCellActionMenuFocusState(row.resolvedRowIndex, columnIndex, false);
|
|
68815
|
+
return;
|
|
68816
|
+
}
|
|
68817
|
+
const contentIndex = cell.cellView.tabbableChildren.indexOf(activeElement);
|
|
68818
|
+
if (contentIndex > -1) {
|
|
68819
|
+
this.setCellContentFocusState(contentIndex, row.resolvedRowIndex, columnIndex, false);
|
|
68820
|
+
return;
|
|
68821
|
+
}
|
|
68822
|
+
}
|
|
68823
|
+
}
|
|
68824
|
+
if (setRowFocus
|
|
68825
|
+
&& this.hasRowOrCellFocusType()
|
|
68826
|
+
&& this.rowIndex !== row.resolvedRowIndex) {
|
|
68827
|
+
this.setRowFocusState(row.resolvedRowIndex);
|
|
68828
|
+
}
|
|
68829
|
+
}
|
|
68830
|
+
}
|
|
68831
|
+
}
|
|
68832
|
+
focusElement(element, focusOptions) {
|
|
68833
|
+
const previousActiveElement = this.getActiveElement();
|
|
68834
|
+
if (previousActiveElement !== element) {
|
|
68835
|
+
this.setElementFocusable(element, true);
|
|
68836
|
+
this.isCurrentlyFocusingElement = true;
|
|
68837
|
+
element.focus(focusOptions);
|
|
68838
|
+
this.isCurrentlyFocusingElement = false;
|
|
68839
|
+
if (previousActiveElement
|
|
68840
|
+
&& this.isInTable(previousActiveElement)) {
|
|
68841
|
+
this.setElementFocusable(previousActiveElement, false);
|
|
68842
|
+
}
|
|
68843
|
+
}
|
|
68844
|
+
}
|
|
68845
|
+
setElementFocusable(element, focusable) {
|
|
68846
|
+
if (element === this.table) {
|
|
68847
|
+
return;
|
|
68848
|
+
}
|
|
68849
|
+
element.tabIndex = focusable ? 0 : -1;
|
|
68850
|
+
}
|
|
68851
|
+
setActionMenuButtonFocused(menuButton, focused) {
|
|
68852
|
+
// The action MenuButton needs to be visible in order to be focused, so this CSS class styling
|
|
68853
|
+
// handles that (see cell/styles.ts).
|
|
68854
|
+
if (focused) {
|
|
68855
|
+
menuButton.classList.add('cell-action-menu-focused');
|
|
68856
|
+
}
|
|
68857
|
+
else {
|
|
68858
|
+
menuButton.classList.remove('cell-action-menu-focused');
|
|
68859
|
+
}
|
|
68860
|
+
}
|
|
68861
|
+
setFocusOnHeader() {
|
|
68862
|
+
if (this.hasHeaderFocusType()) {
|
|
68863
|
+
return this.focusHeaderElement();
|
|
68864
|
+
}
|
|
68865
|
+
this.setDefaultFocus();
|
|
68866
|
+
return this.focusType !== TableFocusType.none;
|
|
68867
|
+
}
|
|
68868
|
+
setDefaultFocus() {
|
|
68869
|
+
const headerElements = this.getTableHeaderFocusableElements();
|
|
68870
|
+
if (!this.trySetHeaderActionFocus(headerElements, 0)
|
|
68871
|
+
&& !this.trySetColumnHeaderFocus(headerElements, 0)
|
|
68872
|
+
&& !this.scrollToAndFocusRow(0)) {
|
|
68873
|
+
this.focusType = TableFocusType.none;
|
|
68874
|
+
}
|
|
68875
|
+
}
|
|
68876
|
+
scrollToAndFocusRow(totalRowIndex, scrollOptions) {
|
|
68877
|
+
if (totalRowIndex >= 0 && totalRowIndex < this.table.tableData.length) {
|
|
68878
|
+
switch (this.focusType) {
|
|
68879
|
+
case TableFocusType.none:
|
|
68880
|
+
case TableFocusType.headerActions:
|
|
68881
|
+
case TableFocusType.columnHeader:
|
|
68882
|
+
this.setRowFocusState(totalRowIndex);
|
|
68883
|
+
break;
|
|
68884
|
+
}
|
|
68885
|
+
this.rowIndex = totalRowIndex;
|
|
68886
|
+
this.virtualizer.scrollToIndex(totalRowIndex, scrollOptions);
|
|
68887
|
+
this.focusCurrentRow(true);
|
|
68888
|
+
return true;
|
|
68889
|
+
}
|
|
68890
|
+
return false;
|
|
68891
|
+
}
|
|
68892
|
+
focusCurrentRow(allowScroll) {
|
|
68893
|
+
const visibleRowIndex = this.getCurrentRowVisibleIndex();
|
|
68894
|
+
if (visibleRowIndex < 0) {
|
|
68895
|
+
return false;
|
|
68896
|
+
}
|
|
68897
|
+
const focusedRow = this.table.rowElements[visibleRowIndex];
|
|
68898
|
+
let focusRowOnly = false;
|
|
68899
|
+
switch (this.focusType) {
|
|
68900
|
+
case TableFocusType.row:
|
|
68901
|
+
focusRowOnly = true;
|
|
68902
|
+
break;
|
|
68903
|
+
case TableFocusType.cell:
|
|
68904
|
+
case TableFocusType.cellActionMenu:
|
|
68905
|
+
case TableFocusType.cellContent:
|
|
68906
|
+
focusRowOnly = focusedRow instanceof TableGroupRow;
|
|
68907
|
+
break;
|
|
68908
|
+
}
|
|
68909
|
+
const focusOptions = { preventScroll: !allowScroll };
|
|
68910
|
+
if (focusRowOnly) {
|
|
68911
|
+
this.focusElement(focusedRow, focusOptions);
|
|
68912
|
+
return true;
|
|
68913
|
+
}
|
|
68914
|
+
this.focusRowElement(focusedRow, focusOptions);
|
|
68915
|
+
return true;
|
|
68916
|
+
}
|
|
68917
|
+
focusRowElement(row, focusOptions) {
|
|
68918
|
+
const rowElements = row.getFocusableElements();
|
|
68919
|
+
let focusableElement;
|
|
68920
|
+
switch (this.focusType) {
|
|
68921
|
+
case TableFocusType.rowSelectionCheckbox:
|
|
68922
|
+
focusableElement = rowElements.selectionCheckbox;
|
|
68923
|
+
break;
|
|
68924
|
+
case TableFocusType.cell: {
|
|
68925
|
+
focusableElement = rowElements.cells[this.columnIndex].cell;
|
|
68926
|
+
break;
|
|
68927
|
+
}
|
|
68928
|
+
case TableFocusType.cellActionMenu: {
|
|
68929
|
+
const actionMenuButton = rowElements.cells[this.columnIndex]?.cell.actionMenuButton;
|
|
68930
|
+
if (actionMenuButton) {
|
|
68931
|
+
focusableElement = actionMenuButton;
|
|
68932
|
+
this.setActionMenuButtonFocused(actionMenuButton, true);
|
|
68933
|
+
}
|
|
68934
|
+
break;
|
|
68935
|
+
}
|
|
68936
|
+
case TableFocusType.cellContent: {
|
|
68937
|
+
focusableElement = rowElements.cells[this.columnIndex]?.cell.cellView
|
|
68938
|
+
.tabbableChildren[this.cellContentIndex];
|
|
68939
|
+
break;
|
|
68940
|
+
}
|
|
68941
|
+
}
|
|
68942
|
+
if (focusableElement) {
|
|
68943
|
+
this.focusElement(focusableElement, focusOptions);
|
|
68944
|
+
}
|
|
68945
|
+
}
|
|
68946
|
+
focusHeaderElement() {
|
|
68947
|
+
const headerElements = this.getTableHeaderFocusableElements();
|
|
68948
|
+
let focusableElement;
|
|
68949
|
+
switch (this.focusType) {
|
|
68950
|
+
case TableFocusType.headerActions:
|
|
68951
|
+
focusableElement = headerElements.headerActions[this.headerActionIndex];
|
|
68952
|
+
break;
|
|
68953
|
+
case TableFocusType.columnHeader:
|
|
68954
|
+
focusableElement = headerElements.columnHeaders[this.columnIndex];
|
|
68955
|
+
break;
|
|
68956
|
+
}
|
|
68957
|
+
if (focusableElement) {
|
|
68958
|
+
this.focusElement(focusableElement);
|
|
68959
|
+
return true;
|
|
68960
|
+
}
|
|
68961
|
+
return false;
|
|
68962
|
+
}
|
|
68963
|
+
getCurrentRowVisibleIndex() {
|
|
68964
|
+
return this.table.rowElements.findIndex(row => row.resolvedRowIndex === this.rowIndex);
|
|
68965
|
+
}
|
|
68966
|
+
getTableHeaderFocusableElements() {
|
|
68967
|
+
const headerActions = [];
|
|
68968
|
+
if (this.table.selectionCheckbox?.getRootNode()
|
|
68969
|
+
=== this.table.shadowRoot) {
|
|
68970
|
+
headerActions.push(this.table.selectionCheckbox);
|
|
68971
|
+
}
|
|
68972
|
+
if (this.table.showCollapseAll
|
|
68973
|
+
&& this.table.collapseAllButton?.getRootNode()
|
|
68974
|
+
=== this.table.shadowRoot) {
|
|
68975
|
+
headerActions.push(this.table.collapseAllButton);
|
|
68976
|
+
}
|
|
68977
|
+
const columnHeaders = [];
|
|
68978
|
+
if (this.canFocusColumnHeaders()) {
|
|
68979
|
+
this.table.columnHeadersContainer
|
|
68980
|
+
.querySelectorAll(tableHeaderTag)
|
|
68981
|
+
.forEach(header => columnHeaders.push(header));
|
|
68982
|
+
}
|
|
68983
|
+
return { headerActions, columnHeaders };
|
|
68984
|
+
}
|
|
68985
|
+
canFocusColumnHeaders() {
|
|
68986
|
+
return (this.table.columns.find(c => !c.columnInternals.sortingDisabled)
|
|
68987
|
+
!== undefined);
|
|
68988
|
+
}
|
|
68989
|
+
getCurrentRow() {
|
|
68990
|
+
return this.table.rowElements[this.getCurrentRowVisibleIndex()];
|
|
68991
|
+
}
|
|
68992
|
+
isRowExpanded(row) {
|
|
68993
|
+
if ((row instanceof TableRow && row.isParentRow)
|
|
68994
|
+
|| row instanceof TableGroupRow) {
|
|
68995
|
+
return row.expanded;
|
|
68996
|
+
}
|
|
68997
|
+
return undefined;
|
|
68998
|
+
}
|
|
68999
|
+
toggleRowExpanded(row) {
|
|
69000
|
+
if (row instanceof TableGroupRow) {
|
|
69001
|
+
row.onGroupExpandToggle();
|
|
69002
|
+
}
|
|
69003
|
+
else {
|
|
69004
|
+
row.onRowExpandToggle();
|
|
69005
|
+
}
|
|
69006
|
+
this.focusRowElement(row);
|
|
69007
|
+
}
|
|
69008
|
+
getContainingRow(start) {
|
|
69009
|
+
return this.getContainingElement(start, e => this.isResolvedRowType(e));
|
|
69010
|
+
}
|
|
69011
|
+
getContainingCell(start) {
|
|
69012
|
+
return this.getContainingElement(start, e => e instanceof TableCell);
|
|
69013
|
+
}
|
|
69014
|
+
getContainingElement(start, isElementMatch) {
|
|
69015
|
+
let possibleMatch = start;
|
|
69016
|
+
while (possibleMatch && possibleMatch !== this.table) {
|
|
69017
|
+
if (isElementMatch(possibleMatch)) {
|
|
69018
|
+
return possibleMatch;
|
|
69019
|
+
}
|
|
69020
|
+
possibleMatch = possibleMatch.parentElement
|
|
69021
|
+
?? possibleMatch.parentNode?.host;
|
|
69022
|
+
}
|
|
69023
|
+
return undefined;
|
|
69024
|
+
}
|
|
69025
|
+
isInTable(start) {
|
|
69026
|
+
let possibleMatch = start;
|
|
69027
|
+
while (possibleMatch && possibleMatch !== this.table) {
|
|
69028
|
+
possibleMatch = possibleMatch.parentElement
|
|
69029
|
+
?? possibleMatch.parentNode?.host;
|
|
69030
|
+
}
|
|
69031
|
+
return possibleMatch === this.table;
|
|
69032
|
+
}
|
|
69033
|
+
getActiveElement() {
|
|
69034
|
+
let activeElement = document.activeElement;
|
|
69035
|
+
while (activeElement?.shadowRoot?.activeElement) {
|
|
69036
|
+
activeElement = activeElement.shadowRoot.activeElement;
|
|
69037
|
+
// In some cases, the active element may be a sub-part of a control (example: MenuButton -> ToggleButton -> a div with tabindex=0). Stop at the outer control boundary, so that
|
|
69038
|
+
// we can more simply check equality against the elements of getTableHeaderFocusableElements() / row.getFocusableElements().
|
|
69039
|
+
// (For rows/cells/cell views, we do need to recurse into them, to get to the appropriate focused controls though)
|
|
69040
|
+
if (activeElement instanceof FoundationElement
|
|
69041
|
+
&& !this.isResolvedRowType(activeElement)
|
|
69042
|
+
&& !(activeElement instanceof TableCell)
|
|
69043
|
+
&& !(activeElement instanceof TableCellView)) {
|
|
69044
|
+
break;
|
|
69045
|
+
}
|
|
69046
|
+
}
|
|
69047
|
+
return activeElement;
|
|
69048
|
+
}
|
|
69049
|
+
focusFirstInteractiveElementInCurrentCell(rowElements) {
|
|
69050
|
+
if (!rowElements) {
|
|
69051
|
+
return false;
|
|
69052
|
+
}
|
|
69053
|
+
return (this.trySetCellContentFocus(rowElements, 0)
|
|
69054
|
+
|| this.trySetCellActionMenuFocus(rowElements));
|
|
69055
|
+
}
|
|
69056
|
+
hasRowOrCellFocusType() {
|
|
69057
|
+
switch (this.focusType) {
|
|
69058
|
+
case TableFocusType.cell:
|
|
69059
|
+
case TableFocusType.cellActionMenu:
|
|
69060
|
+
case TableFocusType.cellContent:
|
|
69061
|
+
case TableFocusType.row:
|
|
69062
|
+
case TableFocusType.rowSelectionCheckbox:
|
|
69063
|
+
return true;
|
|
69064
|
+
default:
|
|
69065
|
+
return false;
|
|
69066
|
+
}
|
|
69067
|
+
}
|
|
69068
|
+
hasHeaderFocusType() {
|
|
69069
|
+
switch (this.focusType) {
|
|
69070
|
+
case TableFocusType.headerActions:
|
|
69071
|
+
case TableFocusType.columnHeader:
|
|
69072
|
+
return true;
|
|
69073
|
+
default:
|
|
69074
|
+
return false;
|
|
69075
|
+
}
|
|
69076
|
+
}
|
|
69077
|
+
trySetRowSelectionCheckboxFocus(rowElements) {
|
|
69078
|
+
if (rowElements?.selectionCheckbox) {
|
|
69079
|
+
this.focusType = TableFocusType.rowSelectionCheckbox;
|
|
69080
|
+
this.focusCurrentRow(true);
|
|
69081
|
+
return true;
|
|
69082
|
+
}
|
|
69083
|
+
return false;
|
|
69084
|
+
}
|
|
69085
|
+
trySetColumnHeaderFocus(headerElements, columnIndex) {
|
|
69086
|
+
if (columnIndex >= 0
|
|
69087
|
+
&& columnIndex < headerElements.columnHeaders.length) {
|
|
69088
|
+
this.focusType = TableFocusType.columnHeader;
|
|
69089
|
+
this.columnIndex = columnIndex;
|
|
69090
|
+
this.focusHeaderElement();
|
|
69091
|
+
return true;
|
|
69092
|
+
}
|
|
69093
|
+
return false;
|
|
69094
|
+
}
|
|
69095
|
+
trySetHeaderActionFocus(headerElements, headerActionIndex) {
|
|
69096
|
+
if (headerActionIndex >= 0
|
|
69097
|
+
&& headerActionIndex < headerElements.headerActions.length) {
|
|
69098
|
+
this.focusType = TableFocusType.headerActions;
|
|
69099
|
+
this.headerActionIndex = headerActionIndex;
|
|
69100
|
+
this.focusHeaderElement();
|
|
69101
|
+
return true;
|
|
69102
|
+
}
|
|
69103
|
+
return false;
|
|
69104
|
+
}
|
|
69105
|
+
trySetCellFocus(rowElements, columnIndex, rowIndex) {
|
|
69106
|
+
if (!rowElements) {
|
|
69107
|
+
return false;
|
|
69108
|
+
}
|
|
69109
|
+
const newColumnIndex = columnIndex ?? this.columnIndex;
|
|
69110
|
+
const newRowIndex = rowIndex ?? this.rowIndex;
|
|
69111
|
+
if (newColumnIndex >= 0 && newColumnIndex < rowElements.cells.length) {
|
|
69112
|
+
this.focusType = TableFocusType.cell;
|
|
69113
|
+
this.setRowCellFocusState(newColumnIndex, newRowIndex, true);
|
|
69114
|
+
return true;
|
|
69115
|
+
}
|
|
69116
|
+
return false;
|
|
69117
|
+
}
|
|
69118
|
+
trySetCellContentFocus(rowElements, cellContentIndex, columnIndex, rowIndex) {
|
|
69119
|
+
if (!rowElements) {
|
|
69120
|
+
return false;
|
|
69121
|
+
}
|
|
69122
|
+
const newColumnIndex = columnIndex ?? this.columnIndex;
|
|
69123
|
+
const newRowIndex = rowIndex ?? this.rowIndex;
|
|
69124
|
+
if (newColumnIndex >= 0
|
|
69125
|
+
&& newColumnIndex < rowElements.cells.length
|
|
69126
|
+
&& cellContentIndex >= 0
|
|
69127
|
+
&& cellContentIndex
|
|
69128
|
+
< rowElements.cells[newColumnIndex].cell.cellView
|
|
69129
|
+
.tabbableChildren.length) {
|
|
69130
|
+
this.setCellContentFocusState(cellContentIndex, newRowIndex, newColumnIndex, true);
|
|
69131
|
+
return true;
|
|
69132
|
+
}
|
|
69133
|
+
return false;
|
|
69134
|
+
}
|
|
69135
|
+
trySetCellActionMenuFocus(rowElements, columnIndex, rowIndex) {
|
|
69136
|
+
const newColumnIndex = columnIndex ?? this.columnIndex;
|
|
69137
|
+
const newRowIndex = rowIndex ?? this.rowIndex;
|
|
69138
|
+
if (newColumnIndex >= 0
|
|
69139
|
+
&& newColumnIndex < rowElements.cells.length
|
|
69140
|
+
&& rowElements.cells[newColumnIndex].actionMenuButton) {
|
|
69141
|
+
this.setCellActionMenuFocusState(newRowIndex, newColumnIndex, true);
|
|
69142
|
+
return true;
|
|
69143
|
+
}
|
|
69144
|
+
return false;
|
|
69145
|
+
}
|
|
69146
|
+
setCellActionMenuFocusState(rowIndex, columnIndex, focusElement) {
|
|
69147
|
+
this.focusType = TableFocusType.cellActionMenu;
|
|
69148
|
+
this.setRowCellFocusState(columnIndex, rowIndex, focusElement);
|
|
69149
|
+
}
|
|
69150
|
+
setCellContentFocusState(cellContentIndex, rowIndex, columnIndex, focusElement) {
|
|
69151
|
+
this.focusType = TableFocusType.cellContent;
|
|
69152
|
+
this.cellContentIndex = cellContentIndex;
|
|
69153
|
+
this.setRowCellFocusState(columnIndex, rowIndex, focusElement);
|
|
69154
|
+
}
|
|
69155
|
+
setRowFocusState(rowIndex) {
|
|
69156
|
+
this.focusType = TableFocusType.row;
|
|
69157
|
+
if (rowIndex !== undefined) {
|
|
69158
|
+
this.rowIndex = rowIndex;
|
|
69159
|
+
}
|
|
69160
|
+
}
|
|
69161
|
+
setCellFocusState(columnIndex, rowIndex, focusElement) {
|
|
69162
|
+
this.focusType = TableFocusType.cell;
|
|
69163
|
+
this.setRowCellFocusState(columnIndex, rowIndex, focusElement);
|
|
69164
|
+
}
|
|
69165
|
+
setRowCellFocusState(columnIndex, rowIndex, focusElement) {
|
|
69166
|
+
this.rowIndex = rowIndex;
|
|
69167
|
+
this.columnIndex = columnIndex;
|
|
69168
|
+
if (focusElement) {
|
|
69169
|
+
this.focusCurrentRow(true);
|
|
69170
|
+
}
|
|
69171
|
+
}
|
|
69172
|
+
isResolvedRowType(row) {
|
|
69173
|
+
return row instanceof TableRow || row instanceof TableGroupRow;
|
|
69174
|
+
}
|
|
69175
|
+
}
|
|
69176
|
+
|
|
67985
69177
|
/**
|
|
67986
69178
|
* A nimble-styled table.
|
|
67987
69179
|
*/
|
|
@@ -68122,6 +69314,7 @@ img.ProseMirror-separator {
|
|
|
68122
69314
|
};
|
|
68123
69315
|
this.table = createTable(this.options);
|
|
68124
69316
|
this.virtualizer = new Virtualizer(this, this.table);
|
|
69317
|
+
this.keyboardNavigationManager = new KeyboardNavigationManager(this, this.virtualizer);
|
|
68125
69318
|
this.layoutManager = new TableLayoutManager(this);
|
|
68126
69319
|
this.layoutManagerNotifier = Observable.getNotifier(this.layoutManager);
|
|
68127
69320
|
this.layoutManagerNotifier.subscribe(this, 'isColumnBeingSized');
|
|
@@ -68162,12 +69355,14 @@ img.ProseMirror-separator {
|
|
|
68162
69355
|
this.viewport.addEventListener('scroll', this.onViewPortScroll, {
|
|
68163
69356
|
passive: true
|
|
68164
69357
|
});
|
|
69358
|
+
this.keyboardNavigationManager.connect();
|
|
68165
69359
|
document.addEventListener('keydown', this.onKeyDown);
|
|
68166
69360
|
document.addEventListener('keyup', this.onKeyUp);
|
|
68167
69361
|
}
|
|
68168
69362
|
disconnectedCallback() {
|
|
68169
69363
|
super.disconnectedCallback();
|
|
68170
69364
|
this.virtualizer.disconnect();
|
|
69365
|
+
this.keyboardNavigationManager.disconnect();
|
|
68171
69366
|
this.viewport.removeEventListener('scroll', this.onViewPortScroll);
|
|
68172
69367
|
document.removeEventListener('keydown', this.onKeyDown);
|
|
68173
69368
|
document.removeEventListener('keyup', this.onKeyUp);
|
|
@@ -68217,6 +69412,14 @@ img.ProseMirror-separator {
|
|
|
68217
69412
|
return true;
|
|
68218
69413
|
}
|
|
68219
69414
|
/** @internal */
|
|
69415
|
+
onRowFocusIn(event) {
|
|
69416
|
+
this.keyboardNavigationManager.onRowFocusIn(event);
|
|
69417
|
+
}
|
|
69418
|
+
/** @internal */
|
|
69419
|
+
onRowBlur(event) {
|
|
69420
|
+
this.keyboardNavigationManager.onRowBlur(event);
|
|
69421
|
+
}
|
|
69422
|
+
/** @internal */
|
|
68220
69423
|
onAllRowsSelectionChange(event) {
|
|
68221
69424
|
event.stopPropagation();
|
|
68222
69425
|
if (this.ignoreSelectionChangeEvents) {
|
|
@@ -68310,6 +69513,18 @@ img.ProseMirror-separator {
|
|
|
68310
69513
|
}
|
|
68311
69514
|
this.emitColumnConfigurationChangeEvent();
|
|
68312
69515
|
}
|
|
69516
|
+
/**
|
|
69517
|
+
* @internal
|
|
69518
|
+
*/
|
|
69519
|
+
onHeaderKeyDown(column, event) {
|
|
69520
|
+
const allowMultiSort = event.shiftKey;
|
|
69521
|
+
if (event.key === keyEnter) {
|
|
69522
|
+
this.toggleColumnSort(column, allowMultiSort);
|
|
69523
|
+
}
|
|
69524
|
+
// Return true so that we don't prevent default behavior. Without this, Tab navigation
|
|
69525
|
+
// gets stuck on the column headers.
|
|
69526
|
+
return true;
|
|
69527
|
+
}
|
|
68313
69528
|
/**
|
|
68314
69529
|
* @internal
|
|
68315
69530
|
*/
|
|
@@ -68325,6 +69540,9 @@ img.ProseMirror-separator {
|
|
|
68325
69540
|
this.rowGridColumns = this.layoutManager.getGridTemplateColumns();
|
|
68326
69541
|
this.visibleColumns = this.columns.filter(column => !column.columnHidden);
|
|
68327
69542
|
}
|
|
69543
|
+
if (this.tableUpdateTracker.requiresKeyboardFocusReset) {
|
|
69544
|
+
this.keyboardNavigationManager.resetFocusState();
|
|
69545
|
+
}
|
|
68328
69546
|
}
|
|
68329
69547
|
get ariaMultiSelectable() {
|
|
68330
69548
|
switch (this.selectionMode) {
|
|
@@ -68367,6 +69585,29 @@ img.ProseMirror-separator {
|
|
|
68367
69585
|
}
|
|
68368
69586
|
return tanStackUpdates;
|
|
68369
69587
|
}
|
|
69588
|
+
/** @internal */
|
|
69589
|
+
handleFocusedCellRecycling() {
|
|
69590
|
+
const hadActiveRowOrCellFocus = this.keyboardNavigationManager.hasActiveRowOrCellFocus;
|
|
69591
|
+
let tableFocusedElement = this.shadowRoot.activeElement;
|
|
69592
|
+
while (tableFocusedElement !== null
|
|
69593
|
+
&& !(tableFocusedElement instanceof TableCellView)) {
|
|
69594
|
+
if (tableFocusedElement.shadowRoot) {
|
|
69595
|
+
tableFocusedElement = tableFocusedElement.shadowRoot.activeElement;
|
|
69596
|
+
}
|
|
69597
|
+
else {
|
|
69598
|
+
break;
|
|
69599
|
+
}
|
|
69600
|
+
}
|
|
69601
|
+
if (tableFocusedElement instanceof TableCellView) {
|
|
69602
|
+
tableFocusedElement.focusedRecycleCallback();
|
|
69603
|
+
}
|
|
69604
|
+
if (this.openActionMenuRecordId !== undefined) {
|
|
69605
|
+
const activeRow = this.rowElements.find(row => row instanceof TableRow
|
|
69606
|
+
&& row.recordId === this.openActionMenuRecordId);
|
|
69607
|
+
activeRow?.closeOpenActionMenus();
|
|
69608
|
+
}
|
|
69609
|
+
this.keyboardNavigationManager.handleFocusedCellRecycling(hadActiveRowOrCellFocus);
|
|
69610
|
+
}
|
|
68370
69611
|
selectionModeChanged(_prev, _next) {
|
|
68371
69612
|
if (!this.$fastController.isConnected) {
|
|
68372
69613
|
return;
|
|
@@ -68402,6 +69643,7 @@ img.ProseMirror-separator {
|
|
|
68402
69643
|
this.$emit('action-menu-beforetoggle', detail);
|
|
68403
69644
|
}
|
|
68404
69645
|
async handleRowActionMenuToggleEvent(event) {
|
|
69646
|
+
this.keyboardNavigationManager.onRowActionMenuToggle(event);
|
|
68405
69647
|
const detail = await this.getActionMenuToggleEventDetail(event);
|
|
68406
69648
|
this.$emit('action-menu-toggle', detail);
|
|
68407
69649
|
if (!event.detail.newState) {
|
|
@@ -68612,6 +69854,7 @@ img.ProseMirror-separator {
|
|
|
68612
69854
|
isParentRow: isParent,
|
|
68613
69855
|
immediateChildCount: row.subRows.length,
|
|
68614
69856
|
groupColumn: this.getGroupRowColumn(row),
|
|
69857
|
+
resolvedRowIndex: row.index,
|
|
68615
69858
|
isLoadingChildren: this.expansionManager.isLoadingChildren(row.id)
|
|
68616
69859
|
};
|
|
68617
69860
|
hasDataHierarchy = hasDataHierarchy || isParent;
|
|
@@ -68779,6 +70022,9 @@ img.ProseMirror-separator {
|
|
|
68779
70022
|
__decorate$1([
|
|
68780
70023
|
observable
|
|
68781
70024
|
], Table.prototype, "selectionCheckbox", void 0);
|
|
70025
|
+
__decorate$1([
|
|
70026
|
+
observable
|
|
70027
|
+
], Table.prototype, "collapseAllButton", void 0);
|
|
68782
70028
|
__decorate$1([
|
|
68783
70029
|
observable
|
|
68784
70030
|
], Table.prototype, "showCollapseAll", void 0);
|
|
@@ -68932,10 +70178,12 @@ img.ProseMirror-separator {
|
|
|
68932
70178
|
}}"
|
|
68933
70179
|
class="${x => (x.isPlaceholder ? 'placeholder' : '')}"
|
|
68934
70180
|
>
|
|
68935
|
-
${when(x =>
|
|
70181
|
+
${when(x => x.showAnchor, html `
|
|
68936
70182
|
<${anchorTag}
|
|
68937
70183
|
${ref('anchor')}
|
|
68938
70184
|
${overflow('hasOverflow')}
|
|
70185
|
+
${'' /* tabindex managed dynamically by KeyboardNavigationManager */}
|
|
70186
|
+
tabindex="-1"
|
|
68939
70187
|
href="${x => x.cellRecord?.href}"
|
|
68940
70188
|
hreflang="${x => x.columnConfig?.hreflang}"
|
|
68941
70189
|
ping="${x => x.columnConfig?.ping}"
|
|
@@ -68950,7 +70198,7 @@ img.ProseMirror-separator {
|
|
|
68950
70198
|
>
|
|
68951
70199
|
${x => x.text}
|
|
68952
70200
|
</${anchorTag}>`)}
|
|
68953
|
-
${when(x =>
|
|
70201
|
+
${when(x => !x.showAnchor, html `
|
|
68954
70202
|
<span
|
|
68955
70203
|
${overflow('hasOverflow')}
|
|
68956
70204
|
title=${x => (x.hasOverflow ? x.text : null)}
|
|
@@ -68987,9 +70235,19 @@ img.ProseMirror-separator {
|
|
|
68987
70235
|
}
|
|
68988
70236
|
return '';
|
|
68989
70237
|
}
|
|
70238
|
+
/** @internal */
|
|
70239
|
+
get showAnchor() {
|
|
70240
|
+
return typeof this.cellRecord?.href === 'string';
|
|
70241
|
+
}
|
|
68990
70242
|
focusedRecycleCallback() {
|
|
68991
70243
|
this.anchor?.blur();
|
|
68992
70244
|
}
|
|
70245
|
+
get tabbableChildren() {
|
|
70246
|
+
if (this.showAnchor) {
|
|
70247
|
+
return [this.anchor];
|
|
70248
|
+
}
|
|
70249
|
+
return [];
|
|
70250
|
+
}
|
|
68993
70251
|
}
|
|
68994
70252
|
__decorate$1([
|
|
68995
70253
|
observable
|
|
@@ -69000,6 +70258,9 @@ img.ProseMirror-separator {
|
|
|
69000
70258
|
__decorate$1([
|
|
69001
70259
|
volatile
|
|
69002
70260
|
], TableColumnAnchorCellView.prototype, "text", null);
|
|
70261
|
+
__decorate$1([
|
|
70262
|
+
volatile
|
|
70263
|
+
], TableColumnAnchorCellView.prototype, "showAnchor", null);
|
|
69003
70264
|
const anchorCellView = TableColumnAnchorCellView.compose({
|
|
69004
70265
|
baseName: 'table-column-anchor-cell-view',
|
|
69005
70266
|
template: template$c,
|