@dxos/react-ui-table 0.4.10-next.71cec10 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -333,18 +333,18 @@ var useColumnSorting = (column) => {
333
333
 
334
334
  // packages/ui/react-ui-table/src/hooks/usePinLastRow.ts
335
335
  import { useCallback as useCallback3, useEffect as useEffect2, useState as useState5 } from "react";
336
- var usePinLastRow = (pinLastRow, table, data, getScrollElement) => {
336
+ var usePinLastRow = (pinLastRow, table, data) => {
337
+ const { scrollContextRef } = useTableRootContext();
337
338
  const [pinnedRowKey, setPinnedRowKey] = useState5();
338
339
  const scrollToBottom = useCallback3(() => {
339
- const scrollElement = getScrollElement?.();
340
- if (scrollElement) {
341
- requestAnimationFrame(() => scrollElement.scrollTo({
342
- top: scrollElement.scrollHeight
340
+ const element = scrollContextRef.current;
341
+ const scrollHeight = element?.scrollHeight;
342
+ if (element && scrollHeight) {
343
+ requestAnimationFrame(() => element.scrollTo({
344
+ top: scrollHeight
343
345
  }));
344
346
  }
345
- }, [
346
- getScrollElement
347
- ]);
347
+ }, []);
348
348
  const pinRow = useCallback3((rowToPin) => {
349
349
  table.resetRowPinning();
350
350
  rowToPin.pin("bottom");
@@ -545,16 +545,16 @@ var SortIndicator = ({ direction, onClick }) => {
545
545
  };
546
546
 
547
547
  // packages/ui/react-ui-table/src/components/Table/Table.tsx
548
+ import { Slot } from "@radix-ui/react-slot";
548
549
  import { getCoreRowModel, getSortedRowModel, useReactTable, getGroupedRowModel, getExpandedRowModel } from "@tanstack/react-table";
549
- import { useVirtualizer } from "@tanstack/react-virtual";
550
- import React9, { Fragment, useCallback as useCallback6, useEffect as useEffect3, useState as useState7 } from "react";
551
- import { log } from "@dxos/log";
550
+ import React9, { Fragment, useCallback as useCallback6, useEffect as useEffect3, useState as useState8, useContext as useContext3 } from "react";
552
551
  import { useDefaultValue } from "@dxos/react-ui";
552
+ import { mx as mx5 } from "@dxos/react-ui-theme";
553
553
 
554
554
  // packages/ui/react-ui-table/src/components/Table/TableBody.tsx
555
555
  import { useArrowNavigationGroup } from "@fluentui/react-tabster";
556
556
  import { flexRender } from "@tanstack/react-table";
557
- import React6 from "react";
557
+ import React6, { useContext as useContext2 } from "react";
558
558
 
559
559
  // packages/ui/react-ui-table/src/components/Table/TableContext.tsx
560
560
  import React4, { useContext, createContext } from "react";
@@ -569,6 +569,35 @@ var useTableContext = () => {
569
569
  return context;
570
570
  };
571
571
 
572
+ // packages/ui/react-ui-table/src/components/Table/TableRootContext.ts
573
+ import { useVirtualizer } from "@tanstack/react-virtual";
574
+ import { createContext as createContext2, useRef as useRef3, useState as useState7 } from "react";
575
+ var useTableRootContext = () => {
576
+ const scrollContextRef = useRef3(null);
577
+ const [tableCount, setTableCount] = useState7(0);
578
+ const virtualizer = useVirtualizer({
579
+ getScrollElement: () => scrollContextRef?.current ?? null,
580
+ count: tableCount,
581
+ overscan: 8,
582
+ estimateSize: () => 40
583
+ });
584
+ const dispatch = (action) => {
585
+ switch (action.type) {
586
+ case "updateTableCount":
587
+ setTableCount(action.count);
588
+ break;
589
+ default:
590
+ break;
591
+ }
592
+ };
593
+ return {
594
+ scrollContextRef,
595
+ virtualizer,
596
+ dispatch
597
+ };
598
+ };
599
+ var TableRootContext = createContext2({});
600
+
572
601
  // packages/ui/react-ui-table/src/theme.ts
573
602
  import { modalSurface, focusRing, ghostSelected, ghostSelectedCurrent, groupBorder, mx as mx4 } from "@dxos/react-ui-theme";
574
603
  var currentRow = "!bg-neutral-75 !dark:bg-neutral-850";
@@ -633,6 +662,7 @@ var TableBody = ({ rows }) => {
633
662
  axis: "grid"
634
663
  });
635
664
  const canBeCurrent = !isGrid && !!onDatumClick;
665
+ const { virtualizer } = useContext2(TableRootContext);
636
666
  return /* @__PURE__ */ React6.createElement("tbody", isGrid && domAttributes, rows.map((row) => {
637
667
  const isCurrent = currentDatum === row.original;
638
668
  const isSelected = rowSelection?.[row.id];
@@ -644,6 +674,8 @@ var TableBody = ({ rows }) => {
644
674
  return /* @__PURE__ */ React6.createElement("tr", {
645
675
  key: keyAccessor ? keyAccessor(row.original) : row.id,
646
676
  className: classNames,
677
+ "data-index": row.index,
678
+ ref: virtualizer.measureElement,
647
679
  ...isCurrent && {
648
680
  "aria-current": "location"
649
681
  },
@@ -741,12 +773,30 @@ var TableHead = (_props) => {
741
773
  TableHead.displayName = TABLE_HEAD_NAME;
742
774
 
743
775
  // packages/ui/react-ui-table/src/components/Table/Table.tsx
744
- var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-table/src/components/Table/Table.tsx";
745
- var Table = (props) => {
746
- const { role, onColumnResize, columnVisibility, header = true, rowsSelectable, debug, onDataSelectionChange, getScrollElement, pinLastRow } = props;
776
+ var TableRoot = ({ children }) => {
777
+ const contextValue = useTableRootContext();
778
+ return /* @__PURE__ */ React9.createElement(TableRootContext.Provider, {
779
+ value: contextValue
780
+ }, children);
781
+ };
782
+ var TableViewport = ({ children, classNames, asChild, ...props }) => {
783
+ const { scrollContextRef } = useContext3(TableRootContext);
784
+ const classes = mx5(classNames);
785
+ return asChild ? /* @__PURE__ */ React9.createElement(Slot, {
786
+ ref: scrollContextRef,
787
+ ...props
788
+ }, children) : /* @__PURE__ */ React9.createElement("div", {
789
+ role: "none",
790
+ className: classes,
791
+ ref: scrollContextRef,
792
+ ...props
793
+ }, children);
794
+ };
795
+ var TablePrimitive = (props) => {
796
+ const { role, onColumnResize, columnVisibility, header = true, rowsSelectable, debug, onDataSelectionChange, pinLastRow } = props;
747
797
  const columns = useDefaultValue(props.columns, []);
748
798
  const incomingData = useDefaultValue(props.data, []);
749
- const [data, setData] = useState7([
799
+ const [data, setData] = useState8([
750
800
  ...incomingData
751
801
  ]);
752
802
  const forceUpdate = useCallback6(() => setData([
@@ -764,7 +814,7 @@ var Table = (props) => {
764
814
  onColumnResize
765
815
  });
766
816
  const { rowSelection, handleRowSelectionChange } = useRowSelection(props);
767
- const [grouping, handleGroupingChange] = useState7(props.grouping ?? []);
817
+ const [grouping, handleGroupingChange] = useState8(props.grouping ?? []);
768
818
  useEffect3(() => handleGroupingChange(props.grouping ?? []), [
769
819
  handleGroupingChange,
770
820
  props.grouping
@@ -814,16 +864,8 @@ var Table = (props) => {
814
864
  rowSelection,
815
865
  table
816
866
  ]);
817
- usePinLastRow(pinLastRow, table, data, getScrollElement);
867
+ usePinLastRow(pinLastRow, table, data);
818
868
  const expand = false;
819
- if (!getScrollElement) {
820
- log.warn("Table: getScrollElement is not set. This is required for virtualized tables.", void 0, {
821
- F: __dxlog_file,
822
- L: 120,
823
- S: void 0,
824
- C: (f, a) => f(...a)
825
- });
826
- }
827
869
  return /* @__PURE__ */ React9.createElement(TableProvider2, {
828
870
  ...props,
829
871
  table,
@@ -832,20 +874,19 @@ var Table = (props) => {
832
874
  isGrid: role === "grid" || role === "treegrid"
833
875
  }, /* @__PURE__ */ React9.createElement(TableImpl, {
834
876
  debug: false,
835
- getScrollElement,
836
877
  ...props
837
878
  }));
838
879
  };
839
880
  var TableImpl = (props) => {
840
- const { debug, classNames, getScrollElement, role, footer, grouping, fullWidth } = props;
881
+ const { debug, classNames, role, footer, grouping, fullWidth } = props;
841
882
  const { table } = useTableContext();
842
883
  if (debug) {
843
884
  return /* @__PURE__ */ React9.createElement("pre", {
844
885
  className: "font-mono text-xs text-neutral-500 m-1 p-2 ring"
845
886
  }, /* @__PURE__ */ React9.createElement("code", null, JSON.stringify(table.getState(), void 0, 2)));
846
887
  }
847
- const virtualisable = getScrollElement !== void 0;
848
888
  const isResizingColumn = table.getState().columnSizingInfo.isResizingColumn;
889
+ const TableComponent = isResizingColumn ? MemoizedVirtualisedTableContent : VirtualizedTableContent;
849
890
  return /* @__PURE__ */ React9.createElement("table", {
850
891
  role,
851
892
  className: tableRoot(props, classNames),
@@ -854,38 +895,26 @@ var TableImpl = (props) => {
854
895
  width: table.getTotalSize()
855
896
  }
856
897
  }
857
- }, /* @__PURE__ */ React9.createElement(TableHead, null), grouping?.length !== 0 ? virtualisable ? isResizingColumn ? /* @__PURE__ */ React9.createElement(MemoizedVirtualisedTableContent, {
858
- getScrollElement
859
- }) : /* @__PURE__ */ React9.createElement(VirtualizedTableContent, {
860
- getScrollElement
861
- }) : /* @__PURE__ */ React9.createElement(UnvirtualizedTableContent, null) : /* @__PURE__ */ React9.createElement(GroupedTableContent, null), footer && /* @__PURE__ */ React9.createElement(TableFooter, null));
862
- };
863
- var UnvirtualizedTableContent = () => {
864
- const { table } = useTableContext();
865
- const centerRows = table.getCenterRows();
866
- const pinnedRows = table.getBottomRows();
867
- const rows = [
868
- ...centerRows,
869
- ...pinnedRows
870
- ];
871
- return /* @__PURE__ */ React9.createElement(TableBody, {
872
- rows
873
- });
898
+ }, /* @__PURE__ */ React9.createElement(TableHead, null), grouping?.length !== 0 ? /* @__PURE__ */ React9.createElement(TableComponent, null) : /* @__PURE__ */ React9.createElement(GroupedTableContent, null), footer && /* @__PURE__ */ React9.createElement(TableFooter, null));
874
899
  };
875
- var VirtualizedTableContent = ({ getScrollElement }) => {
900
+ var VirtualizedTableContent = () => {
876
901
  const { table } = useTableContext();
902
+ const { virtualizer, dispatch } = useContext3(TableRootContext);
877
903
  const centerRows = table.getCenterRows();
878
904
  let pinnedRows = [];
905
+ useEffect3(() => {
906
+ dispatch({
907
+ type: "updateTableCount",
908
+ count: centerRows.length
909
+ });
910
+ }, [
911
+ centerRows.length
912
+ ]);
879
913
  try {
880
914
  pinnedRows = table.getBottomRows();
881
915
  } catch (_) {
882
916
  }
883
- const { getTotalSize, getVirtualItems } = useVirtualizer({
884
- getScrollElement,
885
- count: centerRows.length,
886
- overscan: 8,
887
- estimateSize: () => 40
888
- });
917
+ const { getTotalSize, getVirtualItems } = virtualizer;
889
918
  const virtualRows = getVirtualItems();
890
919
  const totalSize = getTotalSize();
891
920
  const paddingTop = virtualRows.length > 0 ? virtualRows?.[0]?.start || 0 : 0;
@@ -893,8 +922,8 @@ var VirtualizedTableContent = ({ getScrollElement }) => {
893
922
  const rowsToRender = [
894
923
  ...virtualRows.map((virtualRow) => centerRows[virtualRow.index]),
895
924
  ...pinnedRows
896
- ];
897
- return /* @__PURE__ */ React9.createElement(React9.Fragment, null, paddingTop > 0 && /* @__PURE__ */ React9.createElement("tbody", {
925
+ ].filter((r) => !!r);
926
+ return /* @__PURE__ */ React9.createElement(Fragment, null, paddingTop > 0 && /* @__PURE__ */ React9.createElement("tbody", {
898
927
  role: "none"
899
928
  }, /* @__PURE__ */ React9.createElement("tr", {
900
929
  role: "none"
@@ -931,6 +960,11 @@ var GroupedTableContent = () => {
931
960
  }));
932
961
  }));
933
962
  };
963
+ var Table = {
964
+ Root: TableRoot,
965
+ Table: TablePrimitive,
966
+ Viewport: TableViewport
967
+ };
934
968
 
935
969
  // packages/ui/react-ui-table/src/helpers.tsx
936
970
  import { useFocusFinders } from "@fluentui/react-tabster";
@@ -938,11 +972,11 @@ import { Check as Check2, ClipboardText, X as X3 } from "@phosphor-icons/react";
938
972
  import { createColumnHelper } from "@tanstack/react-table";
939
973
  import { format } from "date-fns/format";
940
974
  import { formatDistanceToNow } from "date-fns/formatDistanceToNow";
941
- import React10, { useCallback as useCallback7, useEffect as useEffect4, useRef as useRef3, useState as useState8 } from "react";
942
- import { log as log2 } from "@dxos/log";
975
+ import React10, { useCallback as useCallback7, useEffect as useEffect4, useRef as useRef4, useState as useState9 } from "react";
976
+ import { log } from "@dxos/log";
943
977
  import { Input as Input2, Tooltip } from "@dxos/react-ui";
944
- import { getSize as getSize4, mx as mx5 } from "@dxos/react-ui-theme";
945
- var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-table/src/helpers.tsx";
978
+ import { getSize as getSize4, mx as mx6 } from "@dxos/react-ui-theme";
979
+ var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-table/src/helpers.tsx";
946
980
  var createColumnBuilder = () => ({
947
981
  helper: createColumnHelper(),
948
982
  builder: new ColumnBuilder()
@@ -956,7 +990,7 @@ var ComboboxBuilderCell = (cellContext) => {
956
990
  }) : null;
957
991
  };
958
992
  var StringBuilderCell = (cellContext) => {
959
- const ref = useRef3(null);
993
+ const ref = useRef4(null);
960
994
  const { findPrevFocusable } = useFocusFinders();
961
995
  const { onUpdate, cell } = cellContext.column.columnDef.meta;
962
996
  const initialValue = cellContext.getValue();
@@ -965,7 +999,7 @@ var StringBuilderCell = (cellContext) => {
965
999
  }, [
966
1000
  initialValue
967
1001
  ]);
968
- const [value, setValue] = useState8(getInitialValue);
1002
+ const [value, setValue] = useState9(getInitialValue);
969
1003
  useEffect4(() => setValue(getInitialValue()), [
970
1004
  getInitialValue
971
1005
  ]);
@@ -1005,9 +1039,9 @@ var displayNumber = (value, digits) => value || value === 0 ? value.toLocaleStri
1005
1039
  var NumberBuilderCell = (cellContext) => {
1006
1040
  const { onUpdate, digits } = cellContext.column.columnDef.meta;
1007
1041
  const value = cellContext.getValue();
1008
- const [text, setText] = useState8(displayNumber(value, digits));
1042
+ const [text, setText] = useState9(displayNumber(value, digits));
1009
1043
  const { findPrevFocusable } = useFocusFinders();
1010
- const ref = useRef3(null);
1044
+ const ref = useRef4(null);
1011
1045
  useEffect4(() => {
1012
1046
  (!document.activeElement || document.activeElement !== ref.current) && setText(displayNumber(value, digits));
1013
1047
  }, [
@@ -1095,7 +1129,7 @@ var ColumnBuilder = class {
1095
1129
  cell: model && onUpdate ? ComboboxBuilderCell : (cellContext) => {
1096
1130
  const cellValue = cellContext.getValue();
1097
1131
  return /* @__PURE__ */ React10.createElement("div", {
1098
- className: mx5("truncate", classNames)
1132
+ className: mx6("truncate", classNames)
1099
1133
  }, cellValue ? model?.getText(cellValue) : "");
1100
1134
  },
1101
1135
  ...props,
@@ -1126,7 +1160,7 @@ var ColumnBuilder = class {
1126
1160
  value = value.content;
1127
1161
  }
1128
1162
  return /* @__PURE__ */ React10.createElement("div", {
1129
- className: mx5("truncate", textPadding, classNames)
1163
+ className: mx6("truncate", textPadding, classNames)
1130
1164
  }, value);
1131
1165
  },
1132
1166
  ...props,
@@ -1180,13 +1214,13 @@ var ColumnBuilder = class {
1180
1214
  addSuffix: true
1181
1215
  }) : value.toISOString() : void 0;
1182
1216
  return /* @__PURE__ */ React10.createElement("div", {
1183
- className: mx5(textPadding, classNames)
1217
+ className: mx6(textPadding, classNames)
1184
1218
  }, str);
1185
1219
  } catch (err) {
1186
- log2.info("formatError", {
1220
+ log.info("formatError", {
1187
1221
  value
1188
1222
  }, {
1189
- F: __dxlog_file2,
1223
+ F: __dxlog_file,
1190
1224
  L: 376,
1191
1225
  S: this,
1192
1226
  C: (f, a) => f(...a)
@@ -1319,11 +1353,11 @@ var ColumnBuilder = class {
1319
1353
  const value = cell.getValue();
1320
1354
  if (value) {
1321
1355
  return /* @__PURE__ */ React10.createElement(IconOn, {
1322
- className: mx5("block mli-auto", getSize4(6), on?.className ?? "text-green-700")
1356
+ className: mx6("block mli-auto", getSize4(6), on?.className ?? "text-green-700")
1323
1357
  });
1324
1358
  } else if (value === false) {
1325
1359
  return /* @__PURE__ */ React10.createElement(IconOff, {
1326
- className: mx5("block mli-auto", getSize4(6), off?.className ?? "text-red-700")
1360
+ className: mx6("block mli-auto", getSize4(6), off?.className ?? "text-red-700")
1327
1361
  });
1328
1362
  } else {
1329
1363
  return null;
@@ -1492,6 +1526,8 @@ export {
1492
1526
  MemoizedVirtualisedTableContent,
1493
1527
  SortIndicator,
1494
1528
  Table,
1529
+ TablePrimitive,
1530
+ TableRootContext,
1495
1531
  createColumnBuilder,
1496
1532
  currentRow,
1497
1533
  flushPadding,
@@ -1517,6 +1553,7 @@ export {
1517
1553
  useColumnResizing,
1518
1554
  useColumnSorting,
1519
1555
  usePinLastRow,
1520
- useRowSelection
1556
+ useRowSelection,
1557
+ useTableRootContext
1521
1558
  };
1522
1559
  //# sourceMappingURL=index.mjs.map