@galaxy-io/dls 2.9.0 → 2.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/dist/beacons/Beacon.d.ts +1 -1
  2. package/dist/beacons/Beacon.js +12 -28
  3. package/dist/brand/GalaxyAlchemyWordmark.d.ts +4 -1
  4. package/dist/brand/GalaxyAlchemyWordmark.js +7 -1
  5. package/dist/brand/GalaxyFilamentWordmark.d.ts +5 -2
  6. package/dist/brand/GalaxyFilamentWordmark.js +9 -2
  7. package/dist/brand/GalaxyLogomark.js +3 -0
  8. package/dist/brand/PoweredBy.d.ts +27 -0
  9. package/dist/brand/PoweredBy.js +96 -0
  10. package/dist/brand/internal/svg/GalaxyFilamentWordmarkSvg.d.ts +1 -1
  11. package/dist/brand/internal/svg/GalaxyFilamentWordmarkSvg.js +2 -2
  12. package/dist/charts/Heatmap.js +25 -9
  13. package/dist/charts/Sparkline.d.ts +1 -1
  14. package/dist/charts/Sparkline.js +10 -26
  15. package/dist/charts/chartFormat.d.ts +1 -1
  16. package/dist/charts/chartFormat.js +2 -2
  17. package/dist/charts/heatmapGeometry.d.ts +14 -0
  18. package/dist/charts/heatmapGeometry.js +17 -1
  19. package/dist/chips/Chip.d.ts +2 -2
  20. package/dist/chips/Chip.js +15 -31
  21. package/dist/drawer/Drawer.d.ts +2 -2
  22. package/dist/drawer/Drawer.js +1 -1
  23. package/dist/editor/CodeEditor.d.ts +1 -1
  24. package/dist/editor/CodeEditor.js +2 -1
  25. package/dist/feedback/Alert.d.ts +36 -9
  26. package/dist/feedback/Alert.js +26 -8
  27. package/dist/feedback/ProgressBar.d.ts +4 -1
  28. package/dist/feedback/ProgressBar.js +17 -30
  29. package/dist/feedback/ProgressCircle.d.ts +1 -1
  30. package/dist/feedback/ProgressCircle.js +14 -30
  31. package/dist/hooks/useEndReached.d.ts +40 -0
  32. package/dist/hooks/useEndReached.js +69 -0
  33. package/dist/icons/Icon.d.ts +36 -8
  34. package/dist/icons/Icon.js +14 -7
  35. package/dist/inputs/CronInput.js +114 -78
  36. package/dist/inputs/DateInput.d.ts +1 -1
  37. package/dist/inputs/DateInput.js +10 -10
  38. package/dist/inputs/MultiSelectInput.d.ts +3 -1
  39. package/dist/inputs/MultiSelectInput.js +8 -3
  40. package/dist/inputs/SelectInput.d.ts +8 -1
  41. package/dist/inputs/SelectInput.js +52 -25
  42. package/dist/inputs/internal/selectAll.d.ts +11 -0
  43. package/dist/inputs/internal/selectAll.js +28 -0
  44. package/dist/json/JsonViewer.js +7 -6
  45. package/dist/layout/AppFrame.d.ts +20 -0
  46. package/dist/layout/AppFrame.js +71 -0
  47. package/dist/layout/EmptyLayout.d.ts +53 -0
  48. package/dist/layout/EmptyLayout.js +59 -0
  49. package/dist/layout/ErrorLayout.d.ts +42 -0
  50. package/dist/layout/ErrorLayout.js +60 -0
  51. package/dist/layout/PageLayout.d.ts +26 -0
  52. package/dist/layout/PageLayout.js +116 -0
  53. package/dist/layout/PendingLayout.d.ts +30 -0
  54. package/dist/layout/PendingLayout.js +57 -0
  55. package/dist/layout/internal/errorState.d.ts +14 -0
  56. package/dist/layout/internal/errorState.js +49 -0
  57. package/dist/layout/internal/region.d.ts +10 -0
  58. package/dist/layout/internal/region.js +24 -0
  59. package/dist/lists/DescriptionList.js +1 -0
  60. package/dist/menu/Menu.d.ts +2 -2
  61. package/dist/menu/Menu.js +6 -13
  62. package/dist/modal/Modal.d.ts +2 -2
  63. package/dist/modal/Modal.js +1 -1
  64. package/dist/navigation/CommandPalette.js +4 -11
  65. package/dist/navigation/SidebarNav.d.ts +5 -0
  66. package/dist/navigation/SidebarNav.js +41 -22
  67. package/dist/navigation/Tabs.d.ts +4 -2
  68. package/dist/navigation/Tabs.js +52 -32
  69. package/dist/navigation/Topbar.js +4 -0
  70. package/dist/shapes/Circle.d.ts +1 -1
  71. package/dist/shapes/Circle.js +10 -26
  72. package/dist/shapes/Square.d.ts +1 -1
  73. package/dist/shapes/Square.js +10 -26
  74. package/dist/styles/internal/roleColor.d.ts +3 -0
  75. package/dist/styles/internal/roleColor.js +42 -0
  76. package/dist/styles/mixins.js +1 -1
  77. package/dist/styles.css +1 -1
  78. package/dist/table/InfiniteSpreadsheet.js +6 -6
  79. package/dist/table/InfiniteTable.d.ts +52 -20
  80. package/dist/table/InfiniteTable.js +3 -2
  81. package/dist/table/TableCore.d.ts +7 -1
  82. package/dist/table/TableCore.js +93 -83
  83. package/dist/table/VirtualizedInfiniteTable.d.ts +53 -21
  84. package/dist/table/VirtualizedInfiniteTable.js +7 -5
  85. package/dist/table/useInfiniteScrollSentinel.d.ts +13 -13
  86. package/dist/table/useInfiniteScrollSentinel.js +7 -51
  87. package/dist/theme/tokens/dark.js +1 -1
  88. package/dist/theme/tokens/light.js +4 -3
  89. package/dist/theme/tokens/types.d.ts +7 -7
  90. package/dist/timeline/Timeline.d.ts +1 -1
  91. package/dist/timeline/Timeline.js +6 -24
  92. package/dist/tokens.css +1 -1
  93. package/dist/utils/format.d.ts +35 -10
  94. package/dist/utils/format.js +60 -12
  95. package/dist/utils/search.d.ts +15 -0
  96. package/dist/utils/search.js +24 -0
  97. package/dist/vite/index.d.ts +16 -2
  98. package/dist/vite/index.js +28 -19
  99. package/dist/vite/internal/themeBoot.d.ts +25 -0
  100. package/dist/vite/internal/themeBoot.js +44 -0
  101. package/dist/vite/internal/wywOptions.d.ts +46 -0
  102. package/dist/vite/internal/wywOptions.js +44 -0
  103. package/package.json +34 -1
