@dxos/react-ui-table 0.4.7 → 0.4.8-main.00e6f19

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 (29) hide show
  1. package/dist/lib/browser/index.mjs +70 -54
  2. package/dist/lib/browser/index.mjs.map +3 -3
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/types/src/components/Cell/Cell.d.ts.map +1 -1
  5. package/dist/types/src/components/Cell/CellCombobox.d.ts +0 -1
  6. package/dist/types/src/components/Cell/CellCombobox.d.ts.map +1 -1
  7. package/dist/types/src/components/ColumnMenu.d.ts +0 -1
  8. package/dist/types/src/components/ColumnMenu.d.ts.map +1 -1
  9. package/dist/types/src/components/ColumnMenu.stories.d.ts +0 -1
  10. package/dist/types/src/components/ColumnMenu.stories.d.ts.map +1 -1
  11. package/dist/types/src/components/Table/Table.d.ts +2 -1
  12. package/dist/types/src/components/Table/Table.d.ts.map +1 -1
  13. package/dist/types/src/components/Table/Table.stories.d.ts +0 -1
  14. package/dist/types/src/components/Table/Table.stories.d.ts.map +1 -1
  15. package/dist/types/src/components/Table/TableBody.d.ts +0 -1
  16. package/dist/types/src/components/Table/TableBody.d.ts.map +1 -1
  17. package/dist/types/src/components/Table/TableFooter.d.ts +0 -1
  18. package/dist/types/src/components/Table/TableFooter.d.ts.map +1 -1
  19. package/dist/types/src/components/Table/TableHead.d.ts +0 -1
  20. package/dist/types/src/components/Table/TableHead.d.ts.map +1 -1
  21. package/dist/types/src/helpers.d.ts.map +1 -1
  22. package/dist/types/src/theme.d.ts +1 -1
  23. package/dist/types/src/theme.d.ts.map +1 -1
  24. package/package.json +14 -14
  25. package/src/components/Cell/Cell.tsx +4 -1
  26. package/src/components/Table/Table.stories.tsx +53 -64
  27. package/src/components/Table/Table.tsx +35 -36
  28. package/src/helpers.tsx +50 -42
  29. package/src/theme.ts +3 -1
@@ -196,6 +196,7 @@ import { useVirtualizer } from "@tanstack/react-virtual";
196
196
  import React6, { Fragment, useCallback, useEffect, useState as useState2 } from "react";
197
197
  import { debounce } from "@dxos/async";
198
198
  import { log } from "@dxos/log";
199
+ import { useDefaultValue } from "@dxos/react-ui";
199
200
 
200
201
  // packages/ui/react-ui-table/src/components/Table/TableBody.tsx
201
202
  import { useArrowNavigationGroup } from "@fluentui/react-tabster";
@@ -215,7 +216,7 @@ var selectedRow = "!bg-primary-100 dark:!bg-primary-700";
215
216
  var flushPadding = "pli-0 plb-0";
216
217
  var textPadding = "pli-2 plb-0.5";
217
218
  var headPadding = "pli-2 plb-1.5";
218
- var gridCellFocusRing = "focus:z-[11] focus:outline outline-2 outline-primary-500 dark:outline-primary-400";
219
+ var gridCellFocusRing = "focus-within:z-[11] focus-within:outline outline-2 outline-primary-500 dark:outline-primary-400";
219
220
  var tableRoot = ({ fullWidth }, ...etc) => mx2("table-fixed", fullWidth && "is-full", ...etc);
220
221
  var groupTh = (_props, ...etc) => mx2("text-start font-medium", flushPadding, ...etc);
221
222
  var theadRoot = ({ header, stickyHeader }, ...etc) => mx2(header ? stickyHeader && "sticky block-start-[--sticky-top] z-[1]" : "collapse", header && fixedSurface, ...etc);
@@ -240,10 +241,11 @@ var FocusableCell = ({ cell, children }) => {
240
241
  const domAttributes = useFocusableGroup({
241
242
  tabBehavior: "limited"
242
243
  });
244
+ const className = tdRoot(tableContext, cell.column.columnDef.meta?.cell?.classNames);
243
245
  return /* @__PURE__ */ React2.createElement("td", {
244
246
  tabIndex: 0,
245
247
  ...domAttributes,
246
- className: tdRoot(tableContext, cell.column.columnDef.meta?.cell?.classNames)
248
+ className
247
249
  }, children);
248
250
  };
