@flanksource/clicky-ui 0.3.22 → 0.3.24

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 (257) hide show
  1. package/dist/components/CountryFlag.cjs +55 -0
  2. package/dist/components/CountryFlag.cjs.map +1 -0
  3. package/dist/components/CountryFlag.d.ts +8 -0
  4. package/dist/components/CountryFlag.d.ts.map +1 -0
  5. package/dist/components/CountryFlag.js +38 -0
  6. package/dist/components/CountryFlag.js.map +1 -0
  7. package/dist/components/CountryPicker.cjs +35 -0
  8. package/dist/components/CountryPicker.cjs.map +1 -0
  9. package/dist/components/CountryPicker.d.ts +4 -0
  10. package/dist/components/CountryPicker.d.ts.map +1 -0
  11. package/dist/components/CountryPicker.js +35 -0
  12. package/dist/components/CountryPicker.js.map +1 -0
  13. package/dist/components/SplitButton.cjs +3 -2
  14. package/dist/components/SplitButton.cjs.map +1 -1
  15. package/dist/components/SplitButton.d.ts +6 -1
  16. package/dist/components/SplitButton.d.ts.map +1 -1
  17. package/dist/components/SplitButton.js +3 -2
  18. package/dist/components/SplitButton.js.map +1 -1
  19. package/dist/components/country-options.cjs +34 -0
  20. package/dist/components/country-options.cjs.map +1 -0
  21. package/dist/components/country-options.d.ts +8 -0
  22. package/dist/components/country-options.d.ts.map +1 -0
  23. package/dist/components/country-options.js +34 -0
  24. package/dist/components/country-options.js.map +1 -0
  25. package/dist/components.cjs +11 -0
  26. package/dist/components.cjs.map +1 -1
  27. package/dist/components.d.ts +4 -0
  28. package/dist/components.d.ts.map +1 -1
  29. package/dist/components.js +11 -0
  30. package/dist/components.js.map +1 -1
  31. package/dist/data/Clicky.cjs +4 -1
  32. package/dist/data/Clicky.cjs.map +1 -1
  33. package/dist/data/Clicky.d.ts.map +1 -1
  34. package/dist/data/Clicky.js +4 -1
  35. package/dist/data/Clicky.js.map +1 -1
  36. package/dist/data/CodeDiff.cjs +3 -18
  37. package/dist/data/CodeDiff.cjs.map +1 -1
  38. package/dist/data/CodeDiff.d.ts.map +1 -1
  39. package/dist/data/CodeDiff.js +3 -18
  40. package/dist/data/CodeDiff.js.map +1 -1
  41. package/dist/data/DataTable.cjs +182 -64
  42. package/dist/data/DataTable.cjs.map +1 -1
  43. package/dist/data/DataTable.d.ts +9 -1
  44. package/dist/data/DataTable.d.ts.map +1 -1
  45. package/dist/data/DataTable.grouping.cjs +26 -0
  46. package/dist/data/DataTable.grouping.cjs.map +1 -1
  47. package/dist/data/DataTable.grouping.d.ts +38 -0
  48. package/dist/data/DataTable.grouping.d.ts.map +1 -1
  49. package/dist/data/DataTable.grouping.js +26 -0
  50. package/dist/data/DataTable.grouping.js.map +1 -1
  51. package/dist/data/DataTable.js +183 -65
  52. package/dist/data/DataTable.js.map +1 -1
  53. package/dist/data/DataTableGroupingControls.cjs +84 -0
  54. package/dist/data/DataTableGroupingControls.cjs.map +1 -0
  55. package/dist/data/DataTableGroupingControls.d.ts +17 -0
  56. package/dist/data/DataTableGroupingControls.d.ts.map +1 -0
  57. package/dist/data/DataTableGroupingControls.js +84 -0
  58. package/dist/data/DataTableGroupingControls.js.map +1 -0
  59. package/dist/data/HighlightedTokens.cjs +21 -0
  60. package/dist/data/HighlightedTokens.cjs.map +1 -0
  61. package/dist/data/HighlightedTokens.d.ts +6 -0
  62. package/dist/data/HighlightedTokens.d.ts.map +1 -0
  63. package/dist/data/HighlightedTokens.js +21 -0
  64. package/dist/data/HighlightedTokens.js.map +1 -0
  65. package/dist/data/ai/AdvancedChatConfig.cjs +3 -0
  66. package/dist/data/ai/AdvancedChatConfig.cjs.map +1 -1
  67. package/dist/data/ai/AdvancedChatConfig.d.ts +2 -1
  68. package/dist/data/ai/AdvancedChatConfig.d.ts.map +1 -1
  69. package/dist/data/ai/AdvancedChatConfig.js +3 -0
  70. package/dist/data/ai/AdvancedChatConfig.js.map +1 -1
  71. package/dist/data/ai/ChatWindow.cjs +77 -4
  72. package/dist/data/ai/ChatWindow.cjs.map +1 -1
  73. package/dist/data/ai/ChatWindow.d.ts.map +1 -1
  74. package/dist/data/ai/ChatWindow.js +78 -5
  75. package/dist/data/ai/ChatWindow.js.map +1 -1
  76. package/dist/data/ai/ChatWindow.runtime.cjs +19 -4
  77. package/dist/data/ai/ChatWindow.runtime.cjs.map +1 -1
  78. package/dist/data/ai/ChatWindow.runtime.d.ts +2 -0
  79. package/dist/data/ai/ChatWindow.runtime.d.ts.map +1 -1
  80. package/dist/data/ai/ChatWindow.runtime.js +19 -4
  81. package/dist/data/ai/ChatWindow.runtime.js.map +1 -1
  82. package/dist/data/ai/ChatWindow.test-utils.d.ts +2 -1
  83. package/dist/data/ai/ChatWindow.test-utils.d.ts.map +1 -1
  84. package/dist/data/ai/ToolPreferences.cjs +8 -1
  85. package/dist/data/ai/ToolPreferences.cjs.map +1 -1
  86. package/dist/data/ai/ToolPreferences.d.ts +2 -1
  87. package/dist/data/ai/ToolPreferences.d.ts.map +1 -1
  88. package/dist/data/ai/ToolPreferences.js +8 -1
  89. package/dist/data/ai/ToolPreferences.js.map +1 -1
  90. package/dist/data/chat/Chat.cjs +26 -3
  91. package/dist/data/chat/Chat.cjs.map +1 -1
  92. package/dist/data/chat/Chat.d.ts +9 -1
  93. package/dist/data/chat/Chat.d.ts.map +1 -1
  94. package/dist/data/chat/Chat.js +26 -3
  95. package/dist/data/chat/Chat.js.map +1 -1
  96. package/dist/data/chat/ChatRuntimeToolbar.cjs +2 -0
  97. package/dist/data/chat/ChatRuntimeToolbar.cjs.map +1 -1
  98. package/dist/data/chat/ChatRuntimeToolbar.d.ts +2 -1
  99. package/dist/data/chat/ChatRuntimeToolbar.d.ts.map +1 -1
  100. package/dist/data/chat/ChatRuntimeToolbar.js +2 -0
  101. package/dist/data/chat/ChatRuntimeToolbar.js.map +1 -1
  102. package/dist/data/chat/Message.cjs +36 -1
  103. package/dist/data/chat/Message.cjs.map +1 -1
  104. package/dist/data/chat/Message.d.ts +1 -1
  105. package/dist/data/chat/Message.d.ts.map +1 -1
  106. package/dist/data/chat/Message.js +37 -2
  107. package/dist/data/chat/Message.js.map +1 -1
  108. package/dist/data/chat/approval.cjs +17 -0
  109. package/dist/data/chat/approval.cjs.map +1 -1
  110. package/dist/data/chat/approval.d.ts +5 -0
  111. package/dist/data/chat/approval.d.ts.map +1 -1
  112. package/dist/data/chat/approval.js +17 -0
  113. package/dist/data/chat/approval.js.map +1 -1
  114. package/dist/data/chat/fork-seed.cjs +22 -0
  115. package/dist/data/chat/fork-seed.cjs.map +1 -0
  116. package/dist/data/chat/fork-seed.d.ts +8 -0
  117. package/dist/data/chat/fork-seed.d.ts.map +1 -0
  118. package/dist/data/chat/fork-seed.js +22 -0
  119. package/dist/data/chat/fork-seed.js.map +1 -0
  120. package/dist/data/code-highlight.cjs +0 -6
  121. package/dist/data/code-highlight.cjs.map +1 -1
  122. package/dist/data/code-highlight.d.ts +4 -3
  123. package/dist/data/code-highlight.d.ts.map +1 -1
  124. package/dist/data/code-highlight.js +1 -7
  125. package/dist/data/code-highlight.js.map +1 -1
  126. package/dist/data/diagnostics/DiagnosticsDetailPanel.cjs +6 -2
  127. package/dist/data/diagnostics/DiagnosticsDetailPanel.cjs.map +1 -1
  128. package/dist/data/diagnostics/DiagnosticsDetailPanel.d.ts +8 -1
  129. package/dist/data/diagnostics/DiagnosticsDetailPanel.d.ts.map +1 -1
  130. package/dist/data/diagnostics/DiagnosticsDetailPanel.js +6 -2
  131. package/dist/data/diagnostics/DiagnosticsDetailPanel.js.map +1 -1
  132. package/dist/data/diagnostics/ErrorDetails.cjs +29 -5
  133. package/dist/data/diagnostics/ErrorDetails.cjs.map +1 -1
  134. package/dist/data/diagnostics/ErrorDetails.d.ts +3 -1
  135. package/dist/data/diagnostics/ErrorDetails.d.ts.map +1 -1
  136. package/dist/data/diagnostics/ErrorDetails.js +29 -5
  137. package/dist/data/diagnostics/ErrorDetails.js.map +1 -1
  138. package/dist/data/diagnostics/FrameSourceWindow.cjs +54 -24
  139. package/dist/data/diagnostics/FrameSourceWindow.cjs.map +1 -1
  140. package/dist/data/diagnostics/FrameSourceWindow.d.ts +2 -1
  141. package/dist/data/diagnostics/FrameSourceWindow.d.ts.map +1 -1
  142. package/dist/data/diagnostics/FrameSourceWindow.js +54 -24
  143. package/dist/data/diagnostics/FrameSourceWindow.js.map +1 -1
  144. package/dist/data/diagnostics/FrameSourceWindow.utils.cjs.map +1 -1
  145. package/dist/data/diagnostics/FrameSourceWindow.utils.d.ts +3 -0
  146. package/dist/data/diagnostics/FrameSourceWindow.utils.d.ts.map +1 -1
  147. package/dist/data/diagnostics/FrameSourceWindow.utils.js.map +1 -1
  148. package/dist/data/diagnostics/JvmStackTrace.cjs +14 -30
  149. package/dist/data/diagnostics/JvmStackTrace.cjs.map +1 -1
  150. package/dist/data/diagnostics/JvmStackTrace.d.ts +6 -9
  151. package/dist/data/diagnostics/JvmStackTrace.d.ts.map +1 -1
  152. package/dist/data/diagnostics/JvmStackTrace.js +15 -31
  153. package/dist/data/diagnostics/JvmStackTrace.js.map +1 -1
  154. package/dist/data/diagnostics/RenderedStackTrace.cjs +14 -144
  155. package/dist/data/diagnostics/RenderedStackTrace.cjs.map +1 -1
  156. package/dist/data/diagnostics/RenderedStackTrace.d.ts +6 -6
  157. package/dist/data/diagnostics/RenderedStackTrace.d.ts.map +1 -1
  158. package/dist/data/diagnostics/RenderedStackTrace.js +15 -145
  159. package/dist/data/diagnostics/RenderedStackTrace.js.map +1 -1
  160. package/dist/data/diagnostics/StackFrameRow.cjs +65 -0
  161. package/dist/data/diagnostics/StackFrameRow.cjs.map +1 -0
  162. package/dist/data/diagnostics/StackFrameRow.d.ts +13 -0
  163. package/dist/data/diagnostics/StackFrameRow.d.ts.map +1 -0
  164. package/dist/data/diagnostics/StackFrameRow.js +65 -0
  165. package/dist/data/diagnostics/StackFrameRow.js.map +1 -0
  166. package/dist/data/diagnostics/ThreadCard.cjs +9 -2
  167. package/dist/data/diagnostics/ThreadCard.cjs.map +1 -1
  168. package/dist/data/diagnostics/ThreadCard.d.ts +3 -1
  169. package/dist/data/diagnostics/ThreadCard.d.ts.map +1 -1
  170. package/dist/data/diagnostics/ThreadCard.js +9 -2
  171. package/dist/data/diagnostics/ThreadCard.js.map +1 -1
  172. package/dist/data/diagnostics/frame-heuristics.cjs +26 -0
  173. package/dist/data/diagnostics/frame-heuristics.cjs.map +1 -0
  174. package/dist/data/diagnostics/frame-heuristics.d.ts +5 -0
  175. package/dist/data/diagnostics/frame-heuristics.d.ts.map +1 -0
  176. package/dist/data/diagnostics/frame-heuristics.js +26 -0
  177. package/dist/data/diagnostics/frame-heuristics.js.map +1 -0
  178. package/dist/data/diagnostics/jvm-stacktrace.cjs +5 -7
  179. package/dist/data/diagnostics/jvm-stacktrace.cjs.map +1 -1
  180. package/dist/data/diagnostics/jvm-stacktrace.d.ts.map +1 -1
  181. package/dist/data/diagnostics/jvm-stacktrace.js +5 -7
  182. package/dist/data/diagnostics/jvm-stacktrace.js.map +1 -1
  183. package/dist/data/diagnostics/stacktrace-parse.cjs +4 -9
  184. package/dist/data/diagnostics/stacktrace-parse.cjs.map +1 -1
  185. package/dist/data/diagnostics/stacktrace-parse.d.ts.map +1 -1
  186. package/dist/data/diagnostics/stacktrace-parse.js +4 -9
  187. package/dist/data/diagnostics/stacktrace-parse.js.map +1 -1
  188. package/dist/data/runtime/RuntimeBar.cjs +3 -0
  189. package/dist/data/runtime/RuntimeBar.cjs.map +1 -1
  190. package/dist/data/runtime/RuntimeBar.d.ts +3 -1
  191. package/dist/data/runtime/RuntimeBar.d.ts.map +1 -1
  192. package/dist/data/runtime/RuntimeBar.js +3 -0
  193. package/dist/data/runtime/RuntimeBar.js.map +1 -1
  194. package/dist/data/runtime/RuntimeBarCombo.cjs +15 -1
  195. package/dist/data/runtime/RuntimeBarCombo.cjs.map +1 -1
  196. package/dist/data/runtime/RuntimeBarCombo.d.ts +2 -1
  197. package/dist/data/runtime/RuntimeBarCombo.d.ts.map +1 -1
  198. package/dist/data/runtime/RuntimeBarCombo.js +15 -1
  199. package/dist/data/runtime/RuntimeBarCombo.js.map +1 -1
  200. package/dist/data/runtime/RuntimeBarSegments.cjs +7 -0
  201. package/dist/data/runtime/RuntimeBarSegments.cjs.map +1 -1
  202. package/dist/data/runtime/RuntimeBarSegments.d.ts +2 -1
  203. package/dist/data/runtime/RuntimeBarSegments.d.ts.map +1 -1
  204. package/dist/data/runtime/RuntimeBarSegments.js +7 -0
  205. package/dist/data/runtime/RuntimeBarSegments.js.map +1 -1
  206. package/dist/data/version-info.cjs +3 -3
  207. package/dist/data/version-info.js +3 -3
  208. package/dist/data.cjs +7 -1
  209. package/dist/data.cjs.map +1 -1
  210. package/dist/data.d.ts +4 -2
  211. package/dist/data.d.ts.map +1 -1
  212. package/dist/data.js +8 -2
  213. package/dist/data.js.map +1 -1
  214. package/dist/index.cjs +18 -1
  215. package/dist/index.cjs.map +1 -1
  216. package/dist/index.js +19 -2
  217. package/dist/index.js.map +1 -1
  218. package/dist/rpc/CommandForm.cjs +8 -18
  219. package/dist/rpc/CommandForm.cjs.map +1 -1
  220. package/dist/rpc/CommandForm.d.ts +8 -2
  221. package/dist/rpc/CommandForm.d.ts.map +1 -1
  222. package/dist/rpc/CommandForm.js +9 -19
  223. package/dist/rpc/CommandForm.js.map +1 -1
  224. package/dist/rpc/OperationActionDialog.cjs +3 -3
  225. package/dist/rpc/OperationActionDialog.cjs.map +1 -1
  226. package/dist/rpc/OperationActionDialog.js +3 -3
  227. package/dist/rpc/OperationActionDialog.js.map +1 -1
  228. package/dist/rpc/OperationCommandPage.cjs +7 -7
  229. package/dist/rpc/OperationCommandPage.cjs.map +1 -1
  230. package/dist/rpc/OperationCommandPage.d.ts.map +1 -1
  231. package/dist/rpc/OperationCommandPage.js +7 -7
  232. package/dist/rpc/OperationCommandPage.js.map +1 -1
  233. package/dist/rpc/apiClient.cjs +17 -3
  234. package/dist/rpc/apiClient.cjs.map +1 -1
  235. package/dist/rpc/apiClient.d.ts +4 -4
  236. package/dist/rpc/apiClient.d.ts.map +1 -1
  237. package/dist/rpc/apiClient.js +17 -3
  238. package/dist/rpc/apiClient.js.map +1 -1
  239. package/dist/rpc/formMetadata.cjs +5 -9
  240. package/dist/rpc/formMetadata.cjs.map +1 -1
  241. package/dist/rpc/formMetadata.d.ts +3 -3
  242. package/dist/rpc/formMetadata.d.ts.map +1 -1
  243. package/dist/rpc/formMetadata.js +5 -9
  244. package/dist/rpc/formMetadata.js.map +1 -1
  245. package/dist/rpc/rpc-story.fixtures.d.ts.map +1 -1
  246. package/dist/rpc/types.cjs.map +1 -1
  247. package/dist/rpc/types.d.ts +1 -0
  248. package/dist/rpc/types.d.ts.map +1 -1
  249. package/dist/rpc/types.js.map +1 -1
  250. package/dist/rpc/useOperations.cjs.map +1 -1
  251. package/dist/rpc/useOperations.d.ts +4 -4
  252. package/dist/rpc/useOperations.d.ts.map +1 -1
  253. package/dist/rpc/useOperations.js.map +1 -1
  254. package/dist/rpc.d.ts +2 -2
  255. package/dist/rpc.d.ts.map +1 -1
  256. package/dist/styles.css +1 -1
  257. package/package.json +2 -1
