@skygraph/react 0.5.3 → 0.6.4

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.
package/dist/table.cjs CHANGED
@@ -1741,14 +1741,11 @@ function TableBody(props) {
1741
1741
  onContextMenu({ x: e.clientX, y: e.clientY, items });
1742
1742
  }
1743
1743
  };
1744
- const handleCellCopy = (0, import_react9.useCallback)(
1745
- async (rowId, colKey, value) => {
1746
- await copyToClipboard(String(value ?? ""));
1747
- setCopiedCell(`${rowId}:${colKey}`);
1748
- setTimeout(() => setCopiedCell(null), 1500);
1749
- },
1750
- []
1751
- );
1744
+ const handleCellCopy = (0, import_react9.useCallback)(async (rowId, colKey, value) => {
1745
+ await copyToClipboard(String(value ?? ""));
1746
+ setCopiedCell(`${rowId}:${colKey}`);
1747
+ setTimeout(() => setCopiedCell(null), 1500);
1748
+ }, []);
1752
1749
  if (flatRows.length === 0) {
1753
1750
  return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1754
1751
  "div",
@@ -1813,7 +1810,13 @@ function TableBody(props) {
1813
1810
  {
1814
1811
  className: "sg-table-td sg-table-cell-drag-handle",
1815
1812
  role: "cell",
1816
- style: { cursor: "grab", userSelect: "none", display: "flex", alignItems: "center", justifyContent: "center" },
1813
+ style: {
1814
+ cursor: "grab",
1815
+ userSelect: "none",
1816
+ display: "flex",
1817
+ alignItems: "center",
1818
+ justifyContent: "center"
1819
+ },
1817
1820
  children: "\u283F"
1818
1821
  }
1819
1822
  ),
@@ -1825,10 +1828,24 @@ function TableBody(props) {
1825
1828
  role: "cell",
1826
1829
  onClick: (e) => {
1827
1830
  e.stopPropagation();
1828
- onSelectRow(row.id, row.data);
1831
+ if (e.target === e.currentTarget) {
1832
+ onSelectRow(row.id, row.data);
1833
+ }
1829
1834
  },
1830
- children: rowSelection.type === "radio" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("input", { type: "radio", checked: !!isSelected, readOnly: true }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Checkbox, { checked: !!isSelected, onChange: () => {
1831
- } })
1835
+ children: rowSelection.type === "radio" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1836
+ "input",
1837
+ {
1838
+ type: "radio",
1839
+ checked: !!isSelected,
1840
+ onChange: () => onSelectRow(row.id, row.data)
1841
+ }
1842
+ ) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1843
+ Checkbox,
1844
+ {
1845
+ checked: !!isSelected,
1846
+ onChange: () => onSelectRow(row.id, row.data)
1847
+ }
1848
+ )
1832
1849
  }
1833
1850
  ),
1834
1851
  expandable && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: "sg-table-td sg-table-cell-expand", role: "cell", children: canExpand && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