249
251
  var StaticCell = ({ cell, children }) => {
@@ -379,7 +381,9 @@ TableHead.displayName = TABLE_HEAD_NAME;
379
381
  // packages/ui/react-ui-table/src/components/Table/Table.tsx
380
382
  var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-table/src/components/Table/Table.tsx";
381
383
  var Table = (props) => {
382
- const { role, data = [], columns = [], onColumnResize, columnVisibility, header = true, rowsSelectable, debug, onDataSelectionChange, getScrollElement } = props;
384
+ const { role, onColumnResize, columnVisibility, header = true, rowsSelectable, debug, onDataSelectionChange, getScrollElement } = props;
385
+ const columns = useDefaultValue(props.columns, []);
386
+ const data = useDefaultValue(props.data, []);
383
387
  const TableProvider2 = TableProvider;
384
388
  const [columnSizing, setColumnSizing] = useState2({});
385
389
  useEffect(() => {
@@ -388,28 +392,15 @@ var Table = (props) => {
388
392
  return state;
389
393
  }, {}));
390
394
  }, [
391
- columns
395
+ columns,
396
+ setColumnSizing
392
397
  ]);
393
398
  const [columnSizingInfo, setColumnSizingInfo] = useState2({});
394
- const onColumnResizeDebounced = onColumnResize && debounce(onColumnResize, 1e3);
395
- useEffect(() => {
396
- if (columnSizingInfo.columnSizingStart?.length === 0) {
397
- onColumnResizeDebounced?.(table.getState().columnSizing);
398
- }
399
- }, [
400
- columnSizingInfo
401
- ]);
402
399
  const [rowSelection = {}, setRowSelection] = useControllableState({
403
400
  prop: props.rowSelection,
404
401
  onChange: props.onRowSelectionChange,
405
402
  defaultProp: props.defaultRowSelection
406
403
  });
407
- useEffect(() => {
408
- onDataSelectionChange?.(Object.keys(rowSelection).map((id) => table.getRowModel().rowsById[id].original));
409
- }, [
410
- onDataSelectionChange,
411
- rowSelection
412
- ]);
413
404
  const handleRowSelectionChange = useCallback((updaterOrValue) => {
414
405
  const nextRowSelection = typeof updaterOrValue === "function" ? updaterOrValue(rowSelection) : updaterOrValue;
415
406
  if (rowsSelectable === "multi") {
@@ -423,11 +414,13 @@ var Table = (props) => {
423
414
  setRowSelection({});
424
415
  }
425
416
  }, [
426
- rowSelection,
427
- setRowSelection
417
+ rowsSelectable,
418
+ setRowSelection,
419
+ rowSelection
428
420
  ]);
429
421
  const [grouping, handleGroupingChange] = useState2(props.grouping ?? []);
430
422
  useEffect(() => handleGroupingChange(props.grouping ?? []), [
423
+ handleGroupingChange,
431
424
  props.grouping
432
425
  ]);
433
426
  const table = useReactTable({
@@ -458,21 +451,35 @@ var Table = (props) => {
458
451
  // Grouping
459
452
  getGroupedRowModel: grouping.length > 1 ? getGroupedRowModel() : void 0,
460
453
  onGroupingChange: handleGroupingChange,
461
- // Selection
462
- ...rowsSelectable === "multi" ? {
463
- enableMultiRowSelection: true
464
- } : rowsSelectable ? {
465
- enableRowSelection: true
466
- } : {},
454
+ enableMultiRowSelection: rowsSelectable === "multi" ? true : void 0,
455
+ enableRowSelection: rowsSelectable === true ? true : void 0,
467
456
  onRowSelectionChange: handleRowSelectionChange,
468
457
  // Debug
469
458
  debugTable: debug
470
459
  });
460
+ const onColumnResizeDebounced = onColumnResize && debounce(onColumnResize, 1e3);
461
+ useEffect(() => {
462
+ onDataSelectionChange?.(Object.keys(rowSelection).map((id) => table.getRowModel().rowsById[id].original));
463
+ }, [
464
+ onDataSelectionChange,
465
+ rowSelection,
466
+ table
467
+ ]);
468
+ useEffect(() => {
469
+ const shouldTriggerResize = columnSizingInfo.columnSizingStart?.length === 0;
470
+ if (shouldTriggerResize) {
471
+ onColumnResizeDebounced?.(table.getState().columnSizing);
472
+ }
473
+ }, [
474
+ columnSizingInfo,
475
+ onColumnResizeDebounced,
476
+ table
477
+ ]);
471
478
  const expand = false;
472
479
  if (!getScrollElement) {
473
480
  log.warn("Table: getScrollElement is not set. This is required for virtualized tables.", void 0, {
474
481
  F: __dxlog_file,
475
- L: 159,
482
+ L: 148,
476
483
  S: void 0,
477
484
  C: (f, a) => f(...a)
478
485
  });
@@ -498,6 +505,7 @@ var TableImpl = (props) => {
498
505
  className: "font-mono text-xs text-neutral-500 m-1 p-2 ring"
499
506
  }, /* @__PURE__ */ React6.createElement("code", null, JSON.stringify(table.getState(), void 0, 2)));
500
507
  }
508
+ const isResizingColumn = table.getState().columnSizingInfo.isResizingColumn;
501
509
  return /* @__PURE__ */ React6.createElement("table", {
502
510
  role,
503
511
  className: tableRoot(props, classNames),
@@ -506,7 +514,9 @@ var TableImpl = (props) => {
506
514
  width: table.getTotalSize()
507
515
  }
508
516
  }
509
- }, /* @__PURE__ */ React6.createElement(TableHead, null), grouping?.length !== 0 ? getScrollElement ? /* @__PURE__ */ React6.createElement(VirtualizedTableContent, {
517
+ }, /* @__PURE__ */ React6.createElement(TableHead, null), grouping?.length !== 0 ? getScrollElement ? isResizingColumn ? /* @__PURE__ */ React6.createElement(MemoizedVirtualisedTableContent, {
518
+ getScrollElement
519
+ }) : /* @__PURE__ */ React6.createElement(VirtualizedTableContent, {
510
520
  getScrollElement
511
521
  }) : /* @__PURE__ */ React6.createElement(TableBody, {
512
522
  rows
@@ -547,6 +557,7 @@ var VirtualizedTableContent = ({ getScrollElement }) => {
547
557
  role: "none"
548
558
  }))));