@@ -8,13 +8,14 @@ import { t } from "../theme/tokens/t.js";
8
8
  import Icon, { IconVariant } from "../icons/Icon.js";
9
9
  import Rotate from "../transform/Rotate.js";
10
10
  import Button, { ButtonSize, ButtonVariant } from "../buttons/Button.js";
11
- import EmptyState, { EmptyStateSize, EmptyStateVariant } from "../feedback/EmptyState.js";
11
+ import EmptyState, { EmptyStateSize } from "../feedback/EmptyState.js";
12
12
  import { useElementClientSize } from "../hooks/useElementClientSize.js";
13
- import { formatNumber } from "../utils/format.js";
13
+ import { formatDate, formatNumber } from "../utils/format.js";
14
14
  import ResizeHandle from "../layout/ResizeHandle.js";
15
+ import { useEndReached } from "../hooks/useEndReached.js";
15
16
  import CheckboxInput, { CheckboxInputSize } from "../inputs/CheckboxInput.js";
17
+ import { ErrorStateContent } from "../layout/internal/errorState.js";
16
18
  import Menu, { MenuCheckboxItem, MenuGroup, MenuItem, MenuSeparator, MenuSize } from "../menu/Menu.js";
17
- import { useInfiniteScrollSentinel } from "./useInfiniteScrollSentinel.js";
18
19
  /* empty css */
19
20
  import { styled } from "@linaria/react";
20
21
  import { memo, useCallback, useEffect, useRef, useState } from "react";
@@ -130,66 +131,72 @@ var Head = /*#__PURE__*/ styled("thead")({
130
131
  class: "gx-TableCore-Head-hij68rq",
131
132
  propsAsIs: false
132
133
  });
134
+ /**
135
+ * `hasHeader` false: the header row stays in the DOM, out of view and out of flow, so screen
136
+ * readers keep the column names. It holds plain labels only (no sort, resize or menu buttons), so
137
+ * nothing in it takes focus. Declared after `Head` so the hiding wins over its sticky position.
138
+ */
139
+ var HIDDEN_HEAD_CSS = "gx-TableCore-HIDDEN_HEAD_CSS-h1seyvh2";
133
140
  var Body = /*#__PURE__*/ styled("tbody")({
134
141
  name: "Body",
135
- class: "gx-TableCore-Body-b1seyvh2",
142
+ class: "gx-TableCore-Body-bf09csv",
136
143
  propsAsIs: false
137
144
  });
138
145
  /** Skeleton, empty, error and end-error rows; grows to fill a bounded scrollport. */
139
146
  var StatusBody = /*#__PURE__*/ styled("tbody")({
140
147
  name: "StatusBody",
141
- class: "gx-TableCore-StatusBody-sf09csv",
148
+ class: "gx-TableCore-StatusBody-s1loheb3",
142
149
  propsAsIs: false
143
150
  });
144
151
  var Foot = /*#__PURE__*/ styled("tfoot")({
145
152
  name: "Foot",
146
- class: "gx-TableCore-Foot-f1loheb3",
153
+ class: "gx-TableCore-Foot-f1650vjz",
147
154
  propsAsIs: false
148
155
  });
149
156
  var HeaderRow = /*#__PURE__*/ styled("tr")({
150
157
  name: "HeaderRow",
151
- class: "gx-TableCore-HeaderRow-h1650vjz",
158
+ class: "gx-TableCore-HeaderRow-h3prmx7",
152
159
  propsAsIs: false
153
160
  });
154
161
  var FooterRow = /*#__PURE__*/ styled("tr")({
155
162
  name: "FooterRow",
156
- class: "gx-TableCore-FooterRow-f3prmx7",
163
+ class: "gx-TableCore-FooterRow-f18zsjxh",
157
164
  propsAsIs: false
158
165
  });
159
166
  /** @internal A body row. States are classes (`ROW_*_CSS`). */
160
167
  var TableRow = /*#__PURE__*/ styled("tr")({
161
168
  name: "TableRow",
162
- class: "gx-TableCore-TableRow-t18zsjxh",
169
+ class: "gx-TableCore-TableRow-t1f7xxie",
163
170
  propsAsIs: false
164
171
  });
165
172
  /** @internal A body or footer cell. */
166
173
  var TableCell = /*#__PURE__*/ styled("td")({
167
174
  name: "TableCell",
168
- class: "gx-TableCore-TableCell-t1f7xxie",
175
+ class: "gx-TableCore-TableCell-t1n0v2ch",
169
176
  propsAsIs: false
170
177
  });
171
178
  /** A header cell: not clipped, so the resize handle can straddle the column edge. */
172
179
  var HeaderCell = /*#__PURE__*/ styled("th")({
173
180
  name: "HeaderCell",
174
- class: "gx-TableCore-HeaderCell-h1n0v2ch",
181
+ class: "gx-TableCore-HeaderCell-h1nswbdd",
175
182
  propsAsIs: false
176
183
  });
177
184
  /** The press target of a sortable or movable column: label and sort icon. */
178
185
  var HeaderButton = /*#__PURE__*/ styled("button")({
179
186
  name: "HeaderButton",
180
- class: "gx-TableCore-HeaderButton-h1nswbdd",
187
+ class: "gx-TableCore-HeaderButton-hc3y207",
181
188
  propsAsIs: false
182
189
  });
183
190
  /** The label of a column that cannot be pressed. */
184
191
  var HeaderLabel = /*#__PURE__*/ styled("span")({
185
192
  name: "HeaderLabel",
186
- class: "gx-TableCore-HeaderLabel-hc3y207",
193
+ class: "gx-TableCore-HeaderLabel-h1po1i5a",
187
194
  propsAsIs: false
188
195
  });
189
196
  /** Marks the gap a dragged column would land in. */
190
197
  var DropIndicator = /*#__PURE__*/ styled("span")({
191
198
  name: "DropIndicator",
192
- class: "gx-TableCore-DropIndicator-d1po1i5a",
199
+ class: "gx-TableCore-DropIndicator-dcxvgum",
193
200
  propsAsIs: false
194
201
  });
