@ship-ui/core 0.22.14 → 0.22.16

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 (73) hide show
  1. package/README.md +46 -0
  2. package/assets/mcp/components.json +605 -4
  3. package/bin/src/scanner.zig +9 -18
  4. package/fesm2022/ship-ui-core-sh-form-field-experimental.mjs +17 -2
  5. package/fesm2022/ship-ui-core-sh-form-field-experimental.mjs.map +1 -1
  6. package/fesm2022/ship-ui-core-ship-a11y-keybindings.mjs +442 -0
  7. package/fesm2022/ship-ui-core-ship-a11y-keybindings.mjs.map +1 -0
  8. package/fesm2022/ship-ui-core-ship-accordion.mjs +1 -0
  9. package/fesm2022/ship-ui-core-ship-accordion.mjs.map +1 -1
  10. package/fesm2022/ship-ui-core-ship-alert.mjs +3 -2
  11. package/fesm2022/ship-ui-core-ship-alert.mjs.map +1 -1
  12. package/fesm2022/ship-ui-core-ship-blueprint.mjs +23 -10
  13. package/fesm2022/ship-ui-core-ship-blueprint.mjs.map +1 -1
  14. package/fesm2022/ship-ui-core-ship-checkbox.mjs +16 -14
  15. package/fesm2022/ship-ui-core-ship-checkbox.mjs.map +1 -1
  16. package/fesm2022/ship-ui-core-ship-color-picker.mjs +3 -1
  17. package/fesm2022/ship-ui-core-ship-color-picker.mjs.map +1 -1
  18. package/fesm2022/ship-ui-core-ship-datepicker.mjs +67 -33
  19. package/fesm2022/ship-ui-core-ship-datepicker.mjs.map +1 -1
  20. package/fesm2022/ship-ui-core-ship-dialog.mjs +14 -5
  21. package/fesm2022/ship-ui-core-ship-dialog.mjs.map +1 -1
  22. package/fesm2022/ship-ui-core-ship-divider.mjs +4 -2
  23. package/fesm2022/ship-ui-core-ship-divider.mjs.map +1 -1
  24. package/fesm2022/ship-ui-core-ship-editor.mjs +2673 -0
  25. package/fesm2022/ship-ui-core-ship-editor.mjs.map +1 -0
  26. package/fesm2022/ship-ui-core-ship-icon.mjs +2 -2
  27. package/fesm2022/ship-ui-core-ship-icon.mjs.map +1 -1
  28. package/fesm2022/ship-ui-core-ship-list.mjs +4 -2
  29. package/fesm2022/ship-ui-core-ship-list.mjs.map +1 -1
  30. package/fesm2022/ship-ui-core-ship-menu.mjs +8 -5
  31. package/fesm2022/ship-ui-core-ship-menu.mjs.map +1 -1
  32. package/fesm2022/ship-ui-core-ship-popover.mjs +14 -5
  33. package/fesm2022/ship-ui-core-ship-popover.mjs.map +1 -1
  34. package/fesm2022/ship-ui-core-ship-progress-bar.mjs +5 -1
  35. package/fesm2022/ship-ui-core-ship-progress-bar.mjs.map +1 -1
  36. package/fesm2022/ship-ui-core-ship-radio.mjs +16 -14
  37. package/fesm2022/ship-ui-core-ship-radio.mjs.map +1 -1
  38. package/fesm2022/ship-ui-core-ship-select.mjs +9 -9
  39. package/fesm2022/ship-ui-core-ship-select.mjs.map +1 -1
  40. package/fesm2022/ship-ui-core-ship-sidenav.mjs +2 -2
  41. package/fesm2022/ship-ui-core-ship-sidenav.mjs.map +1 -1
  42. package/fesm2022/ship-ui-core-ship-spinner.mjs +3 -1
  43. package/fesm2022/ship-ui-core-ship-spinner.mjs.map +1 -1
  44. package/fesm2022/ship-ui-core-ship-spotlight.mjs +77 -24
  45. package/fesm2022/ship-ui-core-ship-spotlight.mjs.map +1 -1
  46. package/fesm2022/ship-ui-core-ship-table.mjs +517 -138
  47. package/fesm2022/ship-ui-core-ship-table.mjs.map +1 -1
  48. package/fesm2022/ship-ui-core-ship-theme-toggle.mjs +2 -2
  49. package/fesm2022/ship-ui-core-ship-theme-toggle.mjs.map +1 -1
  50. package/fesm2022/ship-ui-core-ship-toggle-card.mjs +24 -3
  51. package/fesm2022/ship-ui-core-ship-toggle-card.mjs.map +1 -1
  52. package/fesm2022/ship-ui-core-ship-toggle.mjs +16 -14
  53. package/fesm2022/ship-ui-core-ship-toggle.mjs.map +1 -1
  54. package/fesm2022/ship-ui-core-ship-tree.mjs +2 -2
  55. package/fesm2022/ship-ui-core-ship-tree.mjs.map +1 -1
  56. package/fesm2022/ship-ui-core-ship-virtual-scroll.mjs +2 -2
  57. package/fesm2022/ship-ui-core-ship-virtual-scroll.mjs.map +1 -1
  58. package/fesm2022/ship-ui-core.mjs +36 -23
  59. package/fesm2022/ship-ui-core.mjs.map +1 -1
  60. package/package.json +33 -2
  61. package/types/ship-ui-core-sh-form-field-experimental.d.ts +2 -0
  62. package/types/ship-ui-core-ship-a11y-keybindings.d.ts +102 -0
  63. package/types/ship-ui-core-ship-blueprint.d.ts +2 -1
  64. package/types/ship-ui-core-ship-checkbox.d.ts +2 -1
  65. package/types/ship-ui-core-ship-datepicker.d.ts +2 -0
  66. package/types/ship-ui-core-ship-editor.d.ts +168 -0
  67. package/types/ship-ui-core-ship-radio.d.ts +2 -1
  68. package/types/ship-ui-core-ship-spotlight.d.ts +1 -1
  69. package/types/ship-ui-core-ship-table.d.ts +13 -1
  70. package/types/ship-ui-core-ship-toggle-card.d.ts +1 -0
  71. package/types/ship-ui-core-ship-toggle.d.ts +2 -1
  72. package/types/ship-ui-core.d.ts +3 -0
  73. package/bin/ship-fg-scanner +0 -0
@@ -1,16 +1,31 @@
1
1
  import { NgTemplateOutlet } from '@angular/common';
2
2
  import * as i0 from '@angular/core';
3
- import { inject, ElementRef, Renderer2, input, signal, HostListener, Directive, computed, output, model, contentChild, viewChild, DestroyRef, effect, ChangeDetectionStrategy, ViewEncapsulation, Component } from '@angular/core';
3
+ import { inject, ElementRef, Renderer2, Injector, signal, input, effect, HostListener, Directive, computed, output, model, contentChild, viewChild, untracked, ChangeDetectionStrategy, ViewEncapsulation, Component } from '@angular/core';
4
4
  import { shipComponentClasses, observeChildren } from '@ship-ui/core';
5
+ import { ShipA11yKeybindingsService } from '@ship-ui/core/ship-a11y-keybindings';
5
6
  import { ShipChip } from '@ship-ui/core/ship-chip';
6
7
  import { ShipIcon } from '@ship-ui/core/ship-icon';
7
8
  import { ShipProgressBar } from '@ship-ui/core/ship-progress-bar';
8
9
 
