@sebgroup/green-core 3.8.1 → 3.10.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.
Files changed (43) hide show
  1. package/components/card/card.styles.js +1 -0
  2. package/components/card-linked/card-linked.styles.js +1 -1
  3. package/components/table/table.component.d.ts +27 -7
  4. package/components/table/table.component.js +730 -101
  5. package/components/table/table.imports.js +8 -0
  6. package/components/table/table.stories.data.d.ts +8 -5
  7. package/components/table/table.stories.data.js +705 -31
  8. package/components/table/table.styles.js +409 -189
  9. package/components/table/table.types.d.ts +97 -11
  10. package/custom-elements.json +4838 -4724
  11. package/gds-element.js +1 -1
  12. package/generated/locales/da.d.ts +4 -1
  13. package/generated/locales/da.js +4 -1
  14. package/generated/locales/de.d.ts +4 -1
  15. package/generated/locales/de.js +4 -1
  16. package/generated/locales/fi.d.ts +4 -1
  17. package/generated/locales/fi.js +4 -1
  18. package/generated/locales/fr.d.ts +4 -1
  19. package/generated/locales/fr.js +4 -1
  20. package/generated/locales/it.d.ts +4 -1
  21. package/generated/locales/it.js +4 -1
  22. package/generated/locales/nl.d.ts +4 -1
  23. package/generated/locales/nl.js +4 -1
  24. package/generated/locales/no.d.ts +4 -1
  25. package/generated/locales/no.js +4 -1
  26. package/generated/locales/sv.d.ts +4 -1
  27. package/generated/locales/sv.js +4 -1
  28. package/generated/mcp/card-pattern-01/api.md +2 -1
  29. package/generated/mcp/components.json +1 -1
  30. package/generated/mcp/icons.json +1 -1
  31. package/generated/mcp/index.json +1 -1
  32. package/generated/mcp/table/angular.md +1 -0
  33. package/generated/mcp/table/api.md +32 -2
  34. package/generated/mcp/table/react.md +1 -0
  35. package/generated/mcp/tokens.json +1 -1
  36. package/generated/react/index.d.ts +9 -9
  37. package/generated/react/index.js +9 -9
  38. package/generated/react/table/index.d.ts +10 -4
  39. package/package.json +1 -1
  40. package/patterns/card-pattern-01/card-pattern-01.component.d.ts +2 -1
  41. package/patterns/card-pattern-01/card-pattern-01.component.js +49 -25
  42. package/shared-styles/rbcb-toggle.style.js +1 -1
  43. package/utils/helpers/custom-element-scoping.js +1 -1
@@ -5,7 +5,7 @@ import {
5
5
  __privateMethod,
6
6
  __privateSet
7
7
  } from "../../chunks/chunk.CAV4X6PU.js";
8
- var _cache, _cacheDuration, _Density, Density_get, _hasSelection, hasSelection_get, _isAllSelected, isAllSelected_get, _isPartialSelection, isPartialSelection_get, _getCacheKey, getCacheKey_fn, _isCacheValid, isCacheValid_fn, _loadData, loadData_fn, _getRowKey, getRowKey_fn, _renderCellWrapped, renderCellWrapped_fn, _renderMobileLabel, renderMobileLabel_fn, _renderSlotElement, renderSlotElement_fn, _renderCellContent, renderCellContent_fn, _renderSortIcon, renderSortIcon_fn, _hasHeaderContent, hasHeaderContent_fn, _renderHeaderControls, renderHeaderControls_fn, _renderColumnHeader, renderColumnHeader_fn, _renderActionsHeader, renderActionsHeader_fn, _renderSelectableHeader, renderSelectableHeader_fn, _renderColumnHeaders, renderColumnHeaders_fn, _renderTableHeader, renderTableHeader_fn, _renderTableCell, renderTableCell_fn, _renderSelectableCell, renderSelectableCell_fn, _renderRowCells, renderRowCells_fn, _renderActionsCell, renderActionsCell_fn, _renderTableRow, renderTableRow_fn, _renderCheckbox, renderCheckbox_fn, _renderSkeletonCell, renderSkeletonCell_fn, _renderSkeletonRow, renderSkeletonRow_fn, _renderTableBody, renderTableBody_fn, _renderTableFoot, renderTableFoot_fn, _renderTable, renderTable_fn, _renderErrorState, renderErrorState_fn, _renderEmptyState, renderEmptyState_fn, _renderFooter, renderFooter_fn, _renderHeadline, renderHeadline_fn, _handleSearch, handleSearch_fn, _handleSearchClear, handleSearchClear_fn, _handleSort, handleSort_fn, _handlePageChange, handlePageChange_fn, _handlePageSizeChange, handlePageSizeChange_fn, _handleColumnVisibility, handleColumnVisibility_fn, _handleSelectAll, handleSelectAll_fn, _handleRowSelect, handleRowSelect_fn, _selectAllInternal, selectAllInternal_fn, _clearSelectionInternal, clearSelectionInternal_fn, _emitSelectionChange, emitSelectionChange_fn, _initializeScrollTracking, initializeScrollTracking_fn, _updateVerticalScrollState, updateVerticalScrollState_fn, _updateHorizontalScrollState, updateHorizontalScrollState_fn;
8
+ var _cache, _cacheDuration, _isResponsiveStacked, isResponsiveStacked_get, _isExpandableEnabled, isExpandableEnabled_get, _isSelectableEnabled, isSelectableEnabled_get, _Density, Density_get, _expandTransitionTimers, _expandedLoadingExitDuration, _hasSelection, hasSelection_get, _isAllSelected, isAllSelected_get, _isPartialSelection, isPartialSelection_get, _expandableIndices, expandableIndices_get, _isAllExpanded, isAllExpanded_get, _getCacheKey, getCacheKey_fn, _clearExpansionTransitionTimer, clearExpansionTransitionTimer_fn, _clearExpansionLoadingState, clearExpansionLoadingState_fn, _clearAllExpansionLoadingStates, clearAllExpansionLoadingStates_fn, _scheduleExpansionContentReveal, scheduleExpansionContentReveal_fn, _isCacheValid, isCacheValid_fn, _loadData, loadData_fn, _getStickyBorderKeys, getStickyBorderKeys_fn, _updateStickyOffsets, updateStickyOffsets_fn, _getRowKey, getRowKey_fn, _renderCellWrapped, renderCellWrapped_fn, _renderMobileLabel, renderMobileLabel_fn, _renderSlotElement, renderSlotElement_fn, _renderCellContent, renderCellContent_fn, _renderSortIcon, renderSortIcon_fn, _hasHeaderContent, hasHeaderContent_fn, _renderHeaderControls, renderHeaderControls_fn, _renderColumnHeader, renderColumnHeader_fn, _renderSelectableHeader, renderSelectableHeader_fn, _renderExpandableHeader, renderExpandableHeader_fn, _getRowSubRowsSource, getRowSubRowsSource_fn, _getRowFullContentSource, getRowFullContentSource_fn, _getExpandedRows, getExpandedRows_fn, _hasAsyncSubRows, hasAsyncSubRows_fn, _hasAsyncFullContent, hasAsyncFullContent_fn, _getSubRowCount, getSubRowCount_fn, _hasExpandedFullSlot, hasExpandedFullSlot_fn, _hasExpandedFullContent, hasExpandedFullContent_fn, _isRowExpandable, isRowExpandable_fn, _getExpandedGroupId, getExpandedGroupId_fn, _getRenderedColumnCount, getRenderedColumnCount_fn, _renderColumnHeaders, renderColumnHeaders_fn, _renderTableHeader, renderTableHeader_fn, _renderTableCell, renderTableCell_fn, _renderExpandableCell, renderExpandableCell_fn, _renderSelectableCell, renderSelectableCell_fn, _renderRowCells, renderRowCells_fn, _renderFullWidthDetailsRow, renderFullWidthDetailsRow_fn, _renderExpandedLoadingRow, renderExpandedLoadingRow_fn, _renderExpandedLoadingRows, renderExpandedLoadingRows_fn, _renderExpandedFullLoadingRow, renderExpandedFullLoadingRow_fn, _getExpandedChildRowClasses, getExpandedChildRowClasses_fn, _getTableRowClasses, getTableRowClasses_fn, _getRowAriaExpanded, getRowAriaExpanded_fn, _getTableRowPresentation, getTableRowPresentation_fn, _renderExpandedChildRow, renderExpandedChildRow_fn, _getRowExpansionLoadingKind, getRowExpansionLoadingKind_fn, _getRowExpansionState, getRowExpansionState_fn, _renderExpandedRowContent, renderExpandedRowContent_fn, _renderTableRow, renderTableRow_fn, _renderCheckbox, renderCheckbox_fn, _renderSkeletonCell, renderSkeletonCell_fn, _renderSkeletonRow, renderSkeletonRow_fn, _renderTableBody, renderTableBody_fn, _renderTableFoot, renderTableFoot_fn, _renderTable, renderTable_fn, _renderErrorState, renderErrorState_fn, _renderEmptyState, renderEmptyState_fn, _renderFooter, renderFooter_fn, _renderHeadline, renderHeadline_fn, _handleSearch, handleSearch_fn, _handleSearchClear, handleSearchClear_fn, _handleSort, handleSort_fn, _handlePageChange, handlePageChange_fn, _handlePageSizeChange, handlePageSizeChange_fn, _handleColumnVisibility, handleColumnVisibility_fn, _handleSelectAll, handleSelectAll_fn, _handleRowSelect, handleRowSelect_fn, _handleExpandToggle, handleExpandToggle_fn, _handleExpandAll, handleExpandAll_fn, _emitExpandChange, emitExpandChange_fn, _resolveExpandedContent, resolveExpandedContent_fn, _setRowExpanded, setRowExpanded_fn, _selectAllInternal, selectAllInternal_fn, _clearSelectionInternal, clearSelectionInternal_fn, _emitSelectionChange, emitSelectionChange_fn, _initializeScrollTracking, initializeScrollTracking_fn, _updateVerticalScrollState, updateVerticalScrollState_fn, _updateHorizontalScrollState, updateHorizontalScrollState_fn;
9
9
  import { localized, msg } from "@lit/localize";
