@skygraph/react 0.5.2 → 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.
Files changed (51) hide show
  1. package/README.md +70 -70
  2. package/dist/{Table-BmesoMje.d.ts → Table-CAay8MmA.d.ts} +8 -1
  3. package/dist/{Table-CpKMOH2x.d.cts → Table-CMKo6Pc3.d.cts} +8 -1
  4. package/dist/{chunk-ZJF6SJLP.js → chunk-45YW5VSP.js} +44 -10
  5. package/dist/chunk-45YW5VSP.js.map +1 -0
  6. package/dist/{chunk-NXB3VAVF.js → chunk-7AA2JPZB.js} +148 -61
  7. package/dist/chunk-7AA2JPZB.js.map +1 -0
  8. package/dist/{chunk-Z5UGF7EO.js → chunk-EFDB2ENB.js} +87 -25
  9. package/dist/chunk-EFDB2ENB.js.map +1 -0
  10. package/dist/{chunk-UO6VJC3C.js → chunk-KGFFQGCM.js} +3 -3
  11. package/dist/{chunk-FSV73JI4.js → chunk-PEX2UTNG.js} +2 -2
  12. package/dist/chunk-VLRLCHEL.js +184 -0
  13. package/dist/chunk-VLRLCHEL.js.map +1 -0
  14. package/dist/{chunk-MLEBVELO.js → chunk-Y6XZ5TLD.js} +93 -47
  15. package/dist/chunk-Y6XZ5TLD.js.map +1 -0
  16. package/dist/{chunk-GJDDPZH7.js → chunk-ZJC2QUWA.js} +12 -12
  17. package/dist/chunk-ZJC2QUWA.js.map +1 -0
  18. package/dist/datagrid.cjs +76 -21
  19. package/dist/datagrid.cjs.map +1 -1
  20. package/dist/datagrid.js +3 -3
  21. package/dist/devtools.cjs +11 -11
  22. package/dist/devtools.cjs.map +1 -1
  23. package/dist/devtools.js +1 -1
  24. package/dist/form.cjs +168 -86
  25. package/dist/form.cjs.map +1 -1
  26. package/dist/form.d.cts +1 -1
  27. package/dist/form.d.ts +1 -1
  28. package/dist/form.js +3 -3
  29. package/dist/index.cjs +1549 -1021
  30. package/dist/index.cjs.map +1 -1
  31. package/dist/index.d.cts +157 -7
  32. package/dist/index.d.ts +157 -7
  33. package/dist/index.js +444 -231
  34. package/dist/index.js.map +1 -1
  35. package/dist/table.cjs +344 -221
  36. package/dist/table.cjs.map +1 -1
  37. package/dist/table.d.cts +1 -1
  38. package/dist/table.d.ts +1 -1
  39. package/dist/table.js +4 -4
  40. package/dist/tree.cjs.map +1 -1
  41. package/dist/tree.js +3 -3
  42. package/package.json +2 -2
  43. package/dist/chunk-2OCEO636.js +0 -91
  44. package/dist/chunk-2OCEO636.js.map +0 -1
  45. package/dist/chunk-GJDDPZH7.js.map +0 -1
  46. package/dist/chunk-MLEBVELO.js.map +0 -1
  47. package/dist/chunk-NXB3VAVF.js.map +0 -1
  48. package/dist/chunk-Z5UGF7EO.js.map +0 -1
  49. package/dist/chunk-ZJF6SJLP.js.map +0 -1
  50. /package/dist/{chunk-UO6VJC3C.js.map → chunk-KGFFQGCM.js.map} +0 -0
  51. /package/dist/{chunk-FSV73JI4.js.map → chunk-PEX2UTNG.js.map} +0 -0