195
202
  /**
@@ -200,105 +207,105 @@ var DropIndicator = /*#__PURE__*/ styled("span")({
200
207
  */
201
208
  var Sentinel = /*#__PURE__*/ styled("div")({
202
209
  name: "Sentinel",
203
- class: "gx-TableCore-Sentinel-scxvgum",
210
+ class: "gx-TableCore-Sentinel-s7ul01a",
204
211
  propsAsIs: false
205
212
  });
206
213
  /** The visible width of an empty or error body, pinned while the table scrolls sideways. */
207
214
  var StatusViewport = /*#__PURE__*/ styled("div")({
208
215
  name: "StatusViewport",
209
- class: "gx-TableCore-StatusViewport-s7ul01a",
216
+ class: "gx-TableCore-StatusViewport-s1qemn2d",
210
217
  propsAsIs: false
211
218
  });
212
219
  /** The end error row's content: icon and message, sticky like the status viewport. */
213
220
  var EndErrorViewport = /*#__PURE__*/ styled("div")({
214
221
  name: "EndErrorViewport",
215
- class: "gx-TableCore-EndErrorViewport-e1qemn2d",
222
+ class: "gx-TableCore-EndErrorViewport-ejip7oh",
216
223
  propsAsIs: false
217
224
  });
218
225
  var StatusRowElement = /*#__PURE__*/ styled("tr")({
219
226
  name: "StatusRowElement",
220
- class: "gx-TableCore-StatusRowElement-sjip7oh",
227
+ class: "gx-TableCore-StatusRowElement-s1cfdxs6",
221
228
  propsAsIs: false
222
229
  });
223
230
  var StatusCell = /*#__PURE__*/ styled("td")({
224
231
  name: "StatusCell",
225
- class: "gx-TableCore-StatusCell-s1cfdxs6",
232
+ class: "gx-TableCore-StatusCell-slttqlf",
226
233
  propsAsIs: false
227
234
  });
228
235
  var EndErrorRow = /*#__PURE__*/ styled("tr")({
229
236
  name: "EndErrorRow",
230
- class: "gx-TableCore-EndErrorRow-elttqlf",
237
+ class: "gx-TableCore-EndErrorRow-e60f67l",
231
238
  propsAsIs: false
232
239
  });
233
240
  var ExpandedRowElement = /*#__PURE__*/ styled("tr")({
234
241
  name: "ExpandedRowElement",
235
- class: "gx-TableCore-ExpandedRowElement-e60f67l",
242
+ class: "gx-TableCore-ExpandedRowElement-e1xg4fvx",
236
243
  propsAsIs: false
237
244
  });
238
245
  var ExpandedCell = /*#__PURE__*/ styled("td")({
239
246
  name: "ExpandedCell",
240
- class: "gx-TableCore-ExpandedCell-e1xg4fvx",
247
+ class: "gx-TableCore-ExpandedCell-e13bd0ox",
241
248
  propsAsIs: false
242
249
  });
243
250
  /** Pinned to the visible width while the table scrolls sideways; the gutter lines up with the expand column. */
244
251
  var ExpandedViewport = /*#__PURE__*/ styled("div")({
245
252
  name: "ExpandedViewport",
246
- class: "gx-TableCore-ExpandedViewport-e13bd0ox",
253
+ class: "gx-TableCore-ExpandedViewport-enk7ldu",
247
254
  propsAsIs: false
248
255
  });
249
256
  var ExpandedGutter = /*#__PURE__*/ styled("div")({
250
257
  name: "ExpandedGutter",
251
- class: "gx-TableCore-ExpandedGutter-enk7ldu",
258
+ class: "gx-TableCore-ExpandedGutter-e1yoeixn",
252
259
  propsAsIs: false
253
260
  });
254
261
  var ExpandedBody = /*#__PURE__*/ styled("div")({
255
262
  name: "ExpandedBody",
256
- class: "gx-TableCore-ExpandedBody-e1yoeixn",
263
+ class: "gx-TableCore-ExpandedBody-e18ghmlo",
257
264
  propsAsIs: false
258
265
  });
259
266
  /**
260
267
  * The parent paints nothing: the table paints the surface found further up (`--gx-table-surface`,
261
268
  * set by `useTableSurface`) so its sticky parts stay opaque.
262
269
  */
263
- var SURFACE_ANCESTOR_CSS = "gx-TableCore-SURFACE_ANCESTOR_CSS-s18ghmlo";
270
+ var SURFACE_ANCESTOR_CSS = "gx-TableCore-SURFACE_ANCESTOR_CSS-s1g01kh5";
264
271
  /**
265
272
  * @internal Select, expand and row-actions columns: a square of the row height, content centered.
266
273
  * At an end of the row it also holds the table's inset (`--gx-table-cell-edge`, `TABLE_INSET_CSS`).
267
274
  */
268
- var SYNTHETIC_CELL_CSS = "gx-TableCore-SYNTHETIC_CELL_CSS-s1g01kh5";
275
+ var SYNTHETIC_CELL_CSS = "gx-TableCore-SYNTHETIC_CELL_CSS-s1qwxx34";
269
276
  /** @internal Alignment of a column's header and cells. */
270
277
  var COLUMN_ALIGN_TO_CSS_MAP = {
271
- left: "gx-TableCore-left-l1qwxx34",
272
- center: "gx-TableCore-center-c152j0h",
273
- right: "gx-TableCore-right-r1y0un5j"
278
+ left: "gx-TableCore-left-l152j0h",
279
+ center: "gx-TableCore-center-c1y0un5j",
280
+ right: "gx-TableCore-right-r1dzycrm"
274
281
  };
275
282
  /** @internal Sticky to an edge while the table scrolls sideways. */
276
283
  var PIN_TO_CSS_MAP = {
277
- [Side.LEFT]: "gx-TableCore-Side_LEFT-s1dzycrm",
278
- [Side.RIGHT]: "gx-TableCore-Side_RIGHT-s6wh2p6"
284
+ [Side.LEFT]: "gx-TableCore-Side_LEFT-s6wh2p6",
285
+ [Side.RIGHT]: "gx-TableCore-Side_RIGHT-s1imw0tm"
279
286
  };
280
287
  /** @internal The edge hairline of the last left-pinned / first right-pinned data column. */
281
288
  var PIN_TO_EDGE_CSS_MAP = {
282
- [Side.LEFT]: "gx-TableCore-Side_LEFT-s1imw0tm",
283
- [Side.RIGHT]: "gx-TableCore-Side_RIGHT-s1swk4bm"
289
+ [Side.LEFT]: "gx-TableCore-Side_LEFT-s1swk4bm",
290
+ [Side.RIGHT]: "gx-TableCore-Side_RIGHT-s14t0x1z"
284
291
  };
285
292
  /** Pinned header cells stack above pinned body cells and the sticky header. */
286
- var PINNED_HEADER_CSS = "gx-TableCore-PINNED_HEADER_CSS-p14t0x1z";
293
+ var PINNED_HEADER_CSS = "gx-TableCore-PINNED_HEADER_CSS-p1nurjwh";
287
294
  /** The row does something: pointer and a hover fill. */
288
- var ROW_INTERACTIVE_CSS = "gx-TableCore-ROW_INTERACTIVE_CSS-r1nurjwh";
295
+ var ROW_INTERACTIVE_CSS = "gx-TableCore-ROW_INTERACTIVE_CSS-r1g7lrfg";
289
296
  /** A selected row: `background.selected`. Declared after the interactive state so it holds on hover. */
290
- var ROW_SELECTED_CSS = "gx-TableCore-ROW_SELECTED_CSS-r1g7lrfg";
297
+ var ROW_SELECTED_CSS = "gx-TableCore-ROW_SELECTED_CSS-r10dstoh";
291
298
  /** The current row (`activeRowId`): a fill and the `text.primary` bar of active navigation. */
292
- var ROW_ACTIVE_CSS = "gx-TableCore-ROW_ACTIVE_CSS-r10dstoh";
299
+ var ROW_ACTIVE_CSS = "gx-TableCore-ROW_ACTIVE_CSS-rpsswqs";
293
300
  /** @internal The last row, or a row whose panel is open: no bottom hairline. */
294
- var ROW_NO_BORDER_CSS = "gx-TableCore-ROW_NO_BORDER_CSS-rpsswqs";
301
+ var ROW_NO_BORDER_CSS = "gx-TableCore-ROW_NO_BORDER_CSS-rwbqwrq";
295
302
  /**
296
303
  * The rows end above the bottom of the scroll box (a full-height table with a few rows): the last
297
304
  * row keeps its hairline, so the list reads as finished instead of floating in empty space. Set by
298
305
  * `useRowsEndAboveBottom`; it outranks `ROW_NO_BORDER_CSS` and the panel rule by specificity, and
299
306
  * sits inside each row's fixed height, so nothing moves when it toggles.
300
307
  */
301
- var ROWS_END_ABOVE_BOTTOM_CSS = "gx-TableCore-ROWS_END_ABOVE_BOTTOM_CSS-rwbqwrq";
308
+ var ROWS_END_ABOVE_BOTTOM_CSS = "gx-TableCore-ROWS_END_ABOVE_BOTTOM_CSS-r1jxalmm";
302
309
  /**
303
310
  * `inset`: the first and last cell of every header, body and footer row pad their outer side by
304
311
  * `--gx-table-inset` and are that much wider (data columns through `useTableColumnLayout`,
@@ -306,7 +313,7 @@ var ROWS_END_ABOVE_BOTTOM_CSS = "gx-TableCore-ROWS_END_ABOVE_BOTTOM_CSS-rwbqwrq"
306
313
  * and selected fills and the active bar still run edge to edge, and a pinned edge column keeps its
307
314
  * inset while the table scrolls sideways.
308
315
  */
309
- var TABLE_INSET_CSS = "gx-TableCore-TABLE_INSET_CSS-t1jxalmm";
316
+ var TABLE_INSET_CSS = "gx-TableCore-TABLE_INSET_CSS-t1fx3qlj";
310
317
  /**
311
318
  * Whether the table's rows end above the bottom of its scroll box. The last row drops its hairline
312
319
  * only when it lands on the box's bottom edge, where the container's frame (or a scrolled table's
@@ -346,27 +353,25 @@ function useRowsEndAboveBottom(scrollRef, tableRef, isEnabled, bodyKey) {
346
353
  return isAbove;
347
354
  }
348
355
  /** The last expanded panel: no bottom hairline. */
349
- var EXPANDED_LAST_CSS = "gx-TableCore-EXPANDED_LAST_CSS-e1fx3qlj";
356
+ var EXPANDED_LAST_CSS = "gx-TableCore-EXPANDED_LAST_CSS-e2nd1ne";
350
357
  /** The dragged header while reordering. 0.5 is a state, not a color token. */
351
- var HEADER_DRAGGING_CSS = "gx-TableCore-HEADER_DRAGGING_CSS-h2nd1ne";
358
+ var HEADER_DRAGGING_CSS = "gx-TableCore-HEADER_DRAGGING_CSS-harqcf0";
352
359
  /** The label wrapper grows when a trailing control (column actions) follows it. */
353
- var LABEL_GROW_CSS = "gx-TableCore-LABEL_GROW_CSS-larqcf0";
354
- var DROP_START_CSS = "gx-TableCore-DROP_START_CSS-d132cb1v";
355
- var DROP_END_CSS = "gx-TableCore-DROP_END_CSS-d1vn45v6";
360
+ var LABEL_GROW_CSS = "gx-TableCore-LABEL_GROW_CSS-l132cb1v";
361
+ var DROP_START_CSS = "gx-TableCore-DROP_START_CSS-d1vn45v6";
362
+ var DROP_END_CSS = "gx-TableCore-DROP_END_CSS-d14za3v2";
356
363
  /** Shows on hover, while dragged and on keyboard focus; straddles the column edge. */
357
- var COLUMN_RESIZE_HANDLE_CSS = "gx-TableCore-COLUMN_RESIZE_HANDLE_CSS-c14za3v2";
364
+ var COLUMN_RESIZE_HANDLE_CSS = "gx-TableCore-COLUMN_RESIZE_HANDLE_CSS-c1w0t3ir";
358
365
  /** Hovering a header cell reveals its resize handle. */
359
- var HEADER_HOVER_CSS = "gx-TableCore-HEADER_HOVER_CSS-h1w0t3ir";
366
+ var HEADER_HOVER_CSS = "gx-TableCore-HEADER_HOVER_CSS-hb9km4t";
360
367
  /** The expand caret button: a square of its rung. */
361
- var EXPAND_BUTTON_CSS = "gx-TableCore-EXPAND_BUTTON_CSS-eb9km4t";
368
+ var EXPAND_BUTTON_CSS = "gx-TableCore-EXPAND_BUTTON_CSS-e1emgwoo";
362
369
  /** @internal A virtual body: as tall as every row, which are positioned inside it. */
363
- var VIRTUAL_BODY_CSS = "gx-TableCore-VIRTUAL_BODY_CSS-v1emgwoo";
370
+ var VIRTUAL_BODY_CSS = "gx-TableCore-VIRTUAL_BODY_CSS-vw38cm1";
364
371
  /** @internal A virtual row, placed at `--gx-table-row-start`. */
365
- var VIRTUAL_ROW_CSS = "gx-TableCore-VIRTUAL_ROW_CSS-vw38cm1";
372
+ var VIRTUAL_ROW_CSS = "gx-TableCore-VIRTUAL_ROW_CSS-v1n5u17i";
366
373
  /** @internal Default cells and footer strings: shrink to truncate. */
367
- var CELL_TEXT_CSS = "gx-TableCore-CELL_TEXT_CSS-c1n5u17i";
368
- /** "Oct 3, 2026": the DateInput default. */
369
- var DATE_FORMAT_OPTIONS = { dateStyle: "medium" };
374
+ var CELL_TEXT_CSS = "gx-TableCore-CELL_TEXT_CSS-cngkatk";
370
375
  /** @internal The default cell renderer: one truncating line of formatted text. */
371
376
  function TableCellText({ value, textSize }) {
372
377
  if (value === null || value === void 0 || value === "") return /* @__PURE__ */ jsx(Text, {
@@ -377,10 +382,9 @@ function TableCellText({ value, textSize }) {
377
382
  });
378
383
  const isNumeric = typeof value === "number" || typeof value === "bigint";
379
384
  let text;
380
- if (typeof value === "number") text = formatNumber(value);
381
- else if (typeof value === "bigint") text = value.toLocaleString();
385
+ if (typeof value === "number" || typeof value === "bigint") text = formatNumber(value);
382
386
  else if (typeof value === "boolean") text = value ? "Yes" : "No";
383
- else if (value instanceof Date) text = new Intl.DateTimeFormat(void 0, DATE_FORMAT_OPTIONS).format(value);
387
+ else if (value instanceof Date) text = formatDate(value);
384
388
  else text = String(value);
385
389
  return /* @__PURE__ */ jsx(Text, {
386
390
  as: "span",
@@ -543,7 +547,7 @@ var TableBodyRow = memo(function TableBodyRow({ row, rowIndex, rowId, columns, m
543
547
  ...isExpanded === void 0 ? {} : { "aria-expanded": isExpanded },
544
548
  ...isActive ? { "aria-current": true } : {},
545
549
  ...ariaRowIndex === void 0 ? {} : { "aria-rowindex": ariaRowIndex },
546
- className: cx(isClickable && ROW_INTERACTIVE_CSS, isSelected === true && ROW_SELECTED_CSS, isActive && ROW_ACTIVE_CSS, isBorderless && "gx-TableCore-ROW_NO_BORDER_CSS-rpsswqs", className),
550
+ className: cx(isClickable && ROW_INTERACTIVE_CSS, isSelected === true && ROW_SELECTED_CSS, isActive && ROW_ACTIVE_CSS, isBorderless && "gx-TableCore-ROW_NO_BORDER_CSS-rwbqwrq", className),
547
551
  style,
548
552
  onClick: handleClick,
549
553
  onKeyDown: handleKeyDown,
@@ -552,7 +556,7 @@ var TableBodyRow = memo(function TableBodyRow({ row, rowIndex, rowId, columns, m
552
556
  isSelectable && /* @__PURE__ */ jsx(TableCell, {
553
557
  role: cellRole,
554
558
  ...nextColIndex(),
555
- className: cx("gx-TableCore-SYNTHETIC_CELL_CSS-s1g01kh5", PIN_TO_CSS_MAP[Side.LEFT]),
559
+ className: cx("gx-TableCore-SYNTHETIC_CELL_CSS-s1qwxx34", PIN_TO_CSS_MAP[Side.LEFT]),
556
560
  style: syntheticOffset(0, metrics),
557
561
  onClickCapture: (event) => {
558
562
  shiftRef.current = event.shiftKey;
@@ -572,7 +576,7 @@ var TableBodyRow = memo(function TableBodyRow({ row, rowIndex, rowId, columns, m
572
576
  hasExpandColumn && /* @__PURE__ */ jsx(TableCell, {
573
577
  role: cellRole,
574
578
  ...nextColIndex(),
575
- className: cx("gx-TableCore-SYNTHETIC_CELL_CSS-s1g01kh5", PIN_TO_CSS_MAP[Side.LEFT]),
579
+ className: cx("gx-TableCore-SYNTHETIC_CELL_CSS-s1qwxx34", PIN_TO_CSS_MAP[Side.LEFT]),
576
580
  style: syntheticOffset(isSelectable ? 1 : 0, metrics),
577
581
  onClick: (event) => event.stopPropagation(),
578
582
  children: isExpanded !== void 0 && /* @__PURE__ */ jsx(Button, {
@@ -618,7 +622,7 @@ var TableBodyRow = memo(function TableBodyRow({ row, rowIndex, rowId, columns, m
618
622
  hasTrailingColumn && /* @__PURE__ */ jsx(TableCell, {
619
623
  role: cellRole,
620
624
  ...nextColIndex(),
621
- className: cx("gx-TableCore-SYNTHETIC_CELL_CSS-s1g01kh5", PIN_TO_CSS_MAP[Side.RIGHT]),
625
+ className: cx("gx-TableCore-SYNTHETIC_CELL_CSS-s1qwxx34", PIN_TO_CSS_MAP[Side.RIGHT]),
622
626
  style: syntheticOffset(0, metrics),
623
627
  children: actions !== null && actions !== void 0 && /* @__PURE__ */ jsx(Menu, {
624
628
  isOpen: isActionsOpen,
@@ -656,7 +660,7 @@ function TableSkeletonRow({ columns, metrics, leadingCount, hasTrailingColumn, i
656
660
  onFocus: pending.onFocus
657
661
  },
658
662
  ...ariaRowIndex === void 0 ? {} : { "aria-rowindex": ariaRowIndex },
659
- className: cx(isBorderless && "gx-TableCore-ROW_NO_BORDER_CSS-rpsswqs", className),
663
+ className: cx(isBorderless && "gx-TableCore-ROW_NO_BORDER_CSS-rwbqwrq", className),
660
664
  style,
661
665
  children: [
662
666
  Array.from({ length: leadingCount }, (_, index) => /* @__PURE__ */ jsx(TableCell, {
@@ -675,7 +679,7 @@ function TableSkeletonRow({ columns, metrics, leadingCount, hasTrailingColumn, i
675
679
  }, column.id)),
676
680
  hasTrailingColumn && /* @__PURE__ */ jsx(TableCell, {
677
681
  role: "cell",
678
- className: cx("gx-TableCore-SYNTHETIC_CELL_CSS-s1g01kh5", PIN_TO_CSS_MAP[Side.RIGHT]),
682
+ className: cx("gx-TableCore-SYNTHETIC_CELL_CSS-s1qwxx34", PIN_TO_CSS_MAP[Side.RIGHT]),
679
683
  style: syntheticOffset(0, metrics)
680
684
  })
681
685
  ]
@@ -791,7 +795,7 @@ function useTableSurface(rootRef) {
791
795
  return surface;
792
796
  }
793
797
  /** Root → scroll container → table (header, body, status, footer) → sentinel → live region. */
794
- function TableFrame({ metrics, columnLayout, leadingHeaders, trailingHeader, hasTrailingColumn, sort, onSortPress, canCustomizeColumns, rowCount, isLoading, error, emptyState, onEndReached, role, ariaLabel, tableAria, isMultiselectable, ariaRowCount, rootRef, scrollRef, rootProps, className, style, bodyClassName, bodyStyle, announcement, trailingClassName, children }) {
798
+ function TableFrame({ metrics, hasHeader = true, columnLayout, leadingHeaders, trailingHeader, hasTrailingColumn, sort, onSortPress, canCustomizeColumns, rowCount, isLoading, error, emptyState, onEndReached, role, ariaLabel, tableAria, isMultiselectable, ariaRowCount, rootRef, scrollRef, rootProps, className, style, bodyClassName, bodyStyle, announcement, trailingClassName, children }) {
795
799
  const { visibleColumns } = columnLayout;
796
800
  const ownRootRef = useRef(null);
797
801
  const mergedRootRef = useMergeRefs([ownRootRef, rootRef]);
@@ -803,11 +807,11 @@ function TableFrame({ metrics, columnLayout, leadingHeaders, trailingHeader, has
803
807
  const tableRef = useRef(null);
804
808
  const hasFooterRow = columnLayout.visibleColumns.some(({ column }) => column.footer !== void 0 && column.footer !== null);
805
809
  const doRowsEndAboveBottom = useRowsEndAboveBottom(scrollRef, tableRef, !hasFooterRow && (rowCount > 0 || isLoading), `${rowCount}:${isLoading}:${error ?? ""}`);
806
- const sentinelRef = useInfiniteScrollSentinel({
810
+ const sentinelRef = useEndReached({
807
811
  scrollRef,
808
812
  onEndReached,
809
813
  isEnabled: !isLoading && error === void 0,
810
- rowCount,
814
+ itemCount: rowCount,
811
815
  marginPx: 500
812
816
  });
813
817
  const [message, setMessage] = useState("");
@@ -936,6 +940,7 @@ function TableFrame({ metrics, columnLayout, leadingHeaders, trailingHeader, has
936
940
  const variables = { ...columnLayout.variables };
937
941
  if (viewportWidth !== void 0) variables["--gx-table-viewport-width"] = `${viewportWidth}px`;
938
942
  if (hasFooter) variables["--gx-table-footer-height"] = "var(--gx-table-header-height)";
943
+ if (!hasHeader) variables["--gx-table-header-scroll-padding"] = "0px";
939
944
  if (surface !== null) variables["--gx-table-surface"] = surface;
940
945
  let status = null;
941
946
  if (rowCount === 0 && isLoading) status = Array.from({ length: 5 }, (_, index) => /* @__PURE__ */ jsx(TableSkeletonRow, {
@@ -950,15 +955,10 @@ function TableFrame({ metrics, columnLayout, leadingHeaders, trailingHeader, has
950
955
  children: /* @__PURE__ */ jsx(StatusCell, {
951
956
  role: "cell",
952
957
  colSpan: colCount,
953
- children: /* @__PURE__ */ jsx(StatusViewport, { children: error !== void 0 ? /* @__PURE__ */ jsx("div", {
954
- role: "alert",
955
- children: /* @__PURE__ */ jsx(EmptyState, {
956
- icon: WarningCircleIcon,
957
- header: "Couldn't load data",
958
- description: error,
959
- size: metrics.emptyStateSize,
960
- variant: EmptyStateVariant.ERROR
961
- })
958
+ children: /* @__PURE__ */ jsx(StatusViewport, { children: error !== void 0 ? /* @__PURE__ */ jsx(ErrorStateContent, {
959
+ size: metrics.emptyStateSize,
960
+ header: "Couldn't load data",
961
+ description: error
962
962
  }) : emptyState ?? /* @__PURE__ */ jsx(EmptyState, {
963
963
  header: "No results",
964
964
  size: metrics.emptyStateSize,
@@ -997,6 +997,14 @@ function TableFrame({ metrics, columnLayout, leadingHeaders, trailingHeader, has
997
997
  headerColIndex += 1;
998
998
  return hasColIndex ? headerColIndex : void 0;
999
999
  };
1000
+ const hiddenHeaderCells = hasHeader ? null : Array.from({ length: colCount }, (_, index) => {
1001
+ const column = visibleColumns[index - leadingCount]?.column;
1002
+ return /* @__PURE__ */ jsx(HeaderCell, {
1003
+ role: "columnheader",
1004
+ ...hasColIndex ? { "aria-colindex": index + 1 } : {},
1005
+ children: column?.header
1006
+ }, column?.id ?? `synthetic-${index}`);
1007
+ });
1000
1008
  return /* @__PURE__ */ jsxs(Root, {
1001
1009
  ...rootProps,
1002
1010
  ref: mergedRootRef,
@@ -1022,21 +1030,23 @@ function TableFrame({ metrics, columnLayout, leadingHeaders, trailingHeader, has
1022
1030
  children: [
1023
1031
  /* @__PURE__ */ jsx(Head, {
1024
1032
  role: "rowgroup",
1033
+ className: cx(!hasHeader && HIDDEN_HEAD_CSS),
1025
1034
  children: /* @__PURE__ */ jsxs(HeaderRow, {
1026
1035
  role: "row",
1027
1036
  ...hasColIndex ? { "aria-rowindex": 1 } : {},
1028
1037
  children: [
1029
- leadingHeaders.map((content, index) => {
1038
+ !hasHeader && hiddenHeaderCells,
1039
+ hasHeader && leadingHeaders.map((content, index) => {
1030
1040
  const colIndex = nextHeaderColIndex();
1031
1041
  return /* @__PURE__ */ jsx(HeaderCell, {
1032
1042
  role: "columnheader",
1033
1043
  ...colIndex === void 0 ? {} : { "aria-colindex": colIndex },
1034
- className: cx(SYNTHETIC_CELL_CSS, PIN_TO_CSS_MAP[Side.LEFT], PINNED_HEADER_CSS),
1044
+ className: cx("gx-TableCore-SYNTHETIC_CELL_CSS-s1qwxx34", PIN_TO_CSS_MAP[Side.LEFT], PINNED_HEADER_CSS),
1035
1045
  style: syntheticOffset(index, metrics),
1036
1046
  children: content
1037
1047
  }, `leading-${index}`);
1038
1048
  }),
1039
- visibleColumns.map((resolved) => {
1049
+ hasHeader && visibleColumns.map((resolved) => {
1040
1050
  const { column } = resolved;
1041
1051
  const isSorted = sort?.columnId === column.id;
1042
1052
  return /* @__PURE__ */ jsx(TableHeaderCell, {
@@ -1060,12 +1070,12 @@ function TableFrame({ metrics, columnLayout, leadingHeaders, trailingHeader, has
1060
1070
  registerButton
1061
1071
  }, column.id);
1062
1072
  }),
1063
- hasTrailingColumn && (() => {
1073
+ hasHeader && hasTrailingColumn && (() => {
1064
1074
  const colIndex = nextHeaderColIndex();
1065
1075
  return /* @__PURE__ */ jsx(HeaderCell, {
1066
1076
  role: "columnheader",
1067
1077
  ...colIndex === void 0 ? {} : { "aria-colindex": colIndex },
1068
- className: cx("gx-TableCore-SYNTHETIC_CELL_CSS-s1g01kh5", PIN_TO_CSS_MAP[Side.RIGHT], PINNED_HEADER_CSS, trailingClassName),
1078
+ className: cx("gx-TableCore-SYNTHETIC_CELL_CSS-s1qwxx34", PIN_TO_CSS_MAP[Side.RIGHT], PINNED_HEADER_CSS, trailingClassName),
1069
1079
  style: syntheticOffset(0, metrics),
1070
1080
  children: trailingHeader
1071
1081
  });
@@ -1092,7 +1102,7 @@ function TableFrame({ metrics, columnLayout, leadingHeaders, trailingHeader, has
1092
1102
  Array.from({ length: leadingCount }, (_, index) => /* @__PURE__ */ jsx(TableCell, {
1093
1103
  role: "cell",
1094
1104
  ...hasColIndex ? { "aria-colindex": index + 1 } : {},
1095
- className: cx("gx-TableCore-SYNTHETIC_CELL_CSS-s1g01kh5", PIN_TO_CSS_MAP[Side.LEFT]),
1105
+ className: cx("gx-TableCore-SYNTHETIC_CELL_CSS-s1qwxx34", PIN_TO_CSS_MAP[Side.LEFT]),
1096
1106
  style: syntheticOffset(index, metrics)
1097
1107
  }, `leading-${index}`)),
1098
1108
  visibleColumns.map(({ column, pin, isPinEdge, cellStyle, position }) => /* @__PURE__ */ jsx(TableCell, {
@@ -1105,14 +1115,14 @@ function TableFrame({ metrics, columnLayout, leadingHeaders, trailingHeader, has
1105
1115
  size: metrics.textSize,
1106
1116
  weight: TextWeight.MEDIUM,
1107
1117
  lineClamp: 1,
1108
- className: "gx-TableCore-CELL_TEXT_CSS-c1n5u17i",
1118
+ className: "gx-TableCore-CELL_TEXT_CSS-cngkatk",
1109
1119
  children: column.footer
1110
1120
  }) : column.footer
1111
1121
  }, column.id)),
1112
1122
  hasTrailingColumn && /* @__PURE__ */ jsx(TableCell, {
1113
1123
  role: "cell",
1114
1124
  ...hasColIndex ? { "aria-colindex": colCount } : {},
1115
- className: cx("gx-TableCore-SYNTHETIC_CELL_CSS-s1g01kh5", PIN_TO_CSS_MAP[Side.RIGHT], trailingClassName),
1125
+ className: cx("gx-TableCore-SYNTHETIC_CELL_CSS-s1qwxx34", PIN_TO_CSS_MAP[Side.RIGHT], trailingClassName),
1116
1126
  style: syntheticOffset(0, metrics)
1117
1127
  })
1118
1128
  ]
@@ -7,7 +7,7 @@
7
7
  * no client-side sorting (the app re-queries when `sort` changes).
8
8
  *
9
9
  * Built on the shared table core (`TableCore`, `useTableColumnLayout`,
10
- * `useTableKeyboardNavigation`, `useInfiniteScrollSentinel`) plus `useTableVirtualizer`
10
+ * `useTableKeyboardNavigation`, `useEndReached`) plus `useTableVirtualizer`
11
11
  * (`@tanstack/react-virtual`, an optional peer). It imports nothing from `InfiniteTable`, so it
12
12
  * never needs `@tanstack/react-table`.
13
13
  */
@@ -23,7 +23,8 @@ export declare enum VirtualizedInfiniteTableSize {
23
23
  /** 52px rows, body_lg text. */
24
24
  LARGE = "LARGE"
25
25
  }
26
- export interface VirtualizedInfiniteTableProps<TData> extends AriaAttributes {
26
+ /** Every VirtualizedInfiniteTable prop except the header and what lives in it (`hasHeader`, sorting, resize, customize). */
27
+ interface VirtualizedInfiniteTableBaseProps<TData> extends AriaAttributes {
27
28
  /** The columns in their default order. Same column type as InfiniteTable (`@galaxy-io/dls/table/types`). */
28
29
  columns: TableColumn<TData>[];
29
30
  /** Number of rows the table can show, loaded or not. Grow it as pages arrive. */
@@ -60,15 +61,6 @@ export interface VirtualizedInfiniteTableProps<TData> extends AriaAttributes {
60
61
  activeRowId?: string | null;
61
62
  /** Menu rows (`MenuItem`, `MenuSeparator`, …) for a loaded row's actions menu, opened from a trailing "…" button. Return `null` for a row with no actions. */
62
63
  rowActions?: (row: TData, rowIndex: number) => ReactNode;
63
- /** Controlled sorted column, shown in the header. The table never reorders rows itself: the app re-queries with the new sort. */
64
- sort?: TableSort | null;
65
- /**
66
- * Initial sort while uncontrolled.
67
- * @default null
68
- */
69
- defaultSort?: TableSort | null;
70
- /** Called with the next sort when a sortable header is pressed. Reset the data (and scroll) when it changes. */
71
- onSortChange?: (sort: TableSort | null) => void;
72
64
  /** Controlled column arrangement: order, hidden column ids and widths. Persist it to keep a user's layout. */
73
65
  columnLayout?: TableColumnLayout;
74
66
  /**
@@ -78,16 +70,6 @@ export interface VirtualizedInfiniteTableProps<TData> extends AriaAttributes {
78
70
  defaultColumnLayout?: TableColumnLayout;
79
71
  /** Called with the full new arrangement when the user resizes, moves, hides, shows or resets columns. Fires on every resize step; debounce before saving. */
80
72
  onColumnLayoutChange?: (columnLayout: TableColumnLayout) => void;
81
- /**
82
- * Adds a drag handle at the end of each header cell (arrow keys too). Columns opt out with `canResize: false`.
83
- * @default false
84
- */
85
- canResizeColumns?: boolean;
86
- /**
87
- * Lets the user reorder columns (drag a header, or Alt+ArrowLeft / Alt+ArrowRight on it) and show or hide them from a Columns menu at the end of the header. Columns opt out of hiding with `canHide: false`.
88
- * @default false
89
- */
90
- canCustomizeColumns?: boolean;
91
73
  /**
92
74
  * Space between the ends of each row and its first and last cell, on top of the cells' own padding; rows, hairlines and row fills still run the full width.
93
75
  * For a table flush with a panel's edges whose content should sit on the page's padding line (a `SMALL` table takes `4`: 12px cell padding plus 4 is the island's 16), instead of a padded wrapper, which would cut the hairlines short.
@@ -105,6 +87,56 @@ export interface VirtualizedInfiniteTableProps<TData> extends AriaAttributes {
105
87
  /** Inline style on the root `<div>`; only for setting CSS custom properties. */
106
88
  style?: CSSProperties;
107
89
  }
90
+ /** A table with its header row (the default): sorting, resizing and customizing live in it. */
91
+ interface VirtualizedInfiniteTableWithHeaderProps {
92
+ /**
93
+ * Shows the header row. Without it the row stays in the DOM, visually hidden, so screen readers keep the column names; sorting, resizing and customizing go with it (a type error to pass them). For a compact list whose columns explain themselves.
94
+ * @default true
95
+ */
96
+ hasHeader?: true;
97
+ /** Controlled sorted column, shown in the header. The table never reorders rows itself: the app re-queries with the new sort. */
98
+ sort?: TableSort | null;
99
+ /**
100
+ * Initial sort while uncontrolled.
101
+ * @default null
102
+ */
103
+ defaultSort?: TableSort | null;
104
+ /** Called with the next sort when a sortable header is pressed. Reset the data (and scroll) when it changes. */
105
+ onSortChange?: (sort: TableSort | null) => void;
106
+ /**
107
+ * Adds a drag handle at the end of each header cell (arrow keys too). Columns opt out with `canResize: false`.
108
+ * @default false
109
+ */
110
+ canResizeColumns?: boolean;
111
+ /**
112
+ * Lets the user reorder columns (drag a header, or Alt+ArrowLeft / Alt+ArrowRight on it) and show or hide them from a Columns menu at the end of the header. Columns opt out of hiding with `canHide: false`.
113
+ * @default false
114
+ */
115
+ canCustomizeColumns?: boolean;
116
+ }
117
+ /** A table without a visible header row: nothing that lives in the header can be passed. */
118
+ interface VirtualizedInfiniteTableHeaderlessProps {
119
+ /**
120
+ * Shows the header row. Without it the row stays in the DOM, visually hidden, so screen readers keep the column names; sorting, resizing and customizing go with it (a type error to pass them). For a compact list whose columns explain themselves.
121
+ * @default true
122
+ */
123
+ hasHeader: false;
124
+ /** Controlled sorted column. Not without a header. */
125
+ sort?: undefined;
126
+ /** Initial sort while uncontrolled. Not without a header. */
127
+ defaultSort?: undefined;
128
+ /** Called with the next sort. Not without a header. */
129
+ onSortChange?: undefined;
130
+ /** Resize handles live in the header. Not without one. */
131
+ canResizeColumns?: false;
132
+ /** Reordering and the Columns menu live in the header. Not without one. */
133
+ canCustomizeColumns?: false;
134
+ }
135
+ /**
136
+ * VirtualizedInfiniteTable props. `hasHeader: false` with `sort`, `defaultSort`, `onSortChange`,
137
+ * `canResizeColumns` or `canCustomizeColumns` is a type error (the Widget `isCollapsible` precedent).
138
+ */
139
+ export type VirtualizedInfiniteTableProps<TData> = VirtualizedInfiniteTableBaseProps<TData> & (VirtualizedInfiniteTableWithHeaderProps | VirtualizedInfiniteTableHeaderlessProps);
108
140
  /**
109
141
  * The public, generic call signature (`TData` inferred from `getRowData` and `columns`). Never
110
142
  * called: it only types the default export. An arrow function rather than a type literal, so
@@ -16,7 +16,7 @@ import { jsx } from "react/jsx-runtime";
16
16
  * no client-side sorting (the app re-queries when `sort` changes).
17
17
  *
18
18
  * Built on the shared table core (`TableCore`, `useTableColumnLayout`,
19
- * `useTableKeyboardNavigation`, `useInfiniteScrollSentinel`) plus `useTableVirtualizer`
19
+ * `useTableKeyboardNavigation`, `useEndReached`) plus `useTableVirtualizer`
20
20
  * (`@tanstack/react-virtual`, an optional peer). It imports nothing from `InfiniteTable`, so it
21
21
  * never needs `@tanstack/react-table`.
22
22
  */
@@ -53,7 +53,7 @@ function sortAnnouncement(sort, columns) {
53
53
  }
54
54
  /** InfiniteTable with a virtual body, for tens of thousands of rows. */
55
55
  var VirtualizedInfiniteTableInner = forwardRef(function VirtualizedInfiniteTable(props, ref) {
56
- const { columns, totalRowCount, getRowData, getRowId, size: sizeProp, isLoading: isLoadingProp, error: errorProp, emptyState, onEndReached, onRowClick, activeRowId, rowActions, sort, defaultSort, onSortChange, columnLayout, defaultColumnLayout, onColumnLayoutChange, canResizeColumns: canResizeColumnsProp, canCustomizeColumns: canCustomizeColumnsProp, inset: insetProp, ariaLabel, id, className, style, ...rest } = props;
56
+ const { columns, totalRowCount, getRowData, getRowId, size: sizeProp, isLoading: isLoadingProp, error: errorProp, emptyState, onEndReached, onRowClick, activeRowId, rowActions, sort, defaultSort, onSortChange, columnLayout, defaultColumnLayout, onColumnLayoutChange, canResizeColumns: canResizeColumnsProp, canCustomizeColumns: canCustomizeColumnsProp, hasHeader = true, inset: insetProp, ariaLabel, id, className, style, ...rest } = props;
57
57
  const error = errorProp === "" ? void 0 : errorProp;
58
58
  const size = sizeProp ?? "MEDIUM";
59
59
  const isLoading = isLoadingProp ?? false;
@@ -134,13 +134,14 @@ var VirtualizedInfiniteTableInner = forwardRef(function VirtualizedInfiniteTable
134
134
  }
135
135
  }, []);
136
136
  const virtualizerRef = useRef(null);
137
+ const headerHeightPx = hasHeader ? metrics.headerHeightPx : 0;
137
138
  const navigation = useTableKeyboardNavigation({
138
139
  rowCount,
139
140
  getPageSize: useCallback(() => {
140
141
  const scroll = scrollRef.current;
141
142
  if (scroll === null) return 1;
142
- return Math.max(1, Math.floor((scroll.clientHeight - metrics.headerHeightPx) / metrics.rowHeightPx) - 1);
143
- }, [metrics.rowHeightPx, metrics.headerHeightPx]),
143
+ return Math.max(1, Math.floor((scroll.clientHeight - headerHeightPx) / metrics.rowHeightPx) - 1);
144
+ }, [metrics.rowHeightPx, headerHeightPx]),
144
145
  scrollToIndex: (index) => virtualizerRef.current?.scrollToIndex(index),
145
146
  onKeyDown: handleKey
146
147
  });
@@ -152,7 +153,7 @@ var VirtualizedInfiniteTableInner = forwardRef(function VirtualizedInfiniteTable
152
153
  count: rowCount,
153
154
  scrollRef,
154
155
  rowHeightPx: metrics.rowHeightPx,
155
- headerHeightPx: metrics.headerHeightPx,
156
+ headerHeightPx,
156
157
  footerHeightPx: hasFooter ? metrics.headerHeightPx : 0,
157
158
  getItemKey,
158
159
  keepIndexes: rowCount > 0 ? [navigation.tabStopIndex] : []
@@ -210,6 +211,7 @@ var VirtualizedInfiniteTableInner = forwardRef(function VirtualizedInfiniteTable
210
211
  const scrollMargin = virtualizer.options.scrollMargin;
211
212
  return /* @__PURE__ */ jsx(TableFrame, {
212
213
  metrics,
214
+ hasHeader,
213
215
  columnLayout: layout,
214
216
  leadingHeaders: [],
215
217
  trailingHeader: canCustomizeColumns ? /* @__PURE__ */ jsx(TableColumnsMenu, {