@ni/nimble-components 18.10.4 → 18.10.6

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.
@@ -27789,6 +27789,22 @@
27789
27789
  ascending: 'ascending',
27790
27790
  descending: 'descending'
27791
27791
  };
27792
+ /**
27793
+ * The selection modes of rows in the table.
27794
+ */
27795
+ const TableRowSelectionMode = {
27796
+ none: undefined,
27797
+ single: 'single'
27798
+ };
27799
+ /**
27800
+ * @internal
27801
+ *
27802
+ * The possible selection states that the table or a table row can be in.
27803
+ */
27804
+ const TableRowSelectionState = {
27805
+ notSelected: 'notSelected',
27806
+ selected: 'selected'
27807
+ };
27792
27808
 
27793
27809
  /**
27794
27810
  * The possible operations to use when sorting a table column.
@@ -27953,6 +27969,8 @@
27953
27969
  this.missingColumnId = false;
27954
27970
  this.duplicateSortIndex = false;
27955
27971
  this.duplicateGroupIndex = false;
27972
+ this.idFieldNameNotConfigured = false;
27973
+ this.recordIds = new Set();
27956
27974
  }
27957
27975
  getValidity() {
27958
27976
  return {
@@ -27962,21 +27980,37 @@
27962
27980
  duplicateColumnId: this.duplicateColumnId,
27963
27981
  missingColumnId: this.missingColumnId,
27964
27982
  duplicateSortIndex: this.duplicateSortIndex,
27965
- duplicateGroupIndex: this.duplicateGroupIndex
27983
+ duplicateGroupIndex: this.duplicateGroupIndex,
27984
+ idFieldNameNotConfigured: this.idFieldNameNotConfigured
27966
27985
  };
27967
27986
  }
27968
27987
  isValid() {
27969
27988
  return Object.values(this.getValidity()).every(x => x === false);
27970
27989
  }
27990
+ areRecordIdsValid() {
27991
+ const validity = this.getValidity();
27992
+ return (!validity.duplicateRecordId
27993
+ && !validity.missingRecordId
27994
+ && !validity.invalidRecordId);
27995
+ }
27996
+ validateSelectionMode(selectionMode, idFieldName) {
27997
+ if (selectionMode === TableRowSelectionMode.none) {
27998
+ this.idFieldNameNotConfigured = false;
27999
+ }
28000
+ else {
28001
+ this.idFieldNameNotConfigured = typeof idFieldName !== 'string';
28002
+ }
28003
+ return !this.idFieldNameNotConfigured;
28004
+ }
27971
28005
  validateRecordIds(data, idFieldName) {
27972
28006
  // Start off by assuming all IDs are valid.
27973
28007
  this.duplicateRecordId = false;
27974
28008
  this.missingRecordId = false;
27975
28009
  this.invalidRecordId = false;
28010
+ this.recordIds.clear();
27976
28011
  if (typeof idFieldName !== 'string') {
27977
28012
  return true;
27978
28013
  }
27979
- const ids = new Set();
27980
28014
  for (const record of data) {
27981
28015
  if (!Object.prototype.hasOwnProperty.call(record, idFieldName)) {
27982
28016
  this.missingRecordId = true;
@@ -27987,10 +28021,10 @@
27987
28021
  this.invalidRecordId = true;
27988
28022
  continue;
27989
28023
  }
27990
- if (ids.has(id)) {
28024
+ if (this.recordIds.has(id)) {
27991
28025
  this.duplicateRecordId = true;
27992
28026
  }
27993
- ids.add(id);
28027
+ this.recordIds.add(id);
27994
28028
  }
27995
28029
  return (!this.missingRecordId
27996
28030
  && !this.invalidRecordId
@@ -28024,6 +28058,9 @@
28024
28058
  this.duplicateGroupIndex = !this.validateIndicesAreUnique(groupIndices);
28025
28059
  return !this.duplicateGroupIndex;
28026
28060
  }
28061
+ getPresentRecordIds(requestedRecordIds) {
28062
+ return requestedRecordIds.filter(id => this.recordIds.has(id));
28063
+ }
28027
28064
  validateIndicesAreUnique(indices) {
28028
28065
  const numberSet = new Set(indices);
28029
28066
  return numberSet.size === indices.length;
@@ -28104,9 +28141,17 @@
28104
28141
  pointer-events: none;
28105
28142
  }
28106
28143
 
28107
- .row:hover::before {
28144
+ :host([selection-mode='single']) .row:hover::before {
28108
28145
  background: ${fillHoverColor};
28109
28146
  }
28147
+
28148
+ :host([selection-mode='single']) .row[selected]::before {
28149
+ background: ${fillSelectedColor};
28150
+ }
28151
+
28152
+ :host([selection-mode='single']) .row[selected]:hover::before {
28153
+ background: ${fillHoverSelectedColor};
28154
+ }
28110
28155
  `.withBehaviors(themeBehavior(Theme.color, css `
28111
28156
  .header-row::before {
28112
28157
  content: '';
@@ -28121,9 +28166,17 @@
28121
28166
  background: ${fillHoverColor};
28122
28167
  }
28123
28168
 
28124
- .row:hover::before {
28169
+ :host([selection-mode='single']) .row:hover::before {
28125
28170
  background: ${hexToRgbaCssColor(White, 0.15)};
28126
28171
  }
28172
+
28173
+ :host([selection-mode='single']) .row[selected]::before {
28174
+ background: ${hexToRgbaCssColor(White, 0.25)};
28175
+ }
28176
+
28177
+ :host([selection-mode='single']) .row[selected]:hover::before {
28178
+ background: ${hexToRgbaCssColor(White, 0.2)};
28179
+ }
28127
28180
  `));
28128
28181
 
28129
28182
  const styles$f = css `
@@ -28225,6 +28278,10 @@
28225
28278
  :host(:hover) nimble-table-cell {
28226
28279
  --ni-private-table-cell-action-menu-display: block;
28227
28280
  }
28281
+
28282
+ :host([selected]) nimble-table-cell {
28283
+ --ni-private-table-cell-action-menu-display: block;
28284
+ }
28228
28285
  `;
28229
28286
 
28230
28287
  const styles$d = css `
@@ -28305,7 +28362,7 @@
28305
28362
 
28306
28363
  // prettier-ignore
28307
28364
  const template$9 = html `
28308
- <template role="row">
28365
+ <template role="row" aria-selected=${x => x.ariaSelected}>
28309
28366
  ${repeat(x => x.columnStates, html `
28310
28367
  ${when(x => !x.column.columnHidden, html `
28311
28368
  <${tableCellTag}
@@ -28338,6 +28395,8 @@
28338
28395
  class TableRow extends FoundationElement {
28339
28396
  constructor() {
28340
28397
  super(...arguments);
28398
+ this.selectable = false;
28399
+ this.selected = false;
28341
28400
  this.columns = [];
28342
28401
  this.nestingLevel = 0;
28343
28402
  this.menuOpen = false;
@@ -28368,6 +28427,12 @@
28368
28427
  return { column, cellState, cellIndentLevel };
28369
28428
  });
28370
28429
  }
28430
+ get ariaSelected() {
28431
+ if (this.selectable) {
28432
+ return this.selected ? 'true' : 'false';
28433
+ }
28434
+ return null;
28435
+ }
28371
28436
  onCellActionMenuBeforeToggle(event, column) {
28372
28437
  this.currentActionMenuColumn = column;
28373
28438
  this.emitToggleEvent('row-action-menu-beforetoggle', event.detail, column);
@@ -28400,6 +28465,12 @@
28400
28465
  __decorate$1([
28401
28466
  attr({ attribute: 'record-id' })
28402
28467
  ], TableRow.prototype, "recordId", void 0);
28468
+ __decorate$1([
28469
+ attr({ mode: 'boolean' })
28470
+ ], TableRow.prototype, "selectable", void 0);
28471
+ __decorate$1([
28472
+ attr({ mode: 'boolean' })
28473
+ ], TableRow.prototype, "selected", void 0);
28403
28474
  __decorate$1([
28404
28475
  observable
28405
28476
  ], TableRow.prototype, "dataRecord", void 0);
@@ -28418,6 +28489,9 @@
28418
28489
  __decorate$1([
28419
28490
  volatile
28420
28491
  ], TableRow.prototype, "columnStates", null);
28492
+ __decorate$1([
28493
+ volatile
28494
+ ], TableRow.prototype, "ariaSelected", null);
28421
28495
  const nimbleTableRow = TableRow.compose({
28422
28496
  baseName: 'table-row',
28423
28497
  template: template$9,
@@ -28564,7 +28638,7 @@
28564
28638
 
28565
28639
  // prettier-ignore
28566
28640
  const template$7 = html `
28567
- <template role="table" ${children$1({ property: 'childItems', filter: elements() })}>
28641
+ <template role="grid" ${children$1({ property: 'childItems', filter: elements() })}>
28568
28642
  <div class="table-container" style="
28569
28643
  --ni-private-table-scroll-x: -${x => x.scrollX}px;
28570
28644
  --ni-private-table-header-scrollbar-spacer-width: ${x => x.virtualizer.headerContainerMarginRight}px;
@@ -28610,9 +28684,12 @@
28610
28684
  <${tableRowTag}
28611
28685
  class="row"
28612
28686
  record-id="${(x, c) => c.parent.tableData[x.index]?.id}"
28687
+ ?selectable="${(_, c) => c.parent.selectionMode !== TableRowSelectionMode.none}"
28688
+ ?selected="${(x, c) => c.parent.tableData[x.index]?.selectionState === TableRowSelectionState.selected}"
28613
28689
  :dataRecord="${(x, c) => c.parent.tableData[x.index]?.record}"
28614
28690
  :columns="${(_, c) => c.parent.columns}"
28615
28691
  :nestingLevel="${(x, c) => c.parent.tableData[x.index]?.nestingLevel}"
28692
+ @click="${async (x, c) => c.parent.onRowClick(x.index)}"
28616
28693
  @row-action-menu-beforetoggle="${(_, c) => c.parent.onRowActionMenuBeforeToggle(c.event)}"
28617
28694
  @row-action-menu-toggle="${(_, c) => c.parent.onRowActionMenuToggle(c.event)}"
28618
28695
  >
@@ -29446,7 +29523,8 @@
29446
29523
  columnSort: false,
29447
29524
  columnWidths: false,
29448
29525
  columnDefinition: false,
29449
- actionMenuSlots: false
29526
+ actionMenuSlots: false,
29527
+ selectionMode: false
29450
29528
  };
29451
29529
  this.updateQueued = false;
29452
29530
  this.table = table;
@@ -29472,11 +29550,15 @@
29472
29550
  get updateActionMenuSlots() {
29473
29551
  return this.requiredUpdates.actionMenuSlots;
29474
29552
  }
29553
+ get updateSelectionMode() {
29554
+ return this.requiredUpdates.selectionMode;
29555
+ }
29475
29556
  get requiresTanStackUpdate() {
29476
29557
  return (this.requiredUpdates.rowIds
29477
29558
  || this.requiredUpdates.columnSort
29478
29559
  || this.requiredUpdates.columnDefinition
29479
- || this.requiredUpdates.groupRows);
29560
+ || this.requiredUpdates.groupRows
29561
+ || this.requiredUpdates.selectionMode);
29480
29562
  }
29481
29563
  get requiresTanStackDataReset() {
29482
29564
  return (this.requiredUpdates.rowIds || this.requiredUpdates.columnDefinition);
@@ -29485,6 +29567,9 @@
29485
29567
  this.setAllKeys(true);
29486
29568
  this.queueUpdate();
29487
29569
  }
29570
+ get hasPendingUpdates() {
29571
+ return this.updateQueued;
29572
+ }
29488
29573
  trackColumnPropertyChanged(changedColumnProperty) {
29489
29574
  if (isColumnProperty(changedColumnProperty, 'columnId')) {
29490
29575
  this.requiredUpdates.columnIds = true;
@@ -29519,6 +29604,10 @@
29519
29604
  this.requiredUpdates.rowIds = true;
29520
29605
  this.queueUpdate();
29521
29606
  }
29607
+ trackSelectionModeChanged() {
29608
+ this.requiredUpdates.selectionMode = true;
29609
+ this.queueUpdate();
29610
+ }
29522
29611
  setAllKeys(value) {
29523
29612
  Object.keys(this.requiredUpdates).forEach(key => {
29524
29613
  this.requiredUpdates[key] = value;
@@ -29569,6 +29658,7 @@
29569
29658
  class Table extends FoundationElement {
29570
29659
  constructor() {
29571
29660
  super();
29661
+ this.selectionMode = TableRowSelectionMode.none;
29572
29662
  /**
29573
29663
  * @internal
29574
29664
  */