@@ -1851,10 +1868,8 @@ function TableBody(props) {
1851
1868
  const isFocused = keyboardNavigation && focusedCell?.row === rowIdx && focusedCell?.col === colIndex;
1852
1869
  const isCopied = copiedCell === cellKey;
1853
1870
  const cellStyle = { ...fixedStyle(col) };
1854
- if (span?.colSpan && span.colSpan > 1)
1855
- cellStyle.gridColumn = `span ${span.colSpan}`;
1856
- if (span?.rowSpan && span.rowSpan > 1)
1857
- cellStyle.gridRow = `span ${span.rowSpan}`;
1871
+ if (span?.colSpan && span.colSpan > 1) cellStyle.gridColumn = `span ${span.colSpan}`;
1872
+ if (span?.rowSpan && span.rowSpan > 1) cellStyle.gridRow = `span ${span.rowSpan}`;
1858
1873
  const isFirstCol = colIndex === 0;
1859
1874
  const treeIndent = isTreeMode && isFirstCol ? row.depth * indentSize : 0;
1860
1875
  const cellClsExtra = typeof col.cellClassName === "function" ? col.cellClassName(val, row.data, row.id) : col.cellClassName ?? "";
@@ -2868,6 +2883,13 @@ function useTableState(props) {
2868
2883
  [table, refresh]
2869
2884
  );
2870
2885
  const resizeRef = (0, import_react13.useRef)(null);
2886
+ const resizeCleanupRef = (0, import_react13.useRef)(null);
2887
+ (0, import_react13.useEffect)(
2888
+ () => () => {
2889
+ resizeCleanupRef.current?.();
2890
+ },
2891
+ []
2892
+ );
2871
2893
  const [contextMenu, setContextMenu] = (0, import_react13.useState)(null);
2872
2894
  const columns = (0, import_react13.useMemo)(() => {
2873
2895
  const base = hasColumnGroups ? leafColumns : (() => {
@@ -2993,9 +3015,8 @@ function useTableState(props) {
2993
3015
  );
2994
3016
  const handleToggleExpand = (id) => {
2995
3017
  const open = expandedKeys.has(id);
2996
- if (expandable?.onExpand) {
2997
- expandable.onExpand(!open, id);
2998
- } else {
3018
+ expandable?.onExpand?.(!open, id);
3019
+ if (expandable?.expandedKeys == null) {
2999
3020
  setInternalExpanded((prev) => {
3000
3021
  const next = new Set(prev);
3001
3022
  if (open) {
@@ -3071,28 +3092,34 @@ function useTableState(props) {
3071
3092
  const handleResizeStart = (e, colKey) => {
3072
3093
  e.preventDefault();
3073
3094
  e.stopPropagation();
3095
+ resizeCleanupRef.current?.();
3074
3096
  resizeRef.current = {
3075
3097
  col: colKey,
3076
3098
  startX: e.clientX,
3077
3099
  startW: colWidths[colKey] ?? DEFAULT_COL_WIDTH
3078
3100
  };
3079
3101
  const onMove = (ev) => {
3080
- if (!resizeRef.current) return;
3081
- const diff = ev.clientX - resizeRef.current.startX;
3082
- const min = leafColumns.find((c) => c.key === resizeRef.current.col)?.minWidth ?? MIN_COL_WIDTH;
3102
+ const ref = resizeRef.current;
3103
+ if (!ref) return;
3104
+ const diff = ev.clientX - ref.startX;
3105
+ const min = leafColumns.find((c) => c.key === ref.col)?.minWidth ?? MIN_COL_WIDTH;
3106
+ const nextWidth = Math.max(min, ref.startW + diff);
3107
+ const col = ref.col;
3083
3108
  setColWidths((prev) => ({
3084
3109
  ...prev,
3085
- [resizeRef.current.col]: Math.max(min, resizeRef.current.startW + diff)
3110
+ [col]: nextWidth
3086
3111
  }));
3087
- setUserResizedCols(
3088
- (prev) => prev.has(resizeRef.current.col) ? prev : new Set(prev).add(resizeRef.current.col)
3089
- );
3112
+ setUserResizedCols((prev) => prev.has(col) ? prev : new Set(prev).add(col));
3090
3113
  };
3091
- const onUp = () => {
3092
- const ref = resizeRef.current;
3114
+ const cleanup = () => {
3093
3115
  resizeRef.current = null;
3094
3116
  document.removeEventListener("mousemove", onMove);
3095
3117
  document.removeEventListener("mouseup", onUp);
3118
+ resizeCleanupRef.current = null;
3119
+ };
3120
+ const onUp = () => {
3121
+ const ref = resizeRef.current;
3122
+ cleanup();
3096
3123
  if (!ref) return;
3097
3124
  setColWidths((prev) => {
3098
3125
  const w = prev[ref.col];
@@ -3100,6 +3127,7 @@ function useTableState(props) {
3100
3127
  return prev;
3101
3128
  });
3102
3129
  };
3130
+ resizeCleanupRef.current = cleanup;
3103
3131
  document.addEventListener("mousemove", onMove);
3104
3132
  document.addEventListener("mouseup", onUp);
3105
3133
  };
@@ -3120,13 +3148,11 @@ function useTableState(props) {
3120
3148
  setDragOver(null);
3121
3149
  return;
3122
3150
  }
3123
- setColOrder((prev) => {
3124
- const next = prev.filter((k) => k !== dragCol);
3125
- const idx = next.indexOf(targetKey);
3126
- next.splice(idx, 0, dragCol);
3127
- onColumnOrderChange?.(next);
3128
- return next;
3129
- });
3151
+ const next = colOrder.filter((k) => k !== dragCol);
3152
+ const idx = next.indexOf(targetKey);
3153
+ next.splice(idx, 0, dragCol);
3154
+ setColOrder(next);
3155
+ onColumnOrderChange?.(next);
3130
3156
  setDragCol(null);
3131
3157
  setDragOver(null);
3132
3158
  };
@@ -3157,31 +3183,24 @@ function useTableState(props) {
3157
3183
  }));
3158
3184
  table.groupBy(groupBy, aggregates2);
3159
3185
  }, [groupBy, leafColumns, table]);
3160
- const [expandedGroups, setExpandedGroups] = (0, import_react13.useState)(() => {
3161
- return defaultGroupExpanded ? /* @__PURE__ */ new Set(["__all__"]) : /* @__PURE__ */ new Set();
3162
- });
3186
+ const [expandedGroups, setExpandedGroups] = (0, import_react13.useState)(() => /* @__PURE__ */ new Set());
3187
+ const allGroupKeysRef = (0, import_react13.useRef)([]);
3188
+ const groupsSeededRef = (0, import_react13.useRef)(false);
3163
3189
  const toggleGroupExpand = (0, import_react13.useCallback)(
3164
3190
  (groupKey) => {
3191
+ const willExpand = !expandedGroups.has(groupKey);
3165
3192
  setExpandedGroups((prev) => {
3166
3193
  const next = new Set(prev);
3167
- const wasExpanded = next.has(groupKey);
3168
- if (wasExpanded) {
3169
- next.delete(groupKey);
3170
- } else {
3171
- next.add(groupKey);
3172
- }
3173
- onGroupExpandChange?.(groupKey, !wasExpanded);
3194
+ if (next.has(groupKey)) next.delete(groupKey);
3195
+ else next.add(groupKey);
3174
3196
  return next;
3175
3197
  });
3198
+ onGroupExpandChange?.(groupKey, willExpand);
3176
3199
  },
3177
- [onGroupExpandChange]
3200
+ [onGroupExpandChange, expandedGroups]
3178
3201
  );
3179
3202
  const expandAllGroups = (0, import_react13.useCallback)(() => {
3180
- setExpandedGroups((prev) => {
3181
- const next = new Set(prev);
3182
- next.add("__all__");
3183
- return next;
3184
- });
3203
+ setExpandedGroups(new Set(allGroupKeysRef.current));
3185
3204
  }, []);
3186
3205
  const collapseAllGroups = (0, import_react13.useCallback)(() => {
3187
3206
  setExpandedGroups(/* @__PURE__ */ new Set());
@@ -3274,11 +3293,32 @@ function useTableState(props) {
3274
3293
  }
3275
3294
  return flattenTreeRows(visibleRows, childrenKey, treeExpanded);
3276
3295
  }, [visibleRows, isTreeMode, childrenKey, treeExpanded]);
3296
+ const allGroupKeys = (0, import_react13.useMemo)(() => {
3297
+ if (!groupBy) return [];
3298
+ const seen = /* @__PURE__ */ new Set();
3299
+ const keys = [];
3300
+ for (const r of baseFlatRows) {
3301
+ const k = String(r.data[groupBy] ?? "Other");
3302
+ if (!seen.has(k)) {
3303
+ seen.add(k);
3304
+ keys.push(k);
3305
+ }
3306
+ }
3307
+ return keys;
3308
+ }, [baseFlatRows, groupBy]);
3309
+ allGroupKeysRef.current = allGroupKeys;
3310
+ (0, import_react13.useEffect)(() => {
3311
+ groupsSeededRef.current = false;
3312
+ }, [groupBy]);
3313
+ (0, import_react13.useEffect)(() => {
3314
+ if (!groupBy || !defaultGroupExpanded) return;
3315
+ if (groupsSeededRef.current || allGroupKeys.length === 0) return;
3316
+ groupsSeededRef.current = true;
3317
+ setExpandedGroups(new Set(allGroupKeys));
3318
+ }, [groupBy, defaultGroupExpanded, allGroupKeys]);
3277
3319
  const groupedRows = (0, import_react13.useMemo)(() => {
3278
3320
  if (!groupBy) return baseFlatRows;
3279
- const allExpanded = expandedGroups.has("__all__");
3280
- const effectiveExpanded = allExpanded ? /* @__PURE__ */ new Set([...expandedGroups, ...baseFlatRows.map((r) => String(r.data[groupBy] ?? "Other"))]) : expandedGroups;
3281
- return groupByColumn(baseFlatRows, groupBy, columns, effectiveExpanded);
3321
+ return groupByColumn(baseFlatRows, groupBy, columns, expandedGroups);
3282
3322
  }, [baseFlatRows, groupBy, columns, expandedGroups]);
3283
3323
  const {
3284
3324
  top: pinnedTop,