@@ -2,14 +2,14 @@ import {
2
2
  Button,
3
3
  Input,
4
4
  Transition
5
- } from "./chunk-ZJF6SJLP.js";
5
+ } from "./chunk-45YW5VSP.js";
6
6
  import {
7
7
  Checkbox
8
- } from "./chunk-FSV73JI4.js";
8
+ } from "./chunk-PEX2UTNG.js";
9
9
  import {
10
10
  Spin,
11
11
  useConfig
12
- } from "./chunk-2OCEO636.js";
12
+ } from "./chunk-VLRLCHEL.js";
13
13
 
14
14
  // src/components/ui/Pagination.tsx
15
15
  import { useState } from "react";
@@ -53,6 +53,29 @@ function Pagination({
53
53
  }
54
54
  setJumpValue("");
55
55
  };
56
+ const handleKeyDown = (e) => {
57
+ if (disabled) return;
58
+ const tag = e.target.tagName;
59
+ if (tag === "INPUT" || tag === "SELECT") return;
60
+ switch (e.key) {
61
+ case "ArrowLeft":
62
+ e.preventDefault();
63
+ go(safeCurrentPage - 1);
64
+ break;
65
+ case "ArrowRight":
66
+ e.preventDefault();
67
+ go(safeCurrentPage + 1);
68
+ break;
69
+ case "Home":
70
+ e.preventDefault();
71
+ go(1);
72
+ break;
73
+ case "End":
74
+ e.preventDefault();
75
+ go(totalPages);
76
+ break;
77
+ }
78
+ };
56
79
  const pages = buildPages(safeCurrentPage, totalPages);
57
80
  const renderTotal = () => {
58
81
  if (!showTotal) return null;
@@ -103,12 +126,21 @@ function Pagination({
103
126
  ] });
104
127
  };
