@dxos/react-ui-table 0.4.10-main.fe71b4c → 0.4.10-next.169e4e3

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 (39) hide show
  1. package/dist/lib/browser/index.mjs +219 -139
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/types/src/components/ColumnMenu/ColumnMenu.d.ts.map +1 -1
  5. package/dist/types/src/components/Table/Table.d.ts +17 -4
  6. package/dist/types/src/components/Table/Table.d.ts.map +1 -1
  7. package/dist/types/src/components/Table/Table.stories.d.ts +29 -1
  8. package/dist/types/src/components/Table/Table.stories.d.ts.map +1 -1
  9. package/dist/types/src/components/Table/TableBody.d.ts.map +1 -1
  10. package/dist/types/src/components/Table/TableRootContext.d.ts +17 -0
  11. package/dist/types/src/components/Table/TableRootContext.d.ts.map +1 -0
  12. package/dist/types/src/components/Table/index.d.ts +1 -0
  13. package/dist/types/src/components/Table/index.d.ts.map +1 -1
  14. package/dist/types/src/components/Table/props.d.ts +2 -3
  15. package/dist/types/src/components/Table/props.d.ts.map +1 -1
  16. package/dist/types/src/helpers.d.ts.map +1 -1
  17. package/dist/types/src/hooks/index.d.ts +2 -0
  18. package/dist/types/src/hooks/index.d.ts.map +1 -1
  19. package/dist/types/src/hooks/useColumnSizing.d.ts +12 -0
  20. package/dist/types/src/hooks/useColumnSizing.d.ts.map +1 -0
  21. package/dist/types/src/hooks/usePinLastRow.d.ts +1 -1
  22. package/dist/types/src/hooks/usePinLastRow.d.ts.map +1 -1
  23. package/dist/types/src/hooks/useRowSelection.d.ts +7 -0
  24. package/dist/types/src/hooks/useRowSelection.d.ts.map +1 -0
  25. package/dist/types/src/schema/SchemaToTable.stories.d.ts.map +1 -1
  26. package/package.json +18 -15
  27. package/src/components/ColumnMenu/ColumnMenu.tsx +34 -32
  28. package/src/components/Table/Table.stories.tsx +204 -89
  29. package/src/components/Table/Table.tsx +70 -101
  30. package/src/components/Table/TableBody.tsx +6 -1
  31. package/src/components/Table/TableRootContext.ts +39 -0
  32. package/src/components/Table/index.ts +1 -0
  33. package/src/components/Table/props.ts +17 -24
  34. package/src/helpers.tsx +9 -7
  35. package/src/hooks/index.ts +2 -0
  36. package/src/hooks/useColumnSizing.ts +45 -0
  37. package/src/hooks/usePinLastRow.ts +10 -10
  38. package/src/hooks/useRowSelection.ts +39 -0
  39. package/src/schema/SchemaToTable.stories.tsx +15 -16
@@ -92,7 +92,7 @@ var CellCombobox = ({ model, value, onValueChange }) => {
92
92
 
93
93
  // packages/ui/react-ui-table/src/components/ColumnMenu/ColumnMenu.tsx
94
94
  import { X as X2, GearSix, CaretDown as CaretDown2, ArrowDown, ArrowUp } from "@phosphor-icons/react";
95
- import React3, { useRef as useRef2, useState as useState5, useCallback as useCallback3 } from "react";
95
+ import React3, { useRef as useRef2, useState as useState6, useCallback as useCallback5 } from "react";
96
96
  import { Button as Button2, DensityProvider, Popover as Popover2, DropdownMenu } from "@dxos/react-ui";
97
97
  import { getSize as getSize3, mx as mx3 } from "@dxos/react-ui-theme";
98
98
 
@@ -252,11 +252,44 @@ var ColumnSettingsForm = ({ column, tableDef, tableDefs, onUpdate, onDelete, onC
252
252
  }))));
253
253
  };
254
254
 
