@galaxy-io/dls 2.0.1 → 2.0.2

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.
@@ -754,7 +754,7 @@ var InfiniteSpreadsheetInner = forwardRef(function InfiniteSpreadsheet(props, re
754
754
  }), showAddRow && isMounted && /* @__PURE__ */ jsx(AddRow, {
755
755
  role: "row",
756
756
  "aria-rowindex": rowCount + 2,
757
- className: "gx-TableCore-VIRTUAL_ROW_CSS-vb9km4t",
757
+ className: "gx-TableCore-VIRTUAL_ROW_CSS-v1emgwoo",
758
758
  style: startStyle(totalSize),
759
759
  children: /* @__PURE__ */ jsx(AddRowCell, {
760
760
  role: "gridcell",
@@ -289,26 +289,71 @@ var ROW_SELECTED_CSS = "gx-TableCore-ROW_SELECTED_CSS-r1g7lrfg";
289
289
  var ROW_ACTIVE_CSS = "gx-TableCore-ROW_ACTIVE_CSS-r10dstoh";
290
290
  /** @internal The last row, or a row whose panel is open: no bottom hairline. */
291
291
  var ROW_NO_BORDER_CSS = "gx-TableCore-ROW_NO_BORDER_CSS-rpsswqs";
292
+ /**
293
+ * The rows end above the bottom of the scroll box (a full-height table with a few rows): the last
294
+ * row keeps its hairline, so the list reads as finished instead of floating in empty space. Set by
295
+ * `useRowsEndAboveBottom`; it outranks `ROW_NO_BORDER_CSS` and the panel rule by specificity, and
296
+ * sits inside each row's fixed height, so nothing moves when it toggles.
297
+ */
298
+ var ROWS_END_ABOVE_BOTTOM_CSS = "gx-TableCore-ROWS_END_ABOVE_BOTTOM_CSS-rwbqwrq";
299
+ /**
300
+ * Whether the table's rows end above the bottom of its scroll box. The last row drops its hairline
301
+ * only when it lands on the box's bottom edge, where the container's frame (or a scrolled table's
302
+ * end) already draws the line; above the edge, the hairline closes the list. Watches the scroll box
303
+ * and every row group, so rows loading, expanding or the box resizing re-measure it.
304
+ */
305
+ function useRowsEndAboveBottom(scrollRef, tableRef, isEnabled, bodyKey) {
306
+ const [isAbove, setIsAbove] = useState(false);
307
+ useIsomorphicLayoutEffect(() => {
308
+ const scroll = scrollRef.current;
309
+ const table = tableRef.current;
310
+ if (!isEnabled || scroll === null || table === null) {
311
+ setIsAbove(false);
312
+ return;
313
+ }
314
+ const measure = () => {
315
+ const rows = table.querySelectorAll(":scope > tbody > tr");
316
+ const last = rows[rows.length - 1];
317
+ if (last === void 0) {
318
+ setIsAbove(false);
319
+ return;
320
+ }
321
+ setIsAbove(last.getBoundingClientRect().bottom - scroll.getBoundingClientRect().top + scroll.scrollTop < scroll.clientHeight - 1);
322
+ };
323
+ measure();
324
+ if (typeof ResizeObserver === "undefined") return;
325
+ const observer = new ResizeObserver(measure);
326
+ observer.observe(scroll);
327
+ for (const body of Array.from(table.tBodies)) observer.observe(body);
328
+ return () => observer.disconnect();
329
+ }, [
330
+ scrollRef,
331
+ tableRef,
332
+ isEnabled,
333
+ bodyKey
334
+ ]);
335
+ return isAbove;
336
+ }
292
337
  /** The last expanded panel: no bottom hairline. */
293
- var EXPANDED_LAST_CSS = "gx-TableCore-EXPANDED_LAST_CSS-ewbqwrq";
338
+ var EXPANDED_LAST_CSS = "gx-TableCore-EXPANDED_LAST_CSS-e1jxalmm";
294
339
  /** The dragged header while reordering. 0.5 is a state, not a color token. */
295
- var HEADER_DRAGGING_CSS = "gx-TableCore-HEADER_DRAGGING_CSS-h1jxalmm";
340
+ var HEADER_DRAGGING_CSS = "gx-TableCore-HEADER_DRAGGING_CSS-h1fx3qlj";
296
341
  /** The label wrapper grows when a trailing control (column actions) follows it. */
297
- var LABEL_GROW_CSS = "gx-TableCore-LABEL_GROW_CSS-l1fx3qlj";
298
- var DROP_START_CSS = "gx-TableCore-DROP_START_CSS-d2nd1ne";
299
- var DROP_END_CSS = "gx-TableCore-DROP_END_CSS-darqcf0";
342
+ var LABEL_GROW_CSS = "gx-TableCore-LABEL_GROW_CSS-l2nd1ne";
343
+ var DROP_START_CSS = "gx-TableCore-DROP_START_CSS-darqcf0";
344
+ var DROP_END_CSS = "gx-TableCore-DROP_END_CSS-d132cb1v";
300
345
  /** Shows on hover, while dragged and on keyboard focus; straddles the column edge. */
301
- var COLUMN_RESIZE_HANDLE_CSS = "gx-TableCore-COLUMN_RESIZE_HANDLE_CSS-c132cb1v";
346
+ var COLUMN_RESIZE_HANDLE_CSS = "gx-TableCore-COLUMN_RESIZE_HANDLE_CSS-c1vn45v6";
302
347
  /** Hovering a header cell reveals its resize handle. */
303
- var HEADER_HOVER_CSS = "gx-TableCore-HEADER_HOVER_CSS-h1vn45v6";
348
+ var HEADER_HOVER_CSS = "gx-TableCore-HEADER_HOVER_CSS-h14za3v2";
304
349
  /** The expand caret button: a square of its rung. */
305
- var EXPAND_BUTTON_CSS = "gx-TableCore-EXPAND_BUTTON_CSS-e14za3v2";
350
+ var EXPAND_BUTTON_CSS = "gx-TableCore-EXPAND_BUTTON_CSS-e1w0t3ir";
306
351
  /** @internal A virtual body: as tall as every row, which are positioned inside it. */
307
- var VIRTUAL_BODY_CSS = "gx-TableCore-VIRTUAL_BODY_CSS-v1w0t3ir";
352
+ var VIRTUAL_BODY_CSS = "gx-TableCore-VIRTUAL_BODY_CSS-vb9km4t";
308
353
  /** @internal A virtual row, placed at `--gx-table-row-start`. */
309
- var VIRTUAL_ROW_CSS = "gx-TableCore-VIRTUAL_ROW_CSS-vb9km4t";
354
+ var VIRTUAL_ROW_CSS = "gx-TableCore-VIRTUAL_ROW_CSS-v1emgwoo";
310
355
  /** @internal Default cells and footer strings: shrink to truncate. */
311
- var CELL_TEXT_CSS = "gx-TableCore-CELL_TEXT_CSS-c1emgwoo";
356
+ var CELL_TEXT_CSS = "gx-TableCore-CELL_TEXT_CSS-cw38cm1";
312
357
  /** "Oct 3, 2026": the DateInput default. */
313
358
  var DATE_FORMAT_OPTIONS = { dateStyle: "medium" };
314
359
  /** @internal The default cell renderer: one truncating line of formatted text. */
@@ -744,6 +789,9 @@ function TableFrame({ metrics, columnLayout, leadingHeaders, trailingHeader, has
744
789
  const colCount = leadingCount + visibleColumns.length + (hasTrailingColumn ? 1 : 0);
745
790
  const surface = useTableSurface(ownRootRef);
746
791
  const { width: viewportWidth } = useElementClientSize(scrollRef);
792
+ const tableRef = useRef(null);
793
+ const hasFooterRow = columnLayout.visibleColumns.some(({ column }) => column.footer !== void 0 && column.footer !== null);
794
+ const doRowsEndAboveBottom = useRowsEndAboveBottom(scrollRef, tableRef, !hasFooterRow && (rowCount > 0 || isLoading), `${rowCount}:${isLoading}:${error ?? ""}`);
747
795
  const sentinelRef = useInfiniteScrollSentinel({
748
796
  scrollRef,
749
797
  onEndReached,
@@ -872,7 +920,7 @@ function TableFrame({ metrics, columnLayout, leadingHeaders, trailingHeader, has
872
920
  if (drag.beforeId === null && ids.at(-1) === columnId) return "end";
873
921
  return null;
874
922
  };
875
- const hasFooter = visibleColumns.some(({ column }) => column.footer !== void 0 && column.footer !== null);
923
+ const hasFooter = hasFooterRow;
876
924
  const footerRowIndex = ariaRowCount;
877
925
  const variables = { ...columnLayout.variables };
878
926
  if (viewportWidth !== void 0) variables["--gx-table-viewport-width"] = `${viewportWidth}px`;
@@ -948,6 +996,8 @@ function TableFrame({ metrics, columnLayout, leadingHeaders, trailingHeader, has
948
996
  children: [/* @__PURE__ */ jsxs(Scroll, {
949
997
  ref: scrollRef,
950
998
  children: [/* @__PURE__ */ jsxs(TableElement, {
999
+ ref: tableRef,
1000
+ className: cx(doRowsEndAboveBottom && ROWS_END_ABOVE_BOTTOM_CSS),
951
1001
  ...tableAria,
952
1002
  role,
953
1003
  ...ariaLabel === void 0 ? {} : { "aria-label": ariaLabel },
@@ -1043,7 +1093,7 @@ function TableFrame({ metrics, columnLayout, leadingHeaders, trailingHeader, has
1043
1093
  size: metrics.textSize,
1044
1094
  weight: TextWeight.MEDIUM,
1045
1095
  lineClamp: 1,
1046
- className: "gx-TableCore-CELL_TEXT_CSS-c1emgwoo",
1096
+ className: "gx-TableCore-CELL_TEXT_CSS-cw38cm1",
1047
1097
  children: column.footer
1048
1098
  }) : column.footer
1049
1099
  }, column.id)),
@@ -30,12 +30,12 @@ var LIGHT_THEME = {
30
30
  background: {
31
31
  base: "#ffffff",
32
32
  primary: "#fafafb",
33
- secondary: "#f1f1f2",
34
- tertiary: "#ededee",
33
+ secondary: "#f3f3f4",
34
+ tertiary: "#efeff0",
35
35
  hovered: "#f5f5f5",
36
36
  pressed: "#eeeeee",
37
37
  selected: "#e2e2e2",
38
- disabled: "#f1f1f2",
38
+ disabled: "#f3f3f4",
39
39
  success: "#ecfcf0",
40
40
  warning: "#fff8eb",
41
41
  error: "#fff2f2",
@@ -119,7 +119,7 @@ var LIGHT_THEME = {
119
119
  pressed: "#494949"
120
120
  },
121
121
  neutral: {
122
- background: "#f1f1f2",
122
+ background: "#f3f3f4",
123
123
  text: "#101010",
124
124
  hovered: "#e5e5e6",
125
125
  pressed: "#dcdcdd"
package/dist/tokens.css CHANGED
@@ -386,12 +386,12 @@
386
386
  [data-gx-theme="light"] {
387
387
  --gx-color-background-base: #ffffff;
388
388
  --gx-color-background-primary: #fafafb;
389
- --gx-color-background-secondary: #f1f1f2;
390
- --gx-color-background-tertiary: #ededee;
389
+ --gx-color-background-secondary: #f3f3f4;
390
+ --gx-color-background-tertiary: #efeff0;
391
391
  --gx-color-background-hovered: #f5f5f5;
392
392
  --gx-color-background-pressed: #eeeeee;
393
393
  --gx-color-background-selected: #e2e2e2;
394
- --gx-color-background-disabled: #f1f1f2;
394
+ --gx-color-background-disabled: #f3f3f4;
395
395
  --gx-color-background-success: #ecfcf0;
396
396
  --gx-color-background-warning: #fff8eb;
397
397
  --gx-color-background-error: #fff2f2;
@@ -466,7 +466,7 @@
466
466
  --gx-color-solid-primary-text: #ffffff;
467
467
  --gx-color-solid-primary-hovered: #2d2d2d;
468
468
  --gx-color-solid-primary-pressed: #494949;
469
- --gx-color-solid-neutral-background: #f1f1f2;
469
+ --gx-color-solid-neutral-background: #f3f3f4;
470
470
  --gx-color-solid-neutral-text: #101010;
471
471
  --gx-color-solid-neutral-hovered: #e5e5e6;
472
472
  --gx-color-solid-neutral-pressed: #dcdcdd;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@galaxy-io/dls",
3
- "version": "2.0.1",
3
+ "version": "2.0.2",
4
4
  "description": "Galaxy Design Language System",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",