10
10
  import { property, state } from "lit/decorators.js";
11
11
  import { classMap } from "lit/directives/class-map.js";
@@ -26,6 +26,9 @@ import * as Types from "./table.types.js";
26
26
  let GdsTable = class extends GdsElement {
27
27
  constructor() {
28
28
  super(...arguments);
29
+ __privateAdd(this, _isResponsiveStacked);
30
+ __privateAdd(this, _isExpandableEnabled);
31
+ __privateAdd(this, _isSelectableEnabled);
29
32
  /**
30
33
  * Get the current density configuration
31
34
  */
@@ -33,9 +36,26 @@ let GdsTable = class extends GdsElement {
33
36
  __privateAdd(this, _hasSelection);
34
37
  __privateAdd(this, _isAllSelected);
35
38
  __privateAdd(this, _isPartialSelection);
39
+ __privateAdd(this, _expandableIndices);
40
+ __privateAdd(this, _isAllExpanded);
36
41
  __privateAdd(this, _getCacheKey);
42
+ __privateAdd(this, _clearExpansionTransitionTimer);
43
+ __privateAdd(this, _clearExpansionLoadingState);
44
+ __privateAdd(this, _clearAllExpansionLoadingStates);
45
+ __privateAdd(this, _scheduleExpansionContentReveal);
37
46
  __privateAdd(this, _isCacheValid);
38
47
  __privateAdd(this, _loadData);
48
+ /**
49
+ * Returns the column keys for the rightmost sticky-left and leftmost sticky-right
50
+ * visible columns — these are the ones that get the divider border.
51
+ */
52
+ __privateAdd(this, _getStickyBorderKeys);
53
+ /**
54
+ * Measures built-in and user-defined sticky column widths from the DOM
55
+ * and applies matching left/right inline styles to every cell in each
56
+ * sticky column. Uses offsetWidth (layout-relative, scroll-independent).
57
+ */
58
+ __privateAdd(this, _updateStickyOffsets);
39
59
  /**
40
60
  * Gets the unique key for slot naming (prioritizes: custom key > row.id > index)
41
61
  */
@@ -59,14 +79,38 @@ let GdsTable = class extends GdsElement {
59
79
  __privateAdd(this, _hasHeaderContent);
60
80
  __privateAdd(this, _renderHeaderControls);
61
81
  __privateAdd(this, _renderColumnHeader);
62
- __privateAdd(this, _renderActionsHeader);
63
82
  __privateAdd(this, _renderSelectableHeader);
83
+ __privateAdd(this, _renderExpandableHeader);
84
+ __privateAdd(this, _getRowSubRowsSource);
85
+ __privateAdd(this, _getRowFullContentSource);
86
+ __privateAdd(this, _getExpandedRows);
87
+ __privateAdd(this, _hasAsyncSubRows);
88
+ __privateAdd(this, _hasAsyncFullContent);
89
+ __privateAdd(this, _getSubRowCount);
90
+ __privateAdd(this, _hasExpandedFullSlot);
91
+ __privateAdd(this, _hasExpandedFullContent);
92
+ __privateAdd(this, _isRowExpandable);
93
+ __privateAdd(this, _getExpandedGroupId);
94
+ __privateAdd(this, _getRenderedColumnCount);
64
95
  __privateAdd(this, _renderColumnHeaders);
65
96
  __privateAdd(this, _renderTableHeader);
66
97
  __privateAdd(this, _renderTableCell);
98
+ __privateAdd(this, _renderExpandableCell);
67
99
  __privateAdd(this, _renderSelectableCell);
68
100
  __privateAdd(this, _renderRowCells);
69
- __privateAdd(this, _renderActionsCell);
101
+ __privateAdd(this, _renderFullWidthDetailsRow);
102
+ __privateAdd(this, _renderExpandedLoadingRow);
103
+ __privateAdd(this, _renderExpandedLoadingRows);
104
+ __privateAdd(this, _renderExpandedFullLoadingRow);
105
+ __privateAdd(this, _getExpandedChildRowClasses);
106
+ __privateAdd(this, _getTableRowClasses);
107
+ __privateAdd(this, _getRowAriaExpanded);
108
+ __privateAdd(this, _getTableRowPresentation);
109
+ __privateAdd(this, _renderExpandedChildRow);
110
+ __privateAdd(this, _getRowExpansionLoadingKind);
111
+ __privateAdd(this, _getRowExpansionState);
112
+ __privateAdd(this, _renderExpandedRowContent);
113
+ /* Main Table Row · Render */
70
114
  __privateAdd(this, _renderTableRow);
71
115
  __privateAdd(this, _renderCheckbox);
72
116
  __privateAdd(this, _renderSkeletonCell);
@@ -116,6 +160,11 @@ let GdsTable = class extends GdsElement {
116
160
  * Handles individual row selection change
117
161
  */
118
162
  __privateAdd(this, _handleRowSelect);
163
+ __privateAdd(this, _handleExpandToggle);
164
+ __privateAdd(this, _handleExpandAll);
165
+ __privateAdd(this, _emitExpandChange);
166
+ __privateAdd(this, _resolveExpandedContent);
167
+ __privateAdd(this, _setRowExpanded);
119
168
  /**
120
169
  * Internal method to select all rows
121
170
  */
@@ -174,7 +223,14 @@ let GdsTable = class extends GdsElement {
174
223
  this._rowsState = [];
175
224
  this._total = 0;
176
225
  this._selected = /* @__PURE__ */ new Set();
226
+ this._expanded = /* @__PURE__ */ new Set();
227
+ this._expanding = /* @__PURE__ */ new Set();
228
+ this._completingExpansion = /* @__PURE__ */ new Set();
229
+ this._expandedRowsCache = /* @__PURE__ */ new Map();
230
+ this._expandedFullContentResolved = /* @__PURE__ */ new Set();
177
231
  this._error = null;
232
+ __privateAdd(this, _expandTransitionTimers, /* @__PURE__ */ new Map());
233
+ __privateAdd(this, _expandedLoadingExitDuration, 140);
178
234
  }
179
235
  _handleMobile(matches) {
180
236
  this._isMobile = matches;
@@ -206,8 +262,13 @@ let GdsTable = class extends GdsElement {
206
262
  super.connectedCallback();
207
263
  this.updateComplete.then(() => {
208
264
  __privateMethod(this, _initializeScrollTracking, initializeScrollTracking_fn).call(this);
265
+ __privateMethod(this, _updateStickyOffsets, updateStickyOffsets_fn).call(this);
209
266
  });
210
267
  }
268
+ updated(changedProperties) {
269
+ super.updated(changedProperties);
270
+ __privateMethod(this, _updateStickyOffsets, updateStickyOffsets_fn).call(this);
271
+ }
211
272
  render() {
212
273
  const classes = {
213
274
  table: true,
@@ -270,13 +331,55 @@ let GdsTable = class extends GdsElement {
270
331
  data: indices.map((i) => this._rowsState[i])
271
332
  };
272
333
  }
334
+ /**
335
+ * Expand a specific row by index.
336
+ */
337
+ async expandRow(index) {
338
+ return __privateMethod(this, _setRowExpanded, setRowExpanded_fn).call(this, index, true);
339
+ }
340
+ /**
341
+ * Collapse a specific row by index.
342
+ */
343
+ collapseRow(index) {
344
+ void __privateMethod(this, _setRowExpanded, setRowExpanded_fn).call(this, index, false);
345
+ return true;
346
+ }
347
+ /**
348
+ * Toggle expanded state for a specific row by index.
349
+ */
350
+ async toggleRowExpansion(index, rowOverride) {
351
+ if (index < 0 || index >= this._rowsState.length)
352
+ return false;
353
+ const nextExpanded = !this._expanded.has(index);
354
+ return __privateMethod(this, _setRowExpanded, setRowExpanded_fn).call(this, index, nextExpanded, rowOverride);
355
+ }
356
+ /**
357
+ * Get currently expanded row indices.
358
+ */
359
+ getExpandedIndices() {
360
+ return Array.from(this._expanded);
361
+ }
273
362
  };
274
363
  _cache = new WeakMap();
275
364
  _cacheDuration = new WeakMap();
365
+ _isResponsiveStacked = new WeakSet();
366
+ isResponsiveStacked_get = function() {
367
+ return this.responsive && this._isMobile;
368
+ };
369
+ _isExpandableEnabled = new WeakSet();
370
+ isExpandableEnabled_get = function() {
371
+ return !__privateGet(this, _isResponsiveStacked, isResponsiveStacked_get) && __privateGet(this, _expandableIndices, expandableIndices_get).length > 0;
372
+ };
373
+ _isSelectableEnabled = new WeakSet();
374
+ isSelectableEnabled_get = function() {
375
+ return this.selectable && !__privateGet(this, _isResponsiveStacked, isResponsiveStacked_get);
376
+ };
276
377
  _Density = new WeakSet();
277
378
  Density_get = function() {
278
379
  return Types.DENSITY_CONFIG[this.density];
279
380
  };
381
+ _expandTransitionTimers = new WeakMap();
382
+ _expandedLoadingExitDuration = new WeakMap();
280
383
  _hasSelection = new WeakSet();
281
384
  hasSelection_get = function() {
282
385
  return this._selected.size > 0;
@@ -289,6 +392,15 @@ _isPartialSelection = new WeakSet();
289
392
  isPartialSelection_get = function() {
290
393
  return __privateGet(this, _hasSelection, hasSelection_get) && !__privateGet(this, _isAllSelected, isAllSelected_get);
291
394
  };
395
+ _expandableIndices = new WeakSet();
396
+ expandableIndices_get = function() {
397
+ return this._rowsState.map((row, i) => __privateMethod(this, _isRowExpandable, isRowExpandable_fn).call(this, row, i) ? i : -1).filter((i) => i !== -1);
398
+ };
399
+ _isAllExpanded = new WeakSet();
400
+ isAllExpanded_get = function() {
401
+ const expandable = __privateGet(this, _expandableIndices, expandableIndices_get);
402
+ return expandable.length > 0 && expandable.every((i) => this._expanded.has(i));
403
+ };
292
404
  _getCacheKey = new WeakSet();
293
405
  getCacheKey_fn = function() {
294
406
  return JSON.stringify({
@@ -299,6 +411,48 @@ getCacheKey_fn = function() {
299
411
  searchQuery: this._view.searchQuery
300
412
  });
301
413
  };
414
+ _clearExpansionTransitionTimer = new WeakSet();
415
+ clearExpansionTransitionTimer_fn = function(index) {
416
+ const timer = __privateGet(this, _expandTransitionTimers).get(index);
417
+ if (timer === void 0)
418
+ return;
419
+ window.clearTimeout(timer);
420
+ __privateGet(this, _expandTransitionTimers).delete(index);
421
+ };
422
+ _clearExpansionLoadingState = new WeakSet();
423
+ clearExpansionLoadingState_fn = function(index) {
424
+ __privateMethod(this, _clearExpansionTransitionTimer, clearExpansionTransitionTimer_fn).call(this, index);
425
+ if (this._expanding.has(index)) {
426
+ const nextExpanding = new Set(this._expanding);
427
+ nextExpanding.delete(index);
428
+ this._expanding = nextExpanding;
429
+ }
430
+ if (this._completingExpansion.has(index)) {
431
+ const nextCompleting = new Set(this._completingExpansion);
432
+ nextCompleting.delete(index);
433
+ this._completingExpansion = nextCompleting;
434
+ }
435
+ };
436
+ _clearAllExpansionLoadingStates = new WeakSet();
437
+ clearAllExpansionLoadingStates_fn = function() {
438
+ __privateGet(this, _expandTransitionTimers).forEach((timer) => window.clearTimeout(timer));
439
+ __privateGet(this, _expandTransitionTimers).clear();
440
+ this._expanding.clear();
441
+ this._completingExpansion.clear();
442
+ };
443
+ _scheduleExpansionContentReveal = new WeakSet();
444
+ scheduleExpansionContentReveal_fn = function(index) {
445
+ __privateMethod(this, _clearExpansionTransitionTimer, clearExpansionTransitionTimer_fn).call(this, index);
446
+ const nextCompleting = new Set(this._completingExpansion);
447
+ nextCompleting.add(index);
448
+ this._completingExpansion = nextCompleting;
449
+ this.requestUpdate();
450
+ const timer = window.setTimeout(() => {
451
+ __privateMethod(this, _clearExpansionLoadingState, clearExpansionLoadingState_fn).call(this, index);
452
+ this.requestUpdate();
453
+ }, __privateGet(this, _expandedLoadingExitDuration));
454
+ __privateGet(this, _expandTransitionTimers).set(index, timer);
455
+ };
302
456
  _isCacheValid = new WeakSet();
303
457
  isCacheValid_fn = function(entry) {
304
458
  return Date.now() - entry.timestamp < __privateGet(this, _cacheDuration);
@@ -313,6 +467,10 @@ loadData_fn = async function() {
313
467
  if (cachedData && __privateMethod(this, _isCacheValid, isCacheValid_fn).call(this, cachedData)) {
314
468
  this._rowsState = cachedData.rows;
315
469
  this._total = cachedData.total;
470
+ this._expanded.clear();
471
+ __privateMethod(this, _clearAllExpansionLoadingStates, clearAllExpansionLoadingStates_fn).call(this);
472
+ this._expandedRowsCache.clear();
473
+ this._expandedFullContentResolved.clear();
316
474
  this._loaded = false;
317
475
  this.dispatchCustomEvent("gds-table-data-loaded", {
318
476
  detail: {
@@ -350,6 +508,10 @@ loadData_fn = async function() {
350
508
  this._rowsState = response.rows;
351
509
  this._total = response.total;
352
510
  this._selected.clear();
511
+ this._expanded.clear();
512
+ __privateMethod(this, _clearAllExpansionLoadingStates, clearAllExpansionLoadingStates_fn).call(this);
513
+ this._expandedRowsCache.clear();
514
+ this._expandedFullContentResolved.clear();
353
515
  this._loaded = false;
354
516
  this.dispatchCustomEvent("gds-table-data-loaded", {
355
517
  detail: {
@@ -372,6 +534,58 @@ loadData_fn = async function() {
372
534
  this._loading = false;
373
535
  }
374
536
  };
537
+ _getStickyBorderKeys = new WeakSet();
538
+ getStickyBorderKeys_fn = function() {
539
+ const visible = this.columns.filter(
540
+ (c) => this._view.visibleColumns.has(c.key)
541
+ );
542
+ const leftCols = visible.filter((c) => c.sticky === "left");
543
+ const rightCols = visible.filter((c) => c.sticky === "right");
544
+ return {
545
+ lastLeft: leftCols.length ? leftCols[leftCols.length - 1].key : null,
546
+ lastRight: rightCols.length ? rightCols[0].key : null
547
+ };
548
+ };
549
+ _updateStickyOffsets = new WeakSet();
550
+ updateStickyOffsets_fn = function() {
551
+ const root = this.shadowRoot;
552
+ if (!root)
553
+ return;
554
+ const leftHeaders = Array.from(
555
+ root.querySelectorAll("thead th.sticky-left")
556
+ );
557
+ const rightHeaders = Array.from(
558
+ root.querySelectorAll("thead th.sticky-right")
559
+ );
560
+ const expanderTh = root.querySelector("thead th.expander-cell");
561
+ const checkboxTh = root.querySelector("thead th.checkbox-cell");
562
+ if (!leftHeaders.length && !rightHeaders.length)
563
+ return;
564
+ root.querySelectorAll("[data-col-key]").forEach((el) => {
565
+ el.style.left = "";
566
+ el.style.right = "";
567
+ });
568
+ let leftAccum = (expanderTh?.offsetWidth ?? 0) + (checkboxTh?.offsetWidth ?? 0);
569
+ for (const th of leftHeaders) {
570
+ const key = th.dataset.colKey;
571
+ const offset = `${leftAccum}px`;
572
+ th.style.left = offset;
573
+ leftAccum += th.offsetWidth;
574
+ if (key) {
575
+ root.querySelectorAll(`[data-col-key="${key}"]`).forEach((el) => el.style.left = offset);
576
+ }
577
+ }
578
+ let rightAccum = 0;
579
+ for (const th of [...rightHeaders].reverse()) {
580
+ const key = th.dataset.colKey;
581
+ const offset = `${rightAccum}px`;
582
+ th.style.right = offset;
583
+ rightAccum += th.offsetWidth;
584
+ if (key) {
585
+ root.querySelectorAll(`[data-col-key="${key}"]`).forEach((el) => el.style.right = offset);
586
+ }
587
+ }
588
+ };
375
589
  _getRowKey = new WeakSet();
376
590
  getRowKey_fn = function(row, index, slotKey) {
377
591
  if (typeof slotKey === "string" || typeof slotKey === "number") {
@@ -505,6 +719,7 @@ _renderColumnHeader = new WeakSet();
505
719
  renderColumnHeader_fn = function(column) {
506
720
  const isSorted = this._view.sortColumn === column.key;
507
721
  const sortDirection = this._view.sortDirection;
722
+ const { lastLeft, lastRight } = __privateMethod(this, _getStickyBorderKeys, getStickyBorderKeys_fn).call(this);
508
723
  let ariaLabel = column.label;
509
724
  if (column.sortable) {
510
725
  if (isSorted) {
@@ -521,7 +736,11 @@ renderColumnHeader_fn = function(column) {
521
736
  "sort-desc": isSorted && sortDirection === "desc",
522
737
  [`align-${column.align}`]: !!column.align,
523
738
  [`justify-${column.justify}`]: !!column.justify,
524
- wrap: Boolean(column.width)
739
+ wrap: Boolean(column.width),
740
+ "sticky-left": column.sticky === "left",
741
+ "sticky-right": column.sticky === "right",
742
+ "sticky-left-last": column.sticky === "left" && column.key === lastLeft,
743
+ "sticky-right-last": column.sticky === "right" && column.key === lastRight
525
744
  });
526
745
  const style = styleMap({
527
746
  "--cell-width": column.width
@@ -530,6 +749,7 @@ renderColumnHeader_fn = function(column) {
530
749
  <th
531
750
  class=${classes}
532
751
  style=${style}
752
+ data-col-key=${ifDefined(column.sticky ? column.key : void 0)}
533
753
  aria-sort="${isSorted ? sortDirection === "asc" ? "ascending" : "descending" : "none"}"
534
754
  @click=${column.sortable ? () => __privateMethod(this, _handleSort, handleSort_fn).call(this, column.key) : null}
535
755
  >
@@ -547,45 +767,120 @@ renderColumnHeader_fn = function(column) {
547
767
  </th>
548
768
  `;
549
769
  };
550
- _renderActionsHeader = new WeakSet();
551
- renderActionsHeader_fn = function() {
552
- if (!this.actions || typeof this.actions === "function")
553
- return null;
554
- const label = this.actions.label || msg("Actions");
555
- const classes = classMap({
556
- actions: true,
557
- sticky: Boolean(this.actions.sticky),
558
- wrap: Boolean(this.actions.width),
559
- [`align-${this.actions.align}`]: !!this.actions.align,
560
- [`justify-${this.actions.justify}`]: !!this.actions.justify
561
- });
562
- const style = styleMap({
563
- "--cell-width": this.actions.width
564
- });
565
- return html`
566
- <th class="${classes}" style=${style}>
567
- <div class="column-header">
568
- <div class="column-label">${label}</div>
569
- </div>
570
- </th>
571
- `;
572
- };
573
770
  _renderSelectableHeader = new WeakSet();
574
771
  renderSelectableHeader_fn = function() {
575
- if (!this.selectable)
772
+ if (!__privateGet(this, _isSelectableEnabled, isSelectableEnabled_get))
576
773
  return null;
577
774
  return html`
578
775
  <th class="checkbox-cell">
579
- ${__privateMethod(this, _renderCheckbox, renderCheckbox_fn).call(this, {
776
+ <div class="cell-center">
777
+ ${__privateMethod(this, _renderCheckbox, renderCheckbox_fn).call(this, {
580
778
  checked: __privateGet(this, _isAllSelected, isAllSelected_get),
581
779
  indeterminate: __privateGet(this, _isPartialSelection, isPartialSelection_get),
582
780
  ariaLabel: msg("Select all rows"),
583
781
  onToggle: () => __privateMethod(this, _handleSelectAll, handleSelectAll_fn).call(this, {}),
584
782
  skip: this.disableSelectAll
585
783
  })}
784
+ </div>
586
785
  </th>
587
786
  `;
588
787
  };
788
+ _renderExpandableHeader = new WeakSet();
789
+ renderExpandableHeader_fn = function() {
790
+ if (!__privateGet(this, _isExpandableEnabled, isExpandableEnabled_get))
791
+ return null;
792
+ const allExpanded = __privateGet(this, _isAllExpanded, isAllExpanded_get);
793
+ const label = allExpanded ? msg("Collapse all rows") : msg("Expand all rows");
794
+ return html`
795
+ <th class="expander-cell expander-header">
796
+ <div class="cell-center">
797
+ <gds-button
798
+ rank="tertiary"
799
+ size="small"
800
+ label="${label}"
801
+ @click=${() => __privateMethod(this, _handleExpandAll, handleExpandAll_fn).call(this)}
802
+ >
803
+ ${allExpanded ? html`<gds-icon-chevron-grabber-vertical-reversed></gds-icon-chevron-grabber-vertical-reversed>` : html`<gds-icon-chevron-grabber-vertical></gds-icon-chevron-grabber-vertical>`}
804
+ </gds-button>
805
+ </div>
806
+ </th>
807
+ `;
808
+ };
809
+ _getRowSubRowsSource = new WeakSet();
810
+ getRowSubRowsSource_fn = function(row) {
811
+ if ("subRows" in row) {
812
+ return row.subRows;
813
+ }
814
+ return row?.children;
815
+ };
816
+ _getRowFullContentSource = new WeakSet();
817
+ getRowFullContentSource_fn = function(row) {
818
+ if ("fullContent" in row) {
819
+ return row.fullContent;
820
+ }
821
+ return void 0;
822
+ };
823
+ _getExpandedRows = new WeakSet();
824
+ getExpandedRows_fn = function(_row, index) {
825
+ return this._expandedRowsCache.get(index) ?? [];
826
+ };
827
+ _hasAsyncSubRows = new WeakSet();
828
+ hasAsyncSubRows_fn = function(row) {
829
+ const subRows = __privateMethod(this, _getRowSubRowsSource, getRowSubRowsSource_fn).call(this, row);
830
+ return typeof subRows === "function";
831
+ };
832
+ _hasAsyncFullContent = new WeakSet();
833
+ hasAsyncFullContent_fn = function(row) {
834
+ const fullContent = __privateMethod(this, _getRowFullContentSource, getRowFullContentSource_fn).call(this, row);
835
+ return typeof fullContent === "function";
836
+ };
837
+ _getSubRowCount = new WeakSet();
838
+ getSubRowCount_fn = function(row, index) {
839
+ const fallbackCount = __privateMethod(this, _getExpandedRows, getExpandedRows_fn).call(this, row, index).length || 1;
840
+ const count = Number(row.subRowCount);
841
+ if (!Number.isFinite(count) || count <= 0)
842
+ return fallbackCount;
843
+ return Math.floor(count);
844
+ };
845
+ _hasExpandedFullSlot = new WeakSet();
846
+ hasExpandedFullSlot_fn = function(row, index) {
847
+ const rowKey = __privateMethod(this, _getRowKey, getRowKey_fn).call(this, row, index);
848
+ return Boolean(this.querySelector(`[slot="expand:${rowKey}:full"]`));
849
+ };
850
+ _hasExpandedFullContent = new WeakSet();
851
+ hasExpandedFullContent_fn = function(row, index) {
852
+ return __privateMethod(this, _hasExpandedFullSlot, hasExpandedFullSlot_fn).call(this, row, index);
853
+ };
854
+ _isRowExpandable = new WeakSet();
855
+ isRowExpandable_fn = function(row, index) {
856
+ if (__privateGet(this, _isResponsiveStacked, isResponsiveStacked_get))
857
+ return false;
858
+ if (typeof row.isExpandable === "boolean") {
859
+ return row.isExpandable;
860
+ }
861
+ if (__privateMethod(this, _hasAsyncSubRows, hasAsyncSubRows_fn).call(this, row))
862
+ return true;
863
+ if (__privateMethod(this, _hasAsyncFullContent, hasAsyncFullContent_fn).call(this, row))
864
+ return true;
865
+ if (__privateMethod(this, _getExpandedRows, getExpandedRows_fn).call(this, row, index).length > 0)
866
+ return true;
867
+ return __privateMethod(this, _hasExpandedFullContent, hasExpandedFullContent_fn).call(this, row, index);
868
+ };
869
+ _getExpandedGroupId = new WeakSet();
870
+ getExpandedGroupId_fn = function(row, index) {
871
+ const key = String(__privateMethod(this, _getRowKey, getRowKey_fn).call(this, row, index)).replace(
872
+ /[^a-zA-Z0-9_-]/g,
873
+ "-"
874
+ );
875
+ return `row-expand-group-${key}`;
876
+ };
877
+ _getRenderedColumnCount = new WeakSet();
878
+ getRenderedColumnCount_fn = function() {
879
+ const visibleColumnsCount = this.columns.filter(
880
+ (column) => this._view.visibleColumns.has(column.key)
881
+ ).length;
882
+ return visibleColumnsCount + (__privateGet(this, _isExpandableEnabled, isExpandableEnabled_get) ? 1 : 0) + (__privateGet(this, _isSelectableEnabled, isSelectableEnabled_get) ? 1 : 0);
883
+ };
589
884
  _renderColumnHeaders = new WeakSet();
590
885
  renderColumnHeaders_fn = function() {
591
886
  return this.columns.filter((column) => this._view.visibleColumns.has(column.key)).map((column) => __privateMethod(this, _renderColumnHeader, renderColumnHeader_fn).call(this, column));
@@ -596,9 +891,9 @@ renderTableHeader_fn = function() {
596
891
  <thead>
597
892
  <tr>
598
893
  ${[
894
+ __privateMethod(this, _renderExpandableHeader, renderExpandableHeader_fn).call(this),
599
895
  __privateMethod(this, _renderSelectableHeader, renderSelectableHeader_fn).call(this),
600
- __privateMethod(this, _renderColumnHeaders, renderColumnHeaders_fn).call(this),
601
- __privateMethod(this, _renderActionsHeader, renderActionsHeader_fn).call(this)
896
+ __privateMethod(this, _renderColumnHeaders, renderColumnHeaders_fn).call(this)
602
897
  ]}
603
898
  </tr>
604
899
  </thead>
@@ -606,28 +901,67 @@ renderTableHeader_fn = function() {
606
901
  };
607
902
  _renderTableCell = new WeakSet();
608
903
  renderTableCell_fn = function(row, column, index) {
904
+ const { lastLeft, lastRight } = __privateMethod(this, _getStickyBorderKeys, getStickyBorderKeys_fn).call(this);
609
905
  const classes = classMap({
610
906
  [`align-${column.align}`]: !!column.align,
611
907
  [`justify-${column.justify}`]: !!column.justify,
612
- wrap: Boolean(column.width)
908
+ wrap: Boolean(column.width),
909
+ "sticky-left": column.sticky === "left",
910
+ "sticky-right": column.sticky === "right",
911
+ "sticky-left-last": column.sticky === "left" && column.key === lastLeft,
912
+ "sticky-right-last": column.sticky === "right" && column.key === lastRight
613
913
  });
614
914
  const style = styleMap({
615
915
  "--cell-width": column.width
616
916
  });
617
917
  return html`
618
- <td style=${style} class=${classes}>
918
+ <td
919
+ style=${style}
920
+ class=${classes}
921
+ data-col-key=${ifDefined(column.sticky ? column.key : void 0)}
922
+ >
619
923
  ${__privateMethod(this, _renderCellContent, renderCellContent_fn).call(this, row, column, index)}
620
924
  </td>
621
925
  `;
622
926
  };
927
+ _renderExpandableCell = new WeakSet();
928
+ renderExpandableCell_fn = function(row, index) {
929
+ if (!__privateGet(this, _isExpandableEnabled, isExpandableEnabled_get))
930
+ return null;
931
+ const isExpandable = __privateMethod(this, _isRowExpandable, isRowExpandable_fn).call(this, row, index);
932
+ if (!isExpandable) {
933
+ return html`<td class="expander-cell"></td>`;
934
+ }
935
+ const isExpanded = this._expanded.has(index);
936
+ const groupId = __privateMethod(this, _getExpandedGroupId, getExpandedGroupId_fn).call(this, row, index);
937
+ const actionLabel = isExpanded ? row.collapseLabel || msg("Collapse row") : row.expandLabel || msg("Expand row");
938
+ return html`
939
+ <td class="expander-cell">
940
+ <gds-button
941
+ class="expand-toggle"
942
+ rank="tertiary"
943
+ size="small"
944
+ label="${actionLabel} ${index + 1}"
945
+ aria-expanded=${isExpanded ? "true" : "false"}
946
+ aria-controls=${groupId}
947
+ @click=${() => __privateMethod(this, _handleExpandToggle, handleExpandToggle_fn).call(this, row, index)}
948
+ >
949
+ ${isExpanded ? html`<gds-icon-chevron-top size="s"></gds-icon-chevron-top>` : html`<gds-icon-chevron-bottom
950
+ size="s"
951
+ ></gds-icon-chevron-bottom>`}
952
+ </gds-button>
953
+ </td>
954
+ `;
955
+ };
623
956
  _renderSelectableCell = new WeakSet();
624
957
  renderSelectableCell_fn = function(index) {
625
- if (!this.selectable)
958
+ if (!__privateGet(this, _isSelectableEnabled, isSelectableEnabled_get))
626
959
  return null;
627
960
  const selectRowLabel = `${msg("Select row")} ${index + 1}`;
628
961
  return html`
629
962
  <td class="checkbox-cell">
630
- ${__privateMethod(this, _renderCheckbox, renderCheckbox_fn).call(this, {
963
+ <div class="cell-center">
964
+ ${__privateMethod(this, _renderCheckbox, renderCheckbox_fn).call(this, {
631
965
  checked: this._selected.has(index),
632
966
  indeterminate: false,
633
967
  ariaLabel: selectRowLabel,
@@ -635,6 +969,7 @@ renderSelectableCell_fn = function(index) {
635
969
  detail: { checked: !this._selected.has(index) }
636
970
  })
637
971
  })}
972
+ </div>
638
973
  </td>
639
974
  `;
640
975
  };
@@ -642,51 +977,201 @@ _renderRowCells = new WeakSet();
642
977
  renderRowCells_fn = function(row, index) {
643
978
  return this.columns.filter((column) => this._view.visibleColumns.has(column.key)).map((column) => __privateMethod(this, _renderTableCell, renderTableCell_fn).call(this, row, column, index));
644
979
  };
645
- _renderActionsCell = new WeakSet();
646
- renderActionsCell_fn = function(row, index) {
647
- if (!this.actions)
648
- return null;
649
- if (typeof this.actions === "function") {
650
- return html`
651
- <td class="actions-cell">
652
- <div class="cell-content">${this.actions(row, index)}</div>
653
- </td>
654
- `;
655
- }
980
+ _renderFullWidthDetailsRow = new WeakSet();
981
+ renderFullWidthDetailsRow_fn = function(row, index, groupId) {
656
982
  const rowKey = __privateMethod(this, _getRowKey, getRowKey_fn).call(this, row, index);
657
- const classes = classMap({
658
- "actions-cell": true,
659
- sticky: Boolean(this.actions.sticky),
660
- wrap: Boolean(this.actions.width),
661
- [`align-${this.actions.align}`]: !!this.actions.align,
662
- [`justify-${this.actions.justify}`]: !!this.actions.justify
983
+ return html`
984
+ <tr
985
+ class="expanded-row full expanded-group-end"
986
+ id="${groupId}"
987
+ aria-level="2"
988
+ >
989
+ <td
990
+ class="expanded-full-cell"
991
+ colspan=${__privateMethod(this, _getRenderedColumnCount, getRenderedColumnCount_fn).call(this)}
992
+ >
993
+ ${html`<slot name="expand:${rowKey}:full"></slot>`}
994
+ </td>
995
+ </tr>
996
+ `;
997
+ };
998
+ _renderExpandedLoadingRow = new WeakSet();
999
+ renderExpandedLoadingRow_fn = function(_row, _index, groupId, childIndex, rowCount, isCompleting = false) {
1000
+ const visibleColumns = this.columns.filter(
1001
+ (column) => this._view.visibleColumns.has(column.key)
1002
+ );
1003
+ const rowClasses = classMap({
1004
+ "expanded-row": true,
1005
+ aligned: true,
1006
+ "skeleton-leave": isCompleting,
1007
+ "expanded-group-end": childIndex === rowCount - 1
663
1008
  });
664
- const style = styleMap({
665
- "--cell-width": this.actions.width
1009
+ return html`
1010
+ <tr
1011
+ class=${rowClasses}
1012
+ id=${ifDefined(childIndex === 0 ? groupId : void 0)}
1013
+ aria-level="2"
1014
+ aria-busy="true"
1015
+ >
1016
+ ${__privateGet(this, _isExpandableEnabled, isExpandableEnabled_get) ? html`<td class="expander-cell"></td>` : null}
1017
+ ${__privateGet(this, _isSelectableEnabled, isSelectableEnabled_get) ? html`<td class="checkbox-cell"></td>` : null}
1018
+ ${visibleColumns.map((column) => {
1019
+ const classes = classMap({
1020
+ [`align-${column.align}`]: !!column.align,
1021
+ [`justify-${column.justify}`]: !!column.justify,
1022
+ wrap: Boolean(column.width)
1023
+ });
1024
+ const style = styleMap({
1025
+ "--cell-width": column.width
1026
+ });
1027
+ const isActionsColumn = String(column.key) === "actions";
1028
+ return html`
1029
+ <td class=${classes} style=${style}>
1030
+ <div class="cell-content">
1031
+ ${isActionsColumn ? html`<span class="skeleton skeleton-action"></span>` : html`<span class="skeleton skeleton-text"></span>`}
1032
+ </div>
1033
+ </td>
1034
+ `;
1035
+ })}
1036
+ </tr>
1037
+ `;
1038
+ };
1039
+ _renderExpandedLoadingRows = new WeakSet();
1040
+ renderExpandedLoadingRows_fn = function(row, index, groupId, isCompleting = false) {
1041
+ const count = __privateMethod(this, _getSubRowCount, getSubRowCount_fn).call(this, row, index);
1042
+ return Array.from(
1043
+ { length: count },
1044
+ (_, childIndex) => __privateMethod(this, _renderExpandedLoadingRow, renderExpandedLoadingRow_fn).call(this, row, index, groupId, childIndex, count, isCompleting)
1045
+ );
1046
+ };
1047
+ _renderExpandedFullLoadingRow = new WeakSet();
1048
+ renderExpandedFullLoadingRow_fn = function(groupId, isCompleting = false) {
1049
+ const rowClasses = classMap({
1050
+ "expanded-row": true,
1051
+ full: true,
1052
+ "expanded-group-end": true,
1053
+ "skeleton-leave": isCompleting
666
1054
  });
667
1055
  return html`
668
- <td class="${classes}" style=${style}>
669
- <div class="cell-content">
670
- ${__privateMethod(this, _renderSlotElement, renderSlotElement_fn).call(this, "actions", rowKey, "main")}
671
- </div>
672
- </td>
1056
+ <tr class=${rowClasses} id="${groupId}" aria-level="2" aria-busy="true">
1057
+ <td
1058
+ class="expanded-full-cell"
1059
+ colspan=${__privateMethod(this, _getRenderedColumnCount, getRenderedColumnCount_fn).call(this)}
1060
+ >
1061
+ <div class="expanded-full-skeleton" aria-hidden="true">
1062
+ <span class="skeleton skeleton-title"></span>
1063
+ <span class="skeleton skeleton-text"></span>
1064
+ <span class="skeleton skeleton-text"></span>
1065
+ <div class="expanded-full-skeleton-meta">
1066
+ <span class="skeleton skeleton-block"></span>
1067
+ <span class="skeleton skeleton-block"></span>
1068
+ <span class="skeleton skeleton-block"></span>
1069
+ </div>
1070
+ </div>
1071
+ </td>
1072
+ </tr>
673
1073
  `;
674
1074
  };
1075
+ _getExpandedChildRowClasses = new WeakSet();
1076
+ getExpandedChildRowClasses_fn = function(isLast) {
1077
+ return {
1078
+ "expanded-row": true,
1079
+ child: true,
1080
+ "expanded-group-end": isLast
1081
+ };
1082
+ };
1083
+ _getTableRowClasses = new WeakSet();
1084
+ getTableRowClasses_fn = function(index, isExpandable, isExpanded) {
1085
+ return {
1086
+ selected: this._selected.has(index),
1087
+ loading: this._loading,
1088
+ "expanded-parent": isExpanded,
1089
+ "has-expandable-rows": isExpandable
1090
+ };
1091
+ };
1092
+ _getRowAriaExpanded = new WeakSet();
1093
+ getRowAriaExpanded_fn = function(isExpandable, isExpanded) {
1094
+ const value = isExpandable ? isExpanded ? "true" : "false" : void 0;
1095
+ return value;
1096
+ };
1097
+ _getTableRowPresentation = new WeakSet();
1098
+ getTableRowPresentation_fn = function(index, isExpandable, isExpanded) {
1099
+ return {
1100
+ classes: __privateMethod(this, _getTableRowClasses, getTableRowClasses_fn).call(this, index, isExpandable, isExpanded),
1101
+ ariaExpanded: __privateMethod(this, _getRowAriaExpanded, getRowAriaExpanded_fn).call(this, isExpandable, isExpanded)
1102
+ };
1103
+ };
1104
+ _renderExpandedChildRow = new WeakSet();
1105
+ renderExpandedChildRow_fn = function(childRow, parentIndex, childIndex, isLast, groupId) {
1106
+ const childRenderIndex = this._rowsState.length + parentIndex * 1e3 + childIndex;
1107
+ return html`
1108
+ <tr
1109
+ class=${classMap(__privateMethod(this, _getExpandedChildRowClasses, getExpandedChildRowClasses_fn).call(this, isLast))}
1110
+ id=${ifDefined(childIndex === 0 ? groupId : void 0)}
1111
+ aria-level="2"
1112
+ >
1113
+ ${__privateGet(this, _isExpandableEnabled, isExpandableEnabled_get) ? html`<td class="expander-cell"></td>` : null}
1114
+ ${__privateGet(this, _isSelectableEnabled, isSelectableEnabled_get) ? html`<td class="checkbox-cell"></td>` : null}
1115
+ ${__privateMethod(this, _renderRowCells, renderRowCells_fn).call(this, childRow, childRenderIndex)}
1116
+ </tr>
1117
+ `;
1118
+ };
1119
+ _getRowExpansionLoadingKind = new WeakSet();
1120
+ getRowExpansionLoadingKind_fn = function(row) {
1121
+ return __privateMethod(this, _hasAsyncSubRows, hasAsyncSubRows_fn).call(this, row) ? "rows" : "full";
1122
+ };
1123
+ _getRowExpansionState = new WeakSet();
1124
+ getRowExpansionState_fn = function(row, index) {
1125
+ const isExpandable = __privateMethod(this, _isRowExpandable, isRowExpandable_fn).call(this, row, index);
1126
+ const isExpanded = isExpandable && this._expanded.has(index);
1127
+ const isExpanding = this._expanding.has(index);
1128
+ const isCompleting = this._completingExpansion.has(index);
1129
+ const groupId = __privateMethod(this, _getExpandedGroupId, getExpandedGroupId_fn).call(this, row, index);
1130
+ const expandedRows = __privateMethod(this, _getExpandedRows, getExpandedRows_fn).call(this, row, index);
1131
+ const loadingKind = __privateMethod(this, _getRowExpansionLoadingKind, getRowExpansionLoadingKind_fn).call(this, row);
1132
+ return {
1133
+ isExpandable,
1134
+ isExpanded,
1135
+ isExpanding,
1136
+ isCompleting,
1137
+ groupId,
1138
+ expandedRows,
1139
+ hasExpandedRows: expandedRows.length > 0,
1140
+ loadingKind
1141
+ };
1142
+ };
1143
+ _renderExpandedRowContent = new WeakSet();
1144
+ renderExpandedRowContent_fn = function(row, index, state2) {
1145
+ if (state2.isExpanding) {
1146
+ return state2.loadingKind === "full" ? __privateMethod(this, _renderExpandedFullLoadingRow, renderExpandedFullLoadingRow_fn).call(this, state2.groupId, state2.isCompleting) : __privateMethod(this, _renderExpandedLoadingRows, renderExpandedLoadingRows_fn).call(this, row, index, state2.groupId, state2.isCompleting);
1147
+ }
1148
+ if (state2.hasExpandedRows) {
1149
+ return state2.expandedRows.map(
1150
+ (expandedRow, childIndex) => __privateMethod(this, _renderExpandedChildRow, renderExpandedChildRow_fn).call(this, expandedRow, index, childIndex, childIndex === state2.expandedRows.length - 1, childIndex === 0 ? state2.groupId : void 0)
1151
+ );
1152
+ }
1153
+ return __privateMethod(this, _renderFullWidthDetailsRow, renderFullWidthDetailsRow_fn).call(this, row, index, state2.groupId);
1154
+ };
675
1155
  _renderTableRow = new WeakSet();
676
1156
  renderTableRow_fn = function(row, index) {
1157
+ const state2 = __privateMethod(this, _getRowExpansionState, getRowExpansionState_fn).call(this, row, index);
1158
+ const presentation = __privateMethod(this, _getTableRowPresentation, getTableRowPresentation_fn).call(this, index, state2.isExpandable, state2.isExpanded);
677
1159
  return html`
678
1160
  <tr
679
- class=${classMap({
680
- selected: this._selected.has(index),
681
- loading: this._loading
682
- })}
1161
+ class=${classMap(presentation.classes)}
1162
+ aria-level="1"
1163
+ aria-expanded=${ifDefined(presentation.ariaExpanded)}
683
1164
  >
684
1165
  ${[
1166
+ __privateMethod(this, _renderExpandableCell, renderExpandableCell_fn).call(this, row, index),
685
1167
  __privateMethod(this, _renderSelectableCell, renderSelectableCell_fn).call(this, index),
686
- __privateMethod(this, _renderRowCells, renderRowCells_fn).call(this, row, index),
687
- __privateMethod(this, _renderActionsCell, renderActionsCell_fn).call(this, row, index)
1168
+ __privateMethod(this, _renderRowCells, renderRowCells_fn).call(this, row, index)
688
1169
  ]}
689
1170
  </tr>
1171
+ ${when(
1172
+ state2.isExpanded,
1173
+ () => __privateMethod(this, _renderExpandedRowContent, renderExpandedRowContent_fn).call(this, row, index, state2)
1174
+ )}
690
1175
  `;
691
1176
  };
692
1177
  _renderCheckbox = new WeakSet();
@@ -755,24 +1240,22 @@ renderSkeletonRow_fn = function(index) {
755
1240
  return html`
756
1241
  <tr class="skeleton-row">
757
1242
  ${when(
758
- this.selectable,
1243
+ __privateGet(this, _isExpandableEnabled, isExpandableEnabled_get),
759
1244
  () => html`
760
- <td class="checkbox-cell">
761
- <span class="skeleton skeleton-checkbox"></span>
1245
+ <td class="expander-cell">
1246
+ <span class="skeleton skeleton-action"></span>
762
1247
  </td>
763
1248
  `
764
1249
  )}
765
- ${this.columns.filter((column) => this._view.visibleColumns.has(column.key)).map((column) => html`<td>${__privateMethod(this, _renderSkeletonCell, renderSkeletonCell_fn).call(this, column)}</td>`)}
766
1250
  ${when(
767
- this.actions,
1251
+ __privateGet(this, _isSelectableEnabled, isSelectableEnabled_get),
768
1252
  () => html`
769
- <td class="actions-cell">
770
- <div class="cell-content">
771
- <span class="skeleton skeleton-action"></span>
772
- </div>
1253
+ <td class="checkbox-cell">
1254
+ <span class="skeleton skeleton-checkbox"></span>
773
1255
  </td>
774
1256
  `
775
1257
  )}
1258
+ ${this.columns.filter((column) => this._view.visibleColumns.has(column.key)).map((column) => html`<td>${__privateMethod(this, _renderSkeletonCell, renderSkeletonCell_fn).call(this, column)}</td>`)}
776
1259
  </tr>
777
1260
  `;
778
1261
  };
@@ -795,7 +1278,7 @@ renderTableBody_fn = function() {
795
1278
  };
796
1279
  _renderTableFoot = new WeakSet();
797
1280
  renderTableFoot_fn = function() {
798
- if (!this.tfoot)
1281
+ if (!this.tfoot || __privateGet(this, _isResponsiveStacked, isResponsiveStacked_get))
799
1282
  return null;
800
1283
  const label = this.tfoot.label;
801
1284
  const visibleColumns = this.columns.filter(
@@ -808,21 +1291,40 @@ renderTableFoot_fn = function() {
808
1291
  return html`
809
1292
  <tfoot class=${classes}>
810
1293
  <tr>
811
- ${when(this.selectable, () => html`<td class="checkbox-cell"></td>`)}
1294
+ ${when(
1295
+ __privateGet(this, _isExpandableEnabled, isExpandableEnabled_get),
1296
+ () => html`<td class="expander-cell"></td>`
1297
+ )}
1298
+ ${when(
1299
+ __privateGet(this, _isSelectableEnabled, isSelectableEnabled_get),
1300
+ () => html`<td class="checkbox-cell"></td>`
1301
+ )}
812
1302
  ${visibleColumns.map((column, i) => {
1303
+ const { lastLeft, lastRight } = __privateMethod(this, _getStickyBorderKeys, getStickyBorderKeys_fn).call(this);
813
1304
  const cellClasses = classMap({
814
1305
  "tablefoot-cell": true,
815
1306
  "tablefoot-label-cell": i === 0,
816
1307
  [`align-${column.align}`]: !!column.align,
817
1308
  [`justify-${column.justify}`]: !!column.justify,
818
- wrap: Boolean(column.width)
1309
+ wrap: Boolean(column.width),
1310
+ "sticky-left": column.sticky === "left",
1311
+ "sticky-right": column.sticky === "right",
1312
+ "sticky-left-last": column.sticky === "left" && column.key === lastLeft,
1313
+ "sticky-right-last": column.sticky === "right" && column.key === lastRight
819
1314
  });
820
1315
  const style = styleMap({
821
1316
  "--cell-width": column.width
822
1317
  });
823
1318
  if (i === 0 && label) {
824
1319
  return html`
825
- <th scope="row" class=${cellClasses} style=${style}>
1320
+ <th
1321
+ scope="row"
1322
+ class=${cellClasses}
1323
+ style=${style}
1324
+ data-col-key=${ifDefined(
1325
+ column.sticky ? column.key : void 0
1326
+ )}
1327
+ >
826
1328
  <div class="cell-content">
827
1329
  <span class="tablefoot-label">${label}</span>
828
1330
  <slot name="tfoot:${column.key}"></slot>
@@ -831,26 +1333,18 @@ renderTableFoot_fn = function() {
831
1333
  `;
832
1334
  }
833
1335
  return html`
834
- <td class=${cellClasses} style=${style}>
1336
+ <td
1337
+ class=${cellClasses}
1338
+ style=${style}
1339
+ data-col-key=${ifDefined(
1340
+ column.sticky ? column.key : void 0
1341
+ )}
1342
+ >
835
1343
  <div class="cell-content">
836
1344
  <slot name="tfoot:${column.key}"></slot>
837
1345
  </div>
838
1346
  </td>
839
1347
  `;
840
- })}
841
- ${when(this.actions, () => {
842
- const isObj = this.actions && typeof this.actions !== "function";
843
- const stickyAction = isObj && this.actions.sticky;
844
- const actionClasses = classMap({
845
- "actions-cell": true,
846
- "tablefoot-cell": true,
847
- sticky: Boolean(stickyAction)
848
- });
849
- return html`<td class=${actionClasses}>
850
- <div class="cell-content">
851
- <slot name="tfoot:actions"></slot>
852
- </div>
853
- </td>`;
854
1348
  })}
855
1349
  </tr>
856
1350
  </tfoot>
@@ -861,6 +1355,15 @@ renderTable_fn = function() {
861
1355
  const CLASSES = classMap({
862
1356
  responsive: this.responsive,
863
1357
  data: true,
1358
+ "is-expandable": __privateGet(this, _isExpandableEnabled, isExpandableEnabled_get),
1359
+ "is-selectable": __privateGet(this, _isSelectableEnabled, isSelectableEnabled_get),
1360
+ "has-tfoot": Boolean(this.tfoot) && !__privateGet(this, _isResponsiveStacked, isResponsiveStacked_get),
1361
+ "has-sticky-left": this.columns.some((c) => c.sticky === "left"),
1362
+ "has-sticky-right": this.columns.some((c) => c.sticky === "right"),
1363
+ "has-sticky": this.columns.some(
1364
+ (c) => c.sticky === "left" || c.sticky === "right"
1365
+ ),
1366
+ "no-mask": __privateGet(this, _isExpandableEnabled, isExpandableEnabled_get) || __privateGet(this, _isSelectableEnabled, isSelectableEnabled_get) || this.columns.some((c) => c.sticky === "left" || c.sticky === "right"),
864
1367
  [`variant-${this.variant}`]: true,
865
1368
  loading: this._loading,
866
1369
  loaded: !this._loading && !this._loaded
@@ -875,7 +1378,12 @@ renderTable_fn = function() {
875
1378
  class="table-card"
876
1379
  >
877
1380
  <div class=${CLASSES} tabindex="0">
878
- <table aria-label="${caption}">
1381
+ <table
1382
+ aria-label="${caption}"
1383
+ role=${ifDefined(
1384
+ __privateGet(this, _isExpandableEnabled, isExpandableEnabled_get) ? "treegrid" : void 0
1385
+ )}
1386
+ >
879
1387
  <caption class="visually-hidden">
880
1388
  ${caption}
881
1389
  </caption>
@@ -889,7 +1397,7 @@ renderTable_fn = function() {
889
1397
  _renderErrorState = new WeakSet();
890
1398
  renderErrorState_fn = function() {
891
1399
  return html`
892
- <gds-card variant="neutral-02" border-radius="m" outline>
1400
+ <gds-card variant="neutral-02-outlined" border-radius="m">
893
1401
  <slot name="error">
894
1402
  <gds-text tag="p">${msg("Error loading data")}</gds-text>
895
1403
  <gds-button
@@ -908,7 +1416,7 @@ renderEmptyState_fn = function() {
908
1416
  const hasSearch = this._view.searchQuery.length > 0;
909
1417
  if (hasSearch) {
910
1418
  return html`
911
- <gds-card variant="neutral-02" border-radius="m" outline>
1419
+ <gds-card variant="neutral-02-outlined" border-radius="m">
912
1420
  <slot name="no-results">
913
1421
  <gds-flex flex-direction="column" align-items="flex-start" gap="s">
914
1422
  <gds-text tag="p" font="heading-s">
@@ -930,7 +1438,7 @@ renderEmptyState_fn = function() {
930
1438
  `;
931
1439
  }
932
1440
  return html`
933
- <gds-card variant="neutral-02" border-radius="m" outline>
1441
+ <gds-card variant="neutral-02-outlined" border-radius="m">
934
1442
  <slot name="empty">
935
1443
  <gds-text tag="p" font="heading-s">
936
1444
  ${msg("No data available")}
@@ -987,7 +1495,7 @@ renderHeadline_fn = function() {
987
1495
  </gds-flex>
988
1496
  ${when(
989
1497
  this.searchable || this.settings,
990
- () => html`<gds-divider color="subtle-01"></gds-divider>`,
1498
+ () => html`<gds-divider color="neutral-02"></gds-divider>`,
991
1499
  () => html``
992
1500
  )}
993
1501
  `;
@@ -1084,6 +1592,105 @@ handleRowSelect_fn = function(index, e) {
1084
1592
  __privateMethod(this, _emitSelectionChange, emitSelectionChange_fn).call(this);
1085
1593
  this.requestUpdate();
1086
1594
  };
1595
+ _handleExpandToggle = new WeakSet();
1596
+ handleExpandToggle_fn = function(row, index) {
1597
+ void this.toggleRowExpansion(index, row);
1598
+ };
1599
+ _handleExpandAll = new WeakSet();
1600
+ handleExpandAll_fn = async function() {
1601
+ const expandable = __privateGet(this, _expandableIndices, expandableIndices_get);
1602
+ if (__privateGet(this, _isAllExpanded, isAllExpanded_get)) {
1603
+ expandable.forEach((i) => this._expanded.delete(i));
1604
+ this.requestUpdate();
1605
+ } else {
1606
+ await Promise.all(expandable.map((i) => __privateMethod(this, _setRowExpanded, setRowExpanded_fn).call(this, i, true)));
1607
+ }
1608
+ };
1609
+ _emitExpandChange = new WeakSet();
1610
+ emitExpandChange_fn = function(row, index, expanded) {
1611
+ this.dispatchCustomEvent("gds-table-expand-change", {
1612
+ detail: {
1613
+ index,
1614
+ row,
1615
+ expanded,
1616
+ expandedIndices: Array.from(this._expanded)
1617
+ },
1618
+ bubbles: true
1619
+ });
1620
+ };
1621
+ _resolveExpandedContent = new WeakSet();
1622
+ resolveExpandedContent_fn = async function(row, index) {
1623
+ const subRowsSource = __privateMethod(this, _getRowSubRowsSource, getRowSubRowsSource_fn).call(this, row);
1624
+ const fullContentSource = __privateMethod(this, _getRowFullContentSource, getRowFullContentSource_fn).call(this, row);
1625
+ const hasSubRows = typeof subRowsSource === "function";
1626
+ const hasFullContent = typeof fullContentSource === "function";
1627
+ if (!hasSubRows && !hasFullContent) {
1628
+ return;
1629
+ }
1630
+ const rowsPromise = hasSubRows ? subRowsSource() : void 0;
1631
+ const fullPromise = hasFullContent ? fullContentSource() : void 0;
1632
+ const hasAsyncContent = Boolean(rowsPromise || fullPromise);
1633
+ let resolved = false;
1634
+ const nextExpanding = new Set(this._expanding);
1635
+ nextExpanding.add(index);
1636
+ this._expanding = nextExpanding;
1637
+ this.requestUpdate();
1638
+ try {
1639
+ if (rowsPromise) {
1640
+ const rows = await rowsPromise;
1641
+ const normalizedRows = Array.isArray(rows) ? rows : [];
1642
+ const nextCache = new Map(this._expandedRowsCache);
1643
+ nextCache.set(index, normalizedRows);
1644
+ this._expandedRowsCache = nextCache;
1645
+ }
1646
+ if (fullPromise) {
1647
+ await fullPromise;
1648
+ const nextResolved = new Set(this._expandedFullContentResolved);
1649
+ nextResolved.add(index);
1650
+ this._expandedFullContentResolved = nextResolved;
1651
+ }
1652
+ resolved = true;
1653
+ } catch {
1654
+ if (rowsPromise) {
1655
+ const nextCache = new Map(this._expandedRowsCache);
1656
+ nextCache.set(index, []);
1657
+ this._expandedRowsCache = nextCache;
1658
+ }
1659
+ } finally {
1660
+ if (hasAsyncContent && resolved) {
1661
+ __privateMethod(this, _scheduleExpansionContentReveal, scheduleExpansionContentReveal_fn).call(this, index);
1662
+ } else {
1663
+ __privateMethod(this, _clearExpansionLoadingState, clearExpansionLoadingState_fn).call(this, index);
1664
+ }
1665
+ this.requestUpdate();
1666
+ }
1667
+ };
1668
+ _setRowExpanded = new WeakSet();
1669
+ setRowExpanded_fn = async function(index, expanded, rowOverride) {
1670
+ if (index < 0 || index >= this._rowsState.length)
1671
+ return false;
1672
+ const row = rowOverride ?? this._rowsState[index];
1673
+ if (!row)
1674
+ return false;
1675
+ const isExpandable = __privateMethod(this, _isRowExpandable, isRowExpandable_fn).call(this, row, index);
1676
+ if (expanded && !isExpandable)
1677
+ return false;
1678
+ const isExpanded = this._expanded.has(index);
1679
+ if (expanded === isExpanded)
1680
+ return true;
1681
+ if (expanded) {
1682
+ this._expanded.add(index);
1683
+ __privateMethod(this, _emitExpandChange, emitExpandChange_fn).call(this, row, index, true);
1684
+ this.requestUpdate();
1685
+ await __privateMethod(this, _resolveExpandedContent, resolveExpandedContent_fn).call(this, row, index);
1686
+ } else {
1687
+ __privateMethod(this, _clearExpansionLoadingState, clearExpansionLoadingState_fn).call(this, index);
1688
+ this._expanded.delete(index);
1689
+ __privateMethod(this, _emitExpandChange, emitExpandChange_fn).call(this, row, index, false);
1690
+ }
1691
+ this.requestUpdate();
1692
+ return true;
1693
+ };
1087
1694
  _selectAllInternal = new WeakSet();
1088
1695
  selectAllInternal_fn = function() {
1089
1696
  this._selected = new Set(this._rowsState.map((_, i) => i));
@@ -1115,6 +1722,11 @@ initializeScrollTracking_fn = function() {
1115
1722
  __privateMethod(this, _updateHorizontalScrollState, updateHorizontalScrollState_fn).call(this, dataContainer);
1116
1723
  };
1117
1724
  dataContainer.addEventListener("scroll", updateScrollState);
1725
+ const resizeObserver = new ResizeObserver(() => updateScrollState());
1726
+ resizeObserver.observe(dataContainer);
1727
+ const innerTable = dataContainer.querySelector("table");
1728
+ if (innerTable)
1729
+ resizeObserver.observe(innerTable);
1118
1730
  updateScrollState();
1119
1731
  };
1120
1732
  _updateVerticalScrollState = new WeakSet();
@@ -1136,6 +1748,11 @@ _updateHorizontalScrollState = new WeakSet();
1136
1748
  updateHorizontalScrollState_fn = function(container) {
1137
1749
  const { scrollLeft, scrollWidth, clientWidth } = container;
1138
1750
  const maxScrollLeft = scrollWidth - clientWidth;
1751
+ if (scrollWidth > clientWidth) {
1752
+ container.classList.add("overflows-x");
1753
+ } else {
1754
+ container.classList.remove("overflows-x");
1755
+ }
1139
1756
  if (scrollLeft <= 0) {
1140
1757
  container.classList.add("scrolled-x-start");
1141
1758
  container.classList.remove("scrolled-x-middle", "scrolled-x-end");
@@ -1210,9 +1827,6 @@ __decorateClass([
1210
1827
  __decorateClass([
1211
1828
  property({ type: Boolean, reflect: false })
1212
1829
  ], GdsTable.prototype, "striped", 2);
1213
- __decorateClass([
1214
- property()
1215
- ], GdsTable.prototype, "actions", 2);
1216
1830
  __decorateClass([
1217
1831
  property({ type: Boolean, reflect: false })
1218
1832
  ], GdsTable.prototype, "nocache", 2);
@@ -1256,6 +1870,21 @@ __decorateClass([
1256
1870
  __decorateClass([
1257
1871
  state()
1258
1872
  ], GdsTable.prototype, "_selected", 2);
1873
+ __decorateClass([
1874
+ state()
1875
+ ], GdsTable.prototype, "_expanded", 2);
1876
+ __decorateClass([
1877
+ state()
1878
+ ], GdsTable.prototype, "_expanding", 2);
1879
+ __decorateClass([
1880
+ state()
1881
+ ], GdsTable.prototype, "_completingExpansion", 2);
1882
+ __decorateClass([
1883
+ state()
1884
+ ], GdsTable.prototype, "_expandedRowsCache", 2);
1885
+ __decorateClass([
1886
+ state()
1887
+ ], GdsTable.prototype, "_expandedFullContentResolved", 2);
1259
1888
  __decorateClass([
1260
1889
  state()
1261
1890
  ], GdsTable.prototype, "_error", 2);