549
559
  };
560
+ var MemoizedVirtualisedTableContent = /* @__PURE__ */ React6.memo(VirtualizedTableContent);
550
561
  var GroupedTableContent = () => {
551
562
  const { table: { getGroupedRowModel: getGroupedRowModel2, getHeaderGroups, getState }, debug } = useTableContext("GroupedTableContent");
552
563
  return /* @__PURE__ */ React6.createElement(React6.Fragment, null, getGroupedRowModel2().rows.map((row, i) => {
@@ -655,8 +666,9 @@ var ComboboxBuilderCell = (cellContext) => {
655
666
  }) : null;
656
667
  };
657
668
  var StringBuilderCell = (cellContext) => {
658
- const inputRef = useRef2(null);
659
- const { onUpdate } = cellContext.column.columnDef.meta;
669
+ const ref = useRef2(null);
670
+ const { findPrevFocusable } = useFocusFinders();
671
+ const { onUpdate, cell } = cellContext.column.columnDef.meta;
660
672
  const initialValue = cellContext.getValue();
661
673
  const [value, setValue] = useState4(() => {
662
674
  if (initialValue?.content) {
@@ -665,27 +677,26 @@ var StringBuilderCell = (cellContext) => {
665
677
  return initialValue;
666
678
  });
667
679
  const handleSave = () => {
668
- if (value === initialValue) {
669
- return;
680
+ ref.current && document.activeElement === ref.current && findPrevFocusable(ref.current)?.focus();
681
+ if (value !== initialValue) {
682
+ onUpdate?.(cellContext.row.original, cellContext.column.id, value);
670
683
  }
671
- onUpdate?.(cellContext.row.original, cellContext.column.id, value);
672
- };
673
- const handleCancel = () => {
674
- setValue(initialValue);
675
684
  };
685
+ const handleCancel = () => setValue(initialValue);
676
686
  const rows = cellContext.table.getRowModel().flatRows;
677
687
  const columns = cellContext.table.getVisibleFlatColumns();
678
688
  const placeholder = cellContext.row.index === rows.length - 1 && columns[0].id === cellContext.column.id;
679
689
  return /* @__PURE__ */ React8.createElement(Input2.Root, null, /* @__PURE__ */ React8.createElement(Input2.TextInput, {
680
- ref: inputRef,
690
+ ref,
681
691
  variant: "subdued",
682
692
  placeholder: placeholder ? "Add row..." : void 0,
683
693
  classNames: [
684
694
  "is-full",
685
- textPadding
695
+ textPadding,
696
+ cell?.classNames
686
697
  ],
687
698
  value: value ?? "",
688
- onBlur: () => handleSave(),
699
+ onBlur: handleSave,
689
700
  onChange: (event) => setValue(event.target.value),
690
701
  onKeyDown: (event) => event.key === "Enter" && handleSave() || event.key === "Escape" && handleCancel()
691
702
  }));
@@ -707,15 +718,15 @@ var NumberBuilderCell = (cellContext) => {
707
718
  digits,
708
719
  value
709
720
  ]);
710
- const handleEdit = () => {
711
- if (onUpdate) {
712
- setText(value !== void 0 ? String(value) : "");
713
- }
714
- };
721
+ const handleEdit = () => setText(value !== void 0 ? String(value) : "");
715
722
  const handleSave = () => {
716
723
  const nextValue = parseNumber(text);
717
- onUpdate?.(cellContext.row.original, cellContext.column.id, isNaN(nextValue) ? void 0 : nextValue);
718
- setText(displayNumber(nextValue, digits));
724
+ if (!isNaN(nextValue)) {
725
+ onUpdate?.(cellContext.row.original, cellContext.column.id, nextValue);
726
+ setText(displayNumber(nextValue, digits));
727
+ } else {
728
+ setText(displayNumber(value, digits));
729
+ }
719
730
  ref.current && document.activeElement === ref.current && findPrevFocusable(ref.current)?.focus();
720
731
  };
721
732
  const _handleCancel = () => {
@@ -745,10 +756,12 @@ var RowSelectorBuilderCell = (cellContext) => {
745
756
  const { cell } = cellContext.column.columnDef.meta;
746
757
  const { row } = cellContext;
747
758
  const checked = row.getCanSelect() ? row.getIsSelected() : row.getCanSelectSubRows() && (row.getIsSomeSelected() ? "indeterminate" : row.getIsAllSubRowsSelected());
748
- return /* @__PURE__ */ React8.createElement(Input2.Root, null, /* @__PURE__ */ React8.createElement(Input2.Checkbox, {
759
+ return /* @__PURE__ */ React8.createElement("div", {
760
+ className: "flex justify-center w-full h-full",
761
+ role: "presentation"
762
+ }, /* @__PURE__ */ React8.createElement(Input2.Root, null, /* @__PURE__ */ React8.createElement(Input2.Checkbox, {
749
763
  size: 4,
750
764
  classNames: [
751
- "mli-auto",
752
765
  cell?.classNames
753
766
  ],
754
767
  checked,
@@ -758,7 +771,7 @@ var RowSelectorBuilderCell = (cellContext) => {
758
771
  }
759
772
  },
760
773
  disabled: !(row.getCanSelect() || row.getCanSelectSubRows())
761
- }));
774
+ })));
762
775
  };
763
776
  var SwitchBuilderCell = (cellContext) => {
764
777
  const { onUpdate } = cellContext.column.columnDef.meta;
@@ -879,7 +892,7 @@ var ColumnBuilder = class {
879
892
  value
880
893
  }, {
881
894
  F: __dxlog_file2,
882
- L: 363,
895
+ L: 370,
883
896
  S: this,
884
897
  C: (f, a) => f(...a)
885
898
  });
@@ -943,8 +956,7 @@ var ColumnBuilder = class {
943
956
  return {
944
957
  id,
945
958
  size: 32,
946
- minSize: 32,
947
- maxSize: 32,
959
+ enableResizing: false,
948
960
  meta: {
949
961
  onUpdate,
950
962
  cell: {
@@ -954,7 +966,10 @@ var ColumnBuilder = class {
954
966
  header: ({ table }) => {
955
967
  const { rowsSelectable } = useTableContext("HELPER_SELECT_ROW_HEADER_CELL");
956
968
  const checked = table.getIsSomeRowsSelected() ? "indeterminate" : table.getIsAllRowsSelected();
957
- return rowsSelectable === "multi" ? /* @__PURE__ */ React8.createElement(Input2.Root, null, /* @__PURE__ */ React8.createElement(Input2.Checkbox, {
969
+ return rowsSelectable === "multi" ? /* @__PURE__ */ React8.createElement("div", {
970
+ className: "flex justify-center w-full h-full",
971
+ role: "presentation"
972
+ }, /* @__PURE__ */ React8.createElement(Input2.Root, null, /* @__PURE__ */ React8.createElement(Input2.Checkbox, {
958
973
  size: 4,
959
974
  classNames: [
960
975
  "mli-auto",
@@ -962,7 +977,7 @@ var ColumnBuilder = class {
962
977
  ],
963
978
  checked,
964
979
  onCheckedChange: () => table.toggleAllRowsSelected()
965
- })) : null;
980
+ }))) : null;
966
981
  },
967
982
  cell: RowSelectorBuilderCell
968
983
  };
@@ -1024,6 +1039,7 @@ export {
1024
1039
  ColumnBuilder,
1025
1040
  ColumnMenu,
1026
1041
  ColumnPanel,
1042
+ MemoizedVirtualisedTableContent,
1027
1043
  Table,
1028
1044
  createColumnBuilder,
1029
1045
  currentRow,