@@ -22,7 +22,8 @@ import { CellFilterActions } from "./cells/CellFilterActions.js";
22
22
  import { tagActionsFromRecord, tagFilterTokens, normalizeTags, splitTagToken } from "./cells/tag-utils.js";
23
23
  import { StatusDot } from "./cells/StatusDot.js";
24
24
  import { normalizeStatus } from "./cells/status-mapping.js";
25
- import { groupRecords, isGroupCollapsedByDefault } from "./DataTable.grouping.js";
25
+ import { dataTableGroupLabel, dataTableGroupKey, groupRecords, isGroupCollapsedByDefault } from "./DataTable.grouping.js";
26
+ import { DataTableGroupingControls } from "./DataTableGroupingControls.js";
26
27
  import { UiEllipsis } from "../icons/components/UiEllipsis.js";
27
28
  import { UiFilterFilled, UiFilter } from "../icons/components/UiFilter.js";
28
29
  import { UiChevronRight } from "../icons/components/UiChevronRight.js";
@@ -65,6 +66,44 @@ const TIMESTAMP_RANGE_PRESETS = [
65
66
  { label: "Last 7 days", from: "now-7d", to: "now" },
66
67
  { label: "Last 30 days", from: "now-30d", to: "now" }
67
68
  ];
69
+ function assertDataTableGroupingProps({
70
+ grouping,
71
+ groupingModes,
72
+ groupingMode,
73
+ defaultGroupingMode,
74
+ onGroupingModeChange
75
+ }) {
76
+ if (grouping && groupingModes) {
77
+ throw new Error("DataTable accepts grouping or groupingModes, not both");
78
+ }
79
+ if (!groupingModes) {
80
+ if (groupingMode !== void 0 || defaultGroupingMode !== void 0) {
81
+ throw new Error("DataTable groupingMode values require groupingModes");
82
+ }
83
+ return;
84
+ }
85
+ if (groupingModes.length === 0) {
86
+ throw new Error("DataTable groupingModes must not be empty");
87
+ }
88
+ const values = new Set(groupingModes.map((mode) => mode.value));
89
+ if (values.size !== groupingModes.length) {
90
+ throw new Error("DataTable groupingModes values must be unique");
91
+ }
92
+ if (groupingMode !== void 0 && !onGroupingModeChange) {
93
+ throw new Error(
94
+ "DataTable controlled groupingMode requires onGroupingModeChange"
95
+ );
96
+ }
97
+ if (groupingMode !== void 0 && defaultGroupingMode !== void 0) {
98
+ throw new Error(
99
+ "DataTable cannot combine groupingMode with defaultGroupingMode"
100
+ );
101
+ }
102
+ const selected = groupingMode ?? defaultGroupingMode;
103
+ if (selected !== void 0 && !values.has(selected)) {
104
+ throw new Error(`DataTable grouping mode "${selected}" does not exist`);
105
+ }
106
+ }
68
107
  function DataTableInner({
69
108
  data,
70
109
  error,
@@ -101,6 +140,10 @@ function DataTableInner({
101
140
  getRowClassName,
102
141
  footer,
103
142
  grouping,
143
+ groupingModes,
144
+ groupingMode,
145
+ defaultGroupingMode,
146
+ onGroupingModeChange,
104
147
  onRowClick,
105
148
  isRowClickable,
106
149
  getRowHref,
@@ -126,6 +169,14 @@ function DataTableInner({
126
169
  showHeaderFilters = true,
127
170
  menuActions
128
171
  }) {
172
+ var _a;
173
+ assertDataTableGroupingProps({
174
+ grouping,
175
+ groupingModes,
176
+ groupingMode,
177
+ defaultGroupingMode,
178
+ onGroupingModeChange
179
+ });
129
180
  const columns = useMemo(
130
181
  () => columnsInput.map(
131
182
  (column) => typeof column === "string" ? { key: column, label: column } : column
@@ -159,17 +210,18 @@ function DataTableInner({
159
210
  const [numberFilters, setNumberFilters] = useState({});
160
211
  const [expandedRows, setExpandedRows] = useState({});
161
212
  const [detailRow, setDetailRow] = useState(null);
213
+ const [localGroupingMode, setLocalGroupingMode] = useState(defaultGroupingMode);
162
214
  const [localGlobalFilter, setLocalGlobalFilter] = useState("");
163
215
  const [timeRangeFilter, setTimeRangeFilter] = useState(() => {
164
- var _a, _b, _c, _d;
216
+ var _a2, _b, _c, _d;
165
217
  const seed = columns.find(
166
218
  (column) => {
167
- var _a2;
168
- return column.kind === "timestamp" && ((_a2 = column.timestamp) == null ? void 0 : _a2.defaultRange);
219
+ var _a3;
220
+ return column.kind === "timestamp" && ((_a3 = column.timestamp) == null ? void 0 : _a3.defaultRange);
169
221
  }
170
222
  );
171
223
  return {
172
- from: ((_b = (_a = seed == null ? void 0 : seed.timestamp) == null ? void 0 : _a.defaultRange) == null ? void 0 : _b.from) ?? "",
224
+ from: ((_b = (_a2 = seed == null ? void 0 : seed.timestamp) == null ? void 0 : _a2.defaultRange) == null ? void 0 : _b.from) ?? "",
173
225
  to: ((_d = (_c = seed == null ? void 0 : seed.timestamp) == null ? void 0 : _c.defaultRange) == null ? void 0 : _d.to) ?? ""
174
226
  };
175
227
  });
@@ -247,7 +299,7 @@ function DataTableInner({
247
299
  [data, getRowId]
248
300
  );
249
301
  const timestampFormats = useMemo(() => {
250
- var _a;
302
+ var _a2;
251
303
  const out = {};
252
304
  for (const column of columns) {
253
305
  if (column.kind !== "timestamp") continue;
@@ -259,7 +311,7 @@ function DataTableInner({
259
311
  }
260
312
  const dataFormat = chooseTimestampFormat(dates);
261
313
  out[column.key] = modeToFormat(
262
- ((_a = column.timestamp) == null ? void 0 : _a.mode) ?? "auto",
314
+ ((_a2 = column.timestamp) == null ? void 0 : _a2.mode) ?? "auto",
263
315
  dataFormat
264
316
  );
265
317
  }
@@ -271,6 +323,35 @@ function DataTableInner({
271
323
  ),
272
324
  [columns, timestampFormats]
273
325
  );
326
+ const activeGroupingModeValue = groupingMode ?? localGroupingMode ?? defaultGroupingMode ?? ((_a = groupingModes == null ? void 0 : groupingModes[0]) == null ? void 0 : _a.value);
327
+ const activeGroupingMode = groupingModes == null ? void 0 : groupingModes.find(
328
+ (mode) => mode.value === activeGroupingModeValue
329
+ );
330
+ const effectiveGrouping = useMemo(() => {
331
+ if (!activeGroupingMode) return grouping;
332
+ if (activeGroupingMode.type === "none") return void 0;
333
+ if (activeGroupingMode.type === "custom") return activeGroupingMode;
334
+ const column = effectiveColumns.find(
335
+ (candidate) => candidate.key === activeGroupingMode.columnKey
336
+ );
337
+ if (!column) {
338
+ throw new Error(
339
+ `DataTable grouping mode "${activeGroupingMode.value}" references missing column "${activeGroupingMode.columnKey}"`
340
+ );
341
+ }
342
+ return {
343
+ ...activeGroupingMode,
344
+ getGroupKey: (row) => dataTableGroupKey(resolveColumnValue(row, column)),
345
+ // `emptyGroupLabel` is a header label, never a key — resolving it here
346
+ // keeps rows with no value apart from rows whose value happens to read
347
+ // like the label.
348
+ getGroupLabel: (key, rows2) => {
349
+ var _a2;
350
+ const custom = (_a2 = activeGroupingMode.getGroupLabel) == null ? void 0 : _a2.call(activeGroupingMode, key, rows2);
351
+ return custom !== void 0 ? custom : dataTableGroupLabel(key, activeGroupingMode.emptyGroupLabel);
352
+ }
353
+ };
354
+ }, [activeGroupingMode, effectiveColumns, grouping]);
274
355
  const visibleColumns = useMemo(() => {
275
356
  if (!hideableColumns) return effectiveColumns;
276
357
  const next = effectiveColumns.filter(
@@ -294,8 +375,8 @@ function DataTableInner({
294
375
  const rangeCapableColumn = useMemo(
295
376
  () => effectiveColumns.find(
296
377
  (column) => {
297
- var _a;
298
- return column.kind === "timestamp" && column.filterable !== false && ((_a = column.timestamp) == null ? void 0 : _a.autoRangeFilter) !== false;
378
+ var _a2;
379
+ return column.kind === "timestamp" && column.filterable !== false && ((_a2 = column.timestamp) == null ? void 0 : _a2.autoRangeFilter) !== false;
299
380
  }
300
381
  ) ?? null,
301
382
  [effectiveColumns]
@@ -323,7 +404,7 @@ function DataTableInner({
323
404
  const generatedFilters = useMemo(() => {
324
405
  if (!autoFilter || loading) return [];
325
406
  return filterableColumns.map((column) => {
326
- var _a;
407
+ var _a2;
327
408
  const numberBounds = getNumericFilterBounds(rows, column);
328
409
  if (numberBounds) {
329
410
  return {
@@ -345,7 +426,7 @@ function DataTableInner({
345
426
  const multiCap = column.kind === "tags" ? 50 : 20;
346
427
  const fitsMulti = options.length >= 2 && options.length <= multiCap;
347
428
  if (column.kind === "tags" && fitsMulti) {
348
- const separator = ((_a = column.tags) == null ? void 0 : _a.separator) ?? "=";
429
+ const separator = ((_a2 = column.tags) == null ? void 0 : _a2.separator) ?? "=";
349
430
  const groups2 = groupTagOptions(options, separator);
350
431
  if (groups2.length >= 2) {
351
432
  return {
@@ -391,7 +472,7 @@ function DataTableInner({
391
472
  }) : setLocalGlobalFilter;
392
473
  const nativeFilters = useMemo(
393
474
  () => generatedFilters.map((filter) => {
394
- var _a, _b, _c;
475
+ var _a2, _b, _c;
395
476
  const columnKey = filter.column.key;
396
477
  if (filter.kind === "multi") {
397
478
  return {
@@ -427,7 +508,7 @@ function DataTableInner({
427
508
  (current) => updateNumberFilterValue(current, columnKey, next)
428
509
  )
429
510
  };
430
- if (((_a = filter.numberBounds) == null ? void 0 : _a.min) !== void 0) {
511
+ if (((_a2 = filter.numberBounds) == null ? void 0 : _a2.min) !== void 0) {
431
512
  numberFilter.domainMin = filter.numberBounds.min;
432
513
  }
433
514
  if (((_b = filter.numberBounds) == null ? void 0 : _b.max) !== void 0) {
@@ -476,13 +557,13 @@ function DataTableInner({
476
557
  (filterBarProps == null ? void 0 : filterBarProps.leading) || (filterBarProps == null ? void 0 : filterBarProps.children) || (filterBarProps == null ? void 0 : filterBarProps.trailing) || (filterBarProps == null ? void 0 : filterBarProps.timeRange) || (filterBarProps == null ? void 0 : filterBarProps.dateRange)
477
558
  );
478
559
  const autoTimeRange = useMemo(() => {
479
- var _a, _b, _c, _d;
560
+ var _a2, _b, _c, _d;
480
561
  if (!timeRangeColumn) return null;
481
562
  const next = {
482
563
  from: timeRangeFilter.from,
483
564
  to: timeRangeFilter.to,
484
565
  onApply: (from, to) => setTimeRangeFilter({ from, to }),
485
- presets: ((_a = timeRangeColumn.timestamp) == null ? void 0 : _a.rangePresets) ?? TIMESTAMP_RANGE_PRESETS,
566
+ presets: ((_a2 = timeRangeColumn.timestamp) == null ? void 0 : _a2.rangePresets) ?? TIMESTAMP_RANGE_PRESETS,
486
567
  fromPlaceholder: "now-24h",
487
568
  toPlaceholder: "now",
488
569
  emptyLabel: "Any time"
@@ -525,20 +606,11 @@ function DataTableInner({
525
606
  globalFilterControlled: globalFilter !== void 0 || onGlobalFilterChange !== void 0,
526
607
  hasExternalSearch: externalSearch !== void 0
527
608
  });
528
- const showFilterBar = resolvedShowGlobalFilter || nativeFilters.length > 0 || !!barTimeRange || !!externalSearch || externalFilters && externalFilters.length > 0 || hasCustomFilterBarContent || showTablePreferencesControl;
609
+ const showFilterBar = resolvedShowGlobalFilter || nativeFilters.length > 0 || !!barTimeRange || !!externalSearch || externalFilters && externalFilters.length > 0 || hasCustomFilterBarContent || !!groupingModes || showTablePreferencesControl;
529
610
  const setDensityOverride = (next) => {
530
611
  if (!densityControlled) setLocalDensityOverride(next);
531
612
  onDensityChange == null ? void 0 : onDensityChange(next);
532
613
  };
533
- const filterBarTrailing = showTablePreferencesControl ? /* @__PURE__ */ jsxs(Fragment, { children: [
534
- filterBarProps == null ? void 0 : filterBarProps.trailing,
535
- /* @__PURE__ */ jsx(
536
- ColumnVisibilityTrigger,
537
- {
538
- onOpen: (event) => setColumnMenu(menuStateFromTrigger(event))
539
- }
540
- )
541
- ] }) : filterBarProps == null ? void 0 : filterBarProps.trailing;
542
614
  const showHeaderFilterControls = showHeaderFilters && (headerFilterByColumn.size > 0 || !!columnTimeRange);
543
615
  const filteredRows = useMemo(() => {
544
616
  if (manualFilter) return rows;
@@ -648,8 +720,8 @@ function DataTableInner({
648
720
  const selectableVisibleRows = useMemo(
649
721
  () => visibleSorted.filter(
650
722
  (record) => {
651
- var _a;
652
- return ((_a = rowSelection == null ? void 0 : rowSelection.isRowSelectable) == null ? void 0 : _a.call(rowSelection, record.row)) ?? true;
723
+ var _a2;
724
+ return ((_a2 = rowSelection == null ? void 0 : rowSelection.isRowSelectable) == null ? void 0 : _a2.call(rowSelection, record.row)) ?? true;
653
725
  }
654
726
  ),
655
727
  [rowSelection, visibleSorted]
@@ -677,9 +749,9 @@ function DataTableInner({
677
749
  );
678
750
  const toggleRowSelection = useCallback(
679
751
  (record) => {
680
- var _a;
752
+ var _a2;
681
753
  if (!rowSelection) return;
682
- if (((_a = rowSelection.isRowSelectable) == null ? void 0 : _a.call(rowSelection, record.row)) === false) return;
754
+ if (((_a2 = rowSelection.isRowSelectable) == null ? void 0 : _a2.call(rowSelection, record.row)) === false) return;
683
755
  const next = new Set(selectedRowIDs);
684
756
  if (next.has(record.id)) next.delete(record.id);
685
757
  else next.add(record.id);
@@ -718,31 +790,67 @@ function DataTableInner({
718
790
  totalRowCount: data.length,
719
791
  loading
720
792
  }) : footer : pagination ? null : loading && sorted.length === 0 ? loadingMessage : `${sorted.length} of ${data.length} row${data.length === 1 ? "" : "s"}`;
721
- const [collapsedGroups, setCollapsedGroups] = useState({});
793
+ const [collapseStateByMode, setCollapseStateByMode] = useState({});
794
+ const collapseStateKey = activeGroupingMode ? `mode:${activeGroupingMode.value}` : "fixed";
795
+ const collapseState = collapseStateByMode[collapseStateKey];
722
796
  const groups = useMemo(() => {
723
- if (!grouping) return null;
797
+ if (!effectiveGrouping) return null;
724
798
  const buckets = groupRecords(
725
799
  visibleSorted,
726
- (record) => grouping.getGroupKey(record.row)
800
+ (record) => effectiveGrouping.getGroupKey(record.row)
727
801
  );
728
802
  const resolved = buckets.map((bucket) => ({
729
803
  key: bucket.key,
730
804
  records: bucket.rows,
731
805
  rows: bucket.rows.map((record) => record.row)
732
806
  }));
733
- if (grouping.compareGroups) {
734
- resolved.sort((a, b) => grouping.compareGroups(a, b));
807
+ if (effectiveGrouping.compareGroups) {
808
+ resolved.sort((a, b) => effectiveGrouping.compareGroups(a, b));
735
809
  }
736
810
  return resolved.map((group) => {
737
- var _a, _b;
811
+ var _a2, _b;
738
812
  return {
739
813
  ...group,
740
- label: ((_a = grouping.getGroupLabel) == null ? void 0 : _a.call(grouping, group.key, group.rows)) ?? group.key,
741
- meta: (_b = grouping.getGroupMeta) == null ? void 0 : _b.call(grouping, group.key, group.rows),
742
- collapsed: collapsedGroups[group.key] ?? isGroupCollapsedByDefault(group, grouping.defaultCollapsed)
814
+ label: ((_a2 = effectiveGrouping.getGroupLabel) == null ? void 0 : _a2.call(effectiveGrouping, group.key, group.rows)) ?? group.key,
815
+ meta: (_b = effectiveGrouping.getGroupMeta) == null ? void 0 : _b.call(effectiveGrouping, group.key, group.rows),
816
+ collapsed: (collapseState == null ? void 0 : collapseState.groups[group.key]) ?? (collapseState == null ? void 0 : collapseState.all) ?? isGroupCollapsedByDefault(group, effectiveGrouping.defaultCollapsed)
743
817
  };
744
818
  });
745
- }, [collapsedGroups, grouping, visibleSorted]);
819
+ }, [collapseState, effectiveGrouping, visibleSorted]);
820
+ const hasGroups = !!(groups == null ? void 0 : groups.length);
821
+ const allGroupsExpanded = hasGroups && groups.every((group) => !group.collapsed);
822
+ const allGroupsCollapsed = hasGroups && groups.every((group) => group.collapsed);
823
+ const setAllGroupsCollapsed = (collapsed) => {
824
+ setCollapseStateByMode((current) => ({
825
+ ...current,
826
+ [collapseStateKey]: { all: collapsed, groups: {} }
827
+ }));
828
+ };
829
+ const filterBarTrailing = (filterBarProps == null ? void 0 : filterBarProps.trailing) || groupingModes || showTablePreferencesControl ? /* @__PURE__ */ jsxs(Fragment, { children: [
830
+ filterBarProps == null ? void 0 : filterBarProps.trailing,
831
+ groupingModes ? /* @__PURE__ */ jsx(
832
+ DataTableGroupingControls,
833
+ {
834
+ modes: groupingModes,
835
+ value: activeGroupingModeValue,
836
+ hasGroups,
837
+ allExpanded: allGroupsExpanded,
838
+ allCollapsed: allGroupsCollapsed,
839
+ onModeChange: (value) => {
840
+ if (groupingMode === void 0) setLocalGroupingMode(value);
841
+ onGroupingModeChange == null ? void 0 : onGroupingModeChange(value);
842
+ },
843
+ onExpandAll: () => setAllGroupsCollapsed(false),
844
+ onCollapseAll: () => setAllGroupsCollapsed(true)
845
+ }
846
+ ) : null,
847
+ showTablePreferencesControl ? /* @__PURE__ */ jsx(
848
+ ColumnVisibilityTrigger,
849
+ {
850
+ onOpen: (event) => setColumnMenu(menuStateFromTrigger(event))
851
+ }
852
+ ) : null
853
+ ] }) : void 0;
746
854
  const rowStream = useMemo(() => {
747
855
  if (!groups) {
748
856
  return visibleSorted.map((record) => ({ kind: "row", record }));
@@ -757,8 +865,8 @@ function DataTableInner({
757
865
  if (!rowSelection) return;
758
866
  const selectable = records.filter(
759
867
  (record) => {
760
- var _a;
761
- return ((_a = rowSelection.isRowSelectable) == null ? void 0 : _a.call(rowSelection, record.row)) ?? true;
868
+ var _a2;
869
+ return ((_a2 = rowSelection.isRowSelectable) == null ? void 0 : _a2.call(rowSelection, record.row)) ?? true;
762
870
  }
763
871
  );
764
872
  const next = new Set(selectedRowIDs);
@@ -777,8 +885,8 @@ function DataTableInner({
777
885
  if (!node || !sentinelActive) return;
778
886
  revealObserver.current = new IntersectionObserver(
779
887
  (entries) => {
780
- var _a;
781
- if (!((_a = entries[0]) == null ? void 0 : _a.isIntersecting)) return;
888
+ var _a2;
889
+ if (!((_a2 = entries[0]) == null ? void 0 : _a2.isIntersecting)) return;
782
890
  if (infiniteEnabled) {
783
891
  requestMoreRows();
784
892
  return;
@@ -828,14 +936,14 @@ function DataTableInner({
828
936
  document.body.style.userSelect = "none";
829
937
  };
830
938
  const autoFitColumn = (event, column) => {
831
- var _a;
939
+ var _a2;
832
940
  event.preventDefault();
833
941
  event.stopPropagation();
834
942
  const header = event.currentTarget.closest("th");
835
943
  const table = event.currentTarget.closest("table");
836
944
  if (!header || !table) return;
837
945
  const columnIndex = Array.from(
838
- ((_a = header.parentElement) == null ? void 0 : _a.children) ?? []
946
+ ((_a2 = header.parentElement) == null ? void 0 : _a2.children) ?? []
839
947
  ).indexOf(header);
840
948
  if (columnIndex < 0) return;
841
949
  const width = measureColumnContentWidth(table, columnIndex, column);
@@ -1040,28 +1148,37 @@ function DataTableInner({
1040
1148
  children: emptyMessage
1041
1149
  }
1042
1150
  ) }) : rowStream.map((item) => {
1043
- var _a;
1151
+ var _a2;
1044
1152
  if (item.kind === "group") {
1045
1153
  return /* @__PURE__ */ jsx(
1046
1154
  DataTableGroupHeaderRow,
1047
1155
  {
1048
1156
  label: item.group.label,
1049
1157
  meta: item.group.meta,
1050
- metaAlign: (grouping == null ? void 0 : grouping.metaAlign) ?? "end",
1051
- ...(grouping == null ? void 0 : grouping.metaClassName) ? { metaClassName: grouping.metaClassName } : {},
1158
+ metaAlign: (effectiveGrouping == null ? void 0 : effectiveGrouping.metaAlign) ?? "end",
1159
+ ...(effectiveGrouping == null ? void 0 : effectiveGrouping.metaClassName) ? { metaClassName: effectiveGrouping.metaClassName } : {},
1052
1160
  count: item.group.records.length,
1053
1161
  colSpan: visibleColumns.length + (rowSelection ? 1 : 0),
1054
1162
  collapsed: item.group.collapsed,
1055
- onToggleCollapsed: () => setCollapsedGroups((current) => ({
1056
- ...current,
1057
- [item.group.key]: !item.group.collapsed
1058
- })),
1163
+ onToggleCollapsed: () => setCollapseStateByMode((current) => {
1164
+ var _a3;
1165
+ return {
1166
+ ...current,
1167
+ [collapseStateKey]: {
1168
+ ...current[collapseStateKey],
1169
+ groups: {
1170
+ ...(_a3 = current[collapseStateKey]) == null ? void 0 : _a3.groups,
1171
+ [item.group.key]: !item.group.collapsed
1172
+ }
1173
+ }
1174
+ };
1175
+ }),
1059
1176
  ...rowSelection ? {
1060
1177
  selection: {
1061
1178
  selectableCount: item.group.records.filter(
1062
1179
  (record2) => {
1063
- var _a2;
1064
- return ((_a2 = rowSelection.isRowSelectable) == null ? void 0 : _a2.call(
1180
+ var _a3;
1181
+ return ((_a3 = rowSelection.isRowSelectable) == null ? void 0 : _a3.call(
1065
1182
  rowSelection,
1066
1183
  record2.row
1067
1184
  )) ?? true;
@@ -1089,7 +1206,7 @@ function DataTableInner({
1089
1206
  const expandsInline = expandable && detailStyle === "row";
1090
1207
  const opensDialog = expandable && detailStyle === "dialog";
1091
1208
  const rowClickEnabled = (isRowClickable == null ? void 0 : isRowClickable(record.row)) ?? !!onRowClick;
1092
- const rowSelectable = ((_a = rowSelection == null ? void 0 : rowSelection.isRowSelectable) == null ? void 0 : _a.call(rowSelection, record.row)) ?? true;
1209
+ const rowSelectable = ((_a2 = rowSelection == null ? void 0 : rowSelection.isRowSelectable) == null ? void 0 : _a2.call(rowSelection, record.row)) ?? true;
1093
1210
  const selectionClickEnabled = !!(rowSelection == null ? void 0 : rowSelection.toggleOnRowClick) && rowSelectable;
1094
1211
  const clickable = !!href || rowClickEnabled || expandable || selectionClickEnabled;
1095
1212
  return /* @__PURE__ */ jsxs(Fragment$1, { children: [
@@ -1103,7 +1220,8 @@ function DataTableInner({
1103
1220
  getRowClassName == null ? void 0 : getRowClassName(record.row)
1104
1221
  ),
1105
1222
  onClick: () => {
1106
- if (selectionClickEnabled) toggleRowSelection(record);
1223
+ if (selectionClickEnabled)
1224
+ toggleRowSelection(record);
1107
1225
  if (expandsInline) {
1108
1226
  setExpandedRows((current) => ({
1109
1227
  ...current,
@@ -1142,7 +1260,7 @@ function DataTableInner({
1142
1260
  }
1143
1261
  ) : null,
1144
1262
  visibleColumns.map((column, index) => {
1145
- var _a2;
1263
+ var _a3;
1146
1264
  const rawValue = resolveColumnValue(
1147
1265
  record.row,
1148
1266
  column
@@ -1166,7 +1284,7 @@ function DataTableInner({
1166
1284
  {
1167
1285
  value: serverFilterValue,
1168
1286
  ...serverFilterDisplayValue !== void 0 ? { displayValue: serverFilterDisplayValue } : {},
1169
- mode: (_a2 = cellFilters == null ? void 0 : cellFilters[filterKey]) == null ? void 0 : _a2[serverFilterValue],
1287
+ mode: (_a3 = cellFilters == null ? void 0 : cellFilters[filterKey]) == null ? void 0 : _a3[serverFilterValue],
1170
1288
  onChange: (mode) => onCellFilterChange({
1171
1289
  key: filterKey,
1172
1290
  value: serverFilterValue,
@@ -1363,7 +1481,10 @@ function DataTablePaginationFooter({
1363
1481
  const atLast = cursor ? cursor.next == null : pagination.hasMore != null ? !pagination.hasMore : totalPages != null ? safePage >= totalPages - 1 : visibleRowCount < pageSize;
1364
1482
  const hasVisibleRows = visibleRowCount > 0;
1365
1483
  const rangeStart = total === 0 || !hasVisibleRows ? 0 : infinite ? 1 : safePage * pageSize + 1;
1366
- const rangeEnd = total != null && hasVisibleRows ? Math.min(approximate ? Infinity : total, rangeStart + Math.max(visibleRowCount - 1, 0)) : visibleRowCount;
1484
+ const rangeEnd = total != null && hasVisibleRows ? Math.min(
1485
+ approximate ? Infinity : total,
1486
+ rangeStart + Math.max(visibleRowCount - 1, 0)
1487
+ ) : visibleRowCount;
1367
1488
  const rangeLabel = total != null ? `${rangeStart}-${rangeEnd} of ${approximate ? `~${total}+` : total}` : `${visibleRowCount} row${visibleRowCount === 1 ? "" : "s"}`;
1368
1489
  const steppable = !infinite && (cursor != null || onPageChange != null);
1369
1490
  const goPrevious = () => {
@@ -1468,7 +1589,7 @@ function DataTableGroupHeaderRow({
1468
1589
  "aria-expanded": !collapsed,
1469
1590
  onClick: onToggleCollapsed,
1470
1591
  className: cn(
1471
- "flex min-w-0 items-center gap-1.5 text-left text-xs font-semibold text-foreground hover:text-primary",
1592
+ "flex min-w-0 items-center gap-1.5 text-left text-sm font-semibold text-foreground hover:text-primary",
1472
1593
  // `flex-1` is what pushes the meta to the trailing edge. Dropping
1473
1594
  // it lets the meta sit right after the count instead.
1474
1595
  metaAlign === "end" && "flex-1"
@@ -1490,7 +1611,7 @@ function DataTableGroupHeaderRow({
1490
1611
  "div",
1491
1612
  {
1492
1613
  className: cn(
1493
- "shrink-0 text-xs text-muted-foreground",
1614
+ "shrink-0 text-sm text-muted-foreground",
1494
1615
  metaClassName
1495
1616
  ),
1496
1617
  children: meta
@@ -2047,10 +2168,7 @@ function CellContent({
2047
2168
  return /* @__PURE__ */ jsx(
2048
2169
  "div",
2049
2170
  {
2050
- className: cn(
2051
- cellContentClassName(column),
2052
- alignmentClass(column.align)
2053
- ),
2171
+ className: cn(cellContentClassName(column), alignmentClass(column.align)),
2054
2172
  children
2055
2173
  }
2056
2174
  );