255
+ // packages/ui/react-ui-table/src/hooks/useColumnSizing.ts
256
+ import { useCallback as useCallback2, useEffect, useState as useState3 } from "react";
257
+ import { useOnTransition } from "@dxos/react-ui";
258
+ var useColumnResizing = ({ columns, onColumnResize }) => {
259
+ const [columnsInitialised, setColumnsInitialised] = useState3(false);
260
+ const [columnSizing, setColumnSizing] = useState3({});
261
+ useEffect(() => {
262
+ if (columnsInitialised) {
263
+ return;
264
+ }
265
+ setColumnSizing(columns.filter((column) => !!column.size && column.prop !== void 0).reduce((state, column) => {
266
+ state[column.prop] = column.size;
267
+ return state;
268
+ }, {}));
269
+ setColumnsInitialised(true);
270
+ }, [
271
+ columns,
272
+ setColumnSizing
273
+ ]);
274
+ const [columnSizingInfo, setColumnSizingInfo] = useState3({});
275
+ const notifyColumnResize = useCallback2(() => onColumnResize?.(columnSizing), [
276
+ onColumnResize,
277
+ columnSizing
278
+ ]);
279
+ useOnTransition(columnSizingInfo.isResizingColumn, (v) => typeof v === "string", false, notifyColumnResize);
280
+ return {
281
+ columnSizing,
282
+ columnSizingInfo,
283
+ setColumnSizing,
284
+ setColumnSizingInfo
285
+ };
286
+ };
287
+
255
288
  // packages/ui/react-ui-table/src/hooks/useColumnSorting.ts