9
10
  class ShipResize {
11
+ #el;
12
+ #renderer;
13
+ #table;
14
+ #keybindings;
15
+ #injector;
16
+ #sort;
17
+ #startX;
18
+ #startWidth;
19
+ #resizing;
20
+ #animationFrameRequest; // Store request ID
10
21
  constructor() {
11
22
  this.#el = inject(ElementRef);
12
23
  this.#renderer = inject(Renderer2);
13
24
  this.#table = inject(ShipTable);
25
+ this.#keybindings = inject(ShipA11yKeybindingsService);
26
+ this.#injector = inject(Injector);
27
+ this.#sort = signal(null, /* @ts-ignore */
28
+ ...(ngDevMode ? [{ debugName: "#sort" }] : /* istanbul ignore next */ []));
14
29
  this.resizable = input(true, /* @ts-ignore */
15
30
  ...(ngDevMode ? [{ debugName: "resizable" }] : /* istanbul ignore next */ []));
16
31
  this.minWidth = input(50, /* @ts-ignore */
@@ -21,24 +36,97 @@ class ShipResize {
21
36
  ...(ngDevMode ? [{ debugName: "resizingClass" }] : /* istanbul ignore next */ []));
22
37
  this.#resizing = false;
23
38
  this.#animationFrameRequest = null; // Store request ID
39
+ effect(() => {
40
+ if (this.#sort())
41
+ return;
42
+ const hostEl = this.#el.nativeElement;
43
+ if (this.resizable()) {
44
+ const parts = [];
45
+ const decAction = 'table.column-resize-decrease';
46
+ const decShortcut = this.#keybindings.getShortcut(decAction);
47
+ if (decShortcut) {
48
+ parts.push(this.#keybindings.getDisplayShortcut(decAction) || decShortcut);
49
+ }
50
+ const incAction = 'table.column-resize-increase';
51
+ const incShortcut = this.#keybindings.getShortcut(incAction);
52
+ if (incShortcut) {
53
+ parts.push(this.#keybindings.getDisplayShortcut(incAction) || incShortcut);
54
+ }
55
+ if (parts.length > 0) {
56
+ this.#renderer.setAttribute(hostEl, 'aria-keyshortcuts', parts.join(', '));
57
+ }
58
+ else {
59
+ this.#renderer.removeAttribute(hostEl, 'aria-keyshortcuts');
60
+ }
61
+ }
62
+ else {
63
+ this.#renderer.removeAttribute(hostEl, 'aria-keyshortcuts');
64
+ }
65
+ });
24
66
  }
25
- #el;
26
- #renderer;
27
- #table;
28
- #startX;
29
- #startWidth;
30
- #resizing;
31
- #animationFrameRequest; // Store request ID
32
67
  ngOnInit() {
33
68
  if (!this.#table) {
34
69
  console.error('shTableResize directive must be used within a sh-table component.');
35
70
  return;
36
71
  }
72
+ const hostEl = this.#el.nativeElement;
73
+ // Resolve ShipSort lazily to avoid circular DI instantiation issues
74
+ this.#sort.set(this.#injector.get(ShipSort, null, { optional: true, self: true }));
37
75
  if (this.resizable()) {
38
76
  const resizer = this.#renderer.createElement('div');
39
77
  this.#renderer.addClass(resizer, 'sh-resizer');
40
- this.#renderer.appendChild(this.#el.nativeElement, resizer);
78
+ this.#renderer.appendChild(hostEl, resizer);
41
79
  this.#renderer.listen(resizer, 'mousedown', this.#onMouseDown.bind(this));
80
+ if (!hostEl.hasAttribute('role')) {
81
+ this.#renderer.setAttribute(hostEl, 'role', 'columnheader');
82
+ }
83
+ if (!this.#sort() && !hostEl.hasAttribute('tabindex')) {
84
+ this.#renderer.setAttribute(hostEl, 'tabindex', '0');
85
+ }
86
+ }
87
+ }
88
+ onKeyDown(event) {
89
+ if (!this.resizable())
90
+ return;
91
+ const target = event.target;
92
+ const host = this.#el.nativeElement;
93
+ if (target !== host &&
94
+ (target.tagName === 'BUTTON' ||
95
+ target.tagName === 'INPUT' ||
96
+ target.tagName === 'SELECT' ||
97
+ target.tagName === 'TEXTAREA' ||
98
+ target.closest('button, input, select, textarea, a') !== null ||
99
+ target.closest('[role="button"], [role="checkbox"], [role="menuitem"]') !== null)) {
100
+ return;
101
+ }
102
+ if ((event.key === 'ArrowLeft' || event.key === 'ArrowRight') && !event.shiftKey) {
103
+ if (!this.#sort()) {
104
+ const parentRow = host.parentElement;
105
+ if (parentRow) {
106
+ const headers = Array.from(parentRow.querySelectorAll('th')).filter((el) => el.getAttribute('tabindex') === '0' || el.hasAttribute('shSort') || el.hasAttribute('shResize'));
107
+ const currentIndex = headers.indexOf(host);
108
+ if (currentIndex !== -1) {
109
+ const nextIndex = event.key === 'ArrowRight' ? currentIndex + 1 : currentIndex - 1;
110
+ if (nextIndex >= 0 && nextIndex < headers.length) {
111
+ event.preventDefault();
112
+ headers[nextIndex].focus();
113
+ return;
114
+ }
115
+ }
116
+ }
117
+ }
118
+ }
119
+ const isDecrease = this.#keybindings.matches(event, 'table.column-resize-decrease');
120
+ const isIncrease = this.#keybindings.matches(event, 'table.column-resize-increase');
121
+ if (isDecrease || isIncrease) {
122
+ event.preventDefault();
123
+ event.stopPropagation();
124
+ const currentWidth = this.#el.nativeElement.offsetWidth;
125
+ const step = 10;
126
+ const targetWidth = isDecrease ? currentWidth - step : currentWidth + step;
127
+ const constrainedWidth = Math.max(this.minWidth(), this.maxWidth() ? Math.min(targetWidth, this.maxWidth() ?? targetWidth) : targetWidth);
128
+ this.#renderer.setAttribute(this.#el.nativeElement, 'size', `${constrainedWidth}px`);
129
+ this.#table.updateColumnSizes();
42
130
  }
43
131
  }
44
132
  onMouseMove(event) {
@@ -96,7 +184,7 @@ class ShipResize {
96
184
  }
97
185
  }
98
186
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: ShipResize, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
99
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.0", type: ShipResize, isStandalone: true, selector: "[shResize]", inputs: { resizable: { classPropertyName: "resizable", publicName: "resizable", isSignal: true, isRequired: false, transformFunction: null }, minWidth: { classPropertyName: "minWidth", publicName: "minWidth", isSignal: true, isRequired: false, transformFunction: null }, maxWidth: { classPropertyName: "maxWidth", publicName: "maxWidth", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "document:mousemove": "onMouseMove($event)", "document:mouseup": "onMouseUp($event)", "document:click": "onClick($event)" }, properties: { "class.resizing": "resizingClass()" } }, ngImport: i0 }); }
187
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.0", type: ShipResize, isStandalone: true, selector: "[shResize]", inputs: { resizable: { classPropertyName: "resizable", publicName: "resizable", isSignal: true, isRequired: false, transformFunction: null }, minWidth: { classPropertyName: "minWidth", publicName: "minWidth", isSignal: true, isRequired: false, transformFunction: null }, maxWidth: { classPropertyName: "maxWidth", publicName: "maxWidth", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "keydown": "onKeyDown($event)", "document:mousemove": "onMouseMove($event)", "document:mouseup": "onMouseUp($event)", "document:click": "onClick($event)" }, properties: { "class.resizing": "resizingClass()" } }, ngImport: i0 }); }
100
188
  }
101
189
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: ShipResize, decorators: [{
102
190
  type: Directive,
@@ -107,7 +195,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImpor
107
195
  '[class.resizing]': 'resizingClass()',
108
196
  },
109
197
  }]
110
- }], propDecorators: { resizable: [{ type: i0.Input, args: [{ isSignal: true, alias: "resizable", required: false }] }], minWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "minWidth", required: false }] }], maxWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxWidth", required: false }] }], onMouseMove: [{
198
+ }], ctorParameters: () => [], propDecorators: { resizable: [{ type: i0.Input, args: [{ isSignal: true, alias: "resizable", required: false }] }], minWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "minWidth", required: false }] }], maxWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxWidth", required: false }] }], onKeyDown: [{
199
+ type: HostListener,
200
+ args: ['keydown', ['$event']]
201
+ }], onMouseMove: [{
111
202
  type: HostListener,
112
203
  args: ['document:mousemove', ['$event']]
113
204
  }], onMouseUp: [{
@@ -120,8 +211,43 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImpor
120
211
  class ShipSort {
121
212
  constructor() {
122
213
  this.#table = inject(ShipTable);
214
+ this.#keybindings = inject(ShipA11yKeybindingsService);
215
+ this.#injector = inject(Injector);
216
+ this.#el = inject(ElementRef);
217
+ this.#resize = signal(null, /* @ts-ignore */
218
+ ...(ngDevMode ? [{ debugName: "#resize" }] : /* istanbul ignore next */ []));
123
219
  this.shSort = input(/* @ts-ignore */
124
220
  ...(ngDevMode ? [undefined, { debugName: "shSort" }] : /* istanbul ignore next */ []));
221
+ this.tabIndex = computed(() => {
222
+ const resize = this.#resize();
223
+ return this.shSort() || (resize && resize.resizable()) ? '0' : null;
224
+ }, /* @ts-ignore */
225
+ ...(ngDevMode ? [{ debugName: "tabIndex" }] : /* istanbul ignore next */ []));
226
+ this.ariaKeyshortcuts = computed(() => {
227
+ const parts = [];
228
+ const resize = this.#resize();
229
+ if (this.shSort()) {
230
+ const action = 'table.sort';
231
+ const shortcut = this.#keybindings.getShortcut(action);
232
+ if (shortcut) {
233
+ parts.push(this.#keybindings.getDisplayShortcut(action) || shortcut);
234
+ }
235
+ }
236
+ if (resize && resize.resizable()) {
237
+ const decAction = 'table.column-resize-decrease';
238
+ const decShortcut = this.#keybindings.getShortcut(decAction);
239
+ if (decShortcut) {
240
+ parts.push(this.#keybindings.getDisplayShortcut(decAction) || decShortcut);
241
+ }
242
+ const incAction = 'table.column-resize-increase';
243
+ const incShortcut = this.#keybindings.getShortcut(incAction);
244
+ if (incShortcut) {
245
+ parts.push(this.#keybindings.getDisplayShortcut(incAction) || incShortcut);
246
+ }
247
+ }
248
+ return parts.length > 0 ? parts.join(', ') : null;
249
+ }, /* @ts-ignore */
250
+ ...(ngDevMode ? [{ debugName: "ariaKeyshortcuts" }] : /* istanbul ignore next */ []));
125
251
  this.sortAsc = computed(() => {
126
252
  const currentSort = this.#table.sortByColumn();
127
253
  const thisColumn = this.shSort();
@@ -148,8 +274,60 @@ class ShipSort {
148
274
  ...(ngDevMode ? [{ debugName: "ariaSort" }] : /* istanbul ignore next */ []));
149
275
  }
150
276
  #table;
277
+ #keybindings;
278
+ #injector;
279
+ #el;
280
+ #resize;
281
+ ngOnInit() {
282
+ // Resolve ShipResize lazily to avoid circular DI instantiation issues
283
+ this.#resize.set(this.#injector.get(ShipResize, null, { optional: true, self: true }));
284
+ }
285
+ onKeyDown(event) {
286
+ if (!this.shSort())
287
+ return;
288
+ const target = event.target;
289
+ const host = this.#el.nativeElement;
290
+ if (target !== host &&
291
+ (target.tagName === 'BUTTON' ||
292
+ target.tagName === 'INPUT' ||
293
+ target.tagName === 'SELECT' ||
294
+ target.tagName === 'TEXTAREA' ||
295
+ target.closest('button, input, select, textarea, a') !== null ||
296
+ target.closest('[role="button"], [role="checkbox"], [role="menuitem"]') !== null)) {
297
+ return;
298
+ }
299
+ if ((event.key === 'ArrowLeft' || event.key === 'ArrowRight') && !event.shiftKey) {
300
+ const parentRow = host.parentElement;
301
+ if (parentRow) {
302
+ const headers = Array.from(parentRow.querySelectorAll('th')).filter((el) => el.getAttribute('tabindex') === '0' || el.hasAttribute('shSort') || el.hasAttribute('shResize'));
303
+ const currentIndex = headers.indexOf(host);
304
+ if (currentIndex !== -1) {
305
+ const nextIndex = event.key === 'ArrowRight' ? currentIndex + 1 : currentIndex - 1;
306
+ if (nextIndex >= 0 && nextIndex < headers.length) {
307
+ event.preventDefault();
308
+ headers[nextIndex].focus();
309
+ return;
310
+ }
311
+ }
312
+ }
313
+ }
314
+ if (this.#keybindings.matches(event, 'table.sort')) {
315
+ this.toggleSort(event);
316
+ }
317
+ }
151
318
  toggleSort(event) {
152
319
  if (event) {
320
+ const target = event.target;
321
+ const host = this.#el.nativeElement;
322
+ if (target !== host &&
323
+ (target.tagName === 'BUTTON' ||
324
+ target.tagName === 'INPUT' ||
325
+ target.tagName === 'SELECT' ||
326
+ target.tagName === 'TEXTAREA' ||
327
+ target.closest('button, input, select, textarea, a') !== null ||
328
+ target.closest('[role="button"], [role="checkbox"], [role="menuitem"]') !== null)) {
329
+ return;
330
+ }
153
331
  event.preventDefault();
154
332
  }
155
333
  if (this.#table.resizing()) {
@@ -161,7 +339,7 @@ class ShipSort {
161
339
  this.#table.toggleSort(sortCol);
162
340
  }
163
341
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: ShipSort, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
164
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.0", type: ShipSort, isStandalone: true, selector: "[shSort]", inputs: { shSort: { classPropertyName: "shSort", publicName: "shSort", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "columnheader" }, listeners: { "click": "shSort() ? toggleSort() : null", "keydown.enter": "shSort() ? toggleSort() : null", "keydown.space": "shSort() ? toggleSort($event) : null" }, properties: { "class.sortable": "!!shSort()", "attr.tabindex": "shSort() ? \"0\" : null", "attr.aria-sort": "shSort() ? ariaSort() : null", "class.sort-asc": "sortAsc()", "class.sort-desc": "sortDesc()" } }, ngImport: i0 }); }
342
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.0", type: ShipSort, isStandalone: true, selector: "[shSort]", inputs: { shSort: { classPropertyName: "shSort", publicName: "shSort", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "columnheader" }, listeners: { "click": "shSort() ? toggleSort($event) : null", "keydown": "onKeyDown($event)" }, properties: { "class.sortable": "!!shSort()", "attr.tabindex": "tabIndex()", "attr.aria-sort": "shSort() ? ariaSort() : null", "class.sort-asc": "sortAsc()", "class.sort-desc": "sortDesc()", "attr.aria-keyshortcuts": "ariaKeyshortcuts()" } }, ngImport: i0 }); }
165
343
  }
166
344
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: ShipSort, decorators: [{
167
345
  type: Directive,
@@ -171,16 +349,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImpor
171
349
  host: {
172
350
  role: 'columnheader',
173
351
  '[class.sortable]': '!!shSort()',
174
- '[attr.tabindex]': 'shSort() ? "0" : null',
175
- '(click)': 'shSort() ? toggleSort() : null',
176
- '(keydown.enter)': 'shSort() ? toggleSort() : null',
177
- '(keydown.space)': 'shSort() ? toggleSort($event) : null',
352
+ '[attr.tabindex]': 'tabIndex()',
353
+ '(click)': 'shSort() ? toggleSort($event) : null',
178
354
  '[attr.aria-sort]': 'shSort() ? ariaSort() : null',
179
355
  '[class.sort-asc]': 'sortAsc()',
180
356
  '[class.sort-desc]': 'sortDesc()',
357
+ '[attr.aria-keyshortcuts]': 'ariaKeyshortcuts()',
181
358
  },
182
359
  }]
183
- }], propDecorators: { shSort: [{ type: i0.Input, args: [{ isSignal: true, alias: "shSort", required: false }] }] } });
360
+ }], propDecorators: { shSort: [{ type: i0.Input, args: [{ isSignal: true, alias: "shSort", required: false }] }], onKeyDown: [{
361
+ type: HostListener,
362
+ args: ['keydown', ['$event']]
363
+ }] } });
184
364
  class ShipStickyColumns {
185
365
  constructor() {
186
366
  this.#elementRef = inject(ElementRef);
@@ -219,6 +399,12 @@ const SCROLL_TOLERANCE = 1.5;
219
399
  class ShipTable {
220
400
  constructor() {
221
401
  this.#el = inject(ElementRef);
402
+ this.#renderer = inject(Renderer2);
403
+ this.#keybindings = inject(ShipA11yKeybindingsService);
404
+ this.grid = input(false, /* @ts-ignore */
405
+ ...(ngDevMode ? [{ debugName: "grid" }] : /* istanbul ignore next */ []));
406
+ this.role = computed(() => (this.grid() ? 'grid' : 'table'), /* @ts-ignore */
407
+ ...(ngDevMode ? [{ debugName: "role" }] : /* istanbul ignore next */ []));
222
408
  this.loading = input(false, /* @ts-ignore */
223
409
  ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
224
410
  this.data = input([], /* @ts-ignore */
@@ -249,26 +435,18 @@ class ShipTable {
249
435
  this.columns = observeChildren(this.thead, ['tr:first-child th']);
250
436
  this.stickyHeaderHeight = signal(0, /* @ts-ignore */
251
437
  ...(ngDevMode ? [{ debugName: "stickyHeaderHeight" }] : /* istanbul ignore next */ []));
252
- this.#destroyRef = inject(DestroyRef);
253
- this.#resizeObserver = null;
254
- this.theadEffect = effect(() => {
438
+ this.theadEffect = effect((onCleanup) => {
255
439
  const head = this.thead()?.nativeElement;
256
- if (this.#resizeObserver) {
257
- this.#resizeObserver.disconnect();
258
- this.#resizeObserver = null;
259
- }
260
440
  if (head && typeof ResizeObserver !== 'undefined') {
261
- this.#resizeObserver = new ResizeObserver((entries) => {
441
+ const observer = new ResizeObserver((entries) => {
262
442
  const height = head.clientHeight;
263
443
  this.stickyHeaderHeight.set(height);
264
444
  });
265
- this.#resizeObserver.observe(head);
445
+ observer.observe(head);
446
+ onCleanup(() => observer.disconnect());
266
447
  }
267
448
  }, /* @ts-ignore */
268
449
  ...(ngDevMode ? [{ debugName: "theadEffect" }] : /* istanbul ignore next */ []));
269
- this.#cleanup = this.#destroyRef.onDestroy(() => {
270
- this.#resizeObserver?.disconnect();
271
- });
272
450
  this.bodyEffect = effect(() => {
273
451
  const body = this.tbody()?.nativeElement;
274
452
  const head = this.thead()?.nativeElement;
@@ -287,6 +465,64 @@ class ShipTable {
287
465
  });
288
466
  }, /* @ts-ignore */
289
467
  ...(ngDevMode ? [{ debugName: "bodyEffect" }] : /* istanbul ignore next */ []));
468
+ this.gridSetupEffect = effect(() => {
469
+ const gridActive = this.grid();
470
+ const dataVal = this.data();
471
+ const colSignal = this.columns.signal();
472
+ untracked(() => {
473
+ const host = this.#el.nativeElement;
474
+ const allCells = host.querySelectorAll('th, td');
475
+ if (gridActive) {
476
+ if (allCells.length === 0)
477
+ return;
478
+ let hasZero = false;
479
+ allCells.forEach((cell) => {
480
+ if (cell.getAttribute('tabindex') === '0') {
481
+ hasZero = true;
482
+ }
483
+ });
484
+ if (!hasZero) {
485
+ this.#renderer.setAttribute(allCells[0], 'tabindex', '0');
486
+ }
487
+ allCells.forEach((cell) => {
488
+ if (cell.getAttribute('tabindex') !== '0') {
489
+ this.#renderer.setAttribute(cell, 'tabindex', '-1');
490
+ }
491
+ if (!cell.hasAttribute('role')) {
492
+ this.#renderer.setAttribute(cell, 'role', cell.tagName === 'TD' ? 'gridcell' : 'columnheader');
493
+ }
494
+ });
495
+ const allRows = host.querySelectorAll('tr');
496
+ allRows.forEach((row) => {
497
+ if (!row.hasAttribute('role')) {
498
+ this.#renderer.setAttribute(row, 'role', 'row');
499
+ }
500
+ });
501
+ }
502
+ else {
503
+ // Clean up
504
+ allCells.forEach((cell) => {
505
+ const isHeader = cell.tagName === 'TH';
506
+ if (isHeader) {
507
+ const isInteractiveHeader = cell.classList.contains('sortable') ||
508
+ cell.querySelector('.sh-resizer') !== null ||
509
+ cell.hasAttribute('aria-keyshortcuts');
510
+ if (isInteractiveHeader) {
511
+ this.#renderer.setAttribute(cell, 'tabindex', '0');
512
+ }
513
+ else {
514
+ this.#renderer.removeAttribute(cell, 'tabindex');
515
+ }
516
+ }
517
+ else {
518
+ // Remove tabindex from td (data cells)
519
+ this.#renderer.removeAttribute(cell, 'tabindex');
520
+ }
521
+ });
522
+ }
523
+ });
524
+ }, /* @ts-ignore */
525
+ ...(ngDevMode ? [{ debugName: "gridSetupEffect" }] : /* istanbul ignore next */ []));
290
526
  this.resizing = signal(false, /* @ts-ignore */
291
527
  ...(ngDevMode ? [{ debugName: "resizing" }] : /* istanbul ignore next */ []));
292
528
  this.sizeTrigger = signal(true, /* @ts-ignore */
@@ -333,7 +569,8 @@ class ShipTable {
333
569
  }
334
570
  const column = sortByColumn.startsWith('-') ? sortByColumn.slice(1) : sortByColumn;
335
571
  const isDescending = sortByColumn.startsWith('-');
336
- const sortedData = this.data().sort((a, b) => {
572
+ const currentData = this.data();
573
+ const sortedData = [...currentData].sort((a, b) => {
337
574
  const colConfig = this.content()
338
575
  ?.columns()
339
576
  ?.find((c) => c.id === column);
@@ -341,18 +578,24 @@ class ShipTable {
341
578
  const predicateResult = colConfig.sortPredicate(a, b);
342
579
  return isDescending ? -predicateResult : predicateResult;
343
580
  }
344
- const valueA = a[column];
345
- const valueB = b[column];
581
+ const valueA = colConfig ? this.content()?.getValue(a, colConfig) : a[column];
582
+ const valueB = colConfig ? this.content()?.getValue(b, colConfig) : b[column];
583
+ const aNull = valueA === null || valueA === undefined;
584
+ const bNull = valueB === null || valueB === undefined;
585
+ if (aNull && bNull)
586
+ return 0;
587
+ if (aNull)
588
+ return 1;
589
+ if (bNull)
590
+ return -1;
346
591
  let comparison = 0;
347
592
  if (colConfig?.type === 'date') {
348
- const dateA = valueA ? new Date(valueA).getTime() : 0;
349
- const dateB = valueB ? new Date(valueB).getTime() : 0;
350
- comparison = dateA - dateB;
593
+ const dateA = new Date(valueA).getTime();
594
+ const dateB = new Date(valueB).getTime();
595
+ comparison = isNaN(dateA) || isNaN(dateB) ? 0 : dateA - dateB;
351
596
  }
352
597
  else if (colConfig?.type === 'number') {
353
- const numA = Number(valueA) || 0;
354
- const numB = Number(valueB) || 0;
355
- comparison = numA - numB;
598
+ comparison = Number(valueA) - Number(valueB);
356
599
  }
357
600
  else if (colConfig?.type === 'boolean') {
358
601
  const boolA = valueA ? 1 : 0;
@@ -360,9 +603,7 @@ class ShipTable {
360
603
  comparison = boolA - boolB;
361
604
  }
362
605
  else if (colConfig?.type === 'string' || colConfig?.type === 'badge') {
363
- const strA = (valueA ?? '').toString();
364
- const strB = (valueB ?? '').toString();
365
- comparison = strA.localeCompare(strB, undefined, { sensitivity: 'base' });
606
+ comparison = valueA.toString().localeCompare(valueB.toString(), undefined, { sensitivity: 'base' });
366
607
  }
367
608
  else {
368
609
  if (typeof valueA === 'number' && typeof valueB === 'number') {
@@ -377,14 +618,24 @@ class ShipTable {
377
618
  }
378
619
  return isDescending ? -comparison : comparison;
379
620
  });
380
- this.dataChange.emit(sortedData);
621
+ let changed = sortedData.length !== currentData.length;
622
+ if (!changed) {
623
+ for (let i = 0; i < sortedData.length; i++) {
624
+ if (sortedData[i] !== currentData[i]) {
625
+ changed = true;
626
+ break;
627
+ }
628
+ }
629
+ }
630
+ if (changed) {
631
+ this.dataChange.emit(sortedData);
632
+ }
381
633
  }, /* @ts-ignore */
382
634
  ...(ngDevMode ? [{ debugName: "e" }] : /* istanbul ignore next */ []));
383
635
  }
384
636
  #el;
385
- #destroyRef;
386
- #resizeObserver;
387
- #cleanup;
637
+ #renderer;
638
+ #keybindings;
388
639
  #initialData;
389
640
  #initialDataSet;
390
641
  updateColumnSizes() {
@@ -399,6 +650,166 @@ class ShipTable {
399
650
  ngAfterViewInit() {
400
651
  queueMicrotask(() => this.#checkScroll());
401
652
  }
653
+ onFocusIn(event) {
654
+ if (!this.grid())
655
+ return;
656
+ const target = event.target;
657
+ if (!target)
658
+ return;
659
+ const cell = target.tagName === 'TH' || target.tagName === 'TD' ? target : target.closest('th, td');
660
+ if (cell) {
661
+ // Set roles dynamically for cells and rows if not present
662
+ if (!cell.hasAttribute('role')) {
663
+ this.#renderer.setAttribute(cell, 'role', cell.tagName === 'TD' ? 'gridcell' : 'columnheader');
664
+ }
665
+ const parentRow = cell.parentElement;
666
+ if (parentRow && !parentRow.hasAttribute('role')) {
667
+ this.#renderer.setAttribute(parentRow, 'role', 'row');
668
+ }
669
+ // Set tabindex="0" on focused cell and tabindex="-1" on all other cells
670
+ this.#renderer.setAttribute(cell, 'tabindex', '0');
671
+ const allCells = this.#el.nativeElement.querySelectorAll('th, td');
672
+ allCells.forEach((c) => {
673
+ if (c !== cell) {
674
+ this.#renderer.setAttribute(c, 'tabindex', '-1');
675
+ }
676
+ });
677
+ }
678
+ }
679
+ onGridKeyDown(event) {
680
+ if (!this.grid())
681
+ return;
682
+ if (event.key === 'Tab') {
683
+ const target = event.target;
684
+ const cell = target.tagName === 'TH' || target.tagName === 'TD' ? target : target.closest('th, td');
685
+ if (!cell)
686
+ return;
687
+ const focusableSelectors = 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])';
688
+ const focusableChildren = Array.from(cell.querySelectorAll(focusableSelectors));
689
+ const row = cell.parentElement;
690
+ if (!row || row.tagName !== 'TR')
691
+ return;
692
+ const cellsInRow = Array.from(row.querySelectorAll('th, td'));
693
+ const currentColIndex = cellsInRow.indexOf(cell);
694
+ if (currentColIndex === -1)
695
+ return;
696
+ if (!event.shiftKey) {
697
+ // Forward Tab
698
+ const isLastChild = focusableChildren.length === 0 || target === focusableChildren[focusableChildren.length - 1];
699
+ const isCellSelf = target === cell;
700
+ if (isLastChild && !isCellSelf) {
701
+ // Move to next cell in row
702
+ if (currentColIndex < cellsInRow.length - 1) {
703
+ event.preventDefault();
704
+ this.#focusGridCell(cellsInRow[currentColIndex + 1]);
705
+ }
706
+ }
707
+ else if (isCellSelf && focusableChildren.length === 0) {
708
+ // Move to next cell in row
709
+ if (currentColIndex < cellsInRow.length - 1) {
710
+ event.preventDefault();
711
+ this.#focusGridCell(cellsInRow[currentColIndex + 1]);
712
+ }
713
+ }
714
+ }
715
+ else {
716
+ // Shift + Tab (Backward)
717
+ const isFirstChild = focusableChildren.length > 0 && target === focusableChildren[0];
718
+ const isCellSelf = target === cell;
719
+ if (isFirstChild) {
720
+ event.preventDefault();
721
+ this.#focusGridCell(cell);
722
+ }
723
+ else if (isCellSelf) {
724
+ if (currentColIndex > 0) {
725
+ event.preventDefault();
726
+ const prevCell = cellsInRow[currentColIndex - 1];
727
+ const prevFocusableChildren = Array.from(prevCell.querySelectorAll(focusableSelectors));
728
+ if (prevFocusableChildren.length > 0) {
729
+ this.#focusGridCell(prevCell);
730
+ prevFocusableChildren[prevFocusableChildren.length - 1].focus();
731
+ }
732
+ else {
733
+ this.#focusGridCell(prevCell);
734
+ }
735
+ }
736
+ }
737
+ }
738
+ return;
739
+ }
740
+ const isUp = this.#keybindings.matches(event, 'grid.focus-up');
741
+ const isDown = this.#keybindings.matches(event, 'grid.focus-down');
742
+ const isLeft = this.#keybindings.matches(event, 'grid.focus-left');
743
+ const isRight = this.#keybindings.matches(event, 'grid.focus-right');
744
+ const isFirst = this.#keybindings.matches(event, 'grid.focus-first');
745
+ const isLast = this.#keybindings.matches(event, 'grid.focus-last');
746
+ if (!isUp && !isDown && !isLeft && !isRight && !isFirst && !isLast)
747
+ return;
748
+ const target = event.target;
749
+ if (target.tagName !== 'TH' && target.tagName !== 'TD') {
750
+ // Focus is inside a child control, let them operate normally
751
+ return;
752
+ }
753
+ const row = target.parentElement;
754
+ if (!row || row.tagName !== 'TR')
755
+ return;
756
+ const allRows = Array.from(this.#el.nativeElement.querySelectorAll('tr'));
757
+ const currentRowIndex = allRows.indexOf(row);
758
+ if (currentRowIndex === -1)
759
+ return;
760
+ const cellsInRow = Array.from(row.querySelectorAll('th, td'));
761
+ const currentColIndex = cellsInRow.indexOf(target);
762
+ if (currentColIndex === -1)
763
+ return;
764
+ let targetRowIndex = currentRowIndex;
765
+ let targetColIndex = currentColIndex;
766
+ if (isUp) {
767
+ targetRowIndex = currentRowIndex - 1;
768
+ }
769
+ else if (isDown) {
770
+ targetRowIndex = currentRowIndex + 1;
771
+ }
772
+ else if (isLeft) {
773
+ targetColIndex = currentColIndex - 1;
774
+ }
775
+ else if (isRight) {
776
+ targetColIndex = currentColIndex + 1;
777
+ }
778
+ else if (isFirst) {
779
+ targetColIndex = 0;
780
+ }
781
+ else if (isLast) {
782
+ targetColIndex = cellsInRow.length - 1;
783
+ }
784
+ if (targetRowIndex !== currentRowIndex) {
785
+ const targetRow = allRows[targetRowIndex];
786
+ if (targetRow) {
787
+ const targetCells = Array.from(targetRow.querySelectorAll('th, td'));
788
+ const targetCell = targetCells[Math.min(currentColIndex, targetCells.length - 1)];
789
+ if (targetCell) {
790
+ event.preventDefault();
791
+ this.#focusGridCell(targetCell);
792
+ }
793
+ }
794
+ }
795
+ else if (targetColIndex !== currentColIndex) {
796
+ const targetCell = cellsInRow[targetColIndex];
797
+ if (targetCell) {
798
+ event.preventDefault();
799
+ this.#focusGridCell(targetCell);
800
+ }
801
+ }
802
+ }
803
+ #focusGridCell(cell) {
804
+ this.#renderer.setAttribute(cell, 'tabindex', '0');
805
+ cell.focus();
806
+ const allCells = this.#el.nativeElement.querySelectorAll('th, td');
807
+ allCells.forEach((c) => {
808
+ if (c !== cell) {
809
+ this.#renderer.setAttribute(c, 'tabindex', '-1');
810
+ }
811
+ });
812
+ }
402
813
  toggleSort(column) {
403
814
  const currentSort = this.sortByColumn();
404
815
  const sortDir = currentSort === column ? `-${column}` : currentSort === `-${column}` ? null : column;
@@ -436,7 +847,7 @@ class ShipTable {
436
847
  this.canScrollY.set(canScrollY);
437
848
  }
438
849
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: ShipTable, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
439
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.0", type: ShipTable, isStandalone: true, selector: "sh-table", inputs: { loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, sortByColumn: { classPropertyName: "sortByColumn", publicName: "sortByColumn", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null }, ariaLabelledby: { classPropertyName: "ariaLabelledby", publicName: "aria-labelledby", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dataChange: "dataChange", sortByColumn: "sortByColumnChange" }, host: { attributes: { "role": "table" }, listeners: { "scroll": "onScroll()", "window:resize": "onResize($event)" }, properties: { "attr.aria-busy": "loading()", "attr.aria-label": "ariaLabel()", "attr.aria-labelledby": "ariaLabelledby()", "class": "hostClasses()", "style.grid-template-columns": "columnSizes()", "class.resizing": "resizing()", "class.can-scroll-x": "canScrollX()", "class.can-scroll-y": "canScrollY()", "class.scrolled-x": "scrollXState() >= 0", "class.scrolled-x-end": "scrollXState() === 1", "class.scrolled-y": "scrollYState() >= 0", "class.scrolled-y-end": "scrollYState() === 1" } }, queries: [{ propertyName: "content", first: true, predicate: ShipTableContent, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "theadLocal", first: true, predicate: ["theadLocal"], descendants: true, isSignal: true }, { propertyName: "tbodyLocal", first: true, predicate: ["tbodyLocal"], descendants: true, isSignal: true }], ngImport: i0, template: `
850
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.0", type: ShipTable, isStandalone: true, selector: "sh-table", inputs: { grid: { classPropertyName: "grid", publicName: "grid", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, sortByColumn: { classPropertyName: "sortByColumn", publicName: "sortByColumn", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null }, ariaLabelledby: { classPropertyName: "ariaLabelledby", publicName: "aria-labelledby", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dataChange: "dataChange", sortByColumn: "sortByColumnChange" }, host: { listeners: { "scroll": "onScroll()", "window:resize": "onResize($event)", "focusin": "onFocusIn($event)", "keydown": "onGridKeyDown($event)" }, properties: { "attr.role": "role()", "attr.aria-busy": "loading()", "attr.aria-label": "ariaLabel()", "attr.aria-labelledby": "ariaLabelledby()", "class": "hostClasses()", "style.grid-template-columns": "columnSizes()", "class.resizing": "resizing()", "class.can-scroll-x": "canScrollX()", "class.can-scroll-y": "canScrollY()", "class.scrolled-x": "scrollXState() >= 0", "class.scrolled-x-end": "scrollXState() === 1", "class.scrolled-y": "scrollYState() >= 0", "class.scrolled-y-end": "scrollYState() === 1" } }, queries: [{ propertyName: "content", first: true, predicate: ShipTableContent, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "theadLocal", first: true, predicate: ["theadLocal"], descendants: true, isSignal: true }, { propertyName: "tbodyLocal", first: true, predicate: ["tbodyLocal"], descendants: true, isSignal: true }], ngImport: i0, template: `
440
851
  <div class="actionbar">
441
852
  <ng-content select="[actionbar]:not([align-right])" />
442
853
  <div class="actionbar-right">
@@ -466,7 +877,7 @@ class ShipTable {
466
877
  <ng-content select="[table-no-rows]" />
467
878
  </div>
468
879
  }
469
- `, isInline: true, styles: ["sh-table{--table-bc: var(--base-4);--table-th-bg: var(--base-2);--table-tr-bg: var(--base-1);--table-td-bg: var(--base-1);--table-th-c: var(--base-8);--table-th-f: var(--paragraph-30);--table-td-c: var(--base-8);--table-td-f: var(--paragraph-30);--table-th-p: 0 1.25rem;--table-td-p: 0 1.25rem;--table-th-mh: 3rem;--table-td-mh: 4.875rem;--table-th-g: .25rem;--table-td-g: .5rem;--table-ws: nowrap;--table-th-bw: 0;--table-td-bw: .0625rem 0 0;--table-columns: 1fr 1fr 1fr max-content;--table-sticky-bw: .0625rem}sh-table.type-a tbody>th,sh-table.type-a tbody>td,sh-table.type-a thead>th,sh-table.type-a thead>td{padding-right:0}sh-table.type-a tbody>th:first-child,sh-table.type-a tbody>td:first-child,sh-table.type-a thead>th:first-child,sh-table.type-a thead>td:first-child{padding:0}sh-table.type-b{--table-th-p: 0 .75rem;--table-td-p: 0 .75rem;--table-th-mh: 2.25rem;--table-td-mh: 3.5rem;--table-th-bw: .0625rem 0 .0625rem .0625rem;--table-td-bw: 0 0 .0625rem .0625rem;--table-sticky-bw: .0625rem}sh-table.type-b th:first-child{border-left-width:0;padding:var(--table-th-p)}sh-table.type-b td:first-child{border-left-width:0;padding:var(--table-td-p)}sh-table.type-b td.sticky,sh-table.type-b th.sticky{border-left-width:0;border-right:var(--table-sticky-bw) solid var(--table-bc)}sh-table.type-b [shStickyColumns] th,sh-table.type-b [shStickyColumns] td{border-right:var(--table-sticky-bw) solid var(--table-bc)}sh-table.type-b th.sticky-end,sh-table.type-b td.sticky-end,sh-table.type-b [shStickyColumns=end] th,sh-table.type-b [shStickyColumns=end] td{border-left:var(--table-sticky-bw) solid var(--table-bc);border-right:0}sh-table.type-b .sticky+th,sh-table.type-b .sticky+td,sh-table.type-b [shStickyColumns]+th,sh-table.type-b [shStickyColumns]+td{border-left-width:0}sh-table.type-b tr:hover td{background-color:var(--base-2)}sh-table.type-b div[table-header] tr:first-child th{border-bottom:0}sh-table.type-b tbody tr:last-child td{border-bottom-width:0}sh-table.type-b .actionbar{background-color:var(--base-2);border-width:.0625rem 0 0}sh-table{width:100%;display:grid;overflow:auto;overscroll-behavior-x:none;grid-template-columns:var(--table-columns);position:relative;container-type:inline-size}sh-table.resizing{-webkit-user-select:none;user-select:none}sh-table:has([shTableResize]) td{overflow:auto}sh-table.no-resize .sh-resizer{display:none}sh-table.no-resize td{overflow:initial}sh-table .actionbar{display:flex;align-items:center;gap:.5rem;grid-column:1/-1;position:sticky;left:0;z-index:10;background-color:var(--base-1);width:100cqw;box-sizing:border-box;padding:.5rem;border:var(--border-10);border-width:.0625rem 0;opacity:1;transition:padding .3s ease-out,border-width .3s ease-out,opacity .3s ease-out;overflow:hidden}sh-table .actionbar:empty,sh-table .actionbar:not(:has(>:not(.actionbar-right))):has(>.actionbar-right:empty){display:none}sh-table .actionbar>*{min-height:0}sh-table .actionbar .actionbar-right{display:flex;align-items:center;gap:.5rem;margin-left:auto;flex-shrink:0}sh-table .actionbar .actionbar-right:empty{display:none}sh-table tbody{position:relative}sh-table tbody:has(tr.sticky){position:sticky;top:0;z-index:1}sh-table thead{position:relative}sh-table thead:has(tr.sticky){position:sticky;top:0;z-index:2}sh-table sh-progress-bar{grid-column:1/-1;position:absolute;top:100%;transform:translateY(-50%);z-index:200}sh-table tbody,sh-table thead,sh-table tr{display:grid;grid-column:1/-1;grid-template-columns:subgrid}sh-table tr{background:var(--table-tr-bg);position:relative;z-index:0}sh-table tr.sticky{position:sticky;top:0;z-index:1}sh-table tr.sticky-end{position:sticky;bottom:0;z-index:3}sh-table tr:has(th.sticky-end) th:nth-last-child(2){padding:var(--table-th-p)}sh-table tr:has(td.sticky-end) td:nth-last-child(2){padding:var(--table-td-p)}sh-table th{display:flex;align-items:center;padding:var(--table-th-p);min-height:var(--table-th-mh);font:var(--table-th-f);line-height:1em;white-space:var(--table-ws);color:var(--table-th-c);border:0;border-color:var(--table-bc);border-style:solid;border-width:var(--table-th-bw);background:var(--table-th-bg);gap:var(--table-th-g);z-index:auto}sh-table th:hover,sh-table th.resizing{z-index:120}sh-table th:has(.sh-resizer){position:relative}sh-table th.sortable{--caret-color: var(--base-10);--caret-size: .375rem;cursor:pointer;-webkit-user-select:none;user-select:none}sh-table th.sortable sh-icon{opacity:.35;transition:opacity 125ms ease-in-out}sh-table th.sortable:hover sh-icon{opacity:.7}sh-table th.sortable.sort-asc sh-icon,sh-table th.sortable.sort-desc sh-icon{opacity:1}sh-table th.sortable:not(:has(sh-icon)):after{content:\"\";border:var(--caret-size) solid transparent;width:0;height:0;opacity:0;transition:opacity 125ms ease-in-out}sh-table th.sortable:not(:has(sh-icon)).sort-desc:after{opacity:1;transform:translateY(-4px);border-bottom-color:var(--caret-color)}sh-table th.sortable:not(:has(sh-icon)).sort-asc:after{opacity:1;transform:translateY(4px);border-top-color:var(--caret-color)}sh-table th .sh-resizer{width:.75rem;height:100%;position:absolute;top:0;right:-.375rem;cursor:col-resize;z-index:110}sh-table th .sh-resizer:after{content:\"\";position:absolute;top:.3125rem;bottom:.3125rem;border-radius:.125rem;right:.3125rem;width:.1875rem;background-color:var(--base-4);transition:width .15s ease,background-color .15s ease,right .15s ease}sh-table th .sh-resizer:hover:after{width:.3125rem;right:.1875rem;background-color:var(--primary-8)}sh-table th.resizing .sh-resizer:after{width:.3125rem;right:.1875rem;background-color:var(--primary-8)}sh-table td{display:flex;align-items:center;padding:var(--table-td-p);min-height:var(--table-td-mh);gap:var(--table-td-g);color:var(--table-td-c);font:var(--table-td-f);white-space:var(--table-ws);border-color:var(--table-bc);border-style:solid;border-width:var(--table-td-bw);background:var(--table-td-bg)}sh-table td+td.sticky-end:last-child{padding:var(--table-td-p)}sh-table th.sticky,sh-table th.sticky-end,sh-table td.sticky,sh-table td.sticky-end{position:sticky;overflow:hidden;right:auto;left:0;z-index:1;padding:var(--table-td-p)}sh-table th.sticky:first-child,sh-table th.sticky-end:first-child,sh-table td.sticky:first-child,sh-table td.sticky-end:first-child{padding:var(--table-th-p)}sh-table th.sticky-end,sh-table td.sticky-end{right:0;left:auto}sh-table th.sticky,sh-table th.sticky-end{background:var(--base-1);padding:var(--table-th-p);z-index:101}sh-table th.sticky:first-child,sh-table th.sticky-end:first-child{padding:var(--table-th-p)}sh-table [shStickyColumns]{display:grid;grid-template-columns:subgrid;position:sticky;left:0;z-index:1000;border:0;border-color:var(--table-bc);border-style:solid}sh-table [shStickyColumns] th{background-color:var(--base-1)}sh-table [shStickyColumns=end]{left:auto;right:0}sh-table .span-all{grid-column:1/-1;white-space:initial;align-items:flex-start;padding:0;border-left-width:0;position:sticky;left:0;width:100cqw;box-sizing:border-box}sh-table .no-rows{display:none;grid-column:1/-1}sh-table tbody:empty+.no-rows{display:block}\n"], dependencies: [{ kind: "component", type: ShipProgressBar, selector: "sh-progress-bar", inputs: ["value", "color", "variant"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
880
+ `, isInline: true, styles: ["sh-table{--table-bc: var(--base-4);--table-th-bg: var(--base-2);--table-tr-bg: var(--base-1);--table-td-bg: var(--base-1);--table-th-c: var(--base-8);--table-th-f: var(--paragraph-30);--table-td-c: var(--base-8);--table-td-f: var(--paragraph-30);--table-th-p: 0 1.25rem;--table-td-p: 0 1.25rem;--table-th-mh: 3rem;--table-td-mh: 4.875rem;--table-th-g: .25rem;--table-td-g: .5rem;--table-ws: nowrap;--table-th-bw: 0;--table-td-bw: .0625rem 0 0;--table-columns: 1fr 1fr 1fr max-content;--table-sticky-bw: .0625rem}sh-table.type-a tbody>th,sh-table.type-a tbody>td,sh-table.type-a thead>th,sh-table.type-a thead>td{padding-right:0}sh-table.type-a tbody>th:first-child,sh-table.type-a tbody>td:first-child,sh-table.type-a thead>th:first-child,sh-table.type-a thead>td:first-child{padding:0}sh-table.type-b{--table-th-p: 0 .75rem;--table-td-p: 0 .75rem;--table-th-mh: 2.25rem;--table-td-mh: 3.5rem;--table-th-bw: .0625rem 0 .0625rem .0625rem;--table-td-bw: 0 0 .0625rem .0625rem;--table-sticky-bw: .0625rem}sh-table.type-b th:first-child{border-left-width:0;padding:var(--table-th-p)}sh-table.type-b td:first-child{border-left-width:0;padding:var(--table-td-p)}sh-table.type-b td.sticky,sh-table.type-b th.sticky{border-left-width:0;border-right:var(--table-sticky-bw) solid var(--table-bc)}sh-table.type-b [shStickyColumns] th,sh-table.type-b [shStickyColumns] td{border-right:var(--table-sticky-bw) solid var(--table-bc)}sh-table.type-b th.sticky-end,sh-table.type-b td.sticky-end,sh-table.type-b [shStickyColumns=end] th,sh-table.type-b [shStickyColumns=end] td{border-left:var(--table-sticky-bw) solid var(--table-bc);border-right:0}sh-table.type-b .sticky+th,sh-table.type-b .sticky+td,sh-table.type-b [shStickyColumns]+th,sh-table.type-b [shStickyColumns]+td{border-left-width:0}sh-table.type-b tr:hover td{background-color:var(--base-2)}sh-table.type-b div[table-header] tr:first-child th{border-bottom:0}sh-table.type-b tbody tr:last-child td{border-bottom-width:0}sh-table.type-b .actionbar{background-color:var(--base-2);border-width:.0625rem 0 0}sh-table{width:100%;display:grid;overflow:auto;overscroll-behavior-x:none;grid-template-columns:var(--table-columns);position:relative;container-type:inline-size}sh-table.resizing{-webkit-user-select:none;user-select:none}sh-table:has([shTableResize]) td{overflow:auto}sh-table.no-resize .sh-resizer{display:none}sh-table.no-resize td{overflow:initial}sh-table .actionbar{display:flex;align-items:center;gap:.5rem;grid-column:1/-1;position:sticky;left:0;z-index:10;background-color:var(--base-1);width:100cqw;box-sizing:border-box;padding:.5rem;border:var(--border-10);border-width:.0625rem 0;opacity:1;transition:padding .3s ease-out,border-width .3s ease-out,opacity .3s ease-out;overflow:hidden}sh-table .actionbar:empty,sh-table .actionbar:not(:has(>:not(.actionbar-right))):has(>.actionbar-right:empty){display:none}sh-table .actionbar>*{min-height:0}sh-table .actionbar .actionbar-right{display:flex;align-items:center;gap:.5rem;margin-left:auto;flex-shrink:0}sh-table .actionbar .actionbar-right:empty{display:none}sh-table tbody{position:relative}sh-table tbody:has(tr.sticky){position:sticky;top:0;z-index:1}sh-table thead{position:relative}sh-table thead:has(tr.sticky){position:sticky;top:0;z-index:2}sh-table sh-progress-bar{grid-column:1/-1;position:absolute;top:100%;transform:translateY(-50%);z-index:200}sh-table tbody,sh-table thead,sh-table tr{display:grid;grid-column:1/-1;grid-template-columns:subgrid}sh-table tr{background:var(--table-tr-bg);position:relative;z-index:0}sh-table tr.sticky{position:sticky;top:0;z-index:1}sh-table tr.sticky-end{position:sticky;bottom:0;z-index:3}sh-table tr:has(th.sticky-end) th:nth-last-child(2){padding:var(--table-th-p)}sh-table tr:has(td.sticky-end) td:nth-last-child(2){padding:var(--table-td-p)}sh-table th{display:flex;align-items:center;padding:var(--table-th-p);min-height:var(--table-th-mh);font:var(--table-th-f);line-height:1em;white-space:var(--table-ws);color:var(--table-th-c);border:0;border-color:var(--table-bc);border-style:solid;border-width:var(--table-th-bw);background:var(--table-th-bg);gap:var(--table-th-g);z-index:auto}sh-table th:focus-visible{outline:.125rem solid var(--primary-8);outline-offset:-.125rem}sh-table th:hover,sh-table th.resizing{z-index:10}sh-table th:has(.sh-resizer){position:relative;z-index:2}sh-table th.sortable{--caret-color: var(--base-10);--caret-size: .375rem;cursor:pointer;-webkit-user-select:none;user-select:none}sh-table th.sortable sh-icon{opacity:.35;transition:opacity 125ms ease-in-out}sh-table th.sortable:hover sh-icon{opacity:.7}sh-table th.sortable.sort-asc sh-icon,sh-table th.sortable.sort-desc sh-icon{opacity:1}sh-table th.sortable:not(:has(sh-icon)):after{content:\"\";border:var(--caret-size) solid transparent;width:0;height:0;opacity:0;transition:opacity 125ms ease-in-out}sh-table th.sortable:not(:has(sh-icon)).sort-desc:after{opacity:1;transform:translateY(-4px);border-bottom-color:var(--caret-color)}sh-table th.sortable:not(:has(sh-icon)).sort-asc:after{opacity:1;transform:translateY(4px);border-top-color:var(--caret-color)}sh-table th .sh-resizer{width:.75rem;height:100%;position:absolute;top:0;right:-.375rem;cursor:col-resize;z-index:5}sh-table th .sh-resizer:after{content:\"\";position:absolute;top:.3125rem;bottom:.3125rem;border-radius:.125rem;right:.3125rem;width:.1875rem;background-color:var(--base-4);transition:width .15s ease,background-color .15s ease,right .15s ease}sh-table th .sh-resizer:hover:after{width:.3125rem;right:.1875rem;background-color:var(--primary-8)}sh-table th.resizing .sh-resizer:after{width:.3125rem;right:.1875rem;background-color:var(--primary-8)}sh-table td{display:flex;align-items:center;padding:var(--table-td-p);min-height:var(--table-td-mh);gap:var(--table-td-g);color:var(--table-td-c);font:var(--table-td-f);white-space:var(--table-ws);border-color:var(--table-bc);border-style:solid;border-width:var(--table-td-bw);background:var(--table-td-bg)}sh-table td+td.sticky-end:last-child{padding:var(--table-td-p)}sh-table th.sticky,sh-table th.sticky-end,sh-table td.sticky,sh-table td.sticky-end{position:sticky;overflow:hidden;right:auto;left:0;z-index:1;padding:var(--table-td-p)}sh-table th.sticky:first-child,sh-table th.sticky-end:first-child,sh-table td.sticky:first-child,sh-table td.sticky-end:first-child{padding:var(--table-th-p)}sh-table th.sticky-end,sh-table td.sticky-end{right:0;left:auto}sh-table th.sticky,sh-table th.sticky-end{background:var(--base-1);padding:var(--table-th-p);z-index:101}sh-table th.sticky:first-child,sh-table th.sticky-end:first-child{padding:var(--table-th-p)}sh-table [shStickyColumns]{display:grid;grid-template-columns:subgrid;position:sticky;left:0;z-index:1000;border:0;border-color:var(--table-bc);border-style:solid}sh-table [shStickyColumns] th{background-color:var(--base-1)}sh-table [shStickyColumns=end]{left:auto;right:0}sh-table .span-all{grid-column:1/-1;white-space:initial;align-items:flex-start;padding:0;border-left-width:0;position:sticky;left:0;width:100cqw;box-sizing:border-box}sh-table .no-rows{display:none;grid-column:1/-1}sh-table tbody:empty+.no-rows{display:block}\n"], dependencies: [{ kind: "component", type: ShipProgressBar, selector: "sh-progress-bar", inputs: ["value", "color", "variant"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
470
881
  }
471
882
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImport: i0, type: ShipTable, decorators: [{
472
883
  type: Component,
@@ -501,7 +912,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImpor
501
912
  </div>
502
913
  }
503
914
  `, changeDetection: ChangeDetectionStrategy.OnPush, host: {
504
- role: 'table',
915
+ '[attr.role]': 'role()',
505
916
  '[attr.aria-busy]': 'loading()',
506
917
  '[attr.aria-label]': 'ariaLabel()',
507
918
  '[attr.aria-labelledby]': 'ariaLabelledby()',
@@ -515,10 +926,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImpor
515
926
  '[class.scrolled-x-end]': 'scrollXState() === 1',
516
927
  '[class.scrolled-y]': 'scrollYState() >= 0',
517
928
  '[class.scrolled-y-end]': 'scrollYState() === 1',
518
- }, styles: ["sh-table{--table-bc: var(--base-4);--table-th-bg: var(--base-2);--table-tr-bg: var(--base-1);--table-td-bg: var(--base-1);--table-th-c: var(--base-8);--table-th-f: var(--paragraph-30);--table-td-c: var(--base-8);--table-td-f: var(--paragraph-30);--table-th-p: 0 1.25rem;--table-td-p: 0 1.25rem;--table-th-mh: 3rem;--table-td-mh: 4.875rem;--table-th-g: .25rem;--table-td-g: .5rem;--table-ws: nowrap;--table-th-bw: 0;--table-td-bw: .0625rem 0 0;--table-columns: 1fr 1fr 1fr max-content;--table-sticky-bw: .0625rem}sh-table.type-a tbody>th,sh-table.type-a tbody>td,sh-table.type-a thead>th,sh-table.type-a thead>td{padding-right:0}sh-table.type-a tbody>th:first-child,sh-table.type-a tbody>td:first-child,sh-table.type-a thead>th:first-child,sh-table.type-a thead>td:first-child{padding:0}sh-table.type-b{--table-th-p: 0 .75rem;--table-td-p: 0 .75rem;--table-th-mh: 2.25rem;--table-td-mh: 3.5rem;--table-th-bw: .0625rem 0 .0625rem .0625rem;--table-td-bw: 0 0 .0625rem .0625rem;--table-sticky-bw: .0625rem}sh-table.type-b th:first-child{border-left-width:0;padding:var(--table-th-p)}sh-table.type-b td:first-child{border-left-width:0;padding:var(--table-td-p)}sh-table.type-b td.sticky,sh-table.type-b th.sticky{border-left-width:0;border-right:var(--table-sticky-bw) solid var(--table-bc)}sh-table.type-b [shStickyColumns] th,sh-table.type-b [shStickyColumns] td{border-right:var(--table-sticky-bw) solid var(--table-bc)}sh-table.type-b th.sticky-end,sh-table.type-b td.sticky-end,sh-table.type-b [shStickyColumns=end] th,sh-table.type-b [shStickyColumns=end] td{border-left:var(--table-sticky-bw) solid var(--table-bc);border-right:0}sh-table.type-b .sticky+th,sh-table.type-b .sticky+td,sh-table.type-b [shStickyColumns]+th,sh-table.type-b [shStickyColumns]+td{border-left-width:0}sh-table.type-b tr:hover td{background-color:var(--base-2)}sh-table.type-b div[table-header] tr:first-child th{border-bottom:0}sh-table.type-b tbody tr:last-child td{border-bottom-width:0}sh-table.type-b .actionbar{background-color:var(--base-2);border-width:.0625rem 0 0}sh-table{width:100%;display:grid;overflow:auto;overscroll-behavior-x:none;grid-template-columns:var(--table-columns);position:relative;container-type:inline-size}sh-table.resizing{-webkit-user-select:none;user-select:none}sh-table:has([shTableResize]) td{overflow:auto}sh-table.no-resize .sh-resizer{display:none}sh-table.no-resize td{overflow:initial}sh-table .actionbar{display:flex;align-items:center;gap:.5rem;grid-column:1/-1;position:sticky;left:0;z-index:10;background-color:var(--base-1);width:100cqw;box-sizing:border-box;padding:.5rem;border:var(--border-10);border-width:.0625rem 0;opacity:1;transition:padding .3s ease-out,border-width .3s ease-out,opacity .3s ease-out;overflow:hidden}sh-table .actionbar:empty,sh-table .actionbar:not(:has(>:not(.actionbar-right))):has(>.actionbar-right:empty){display:none}sh-table .actionbar>*{min-height:0}sh-table .actionbar .actionbar-right{display:flex;align-items:center;gap:.5rem;margin-left:auto;flex-shrink:0}sh-table .actionbar .actionbar-right:empty{display:none}sh-table tbody{position:relative}sh-table tbody:has(tr.sticky){position:sticky;top:0;z-index:1}sh-table thead{position:relative}sh-table thead:has(tr.sticky){position:sticky;top:0;z-index:2}sh-table sh-progress-bar{grid-column:1/-1;position:absolute;top:100%;transform:translateY(-50%);z-index:200}sh-table tbody,sh-table thead,sh-table tr{display:grid;grid-column:1/-1;grid-template-columns:subgrid}sh-table tr{background:var(--table-tr-bg);position:relative;z-index:0}sh-table tr.sticky{position:sticky;top:0;z-index:1}sh-table tr.sticky-end{position:sticky;bottom:0;z-index:3}sh-table tr:has(th.sticky-end) th:nth-last-child(2){padding:var(--table-th-p)}sh-table tr:has(td.sticky-end) td:nth-last-child(2){padding:var(--table-td-p)}sh-table th{display:flex;align-items:center;padding:var(--table-th-p);min-height:var(--table-th-mh);font:var(--table-th-f);line-height:1em;white-space:var(--table-ws);color:var(--table-th-c);border:0;border-color:var(--table-bc);border-style:solid;border-width:var(--table-th-bw);background:var(--table-th-bg);gap:var(--table-th-g);z-index:auto}sh-table th:hover,sh-table th.resizing{z-index:120}sh-table th:has(.sh-resizer){position:relative}sh-table th.sortable{--caret-color: var(--base-10);--caret-size: .375rem;cursor:pointer;-webkit-user-select:none;user-select:none}sh-table th.sortable sh-icon{opacity:.35;transition:opacity 125ms ease-in-out}sh-table th.sortable:hover sh-icon{opacity:.7}sh-table th.sortable.sort-asc sh-icon,sh-table th.sortable.sort-desc sh-icon{opacity:1}sh-table th.sortable:not(:has(sh-icon)):after{content:\"\";border:var(--caret-size) solid transparent;width:0;height:0;opacity:0;transition:opacity 125ms ease-in-out}sh-table th.sortable:not(:has(sh-icon)).sort-desc:after{opacity:1;transform:translateY(-4px);border-bottom-color:var(--caret-color)}sh-table th.sortable:not(:has(sh-icon)).sort-asc:after{opacity:1;transform:translateY(4px);border-top-color:var(--caret-color)}sh-table th .sh-resizer{width:.75rem;height:100%;position:absolute;top:0;right:-.375rem;cursor:col-resize;z-index:110}sh-table th .sh-resizer:after{content:\"\";position:absolute;top:.3125rem;bottom:.3125rem;border-radius:.125rem;right:.3125rem;width:.1875rem;background-color:var(--base-4);transition:width .15s ease,background-color .15s ease,right .15s ease}sh-table th .sh-resizer:hover:after{width:.3125rem;right:.1875rem;background-color:var(--primary-8)}sh-table th.resizing .sh-resizer:after{width:.3125rem;right:.1875rem;background-color:var(--primary-8)}sh-table td{display:flex;align-items:center;padding:var(--table-td-p);min-height:var(--table-td-mh);gap:var(--table-td-g);color:var(--table-td-c);font:var(--table-td-f);white-space:var(--table-ws);border-color:var(--table-bc);border-style:solid;border-width:var(--table-td-bw);background:var(--table-td-bg)}sh-table td+td.sticky-end:last-child{padding:var(--table-td-p)}sh-table th.sticky,sh-table th.sticky-end,sh-table td.sticky,sh-table td.sticky-end{position:sticky;overflow:hidden;right:auto;left:0;z-index:1;padding:var(--table-td-p)}sh-table th.sticky:first-child,sh-table th.sticky-end:first-child,sh-table td.sticky:first-child,sh-table td.sticky-end:first-child{padding:var(--table-th-p)}sh-table th.sticky-end,sh-table td.sticky-end{right:0;left:auto}sh-table th.sticky,sh-table th.sticky-end{background:var(--base-1);padding:var(--table-th-p);z-index:101}sh-table th.sticky:first-child,sh-table th.sticky-end:first-child{padding:var(--table-th-p)}sh-table [shStickyColumns]{display:grid;grid-template-columns:subgrid;position:sticky;left:0;z-index:1000;border:0;border-color:var(--table-bc);border-style:solid}sh-table [shStickyColumns] th{background-color:var(--base-1)}sh-table [shStickyColumns=end]{left:auto;right:0}sh-table .span-all{grid-column:1/-1;white-space:initial;align-items:flex-start;padding:0;border-left-width:0;position:sticky;left:0;width:100cqw;box-sizing:border-box}sh-table .no-rows{display:none;grid-column:1/-1}sh-table tbody:empty+.no-rows{display:block}\n"] }]
519
- }], propDecorators: { loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], dataChange: [{ type: i0.Output, args: ["dataChange"] }], sortByColumn: [{ type: i0.Input, args: [{ isSignal: true, alias: "sortByColumn", required: false }] }, { type: i0.Output, args: ["sortByColumnChange"] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-label", required: false }] }], ariaLabelledby: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-labelledby", required: false }] }], content: [{ type: i0.ContentChild, args: [i0.forwardRef(() => ShipTableContent), { isSignal: true }] }], theadLocal: [{ type: i0.ViewChild, args: ['theadLocal', { isSignal: true }] }], tbodyLocal: [{ type: i0.ViewChild, args: ['tbodyLocal', { isSignal: true }] }], onResize: [{
929
+ }, styles: ["sh-table{--table-bc: var(--base-4);--table-th-bg: var(--base-2);--table-tr-bg: var(--base-1);--table-td-bg: var(--base-1);--table-th-c: var(--base-8);--table-th-f: var(--paragraph-30);--table-td-c: var(--base-8);--table-td-f: var(--paragraph-30);--table-th-p: 0 1.25rem;--table-td-p: 0 1.25rem;--table-th-mh: 3rem;--table-td-mh: 4.875rem;--table-th-g: .25rem;--table-td-g: .5rem;--table-ws: nowrap;--table-th-bw: 0;--table-td-bw: .0625rem 0 0;--table-columns: 1fr 1fr 1fr max-content;--table-sticky-bw: .0625rem}sh-table.type-a tbody>th,sh-table.type-a tbody>td,sh-table.type-a thead>th,sh-table.type-a thead>td{padding-right:0}sh-table.type-a tbody>th:first-child,sh-table.type-a tbody>td:first-child,sh-table.type-a thead>th:first-child,sh-table.type-a thead>td:first-child{padding:0}sh-table.type-b{--table-th-p: 0 .75rem;--table-td-p: 0 .75rem;--table-th-mh: 2.25rem;--table-td-mh: 3.5rem;--table-th-bw: .0625rem 0 .0625rem .0625rem;--table-td-bw: 0 0 .0625rem .0625rem;--table-sticky-bw: .0625rem}sh-table.type-b th:first-child{border-left-width:0;padding:var(--table-th-p)}sh-table.type-b td:first-child{border-left-width:0;padding:var(--table-td-p)}sh-table.type-b td.sticky,sh-table.type-b th.sticky{border-left-width:0;border-right:var(--table-sticky-bw) solid var(--table-bc)}sh-table.type-b [shStickyColumns] th,sh-table.type-b [shStickyColumns] td{border-right:var(--table-sticky-bw) solid var(--table-bc)}sh-table.type-b th.sticky-end,sh-table.type-b td.sticky-end,sh-table.type-b [shStickyColumns=end] th,sh-table.type-b [shStickyColumns=end] td{border-left:var(--table-sticky-bw) solid var(--table-bc);border-right:0}sh-table.type-b .sticky+th,sh-table.type-b .sticky+td,sh-table.type-b [shStickyColumns]+th,sh-table.type-b [shStickyColumns]+td{border-left-width:0}sh-table.type-b tr:hover td{background-color:var(--base-2)}sh-table.type-b div[table-header] tr:first-child th{border-bottom:0}sh-table.type-b tbody tr:last-child td{border-bottom-width:0}sh-table.type-b .actionbar{background-color:var(--base-2);border-width:.0625rem 0 0}sh-table{width:100%;display:grid;overflow:auto;overscroll-behavior-x:none;grid-template-columns:var(--table-columns);position:relative;container-type:inline-size}sh-table.resizing{-webkit-user-select:none;user-select:none}sh-table:has([shTableResize]) td{overflow:auto}sh-table.no-resize .sh-resizer{display:none}sh-table.no-resize td{overflow:initial}sh-table .actionbar{display:flex;align-items:center;gap:.5rem;grid-column:1/-1;position:sticky;left:0;z-index:10;background-color:var(--base-1);width:100cqw;box-sizing:border-box;padding:.5rem;border:var(--border-10);border-width:.0625rem 0;opacity:1;transition:padding .3s ease-out,border-width .3s ease-out,opacity .3s ease-out;overflow:hidden}sh-table .actionbar:empty,sh-table .actionbar:not(:has(>:not(.actionbar-right))):has(>.actionbar-right:empty){display:none}sh-table .actionbar>*{min-height:0}sh-table .actionbar .actionbar-right{display:flex;align-items:center;gap:.5rem;margin-left:auto;flex-shrink:0}sh-table .actionbar .actionbar-right:empty{display:none}sh-table tbody{position:relative}sh-table tbody:has(tr.sticky){position:sticky;top:0;z-index:1}sh-table thead{position:relative}sh-table thead:has(tr.sticky){position:sticky;top:0;z-index:2}sh-table sh-progress-bar{grid-column:1/-1;position:absolute;top:100%;transform:translateY(-50%);z-index:200}sh-table tbody,sh-table thead,sh-table tr{display:grid;grid-column:1/-1;grid-template-columns:subgrid}sh-table tr{background:var(--table-tr-bg);position:relative;z-index:0}sh-table tr.sticky{position:sticky;top:0;z-index:1}sh-table tr.sticky-end{position:sticky;bottom:0;z-index:3}sh-table tr:has(th.sticky-end) th:nth-last-child(2){padding:var(--table-th-p)}sh-table tr:has(td.sticky-end) td:nth-last-child(2){padding:var(--table-td-p)}sh-table th{display:flex;align-items:center;padding:var(--table-th-p);min-height:var(--table-th-mh);font:var(--table-th-f);line-height:1em;white-space:var(--table-ws);color:var(--table-th-c);border:0;border-color:var(--table-bc);border-style:solid;border-width:var(--table-th-bw);background:var(--table-th-bg);gap:var(--table-th-g);z-index:auto}sh-table th:focus-visible{outline:.125rem solid var(--primary-8);outline-offset:-.125rem}sh-table th:hover,sh-table th.resizing{z-index:10}sh-table th:has(.sh-resizer){position:relative;z-index:2}sh-table th.sortable{--caret-color: var(--base-10);--caret-size: .375rem;cursor:pointer;-webkit-user-select:none;user-select:none}sh-table th.sortable sh-icon{opacity:.35;transition:opacity 125ms ease-in-out}sh-table th.sortable:hover sh-icon{opacity:.7}sh-table th.sortable.sort-asc sh-icon,sh-table th.sortable.sort-desc sh-icon{opacity:1}sh-table th.sortable:not(:has(sh-icon)):after{content:\"\";border:var(--caret-size) solid transparent;width:0;height:0;opacity:0;transition:opacity 125ms ease-in-out}sh-table th.sortable:not(:has(sh-icon)).sort-desc:after{opacity:1;transform:translateY(-4px);border-bottom-color:var(--caret-color)}sh-table th.sortable:not(:has(sh-icon)).sort-asc:after{opacity:1;transform:translateY(4px);border-top-color:var(--caret-color)}sh-table th .sh-resizer{width:.75rem;height:100%;position:absolute;top:0;right:-.375rem;cursor:col-resize;z-index:5}sh-table th .sh-resizer:after{content:\"\";position:absolute;top:.3125rem;bottom:.3125rem;border-radius:.125rem;right:.3125rem;width:.1875rem;background-color:var(--base-4);transition:width .15s ease,background-color .15s ease,right .15s ease}sh-table th .sh-resizer:hover:after{width:.3125rem;right:.1875rem;background-color:var(--primary-8)}sh-table th.resizing .sh-resizer:after{width:.3125rem;right:.1875rem;background-color:var(--primary-8)}sh-table td{display:flex;align-items:center;padding:var(--table-td-p);min-height:var(--table-td-mh);gap:var(--table-td-g);color:var(--table-td-c);font:var(--table-td-f);white-space:var(--table-ws);border-color:var(--table-bc);border-style:solid;border-width:var(--table-td-bw);background:var(--table-td-bg)}sh-table td+td.sticky-end:last-child{padding:var(--table-td-p)}sh-table th.sticky,sh-table th.sticky-end,sh-table td.sticky,sh-table td.sticky-end{position:sticky;overflow:hidden;right:auto;left:0;z-index:1;padding:var(--table-td-p)}sh-table th.sticky:first-child,sh-table th.sticky-end:first-child,sh-table td.sticky:first-child,sh-table td.sticky-end:first-child{padding:var(--table-th-p)}sh-table th.sticky-end,sh-table td.sticky-end{right:0;left:auto}sh-table th.sticky,sh-table th.sticky-end{background:var(--base-1);padding:var(--table-th-p);z-index:101}sh-table th.sticky:first-child,sh-table th.sticky-end:first-child{padding:var(--table-th-p)}sh-table [shStickyColumns]{display:grid;grid-template-columns:subgrid;position:sticky;left:0;z-index:1000;border:0;border-color:var(--table-bc);border-style:solid}sh-table [shStickyColumns] th{background-color:var(--base-1)}sh-table [shStickyColumns=end]{left:auto;right:0}sh-table .span-all{grid-column:1/-1;white-space:initial;align-items:flex-start;padding:0;border-left-width:0;position:sticky;left:0;width:100cqw;box-sizing:border-box}sh-table .no-rows{display:none;grid-column:1/-1}sh-table tbody:empty+.no-rows{display:block}\n"] }]
930
+ }], propDecorators: { grid: [{ type: i0.Input, args: [{ isSignal: true, alias: "grid", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], data: [{ type: i0.Input, args: [{ isSignal: true, alias: "data", required: false }] }], dataChange: [{ type: i0.Output, args: ["dataChange"] }], sortByColumn: [{ type: i0.Input, args: [{ isSignal: true, alias: "sortByColumn", required: false }] }, { type: i0.Output, args: ["sortByColumnChange"] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-label", required: false }] }], ariaLabelledby: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-labelledby", required: false }] }], content: [{ type: i0.ContentChild, args: [i0.forwardRef(() => ShipTableContent), { isSignal: true }] }], theadLocal: [{ type: i0.ViewChild, args: ['theadLocal', { isSignal: true }] }], tbodyLocal: [{ type: i0.ViewChild, args: ['tbodyLocal', { isSignal: true }] }], onResize: [{
520
931
  type: HostListener,
521
932
  args: ['window:resize', ['$event']]
933
+ }], onFocusIn: [{
934
+ type: HostListener,
935
+ args: ['focusin', ['$event']]
936
+ }], onGridKeyDown: [{
937
+ type: HostListener,
938
+ args: ['keydown', ['$event']]
522
939
  }] } });
523
940
  class ShipTableContent {
524
941
  constructor() {
@@ -528,6 +945,7 @@ class ShipTableContent {
528
945
  this.data = input([], /* @ts-ignore */
529
946
  ...(ngDevMode ? [{ debugName: "data" }] : /* istanbul ignore next */ []));
530
947
  this.sortByColumn = this.#table.sortByColumn;
948
+ this.grid = this.#table.grid;
531
949
  this.thead = viewChild('thead', /* @ts-ignore */
532
950
  ...(ngDevMode ? [{ debugName: "thead" }] : /* istanbul ignore next */ []));
533
951
  this.tbody = viewChild('tbody', /* @ts-ignore */
@@ -538,6 +956,9 @@ class ShipTableContent {
538
956
  if (!row)
539
957
  return '';
540
958
  const key = col.accessorKey || col.id;
959
+ if (typeof key === 'string' && key.includes('.')) {
960
+ return key.split('.').reduce((acc, part) => acc?.[part], row);
961
+ }
541
962
  return row[key];
542
963
  }
543
964
  formatDate(value) {
@@ -553,50 +974,29 @@ class ShipTableContent {
553
974
  <thead #thead role="rowgroup">
554
975
  <tr role="row">
555
976
  @for (col of columns(); track col.id) {
556
- @if (col.resizable) {
557
- <th
558
- role="columnheader"
559
- [id]="col.id"
560
- [attr.aria-label]="col.header"
561
- [shSort]="col.sortable ? col.id : undefined"
562
- shResize
563
- [minWidth]="col.minWidth ?? 50"
564
- [maxWidth]="col.maxWidth ?? null"
565
- [attr.size]="col.size || null"
566
- [class.sticky]="col.sticky === 'start'"
567
- [class.sticky-end]="col.sticky === 'end'">
568
- {{ col.header }}
569
- @if (col.sortable) {
570
- @if (sortByColumn() === col.id) {
571
- <sh-icon>caret-up</sh-icon>
572
- } @else if (sortByColumn() === '-' + col.id) {
573
- <sh-icon>caret-down</sh-icon>
574
- } @else {
575
- <sh-icon>arrows-down-up</sh-icon>
576
- }
577
- }
578
- </th>
579
- } @else {
580
- <th
581
- role="columnheader"
582
- [id]="col.id"
583
- [attr.aria-label]="col.header"
584
- [shSort]="col.sortable ? col.id : undefined"
585
- [attr.size]="col.size || null"
586
- [class.sticky]="col.sticky === 'start'"
587
- [class.sticky-end]="col.sticky === 'end'">
588
- {{ col.header }}
589
- @if (col.sortable) {
590
- @if (sortByColumn() === col.id) {
591
- <sh-icon>caret-up</sh-icon>
592
- } @else if (sortByColumn() === '-' + col.id) {
593
- <sh-icon>caret-down</sh-icon>
594
- } @else {
595
- <sh-icon>arrows-down-up</sh-icon>
596
- }
977
+ <th
978
+ role="columnheader"
979
+ [id]="col.id"
980
+ [attr.aria-label]="col.header"
981
+ [shSort]="col.sortable ? col.id : undefined"
982
+ shResize
983
+ [resizable]="!!col.resizable"
984
+ [minWidth]="col.minWidth ?? 50"
985
+ [maxWidth]="col.maxWidth ?? null"
986
+ [attr.size]="col.size || null"
987
+ [class.sticky]="col.sticky === 'start'"
988
+ [class.sticky-end]="col.sticky === 'end'">
989
+ {{ col.header }}
990
+ @if (col.sortable) {
991
+ @if (sortByColumn() === col.id) {
992
+ <sh-icon>caret-up</sh-icon>
993
+ } @else if (sortByColumn() === '-' + col.id) {
994
+ <sh-icon>caret-down</sh-icon>
995
+ } @else {
996
+ <sh-icon>arrows-down-up</sh-icon>
597
997
  }
598
- </th>
599
- }
998
+ }
999
+ </th>
600
1000
  }
601
1001
  </tr>
602
1002
  </thead>
@@ -611,7 +1011,7 @@ class ShipTableContent {
611
1011
  [class.sticky-end]="col.sticky === 'end'"
612
1012
  [id]="col.id + '-' + rowIndex"
613
1013
  [attr.aria-labelledby]="col.id + ' ' + col.id + '-' + rowIndex"
614
- [attr.role]="col.rowHeader ? 'rowheader' : 'cell'">
1014
+ [attr.role]="col.rowHeader ? 'rowheader' : grid() ? 'gridcell' : 'cell'">
615
1015
  @if (col.cellTemplate) {
616
1016
  <ng-container
617
1017
  [ngTemplateOutlet]="col.cellTemplate"
@@ -660,50 +1060,29 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImpor
660
1060
  <thead #thead role="rowgroup">
661
1061
  <tr role="row">
662
1062
  @for (col of columns(); track col.id) {
663
- @if (col.resizable) {
664
- <th
665
- role="columnheader"
666
- [id]="col.id"
667
- [attr.aria-label]="col.header"
668
- [shSort]="col.sortable ? col.id : undefined"
669
- shResize
670
- [minWidth]="col.minWidth ?? 50"
671
- [maxWidth]="col.maxWidth ?? null"
672
- [attr.size]="col.size || null"
673
- [class.sticky]="col.sticky === 'start'"
674
- [class.sticky-end]="col.sticky === 'end'">
675
- {{ col.header }}
676
- @if (col.sortable) {
677
- @if (sortByColumn() === col.id) {
678
- <sh-icon>caret-up</sh-icon>
679
- } @else if (sortByColumn() === '-' + col.id) {
680
- <sh-icon>caret-down</sh-icon>
681
- } @else {
682
- <sh-icon>arrows-down-up</sh-icon>
683
- }
684
- }
685
- </th>
686
- } @else {
687
- <th
688
- role="columnheader"
689
- [id]="col.id"
690
- [attr.aria-label]="col.header"
691
- [shSort]="col.sortable ? col.id : undefined"
692
- [attr.size]="col.size || null"
693
- [class.sticky]="col.sticky === 'start'"
694
- [class.sticky-end]="col.sticky === 'end'">
695
- {{ col.header }}
696
- @if (col.sortable) {
697
- @if (sortByColumn() === col.id) {
698
- <sh-icon>caret-up</sh-icon>
699
- } @else if (sortByColumn() === '-' + col.id) {
700
- <sh-icon>caret-down</sh-icon>
701
- } @else {
702
- <sh-icon>arrows-down-up</sh-icon>
703
- }
1063
+ <th
1064
+ role="columnheader"
1065
+ [id]="col.id"
1066
+ [attr.aria-label]="col.header"
1067
+ [shSort]="col.sortable ? col.id : undefined"
1068
+ shResize
1069
+ [resizable]="!!col.resizable"
1070
+ [minWidth]="col.minWidth ?? 50"
1071
+ [maxWidth]="col.maxWidth ?? null"
1072
+ [attr.size]="col.size || null"
1073
+ [class.sticky]="col.sticky === 'start'"
1074
+ [class.sticky-end]="col.sticky === 'end'">
1075
+ {{ col.header }}
1076
+ @if (col.sortable) {
1077
+ @if (sortByColumn() === col.id) {
1078
+ <sh-icon>caret-up</sh-icon>
1079
+ } @else if (sortByColumn() === '-' + col.id) {
1080
+ <sh-icon>caret-down</sh-icon>
1081
+ } @else {
1082
+ <sh-icon>arrows-down-up</sh-icon>
704
1083
  }
705
- </th>
706
- }
1084
+ }
1085
+ </th>
707
1086
  }
708
1087
  </tr>
709
1088
  </thead>
@@ -718,7 +1097,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.0", ngImpor
718
1097
  [class.sticky-end]="col.sticky === 'end'"
719
1098
  [id]="col.id + '-' + rowIndex"
720
1099
  [attr.aria-labelledby]="col.id + ' ' + col.id + '-' + rowIndex"
721
- [attr.role]="col.rowHeader ? 'rowheader' : 'cell'">
1100
+ [attr.role]="col.rowHeader ? 'rowheader' : grid() ? 'gridcell' : 'cell'">
722
1101
  @if (col.cellTemplate) {
723
1102
  <ng-container
724
1103
  [ngTemplateOutlet]="col.cellTemplate"