@@ -29600,6 +29690,7 @@
29600
29690
  this.tableValidator = new TableValidator();
29601
29691
  this.updateTracker = new UpdateTracker(this);
29602
29692
  this.columnNotifiers = [];
29693
+ this.isInitialized = false;
29603
29694
  this.collapsedRows = new Set();
29604
29695
  this.onViewPortScroll = (event) => {
29605
29696
  this.scrollX = event.target.scrollLeft;
@@ -29617,6 +29708,16 @@
29617
29708
  }
29618
29709
  return !this.collapsedRows.has(row.id);
29619
29710
  };
29711
+ this.handleRowSelectionChange = (updaterOrValue) => {
29712
+ const rowSelectionState = updaterOrValue instanceof Function
29713
+ ? updaterOrValue(this.table.getState().rowSelection)
29714
+ : updaterOrValue;
29715
+ this.updateTableOptions({
29716
+ state: {
29717
+ rowSelection: rowSelectionState
29718
+ }
29719
+ });
29720
+ };
29620
29721
  this.handleExpandedChange = (updaterOrValue) => {
29621
29722
  const expandedState = updaterOrValue instanceof Function
29622
29723
  ? updaterOrValue(this.table.getState().expanded)
@@ -29630,6 +29731,7 @@
29630
29731
  this.options = {
29631
29732
  data: [],
29632
29733
  onStateChange: (_) => { },
29734
+ onRowSelectionChange: this.handleRowSelectionChange,
29633
29735
  onExpandedChange: this.handleExpandedChange,
29634
29736
  getCoreRowModel: getCoreRowModel(),
29635
29737
  getSortedRowModel: getSortedRowModel(),
@@ -29638,9 +29740,11 @@
29638
29740
  getIsRowExpanded: this.getIsRowExpanded,
29639
29741
  columns: [],
29640
29742
  state: {
29743
+ rowSelection: {},
29641
29744
  grouping: [],
29642
29745
  expanded: true // Workaround until we can apply a fix to TanStack regarding leveraging our getIsRowExpanded implementation
29643
29746
  },
29747
+ enableRowSelection: false,
29644
29748
  enableSorting: true,
29645
29749
  enableGrouping: true,
29646
29750
  renderFallbackValue: null,
@@ -29652,14 +29756,54 @@
29652
29756
  get validity() {
29653
29757
  return this.tableValidator.getValidity();
29654
29758
  }
29655
- setData(newData) {
29656
- this.setTableData(newData);
29759
+ async setData(newData) {
29760
+ await this.processPendingUpdates();
29761
+ const data = newData.map(record => {
29762
+ return { ...record };
29763
+ });
29764
+ const tanStackUpdates = {
29765
+ data
29766
+ };
29767
+ this.validateWithData(data);
29768
+ if (this.tableValidator.areRecordIdsValid()) {
29769
+ // Update the selection state to remove previously selected records that no longer exist in the
29770
+ // data set while maintaining the selection state of records that still exist in the data set.
29771
+ const previousSelection = await this.getSelectedRecordIds();
29772
+ tanStackUpdates.state = {
29773
+ rowSelection: this.calculateTanStackSelectionState(previousSelection)
29774
+ };
29775
+ }
29776
+ this.updateTableOptions(tanStackUpdates);
29777
+ }
29778
+ async getSelectedRecordIds() {
29779
+ await this.processPendingUpdates();
29780
+ const tanStackSelectionState = this.options.state.rowSelection;
29781
+ if (!tanStackSelectionState) {
29782
+ return [];
29783
+ }
29784
+ const selectedRecordIds = [];
29785
+ Object.entries(tanStackSelectionState).forEach(([recordId, isSelected]) => {
29786
+ if (isSelected) {
29787
+ selectedRecordIds.push(recordId);
29788
+ }
29789
+ });
29790
+ return selectedRecordIds;
29791
+ }
29792
+ async setSelectedRecordIds(recordIds) {
29793
+ await this.processPendingUpdates();
29794
+ if (this.selectionMode === TableRowSelectionMode.none) {
29795
+ return;
29796
+ }
29797
+ this.updateTableOptions({
29798
+ state: {
29799
+ rowSelection: this.calculateTanStackSelectionState(recordIds)
29800
+ }
29801
+ });
29657
29802
  }
29658
29803
  connectedCallback() {
29659
29804
  super.connectedCallback();
29805
+ this.initialize();
29660
29806
  this.virtualizer.connectedCallback();
29661
- this.updateTracker.trackAllStateChanged();
29662
- this.observeColumns();
29663
29807
  this.viewport.addEventListener('scroll', this.onViewPortScroll, {
29664
29808
  passive: true
29665
29809
  });
@@ -29667,7 +29811,6 @@
29667
29811
  disconnectedCallback() {
29668
29812
  super.disconnectedCallback();
29669
29813
  this.virtualizer.disconnectedCallback();
29670
- this.removeColumnObservers();
29671
29814
  this.viewport.removeEventListener('scroll', this.onViewPortScroll);
29672
29815
  }
29673
29816
  checkValidity() {
@@ -29685,11 +29828,33 @@
29685
29828
  this.updateTracker.trackColumnPropertyChanged(args);
29686
29829
  }
29687
29830
  }
29831
+ /** @internal */
29832
+ async onRowClick(rowIndex) {
29833
+ if (this.selectionMode === TableRowSelectionMode.none) {
29834
+ return;
29835
+ }
29836
+ const row = this.table.getRowModel().rows[rowIndex];
29837
+ if (!row) {
29838
+ return;
29839
+ }
29840
+ const currentSelection = await this.getSelectedRecordIds();
29841
+ if (currentSelection.length === 1 && currentSelection[0] === row.id) {
29842
+ // The clicked row is already the only selected row. Do nothing.
29843
+ return;
29844
+ }
29845
+ this.table.toggleAllRowsSelected(false);
29846
+ row.toggleSelected(true);
29847
+ await this.emitSelectionChangeEvent();
29848
+ }
29849
+ /** @internal */
29688
29850
  onRowActionMenuBeforeToggle(event) {
29851
+ event.stopImmediatePropagation();
29689
29852
  this.openActionMenuRecordId = event.detail.recordIds[0];
29690
29853
  this.$emit('action-menu-beforetoggle', event.detail);
29691
29854
  }
29855
+ /** @internal */
29692
29856
  onRowActionMenuToggle(event) {
29857
+ event.stopImmediatePropagation();
29693
29858
  this.$emit('action-menu-toggle', event.detail);
29694
29859
  if (!event.detail.newState) {
29695
29860
  this.openActionMenuRecordId = undefined;
@@ -29714,6 +29879,12 @@
29714
29879
  this.updateRowGridColumns();
29715
29880
  }
29716
29881
  }
29882
+ selectionModeChanged(_prev, _next) {
29883
+ if (!this.$fastController.isConnected) {
29884
+ return;
29885
+ }
29886
+ this.updateTracker.trackSelectionModeChanged();
29887
+ }
29717
29888
  idFieldNameChanged(_prev, _next) {
29718
29889
  if (!this.$fastController.isConnected) {
29719
29890
  return;
@@ -29733,6 +29904,24 @@
29733
29904
  });
29734
29905
  this.columnNotifiers = [];
29735
29906
  }
29907
+ initialize() {
29908
+ if (this.isInitialized) {
29909
+ // The table is already initialized. There is nothing more to do.
29910
+ return;
29911
+ }
29912
+ this.isInitialized = true;
29913
+ // Initialize the controller to ensure that FAST functionality such as Observables work as expected.
29914
+ this.$fastController.onConnectedCallback();
29915
+ this.updateTracker.trackAllStateChanged();
29916
+ this.observeColumns();
29917
+ }
29918
+ async processPendingUpdates() {
29919
+ this.initialize();
29920
+ await DOM.nextUpdate();
29921
+ if (this.updateTracker.hasPendingUpdates) {
29922
+ throw new Error('Expected pending updates to be resolved');
29923
+ }
29924
+ }
29736
29925
  observeColumns() {
29737
29926
  this.removeColumnObservers();
29738
29927
  for (const column of this.columns) {
@@ -29760,9 +29949,8 @@
29760
29949
  this.columns = this.childItems.filter((x) => x instanceof TableColumn);
29761
29950
  }
29762
29951
  updateTanStack() {
29763
- const updatedOptions = {
29764
- state: {}
29765
- };
29952
+ const updatedOptions = {};
29953
+ updatedOptions.state = {};
29766
29954
  if (this.updateTracker.updateColumnSort) {
29767
29955
  updatedOptions.state.sorting = this.calculateTanStackSortState();
29768
29956
  }
@@ -29771,6 +29959,11 @@
29771
29959
  }
29772
29960
  if (this.updateTracker.updateRowIds) {
29773
29961
  updatedOptions.getRowId = this.calculateTanStackRowIdFunction();
29962
+ updatedOptions.state.rowSelection = {};
29963
+ }
29964
+ if (this.updateTracker.updateSelectionMode) {
29965
+ updatedOptions.enableRowSelection = this.selectionMode !== TableRowSelectionMode.none;
29966
+ updatedOptions.state.rowSelection = {};
29774
29967
  }
29775
29968
  if (this.updateTracker.requiresTanStackDataReset) {
29776
29969
  // Perform a shallow copy of the data to trigger tanstack to regenerate the row models and columns.
@@ -29796,6 +29989,7 @@
29796
29989
  this.rowGridColumns = TableLayoutHelper.getGridTemplateColumns(this.columns);
29797
29990
  }
29798
29991
  validate() {
29992
+ this.tableValidator.validateSelectionMode(this.selectionMode, this.idFieldName);
29799
29993
  this.tableValidator.validateColumnIds(this.columns.map(x => x.columnId));
29800
29994
  this.tableValidator.validateColumnSortIndices(this.getColumnsParticipatingInSorting().map(x => x.sortIndex));
29801
29995
  this.tableValidator.validateColumnGroupIndices(this.getColumnsParticipatingInGrouping().map(x => x.internalGroupIndex));
@@ -29805,14 +29999,11 @@
29805
29999
  this.tableValidator.validateRecordIds(data, this.idFieldName);
29806
30000
  this.canRenderRows = this.checkValidity();
29807
30001
  }
29808
- setTableData(newData) {
29809
- const data = newData.map(record => {
29810
- return { ...record };
29811
- });
29812
- this.validateWithData(data);
29813
- this.updateTableOptions({
29814
- data
29815
- });
30002
+ async emitSelectionChangeEvent() {
30003
+ const detail = {
30004
+ selectedRecordIds: await this.getSelectedRecordIds()
30005
+ };
30006
+ this.$emit('selection-change', detail);
29816
30007
  }
29817
30008
  refreshRows() {
29818
30009
  const rows = this.table.getRowModel().rows;
@@ -29820,6 +30011,9 @@
29820
30011
  const rowState = {
29821
30012
  record: row.original,
29822
30013
  id: row.id,
30014
+ selectionState: row.getIsSelected()
30015
+ ? TableRowSelectionState.selected
30016
+ : TableRowSelectionState.notSelected,
29823
30017
  isGrouped: row.getIsGrouped(),
29824
30018
  isExpanded: row.getIsExpanded(),
29825
30019
  groupRowValue: row.getIsGrouped()
@@ -29900,10 +30094,26 @@
29900
30094
  };
29901
30095
  });
29902
30096
  }
30097
+ calculateTanStackSelectionState(recordIdsToSelect) {
30098
+ if (this.selectionMode === TableRowSelectionMode.none) {
30099
+ return {};
30100
+ }
30101
+ const tanstackSelectionState = {};
30102
+ const selectableRecordIds = this.tableValidator.getPresentRecordIds(recordIdsToSelect);
30103
+ if (selectableRecordIds.length) {
30104
+ // In single selection mode, only select the first record ID that is requested
30105
+ const firstSelectableRecordId = selectableRecordIds[0];
30106
+ tanstackSelectionState[firstSelectableRecordId] = true;
30107
+ }
30108
+ return tanstackSelectionState;
30109
+ }
29903
30110
  }
29904
30111
  __decorate$1([
29905
30112
  attr({ attribute: 'id-field-name' })
29906
30113
  ], Table.prototype, "idFieldName", void 0);
30114
+ __decorate$1([
30115
+ attr({ attribute: 'selection-mode' })
30116
+ ], Table.prototype, "selectionMode", void 0);
29907
30117
  __decorate$1([
29908
30118
  observable
29909
30119
  ], Table.prototype, "tableData", void 0);