256
- import { useState as useState3 } from "react";
289
+ import { useState as useState4 } from "react";
257
290
  var useColumnSorting = (column) => {
258
- const [sortDirection, setSortDirection] = useState3(column.getIsSorted());
259
- const [firstSort, setFirstSort] = useState3();
291
+ const [sortDirection, setSortDirection] = useState4(column.getIsSorted());
292
+ const [firstSort, setFirstSort] = useState4();
260
293
  const canSort = column.getCanSort();
261
294
  const updateColumnSort = (direction) => {
262
295
  setSortDirection(direction);
@@ -299,33 +332,33 @@ var useColumnSorting = (column) => {
299
332
  };
300
333
 
301
334
  // packages/ui/react-ui-table/src/hooks/usePinLastRow.ts
302
- import { useCallback as useCallback2, useEffect, useState as useState4 } from "react";
303
- var usePinLastRow = (pinLastRow, table, data, getScrollElement) => {
304
- const [pinnedRowKey, setPinnedRowKey] = useState4();
305
- const scrollToBottom = useCallback2(() => {
306
- const scrollElement = getScrollElement?.();
307
- if (scrollElement) {
308
- requestAnimationFrame(() => scrollElement.scrollTo({
309
- top: scrollElement.scrollHeight
335
+ import { useCallback as useCallback3, useEffect as useEffect2, useState as useState5 } from "react";
336
+ var usePinLastRow = (pinLastRow, table, data) => {
337
+ const { scrollContextRef } = useTableRootContext();
338
+ const [pinnedRowKey, setPinnedRowKey] = useState5();
339
+ const scrollToBottom = useCallback3(() => {
340
+ const element = scrollContextRef.current;
341
+ const scrollHeight = element?.scrollHeight;
342
+ if (element && scrollHeight) {
343
+ requestAnimationFrame(() => element.scrollTo({
344
+ top: scrollHeight
310
345
  }));
311
346
  }
312
- }, [
313
- getScrollElement
314
- ]);
315
- const pinRow = useCallback2((rowToPin) => {
347
+ }, []);
348
+ const pinRow = useCallback3((rowToPin) => {
316
349
  table.resetRowPinning();
317
350
  rowToPin.pin("bottom");
318
351
  setPinnedRowKey(rowToPin.id);
319
352
  }, [
320
353
  table
321
354
  ]);
322
- const clearRowPinning = useCallback2(() => {
355
+ const clearRowPinning = useCallback3(() => {
323
356
  table.resetRowPinning();
324
357
  setPinnedRowKey(void 0);
325
358
  }, [
326
359
  table
327
360
  ]);
328
- const pinLastRowCallback = useCallback2(() => {
361
+ const pinLastRowCallback = useCallback3(() => {
329
362
  const rows = table.getRowModel().rows;
330
363
  if (rows.length === 0) {
331
364
  return clearRowPinning();
@@ -343,7 +376,7 @@ var usePinLastRow = (pinLastRow, table, data, getScrollElement) => {
343
376
  scrollToBottom,
344
377
  pinnedRowKey
345
378
  ]);
346
- useEffect(() => {
379
+ useEffect2(() => {
347
380
  if (pinLastRow) {
348
381
  pinLastRowCallback();
349
382
  }
@@ -354,22 +387,54 @@ var usePinLastRow = (pinLastRow, table, data, getScrollElement) => {
354
387
  ]);
355
388
  };
356
389
 
390
+ // packages/ui/react-ui-table/src/hooks/useRowSelection.ts
391
+ import { useControllableState } from "@radix-ui/react-use-controllable-state";
392
+ import { useCallback as useCallback4 } from "react";
393
+ var useRowSelection = (props) => {
394
+ const [rowSelection = {}, setRowSelection] = useControllableState({
395
+ prop: props.rowSelection,
396
+ onChange: props.onRowSelectionChange,
397
+ defaultProp: props.defaultRowSelection
398
+ });
399
+ const handleRowSelectionChange = useCallback4((updaterOrValue) => {
400
+ const nextRowSelection = typeof updaterOrValue === "function" ? updaterOrValue(rowSelection) : updaterOrValue;
401
+ if (props.rowsSelectable === "multi") {
402
+ setRowSelection(nextRowSelection);
403
+ } else if (props.rowsSelectable) {
404
+ const nextRowSelectionKey = Object.keys(nextRowSelection).filter((id) => !rowSelection[id])[0];
405
+ setRowSelection(nextRowSelectionKey ? {
406
+ [nextRowSelectionKey]: true
407
+ } : {});
408
+ } else {
409
+ setRowSelection({});
410
+ }
411
+ }, [
412
+ props.rowsSelectable,
413
+ setRowSelection,
414
+ rowSelection
415
+ ]);
416
+ return {
417
+ rowSelection,
418
+ handleRowSelectionChange
419
+ };
420
+ };
421
+
357
422
  // packages/ui/react-ui-table/src/components/ColumnMenu/ColumnMenu.tsx
358
423
  var ColumnMenu = ({ column, ...props }) => {
359
424
  const title = column.label?.length ? column.label : column.id;
360
425
  const header = props.context.header;
361
426
  const { canSort, sortDirection, onSelectSort, onToggleSort, onClearSort } = useColumnSorting(header.column);
362
427
  const columnSettingsAnchorRef = useRef2(null);
363
- const [isColumnSettingsOpen, setIsColumnSettingsOpen] = useState5(false);
428
+ const [isColumnSettingsOpen, setIsColumnSettingsOpen] = useState6(false);
364
429
  const shouldPreventFocusOnClose = useRef2(false);
365
- const onOpenColumnSettings = useCallback3(() => {
430
+ const onOpenColumnSettings = useCallback5(() => {
366
431
  shouldPreventFocusOnClose.current = true;
367
432
  setIsColumnSettingsOpen(true);
368
433
  }, [
369
434
  shouldPreventFocusOnClose,
370
435
  setIsColumnSettingsOpen
371
436
  ]);
372
- const onDropdownCloseAutoFocus = useCallback3((event) => {
437
+ const onDropdownCloseAutoFocus = useCallback5((event) => {
373
438
  if (shouldPreventFocusOnClose.current) {
374
439
  event.preventDefault();
375
440
  shouldPreventFocusOnClose.current = false;
@@ -402,7 +467,7 @@ var ColumnMenu = ({ column, ...props }) => {
402
467
  variant: "ghost"
403
468
  }, /* @__PURE__ */ React3.createElement(CaretDown2, {
404
469
  className: getSize3(4)
405
- })))), /* @__PURE__ */ React3.createElement(DropdownMenu.Content, {
470
+ })))), /* @__PURE__ */ React3.createElement(DropdownMenu.Portal, null, /* @__PURE__ */ React3.createElement(DropdownMenu.Content, {
406
471
  onCloseAutoFocus: onDropdownCloseAutoFocus,
407
472
  sideOffset: 4,
408
473
  collisionPadding: 8
@@ -438,7 +503,7 @@ var ColumnMenu = ({ column, ...props }) => {
438
503
  className: "opacity-50"
439
504
  }, /* @__PURE__ */ React3.createElement(GearSix, {
440
505
  className: mx3(getSize3(4), "rotate-90")
441
- })))), /* @__PURE__ */ React3.createElement(DropdownMenu.Arrow, null)), /* @__PURE__ */ React3.createElement(ColumnSettingsPanel, {
506
+ })))), /* @__PURE__ */ React3.createElement(DropdownMenu.Arrow, null))), /* @__PURE__ */ React3.createElement(ColumnSettingsPanel, {
442
507
  ...props,
443
508
  column,
444
509
  onClose: () => setIsColumnSettingsOpen(false)
@@ -480,17 +545,16 @@ var SortIndicator = ({ direction, onClick }) => {
480
545
  };
481
546
 
482
547
  // packages/ui/react-ui-table/src/components/Table/Table.tsx
483
- import { useControllableState } from "@radix-ui/react-use-controllable-state";
548
+ import { Slot } from "@radix-ui/react-slot";
484
549
  import { getCoreRowModel, getSortedRowModel, useReactTable, getGroupedRowModel, getExpandedRowModel } from "@tanstack/react-table";
485
- import { useVirtualizer } from "@tanstack/react-virtual";
486
- import React9, { Fragment, useCallback as useCallback4, useEffect as useEffect2, useState as useState6 } from "react";
487
- import { log } from "@dxos/log";
488
- import { useDefaultValue, useOnTransition } from "@dxos/react-ui";
550
+ import React9, { Fragment, useCallback as useCallback6, useEffect as useEffect3, useState as useState8, useContext as useContext3 } from "react";
551
+ import { useDefaultValue } from "@dxos/react-ui";
552
+ import { mx as mx5 } from "@dxos/react-ui-theme";
489
553
 
490
554
  // packages/ui/react-ui-table/src/components/Table/TableBody.tsx
491
555
  import { useArrowNavigationGroup } from "@fluentui/react-tabster";
492
556
  import { flexRender } from "@tanstack/react-table";
493
- import React6 from "react";
557
+ import React6, { useContext as useContext2 } from "react";
494
558
 
495
559
  // packages/ui/react-ui-table/src/components/Table/TableContext.tsx
496
560
  import React4, { useContext, createContext } from "react";
@@ -505,6 +569,35 @@ var useTableContext = () => {
505
569
  return context;
506
570
  };
507
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
+
508
601
  // packages/ui/react-ui-table/src/theme.ts
509
602
  import { modalSurface, focusRing, ghostSelected, ghostSelectedCurrent, groupBorder, mx as mx4 } from "@dxos/react-ui-theme";
510
603
  var currentRow = "!bg-neutral-75 !dark:bg-neutral-850";
@@ -569,6 +662,7 @@ var TableBody = ({ rows }) => {
569
662
  axis: "grid"
570
663
  });
571
664
  const canBeCurrent = !isGrid && !!onDatumClick;
665
+ const { virtualizer } = useContext2(TableRootContext);
572
666
  return /* @__PURE__ */ React6.createElement("tbody", isGrid && domAttributes, rows.map((row) => {
573
667
  const isCurrent = currentDatum === row.original;
574
668
  const isSelected = rowSelection?.[row.id];
@@ -580,6 +674,8 @@ var TableBody = ({ rows }) => {
580
674
  return /* @__PURE__ */ React6.createElement("tr", {
581
675
  key: keyAccessor ? keyAccessor(row.original) : row.id,
582
676
  className: classNames,
677
+ "data-index": row.index,
678
+ ref: virtualizer.measureElement,
583
679
  ...isCurrent && {
584
680
  "aria-current": "location"
585
681
  },
@@ -677,57 +773,49 @@ var TableHead = (_props) => {
677
773
  TableHead.displayName = TABLE_HEAD_NAME;
678
774
 
679
775
  // packages/ui/react-ui-table/src/components/Table/Table.tsx
680
- var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-table/src/components/Table/Table.tsx";
681
- var Table = (props) => {
682
- 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;
683
797
  const columns = useDefaultValue(props.columns, []);
684
- const data = useDefaultValue(props.data, []);
685
- const TableProvider2 = TableProvider;
686
- const [columnsInitialised, setColumnsInitialised] = useState6(false);
687
- const [columnSizing, setColumnSizing] = useState6({});
688
- useEffect2(() => {
689
- if (columnsInitialised) {
690
- return;
691
- }
692
- setColumnSizing(columns.filter((column) => !!column.size && column.prop !== void 0).reduce((state, column) => {
693
- state[column.prop] = column.size;
694
- return state;
695
- }, {}));
696
- setColumnsInitialised(true);
697
- }, [
698
- columns,
699
- setColumnSizing
798
+ const incomingData = useDefaultValue(props.data, []);
799
+ const [data, setData] = useState8([
800
+ ...incomingData
700
801
  ]);
701
- const [columnSizingInfo, setColumnSizingInfo] = useState6({});
702
- const notifyColumnResize = useCallback4(() => onColumnResize?.(columnSizing), [
703
- onColumnResize,
704
- columnSizing
802
+ const forceUpdate = useCallback6(() => setData([
803
+ ...incomingData
804
+ ]), [
805
+ incomingData
705
806
  ]);
706
- useOnTransition(columnSizingInfo.isResizingColumn, (v) => typeof v === "string", false, notifyColumnResize);
707
- const [rowSelection = {}, setRowSelection] = useControllableState({
708
- prop: props.rowSelection,
709
- onChange: props.onRowSelectionChange,
710
- defaultProp: props.defaultRowSelection
711
- });
712
- const handleRowSelectionChange = useCallback4((updaterOrValue) => {
713
- const nextRowSelection = typeof updaterOrValue === "function" ? updaterOrValue(rowSelection) : updaterOrValue;
714
- if (rowsSelectable === "multi") {
715
- setRowSelection(nextRowSelection);
716
- } else if (rowsSelectable) {
717
- const nextRowSelectionKey = Object.keys(nextRowSelection).filter((id) => !rowSelection[id])[0];
718
- setRowSelection(nextRowSelectionKey ? {
719
- [nextRowSelectionKey]: true
720
- } : {});
721
- } else {
722
- setRowSelection({});
723
- }
724
- }, [
725
- rowsSelectable,
726
- setRowSelection,
727
- rowSelection
807
+ useEffect3(() => forceUpdate(), [
808
+ JSON.stringify(incomingData),
809
+ forceUpdate
728
810
  ]);
729
- const [grouping, handleGroupingChange] = useState6(props.grouping ?? []);
730
- useEffect2(() => handleGroupingChange(props.grouping ?? []), [
811
+ const TableProvider2 = TableProvider;
812
+ const { columnSizing, setColumnSizing, columnSizingInfo, setColumnSizingInfo } = useColumnResizing({
813
+ columns,
814
+ onColumnResize
815
+ });
816
+ const { rowSelection, handleRowSelectionChange } = useRowSelection(props);
817
+ const [grouping, handleGroupingChange] = useState8(props.grouping ?? []);
818
+ useEffect3(() => handleGroupingChange(props.grouping ?? []), [
731
819
  handleGroupingChange,
732
820
  props.grouping
733
821
  ]);
@@ -769,23 +857,15 @@ var Table = (props) => {
769
857
  // Debug
770
858
  debugTable: debug
771
859
  });
772
- useEffect2(() => {
860
+ useEffect3(() => {
773
861
  onDataSelectionChange?.(Object.keys(rowSelection).map((id) => table.getRowModel().rowsById[id].original));
774
862
  }, [
775
863
  onDataSelectionChange,
776
864
  rowSelection,
777
865
  table
778
866
  ]);
779
- usePinLastRow(pinLastRow, table, data, getScrollElement);
867
+ usePinLastRow(pinLastRow, table, data);
780
868
  const expand = false;
781
- if (!getScrollElement) {
782
- log.warn("Table: getScrollElement is not set. This is required for virtualized tables.", void 0, {
783
- F: __dxlog_file,
784
- L: 160,
785
- S: void 0,
786
- C: (f, a) => f(...a)
787
- });
788
- }
789
869
  return /* @__PURE__ */ React9.createElement(TableProvider2, {
790
870
  ...props,
791
871
  table,
@@ -794,20 +874,19 @@ var Table = (props) => {
794
874
  isGrid: role === "grid" || role === "treegrid"
795
875
  }, /* @__PURE__ */ React9.createElement(TableImpl, {
796
876
  debug: false,
797
- getScrollElement,
798
877
  ...props
799
878
  }));
800
879
  };
801
880
  var TableImpl = (props) => {
802
- const { debug, classNames, getScrollElement, role, footer, grouping, fullWidth } = props;
881
+ const { debug, classNames, role, footer, grouping, fullWidth } = props;
803
882
  const { table } = useTableContext();
804
883
  if (debug) {
805
884
  return /* @__PURE__ */ React9.createElement("pre", {
806
885
  className: "font-mono text-xs text-neutral-500 m-1 p-2 ring"
807
886
  }, /* @__PURE__ */ React9.createElement("code", null, JSON.stringify(table.getState(), void 0, 2)));
808
887
  }
809
- const virtualisable = getScrollElement !== void 0;
810
888
  const isResizingColumn = table.getState().columnSizingInfo.isResizingColumn;
889
+ const TableComponent = isResizingColumn ? MemoizedVirtualisedTableContent : VirtualizedTableContent;
811
890
  return /* @__PURE__ */ React9.createElement("table", {
812
891
  role,
813
892
  className: tableRoot(props, classNames),
@@ -816,38 +895,26 @@ var TableImpl = (props) => {
816
895
  width: table.getTotalSize()
817
896
  }
818
897
  }
819
- }, /* @__PURE__ */ React9.createElement(TableHead, null), grouping?.length !== 0 ? virtualisable ? isResizingColumn ? /* @__PURE__ */ React9.createElement(MemoizedVirtualisedTableContent, {
820
- getScrollElement
821
- }) : /* @__PURE__ */ React9.createElement(VirtualizedTableContent, {
822
- getScrollElement
823
- }) : /* @__PURE__ */ React9.createElement(UnvirtualizedTableContent, null) : /* @__PURE__ */ React9.createElement(GroupedTableContent, null), footer && /* @__PURE__ */ React9.createElement(TableFooter, null));
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));
824
899
  };
825
- var UnvirtualizedTableContent = () => {
826
- const { table } = useTableContext();
827
- const centerRows = table.getCenterRows();
828
- const pinnedRows = table.getBottomRows();
829
- const rows = [
830
- ...centerRows,
831
- ...pinnedRows
832
- ];
833
- return /* @__PURE__ */ React9.createElement(TableBody, {
834
- rows
835
- });
836
- };
837
- var VirtualizedTableContent = ({ getScrollElement }) => {
900
+ var VirtualizedTableContent = () => {
838
901
  const { table } = useTableContext();
902
+ const { virtualizer, dispatch } = useContext3(TableRootContext);
839
903
  const centerRows = table.getCenterRows();
840
904
  let pinnedRows = [];
905
+ useEffect3(() => {
906
+ dispatch({
907
+ type: "updateTableCount",
908
+ count: centerRows.length
909
+ });
910
+ }, [
911
+ centerRows.length
912
+ ]);
841
913
  try {
842
914
  pinnedRows = table.getBottomRows();
843
915
  } catch (_) {
844
916
  }
845
- const { getTotalSize, getVirtualItems } = useVirtualizer({
846
- getScrollElement,
847
- count: centerRows.length,
848
- overscan: 8,
849
- estimateSize: () => 40
850
- });
917
+ const { getTotalSize, getVirtualItems } = virtualizer;
851
918
  const virtualRows = getVirtualItems();
852
919
  const totalSize = getTotalSize();
853
920
  const paddingTop = virtualRows.length > 0 ? virtualRows?.[0]?.start || 0 : 0;
@@ -855,8 +922,8 @@ var VirtualizedTableContent = ({ getScrollElement }) => {
855
922
  const rowsToRender = [
856
923
  ...virtualRows.map((virtualRow) => centerRows[virtualRow.index]),
857
924
  ...pinnedRows
858
- ];
859
- 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", {
860
927
  role: "none"
861
928
  }, /* @__PURE__ */ React9.createElement("tr", {
862
929
  role: "none"
@@ -893,6 +960,11 @@ var GroupedTableContent = () => {
893
960
  }));
894
961
  }));
895
962
  };
963
+ var Table = {
964
+ Root: TableRoot,
965
+ Table: TablePrimitive,
966
+ Viewport: TableViewport
967
+ };
896
968
 
897
969
  // packages/ui/react-ui-table/src/helpers.tsx
898
970
  import { useFocusFinders } from "@fluentui/react-tabster";
@@ -900,11 +972,11 @@ import { Check as Check2, ClipboardText, X as X3 } from "@phosphor-icons/react";
900
972
  import { createColumnHelper } from "@tanstack/react-table";
901
973
  import { format } from "date-fns/format";
902
974
  import { formatDistanceToNow } from "date-fns/formatDistanceToNow";
903
- import React10, { useEffect as useEffect3, useRef as useRef3, useState as useState7 } from "react";
904
- 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";
905
977
  import { Input as Input2, Tooltip } from "@dxos/react-ui";
906
- import { getSize as getSize4, mx as mx5 } from "@dxos/react-ui-theme";
907
- 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";
908
980
  var createColumnBuilder = () => ({
909
981
  helper: createColumnHelper(),
910
982
  builder: new ColumnBuilder()
@@ -918,16 +990,19 @@ var ComboboxBuilderCell = (cellContext) => {
918
990
  }) : null;
919
991
  };
920
992
  var StringBuilderCell = (cellContext) => {
921
- const ref = useRef3(null);
993
+ const ref = useRef4(null);
922
994
  const { findPrevFocusable } = useFocusFinders();
923
995
  const { onUpdate, cell } = cellContext.column.columnDef.meta;
924
996
  const initialValue = cellContext.getValue();
925
- const [value, setValue] = useState7(() => {
926
- if (initialValue?.content) {
927
- return initialValue?.content;
928
- }
929
- return initialValue;
930
- });
997
+ const getInitialValue = useCallback7(() => {
998
+ return initialValue?.content ?? initialValue;
999
+ }, [
1000
+ initialValue
1001
+ ]);
1002
+ const [value, setValue] = useState9(getInitialValue);
1003
+ useEffect4(() => setValue(getInitialValue()), [
1004
+ getInitialValue
1005
+ ]);
931
1006
  const handleSave = () => {
932
1007
  ref.current && document.activeElement === ref.current && findPrevFocusable(ref.current)?.focus();
933
1008
  if (value !== initialValue) {
@@ -964,10 +1039,10 @@ var displayNumber = (value, digits) => value || value === 0 ? value.toLocaleStri
964
1039
  var NumberBuilderCell = (cellContext) => {
965
1040
  const { onUpdate, digits } = cellContext.column.columnDef.meta;
966
1041
  const value = cellContext.getValue();
967
- const [text, setText] = useState7(displayNumber(value, digits));
1042
+ const [text, setText] = useState9(displayNumber(value, digits));
968
1043
  const { findPrevFocusable } = useFocusFinders();
969
- const ref = useRef3(null);
970
- useEffect3(() => {
1044
+ const ref = useRef4(null);
1045
+ useEffect4(() => {
971
1046
  (!document.activeElement || document.activeElement !== ref.current) && setText(displayNumber(value, digits));
972
1047
  }, [
973
1048
  digits,
@@ -1054,7 +1129,7 @@ var ColumnBuilder = class {
1054
1129
  cell: model && onUpdate ? ComboboxBuilderCell : (cellContext) => {
1055
1130
  const cellValue = cellContext.getValue();
1056
1131
  return /* @__PURE__ */ React10.createElement("div", {
1057
- className: mx5("truncate", classNames)
1132
+ className: mx6("truncate", classNames)
1058
1133
  }, cellValue ? model?.getText(cellValue) : "");
1059
1134
  },
1060
1135
  ...props,
@@ -1085,7 +1160,7 @@ var ColumnBuilder = class {
1085
1160
  value = value.content;
1086
1161
  }
1087
1162
  return /* @__PURE__ */ React10.createElement("div", {
1088
- className: mx5("truncate", textPadding, classNames)
1163
+ className: mx6("truncate", textPadding, classNames)
1089
1164
  }, value);
1090
1165
  },
1091
1166
  ...props,
@@ -1139,14 +1214,14 @@ var ColumnBuilder = class {
1139
1214
  addSuffix: true
1140
1215
  }) : value.toISOString() : void 0;
1141
1216
  return /* @__PURE__ */ React10.createElement("div", {
1142
- className: mx5(textPadding, classNames)
1217
+ className: mx6(textPadding, classNames)
1143
1218
  }, str);
1144
1219
  } catch (err) {
1145
- log2.info("formatError", {
1220
+ log.info("formatError", {
1146
1221
  value
1147
1222
  }, {
1148
- F: __dxlog_file2,
1149
- L: 374,
1223
+ F: __dxlog_file,
1224
+ L: 376,
1150
1225
  S: this,
1151
1226
  C: (f, a) => f(...a)
1152
1227
  });
@@ -1278,11 +1353,11 @@ var ColumnBuilder = class {
1278
1353
  const value = cell.getValue();
1279
1354
  if (value) {
1280
1355
  return /* @__PURE__ */ React10.createElement(IconOn, {
1281
- 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")
1282
1357
  });
1283
1358
  } else if (value === false) {
1284
1359
  return /* @__PURE__ */ React10.createElement(IconOff, {
1285
- 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")
1286
1361
  });
1287
1362
  } else {
1288
1363
  return null;
@@ -1451,6 +1526,8 @@ export {
1451
1526
  MemoizedVirtualisedTableContent,
1452
1527
  SortIndicator,
1453
1528
  Table,
1529
+ TablePrimitive,
1530
+ TableRootContext,
1454
1531
  createColumnBuilder,
1455
1532
  currentRow,
1456
1533
  flushPadding,
@@ -1473,7 +1550,10 @@ export {
1473
1550
  theadTh,
1474
1551
  theadTr,
1475
1552
  translations_default as translations,
1553
+ useColumnResizing,
1476
1554
  useColumnSorting,
1477
- usePinLastRow
1555
+ usePinLastRow,
1556
+ useRowSelection,
1557
+ useTableRootContext
1478
1558
  };
1479
1559
  //# sourceMappingURL=index.mjs.map