105
128
  if (unstyled) {
106
- return /* @__PURE__ */ jsxs("nav", { className, style, "aria-label": ariaLabel, children: [
107
- /* @__PURE__ */ jsx("button", { disabled: safeCurrentPage <= 1, onClick: () => go(safeCurrentPage - 1), children: "\u2039" }),
129
+ return /* @__PURE__ */ jsxs("nav", { className, style, "aria-label": ariaLabel, onKeyDown: handleKeyDown, children: [
130
+ /* @__PURE__ */ jsx(
131
+ "button",
132
+ {
133
+ type: "button",
134
+ disabled: safeCurrentPage <= 1,
135
+ onClick: () => go(safeCurrentPage - 1),
136
+ children: "\u2039"
137
+ }
138
+ ),
108
139
  pages.map(
109
140
  (p, i) => p === "..." ? /* @__PURE__ */ jsx("span", { children: "\u2026" }, `e${i}`) : /* @__PURE__ */ jsx(
110
141
  "button",
111
142
  {
143
+ type: "button",
112
144
  onClick: () => go(p),
113
145
  "aria-current": p === safeCurrentPage ? "page" : void 0,
114
146
  children: p
@@ -116,7 +148,15 @@ function Pagination({
116
148
  p
117
149
  )
118
150
  ),
119
- /* @__PURE__ */ jsx("button", { disabled: safeCurrentPage >= totalPages, onClick: () => go(safeCurrentPage + 1), children: "\u203A" })
151
+ /* @__PURE__ */ jsx(
152
+ "button",
153
+ {
154
+ type: "button",
155
+ disabled: safeCurrentPage >= totalPages,
156
+ onClick: () => go(safeCurrentPage + 1),
157
+ children: "\u203A"
158
+ }
159
+ )
120
160
  ] });
121
161
  }
122
162
  if (simple) {
@@ -130,10 +170,12 @@ function Pagination({
130
170
  ].filter(Boolean).join(" "),
131
171
  style,
132
172
  "aria-label": ariaLabel,
173
+ onKeyDown: handleKeyDown,
133
174
  children: [
134
175
  /* @__PURE__ */ jsx(
135
176
  "button",
136
177
  {
178
+ type: "button",
137
179
  className: "sg-pagination-item sg-pagination-prev",
138
180
  disabled: safeCurrentPage <= 1,
139
181
  onClick: () => go(safeCurrentPage - 1),
@@ -148,6 +190,7 @@ function Pagination({
148
190
  /* @__PURE__ */ jsx(
149
191
  "button",
150
192
  {
193
+ type: "button",
151
194
  className: "sg-pagination-item sg-pagination-next",
152
195
  disabled: safeCurrentPage >= totalPages,
153
196
  onClick: () => go(safeCurrentPage + 1),
@@ -164,11 +207,13 @@ function Pagination({
164
207
  className: ["sg-pagination", disabled ? "sg-pagination-disabled" : "", className].filter(Boolean).join(" "),
165
208
  style,
166
209
  "aria-label": ariaLabel,
210
+ onKeyDown: handleKeyDown,
167
211
  children: [
168
212
  renderTotal(),
169
213
  /* @__PURE__ */ jsx(
170
214
  "button",
171
215
  {
216
+ type: "button",
172
217
  className: "sg-pagination-item sg-pagination-prev",
173
218
  disabled: safeCurrentPage <= 1,
174
219
  onClick: () => go(safeCurrentPage - 1),
@@ -179,6 +224,7 @@ function Pagination({
179
224
  (p, i) => p === "..." ? /* @__PURE__ */ jsx("span", { className: "sg-pagination-ellipsis", children: "\u2026" }, `e${i}`) : /* @__PURE__ */ jsx(
180
225
  "button",
181
226
  {
227
+ type: "button",
182
228
  className: `sg-pagination-item${p === safeCurrentPage ? " sg-pagination-item-active" : ""}`,
183
229
  onClick: () => go(p),
184
230
  "aria-current": p === safeCurrentPage ? "page" : void 0,
@@ -190,6 +236,7 @@ function Pagination({
190
236
  /* @__PURE__ */ jsx(
191
237
  "button",
192
238
  {
239
+ type: "button",
193
240
  className: "sg-pagination-item sg-pagination-next",
194
241
  disabled: safeCurrentPage >= totalPages,
195
242
  onClick: () => go(safeCurrentPage + 1),
@@ -1549,14 +1596,11 @@ function TableBody(props) {
1549
1596
  onContextMenu({ x: e.clientX, y: e.clientY, items });
1550
1597
  }
1551
1598
  };
1552
- const handleCellCopy = useCallback2(
1553
- async (rowId, colKey, value) => {
1554
- await copyToClipboard(String(value ?? ""));
1555
- setCopiedCell(`${rowId}:${colKey}`);
1556
- setTimeout(() => setCopiedCell(null), 1500);
1557
- },
1558
- []
1559
- );
1599
+ const handleCellCopy = useCallback2(async (rowId, colKey, value) => {
1600
+ await copyToClipboard(String(value ?? ""));
1601
+ setCopiedCell(`${rowId}:${colKey}`);
1602
+ setTimeout(() => setCopiedCell(null), 1500);
1603
+ }, []);
1560
1604
  if (flatRows.length === 0) {
1561
1605
  return /* @__PURE__ */ jsx6(
1562
1606
  "div",
@@ -1621,7 +1665,13 @@ function TableBody(props) {
1621
1665
  {
1622
1666
  className: "sg-table-td sg-table-cell-drag-handle",
1623
1667
  role: "cell",
1624
- style: { cursor: "grab", userSelect: "none", display: "flex", alignItems: "center", justifyContent: "center" },
1668
+ style: {
1669
+ cursor: "grab",
1670
+ userSelect: "none",
1671
+ display: "flex",
1672
+ alignItems: "center",
1673
+ justifyContent: "center"
1674
+ },
1625
1675
  children: "\u283F"
1626
1676
  }
1627
1677
  ),
@@ -1633,10 +1683,24 @@ function TableBody(props) {
1633
1683
  role: "cell",
1634
1684
  onClick: (e) => {
1635
1685
  e.stopPropagation();
1636
- onSelectRow(row.id, row.data);
1686
+ if (e.target === e.currentTarget) {
1687
+ onSelectRow(row.id, row.data);
1688
+ }
1637
1689
  },
1638
- children: rowSelection.type === "radio" ? /* @__PURE__ */ jsx6("input", { type: "radio", checked: !!isSelected, readOnly: true }) : /* @__PURE__ */ jsx6(Checkbox, { checked: !!isSelected, onChange: () => {
1639
- } })
1690
+ children: rowSelection.type === "radio" ? /* @__PURE__ */ jsx6(
1691
+ "input",
1692
+ {
1693
+ type: "radio",
1694
+ checked: !!isSelected,
1695
+ onChange: () => onSelectRow(row.id, row.data)
1696
+ }
1697
+ ) : /* @__PURE__ */ jsx6(
1698
+ Checkbox,
1699
+ {
1700
+ checked: !!isSelected,
1701
+ onChange: () => onSelectRow(row.id, row.data)
1702
+ }
1703
+ )
1640
1704
  }
1641
1705
  ),
1642
1706
  expandable && /* @__PURE__ */ jsx6("div", { className: "sg-table-td sg-table-cell-expand", role: "cell", children: canExpand && /* @__PURE__ */ jsx6(
@@ -1659,10 +1723,8 @@ function TableBody(props) {
1659
1723
  const isFocused = keyboardNavigation && focusedCell?.row === rowIdx && focusedCell?.col === colIndex;
1660
1724
  const isCopied = copiedCell === cellKey;
1661
1725
  const cellStyle = { ...fixedStyle(col) };
1662
- if (span?.colSpan && span.colSpan > 1)
1663
- cellStyle.gridColumn = `span ${span.colSpan}`;
1664
- if (span?.rowSpan && span.rowSpan > 1)
1665
- cellStyle.gridRow = `span ${span.rowSpan}`;
1726
+ if (span?.colSpan && span.colSpan > 1) cellStyle.gridColumn = `span ${span.colSpan}`;
1727
+ if (span?.rowSpan && span.rowSpan > 1) cellStyle.gridRow = `span ${span.rowSpan}`;
1666
1728
  const isFirstCol = colIndex === 0;
1667
1729
  const treeIndent = isTreeMode && isFirstCol ? row.depth * indentSize : 0;
1668
1730
  const cellClsExtra = typeof col.cellClassName === "function" ? col.cellClassName(val, row.data, row.id) : col.cellClassName ?? "";
@@ -2510,6 +2572,13 @@ function useTableState(props) {
2510
2572
  [table, refresh]
2511
2573
  );
2512
2574
  const resizeRef = useRef6(null);
2575
+ const resizeCleanupRef = useRef6(null);
2576
+ useEffect6(
2577
+ () => () => {
2578
+ resizeCleanupRef.current?.();
2579
+ },
2580
+ []
2581
+ );
2513
2582
  const [contextMenu, setContextMenu] = useState7(null);
2514
2583
  const columns = useMemo3(() => {
2515
2584
  const base = hasColumnGroups ? leafColumns : (() => {
@@ -2635,9 +2704,8 @@ function useTableState(props) {
2635
2704
  );
2636
2705
  const handleToggleExpand = (id) => {
2637
2706
  const open = expandedKeys.has(id);
2638
- if (expandable?.onExpand) {
2639
- expandable.onExpand(!open, id);
2640
- } else {
2707
+ expandable?.onExpand?.(!open, id);
2708
+ if (expandable?.expandedKeys == null) {
2641
2709
  setInternalExpanded((prev) => {
2642
2710
  const next = new Set(prev);
2643
2711
  if (open) {
@@ -2713,28 +2781,34 @@ function useTableState(props) {
2713
2781
  const handleResizeStart = (e, colKey) => {
2714
2782
  e.preventDefault();
2715
2783
  e.stopPropagation();
2784
+ resizeCleanupRef.current?.();
2716
2785
  resizeRef.current = {
2717
2786
  col: colKey,
2718
2787
  startX: e.clientX,
2719
2788
  startW: colWidths[colKey] ?? DEFAULT_COL_WIDTH
2720
2789
  };
2721
2790
  const onMove = (ev) => {
2722
- if (!resizeRef.current) return;
2723
- const diff = ev.clientX - resizeRef.current.startX;
2724
- const min = leafColumns.find((c) => c.key === resizeRef.current.col)?.minWidth ?? MIN_COL_WIDTH;
2791
+ const ref = resizeRef.current;
2792
+ if (!ref) return;
2793
+ const diff = ev.clientX - ref.startX;
2794
+ const min = leafColumns.find((c) => c.key === ref.col)?.minWidth ?? MIN_COL_WIDTH;
2795
+ const nextWidth = Math.max(min, ref.startW + diff);
2796
+ const col = ref.col;
2725
2797
  setColWidths((prev) => ({
2726
2798
  ...prev,
2727
- [resizeRef.current.col]: Math.max(min, resizeRef.current.startW + diff)
2799
+ [col]: nextWidth
2728
2800
  }));
2729
- setUserResizedCols(
2730
- (prev) => prev.has(resizeRef.current.col) ? prev : new Set(prev).add(resizeRef.current.col)
2731
- );
2801
+ setUserResizedCols((prev) => prev.has(col) ? prev : new Set(prev).add(col));
2732
2802
  };
2733
- const onUp = () => {
2734
- const ref = resizeRef.current;
2803
+ const cleanup = () => {
2735
2804
  resizeRef.current = null;
2736
2805
  document.removeEventListener("mousemove", onMove);
2737
2806
  document.removeEventListener("mouseup", onUp);
2807
+ resizeCleanupRef.current = null;
2808
+ };
2809
+ const onUp = () => {
2810
+ const ref = resizeRef.current;
2811
+ cleanup();
2738
2812
  if (!ref) return;
2739
2813
  setColWidths((prev) => {
2740
2814
  const w = prev[ref.col];
@@ -2742,6 +2816,7 @@ function useTableState(props) {
2742
2816
  return prev;
2743
2817
  });
2744
2818
  };
2819
+ resizeCleanupRef.current = cleanup;
2745
2820
  document.addEventListener("mousemove", onMove);
2746
2821
  document.addEventListener("mouseup", onUp);
2747
2822
  };
@@ -2762,13 +2837,11 @@ function useTableState(props) {
2762
2837
  setDragOver(null);
2763
2838
  return;
2764
2839
  }
2765
- setColOrder((prev) => {
2766
- const next = prev.filter((k) => k !== dragCol);
2767
- const idx = next.indexOf(targetKey);
2768
- next.splice(idx, 0, dragCol);
2769
- onColumnOrderChange?.(next);
2770
- return next;
2771
- });
2840
+ const next = colOrder.filter((k) => k !== dragCol);
2841
+ const idx = next.indexOf(targetKey);
2842
+ next.splice(idx, 0, dragCol);
2843
+ setColOrder(next);
2844
+ onColumnOrderChange?.(next);
2772
2845
  setDragCol(null);
2773
2846
  setDragOver(null);
2774
2847
  };
@@ -2799,31 +2872,24 @@ function useTableState(props) {
2799
2872
  }));
2800
2873
  table.groupBy(groupBy, aggregates2);
2801
2874
  }, [groupBy, leafColumns, table]);
2802
- const [expandedGroups, setExpandedGroups] = useState7(() => {
2803
- return defaultGroupExpanded ? /* @__PURE__ */ new Set(["__all__"]) : /* @__PURE__ */ new Set();
2804
- });
2875
+ const [expandedGroups, setExpandedGroups] = useState7(() => /* @__PURE__ */ new Set());
2876
+ const allGroupKeysRef = useRef6([]);
2877
+ const groupsSeededRef = useRef6(false);
2805
2878
  const toggleGroupExpand = useCallback3(
2806
2879
  (groupKey) => {
2880
+ const willExpand = !expandedGroups.has(groupKey);
2807
2881
  setExpandedGroups((prev) => {
2808
2882
  const next = new Set(prev);
2809
- const wasExpanded = next.has(groupKey);
2810
- if (wasExpanded) {
2811
- next.delete(groupKey);
2812
- } else {
2813
- next.add(groupKey);
2814
- }
2815
- onGroupExpandChange?.(groupKey, !wasExpanded);
2883
+ if (next.has(groupKey)) next.delete(groupKey);
2884
+ else next.add(groupKey);
2816
2885
  return next;
2817
2886
  });
2887
+ onGroupExpandChange?.(groupKey, willExpand);
2818
2888
  },
2819
- [onGroupExpandChange]
2889
+ [onGroupExpandChange, expandedGroups]
2820
2890
  );
2821
2891
  const expandAllGroups = useCallback3(() => {
2822
- setExpandedGroups((prev) => {
2823
- const next = new Set(prev);
2824
- next.add("__all__");
2825
- return next;
2826
- });
2892
+ setExpandedGroups(new Set(allGroupKeysRef.current));
2827
2893
  }, []);
2828
2894
  const collapseAllGroups = useCallback3(() => {
2829
2895
  setExpandedGroups(/* @__PURE__ */ new Set());
@@ -2916,11 +2982,32 @@ function useTableState(props) {
2916
2982
  }
2917
2983
  return flattenTreeRows(visibleRows, childrenKey, treeExpanded);
2918
2984
  }, [visibleRows, isTreeMode, childrenKey, treeExpanded]);
2985
+ const allGroupKeys = useMemo3(() => {
2986
+ if (!groupBy) return [];
2987
+ const seen = /* @__PURE__ */ new Set();
2988
+ const keys = [];
2989
+ for (const r of baseFlatRows) {
2990
+ const k = String(r.data[groupBy] ?? "Other");
2991
+ if (!seen.has(k)) {
2992
+ seen.add(k);
2993
+ keys.push(k);
2994
+ }
2995
+ }
2996
+ return keys;
2997
+ }, [baseFlatRows, groupBy]);
2998
+ allGroupKeysRef.current = allGroupKeys;
2999
+ useEffect6(() => {
3000
+ groupsSeededRef.current = false;
3001
+ }, [groupBy]);
3002
+ useEffect6(() => {
3003
+ if (!groupBy || !defaultGroupExpanded) return;
3004
+ if (groupsSeededRef.current || allGroupKeys.length === 0) return;
3005
+ groupsSeededRef.current = true;
3006
+ setExpandedGroups(new Set(allGroupKeys));
3007
+ }, [groupBy, defaultGroupExpanded, allGroupKeys]);
2919
3008
  const groupedRows = useMemo3(() => {
2920
3009
  if (!groupBy) return baseFlatRows;
2921
- const allExpanded = expandedGroups.has("__all__");
2922
- const effectiveExpanded = allExpanded ? /* @__PURE__ */ new Set([...expandedGroups, ...baseFlatRows.map((r) => String(r.data[groupBy] ?? "Other"))]) : expandedGroups;
2923
- return groupByColumn(baseFlatRows, groupBy, columns, effectiveExpanded);
3010
+ return groupByColumn(baseFlatRows, groupBy, columns, expandedGroups);
2924
3011
  }, [baseFlatRows, groupBy, columns, expandedGroups]);
2925
3012
  const {
2926
3013
  top: pinnedTop,
@@ -3791,4 +3878,4 @@ export {
3791
3878
  printElement,
3792
3879
  Table
3793
3880
  };
3794
- //# sourceMappingURL=chunk-NXB3VAVF.js.map
3881
+ //# sourceMappingURL=chunk-7AA2JPZB.js.map