@simpleapps-com/augur-web 2.3.1 → 2026.11.1

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 (255) hide show
  1. package/EXPORTS.md +18 -189
  2. package/README.md +18 -364
  3. package/dist/accordion.cjs.map +1 -1
  4. package/dist/accordion.d.ts +4 -5
  5. package/dist/accordion.d.ts.map +1 -0
  6. package/dist/add-to-cart-button.cjs.map +1 -1
  7. package/dist/add-to-cart-button.d.ts +5 -8
  8. package/dist/add-to-cart-button.d.ts.map +1 -0
  9. package/dist/breadcrumb.cjs.map +1 -1
  10. package/dist/breadcrumb.d.ts +5 -7
  11. package/dist/breadcrumb.d.ts.map +1 -0
  12. package/dist/breadcrumbs.cjs.map +1 -1
  13. package/dist/breadcrumbs.d.ts +4 -4
  14. package/dist/breadcrumbs.d.ts.map +1 -0
  15. package/dist/button.cjs.map +1 -1
  16. package/dist/button.d.ts +7 -9
  17. package/dist/button.d.ts.map +1 -0
  18. package/dist/card.cjs.map +1 -1
  19. package/dist/card.d.ts +3 -4
  20. package/dist/card.d.ts.map +1 -0
  21. package/dist/checkbox.cjs.map +1 -1
  22. package/dist/checkbox.d.ts +3 -4
  23. package/dist/checkbox.d.ts.map +1 -0
  24. package/dist/chunk-32XB3REY.cjs.map +1 -1
  25. package/dist/chunk-5VMEEKZ5.cjs.map +1 -1
  26. package/dist/chunk-5ZITWMV4.cjs.map +1 -1
  27. package/dist/chunk-76RSVRGB.cjs.map +1 -1
  28. package/dist/chunk-7EXXNELX.cjs.map +1 -1
  29. package/dist/chunk-BXMTQGKV.cjs.map +1 -1
  30. package/dist/chunk-EEJYDSXR.cjs +220 -0
  31. package/dist/chunk-EEJYDSXR.cjs.map +1 -0
  32. package/dist/chunk-GSR6SMQ2.cjs.map +1 -1
  33. package/dist/{chunk-3VN3FX2Q.js → chunk-JWTTXZDS.js} +18 -20
  34. package/dist/chunk-JWTTXZDS.js.map +1 -0
  35. package/dist/chunk-JXW4XE2P.cjs.map +1 -1
  36. package/dist/chunk-MAENILZP.cjs.map +1 -1
  37. package/dist/chunk-NEY26NNF.cjs.map +1 -1
  38. package/dist/{chunk-NSSX7USQ.cjs → chunk-OQV27VC5.cjs} +18 -20
  39. package/dist/chunk-OQV27VC5.cjs.map +1 -0
  40. package/dist/{chunk-DCXYO3RB.js → chunk-PFEPE5UE.js} +7 -3
  41. package/dist/chunk-PFEPE5UE.js.map +1 -0
  42. package/dist/chunk-T52J3SHP.cjs.map +1 -1
  43. package/dist/chunk-UFL6PVLI.cjs.map +1 -1
  44. package/dist/chunk-VI2IE6RC.js +220 -0
  45. package/dist/chunk-VI2IE6RC.js.map +1 -0
  46. package/dist/chunk-VL6L4GDA.cjs.map +1 -1
  47. package/dist/chunk-WJUDOEVB.cjs.map +1 -1
  48. package/dist/chunk-XGKBDPGD.cjs.map +1 -1
  49. package/dist/{chunk-AE4GLYJE.cjs → chunk-YTBB63IE.cjs} +7 -3
  50. package/dist/chunk-YTBB63IE.cjs.map +1 -0
  51. package/dist/chunk-Z57QBVUC.cjs.map +1 -1
  52. package/dist/command.cjs +7 -2
  53. package/dist/command.cjs.map +1 -1
  54. package/dist/command.d.ts +17 -16
  55. package/dist/command.d.ts.map +1 -0
  56. package/dist/command.js +8 -3
  57. package/dist/command.js.map +1 -1
  58. package/dist/confirm-dialog.cjs +1 -1
  59. package/dist/confirm-dialog.cjs.map +1 -1
  60. package/dist/confirm-dialog.d.ts +4 -6
  61. package/dist/confirm-dialog.d.ts.map +1 -0
  62. package/dist/confirm-dialog.js +1 -1
  63. package/dist/confirm-dialog.js.map +1 -1
  64. package/dist/data-table.cjs +46 -34
  65. package/dist/data-table.cjs.map +1 -1
  66. package/dist/data-table.d.ts +9 -11
  67. package/dist/data-table.d.ts.map +1 -0
  68. package/dist/data-table.js +45 -33
  69. package/dist/data-table.js.map +1 -1
  70. package/dist/detail-panel.cjs +3 -3
  71. package/dist/detail-panel.cjs.map +1 -1
  72. package/dist/detail-panel.d.ts +6 -8
  73. package/dist/detail-panel.d.ts.map +1 -0
  74. package/dist/detail-panel.js +3 -3
  75. package/dist/dialog.cjs.map +1 -1
  76. package/dist/dialog.d.ts +6 -8
  77. package/dist/dialog.d.ts.map +1 -0
  78. package/dist/dropdown-menu.cjs.map +1 -1
  79. package/dist/dropdown-menu.d.ts +5 -7
  80. package/dist/dropdown-menu.d.ts.map +1 -0
  81. package/dist/financing-widget.cjs +1 -3
  82. package/dist/financing-widget.cjs.map +1 -1
  83. package/dist/financing-widget.d.ts +5 -6
  84. package/dist/financing-widget.d.ts.map +1 -0
  85. package/dist/financing-widget.js +1 -3
  86. package/dist/financing-widget.js.map +1 -1
  87. package/dist/form-field.cjs.map +1 -1
  88. package/dist/form-field.d.ts +4 -5
  89. package/dist/form-field.d.ts.map +1 -0
  90. package/dist/form-input.cjs.map +1 -1
  91. package/dist/form-input.d.ts +4 -5
  92. package/dist/form-input.d.ts.map +1 -0
  93. package/dist/form-select.cjs.map +1 -1
  94. package/dist/form-select.d.ts +4 -5
  95. package/dist/form-select.d.ts.map +1 -0
  96. package/dist/form-textarea.cjs.map +1 -1
  97. package/dist/form-textarea.d.ts +4 -5
  98. package/dist/form-textarea.d.ts.map +1 -0
  99. package/dist/gtm.cjs +3 -2
  100. package/dist/gtm.cjs.map +1 -1
  101. package/dist/gtm.d.ts +12 -15
  102. package/dist/gtm.d.ts.map +1 -0
  103. package/dist/gtm.js +2 -1
  104. package/dist/input.cjs.map +1 -1
  105. package/dist/input.d.ts +4 -5
  106. package/dist/input.d.ts.map +1 -0
  107. package/dist/label.cjs.map +1 -1
  108. package/dist/label.d.ts +5 -7
  109. package/dist/label.d.ts.map +1 -0
  110. package/dist/list-view.cjs.map +1 -1
  111. package/dist/list-view.d.ts +5 -7
  112. package/dist/list-view.d.ts.map +1 -0
  113. package/dist/mdx-components.cjs +5 -2
  114. package/dist/mdx-components.cjs.map +1 -1
  115. package/dist/mdx-components.d.ts +11 -6
  116. package/dist/mdx-components.d.ts.map +1 -0
  117. package/dist/mdx-components.js +5 -2
  118. package/dist/mdx-components.js.map +1 -1
  119. package/dist/navigation-menu.cjs.map +1 -1
  120. package/dist/navigation-menu.d.ts +5 -7
  121. package/dist/navigation-menu.d.ts.map +1 -0
  122. package/dist/pagination.cjs +3 -2
  123. package/dist/pagination.cjs.map +1 -1
  124. package/dist/pagination.d.ts +10 -14
  125. package/dist/pagination.d.ts.map +1 -0
  126. package/dist/pagination.js +2 -1
  127. package/dist/payment-modal.cjs +20 -19
  128. package/dist/payment-modal.cjs.map +1 -1
  129. package/dist/payment-modal.d.ts +5 -7
  130. package/dist/payment-modal.d.ts.map +1 -0
  131. package/dist/payment-modal.js +19 -18
  132. package/dist/payment-modal.js.map +1 -1
  133. package/dist/popover.cjs.map +1 -1
  134. package/dist/popover.d.ts +4 -5
  135. package/dist/popover.d.ts.map +1 -0
  136. package/dist/price-format.cjs +27 -5
  137. package/dist/price-format.cjs.map +1 -1
  138. package/dist/price-format.d.ts +4 -5
  139. package/dist/price-format.d.ts.map +1 -0
  140. package/dist/price-format.js +26 -4
  141. package/dist/price-format.js.map +1 -1
  142. package/dist/price.cjs +34 -5
  143. package/dist/price.cjs.map +1 -1
  144. package/dist/price.d.ts +8 -10
  145. package/dist/price.d.ts.map +1 -0
  146. package/dist/price.js +32 -3
  147. package/dist/price.js.map +1 -1
  148. package/dist/provider.cjs +4 -2
  149. package/dist/provider.cjs.map +1 -1
  150. package/dist/provider.d.ts +7 -10
  151. package/dist/provider.d.ts.map +1 -0
  152. package/dist/provider.js +3 -1
  153. package/dist/provider.js.map +1 -1
  154. package/dist/quantity-input.cjs +27 -40
  155. package/dist/quantity-input.cjs.map +1 -1
  156. package/dist/quantity-input.d.ts +4 -5
  157. package/dist/quantity-input.d.ts.map +1 -0
  158. package/dist/quantity-input.js +27 -40
  159. package/dist/quantity-input.js.map +1 -1
  160. package/dist/radio-group.cjs.map +1 -1
  161. package/dist/radio-group.d.ts +3 -4
  162. package/dist/radio-group.d.ts.map +1 -0
  163. package/dist/resource-tabs.cjs +1 -0
  164. package/dist/resource-tabs.cjs.map +1 -1
  165. package/dist/resource-tabs.d.ts +6 -8
  166. package/dist/resource-tabs.d.ts.map +1 -0
  167. package/dist/resource-tabs.js +1 -0
  168. package/dist/resource-tabs.js.map +1 -1
  169. package/dist/rules.d.ts +210 -0
  170. package/dist/rules.d.ts.map +1 -0
  171. package/dist/select.cjs.map +1 -1
  172. package/dist/select.d.ts +4 -5
  173. package/dist/select.d.ts.map +1 -0
  174. package/dist/separator.cjs.map +1 -1
  175. package/dist/separator.d.ts +3 -4
  176. package/dist/separator.d.ts.map +1 -0
  177. package/dist/session-replay.cjs +4 -2
  178. package/dist/session-replay.cjs.map +1 -1
  179. package/dist/session-replay.d.ts +4 -5
  180. package/dist/session-replay.d.ts.map +1 -0
  181. package/dist/session-replay.js +4 -2
  182. package/dist/session-replay.js.map +1 -1
  183. package/dist/skeleton.cjs.map +1 -1
  184. package/dist/skeleton.d.ts +2 -4
  185. package/dist/skeleton.d.ts.map +1 -0
  186. package/dist/spinner.cjs.map +1 -1
  187. package/dist/spinner.d.ts +2 -4
  188. package/dist/spinner.d.ts.map +1 -0
  189. package/dist/stock-label.cjs +14 -12
  190. package/dist/stock-label.cjs.map +1 -1
  191. package/dist/stock-label.d.ts +7 -7
  192. package/dist/stock-label.d.ts.map +1 -0
  193. package/dist/stock-label.js +14 -12
  194. package/dist/stock-label.js.map +1 -1
  195. package/dist/table.cjs.map +1 -1
  196. package/dist/table.d.ts +3 -4
  197. package/dist/table.d.ts.map +1 -0
  198. package/dist/tabs.cjs.map +1 -1
  199. package/dist/tabs.d.ts +4 -5
  200. package/dist/tabs.d.ts.map +1 -0
  201. package/dist/textarea.cjs.map +1 -1
  202. package/dist/textarea.d.ts +4 -5
  203. package/dist/textarea.d.ts.map +1 -0
  204. package/llms.txt +23 -38
  205. package/package.json +26 -17
  206. package/dist/accordion.d.cts +0 -9
  207. package/dist/add-to-cart-button.d.cts +0 -14
  208. package/dist/breadcrumb.d.cts +0 -22
  209. package/dist/breadcrumbs.d.cts +0 -31
  210. package/dist/button.d.cts +0 -27
  211. package/dist/card.d.cts +0 -10
  212. package/dist/checkbox.d.cts +0 -6
  213. package/dist/chunk-3VN3FX2Q.js.map +0 -1
  214. package/dist/chunk-AE4GLYJE.cjs.map +0 -1
  215. package/dist/chunk-DCXYO3RB.js.map +0 -1
  216. package/dist/chunk-DZDC4HHK.js +0 -33
  217. package/dist/chunk-DZDC4HHK.js.map +0 -1
  218. package/dist/chunk-NSSX7USQ.cjs.map +0 -1
  219. package/dist/chunk-VLZDTWPR.cjs +0 -33
  220. package/dist/chunk-VLZDTWPR.cjs.map +0 -1
  221. package/dist/command.d.cts +0 -84
  222. package/dist/confirm-dialog.d.cts +0 -35
  223. package/dist/data-table.d.cts +0 -55
  224. package/dist/detail-panel.d.cts +0 -59
  225. package/dist/dialog.d.cts +0 -22
  226. package/dist/dropdown-menu.d.cts +0 -30
  227. package/dist/financing-widget.d.cts +0 -45
  228. package/dist/form-field.d.cts +0 -14
  229. package/dist/form-input.d.cts +0 -19
  230. package/dist/form-select.d.cts +0 -34
  231. package/dist/form-textarea.d.cts +0 -12
  232. package/dist/gtm.d.cts +0 -69
  233. package/dist/input.d.cts +0 -6
  234. package/dist/label.d.cts +0 -8
  235. package/dist/list-view.d.cts +0 -18
  236. package/dist/mdx-components.d.cts +0 -20
  237. package/dist/navigation-menu.d.cts +0 -15
  238. package/dist/pagination.d.cts +0 -50
  239. package/dist/payment-modal.d.cts +0 -30
  240. package/dist/popover.d.cts +0 -9
  241. package/dist/price-format.d.cts +0 -21
  242. package/dist/price.d.cts +0 -78
  243. package/dist/provider.d.cts +0 -47
  244. package/dist/quantity-input.d.cts +0 -33
  245. package/dist/radio-group.d.cts +0 -7
  246. package/dist/resource-tabs.d.cts +0 -33
  247. package/dist/select.d.cts +0 -15
  248. package/dist/separator.d.cts +0 -6
  249. package/dist/session-replay.d.cts +0 -44
  250. package/dist/skeleton.d.cts +0 -5
  251. package/dist/spinner.d.cts +0 -10
  252. package/dist/stock-label.d.cts +0 -47
  253. package/dist/table.d.cts +0 -12
  254. package/dist/tabs.d.cts +0 -9
  255. package/dist/textarea.d.cts +0 -6
@@ -10,7 +10,13 @@ import {
10
10
  } from "./chunk-XIKSI7NY.js";
11
11
  import {
12
12
  ListPagination
13
- } from "./chunk-3VN3FX2Q.js";
13
+ } from "./chunk-JWTTXZDS.js";
14
+ import {
15
+ alignClass,
16
+ ariaSortOf,
17
+ bodyViewOf,
18
+ csvField
19
+ } from "./chunk-VI2IE6RC.js";
14
20
  import {
15
21
  Select,
16
22
  SelectContent,
@@ -43,6 +49,7 @@ import {
43
49
  import * as React from "react";
44
50
  import {
45
51
  flexRender,
52
+ functionalUpdate,
46
53
  getCoreRowModel,
47
54
  getSortedRowModel,
48
55
  getFilteredRowModel,
@@ -51,10 +58,8 @@ import {
51
58
  import { cn } from "@simpleapps-com/augur-utils/web";
52
59
  import { LuArrowDown, LuArrowUp, LuArrowUpDown, LuDownload, LuSettings2 } from "react-icons/lu";
53
60
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
54
- var ALIGN_CLASS = { left: "text-left", center: "text-center", right: "text-right" };
55
61
  function getAlignCn(meta) {
56
- const align = meta?.align ?? "left";
57
- return ALIGN_CLASS[align];
62
+ return alignClass(meta?.align ?? "left");
58
63
  }
59
64
  function buildTanstackColumns(columns, selectable) {
60
65
  const cols = [];
@@ -98,12 +103,7 @@ function buildTanstackColumns(columns, selectable) {
98
103
  }
99
104
  function exportToCsv(columns, data, filename) {
100
105
  const headers = columns.map((c) => c.header);
101
- const rows = data.map(
102
- (row) => columns.map((col) => {
103
- const str = String(row[col.key] ?? "");
104
- return str.includes(",") || str.includes('"') || str.includes("\n") ? `"${str.replace(/"/g, '""')}"` : str;
105
- })
106
- );
106
+ const rows = data.map((row) => columns.map((col) => csvField(String(row[col.key] ?? ""))));
107
107
  const csv = [headers.join(","), ...rows.map((r) => r.join(","))].join("\n");
108
108
  const blob = new Blob([csv], { type: "text/csv;charset=utf-8;" });
109
109
  const url = URL.createObjectURL(blob);
@@ -140,20 +140,21 @@ function ColumnToggle({ table }) {
140
140
  ] });
141
141
  }
142
142
  function HeaderCell({ header }) {
143
- return /* @__PURE__ */ jsx(
144
- TableHead,
143
+ const canSort = header.column.getCanSort();
144
+ const sorted = header.column.getIsSorted();
145
+ const ariaSort = ariaSortOf(canSort, sorted === false ? "unsorted" : sorted);
146
+ return /* @__PURE__ */ jsx(TableHead, { className: getAlignCn(header.column.columnDef.meta), "aria-sort": ariaSort, children: canSort ? /* @__PURE__ */ jsxs(
147
+ "button",
145
148
  {
146
- className: cn(
147
- getAlignCn(header.column.columnDef.meta),
148
- header.column.getCanSort() && "cursor-pointer select-none"
149
- ),
149
+ type: "button",
150
150
  onClick: header.column.getToggleSortingHandler(),
151
- children: /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1", children: [
151
+ className: "inline-flex cursor-pointer select-none items-center gap-1",
152
+ children: [
152
153
  flexRender(header.column.columnDef.header, header.getContext()),
153
- header.column.getCanSort() && /* @__PURE__ */ jsx(SortIndicator, { direction: header.column.getIsSorted() })
154
- ] })
154
+ /* @__PURE__ */ jsx(SortIndicator, { direction: sorted })
155
+ ]
155
156
  }
156
- );
157
+ ) : /* @__PURE__ */ jsx("span", { className: "inline-flex items-center gap-1", children: flexRender(header.column.columnDef.header, header.getContext()) }) });
157
158
  }
158
159
  function DataCell({ cell }) {
159
160
  return /* @__PURE__ */ jsx(TableCell, { className: getAlignCn(cell.column.columnDef.meta), children: flexRender(cell.column.columnDef.cell, cell.getContext()) });
@@ -232,10 +233,11 @@ function TableBodyContent({
232
233
  rows,
233
234
  onRowClick
234
235
  }) {
235
- if (loading) {
236
+ const view = bodyViewOf(loading, rows.length);
237
+ if (view === "loading") {
236
238
  return /* @__PURE__ */ jsx(TableRow, { children: /* @__PURE__ */ jsx(TableCell, { colSpan, className: "h-24 text-center", children: /* @__PURE__ */ jsx(Spinner, { size: "lg", className: "mx-auto" }) }) });
237
239
  }
238
- if (rows.length === 0) {
240
+ if (view === "empty") {
239
241
  return /* @__PURE__ */ jsx(TableRow, { children: /* @__PURE__ */ jsx(TableCell, { colSpan, className: "h-24 text-center", children: emptyMessage }) });
240
242
  }
241
243
  return /* @__PURE__ */ jsx(Fragment, { children: rows.map((row) => /* @__PURE__ */ jsx(DataRow, { row, onRowClick }, row.id)) });
@@ -278,6 +280,16 @@ function PaginationFooter({ pagination }) {
278
280
  )
279
281
  ] });
280
282
  }
283
+ function changeHandler(onChange, current, setInternal) {
284
+ if (!onChange) return setInternal;
285
+ return (updater) => onChange(functionalUpdate(updater, current));
286
+ }
287
+ function clientRowModels(isManualSorting, isManualFiltering) {
288
+ return {
289
+ getSortedRowModel: isManualSorting ? void 0 : getSortedRowModel(),
290
+ getFilteredRowModel: isManualFiltering ? void 0 : getFilteredRowModel()
291
+ };
292
+ }
281
293
  function useDataTable(opts) {
282
294
  const isManualFiltering = opts.externalGlobalFilter !== void 0;
283
295
  const isManualSorting = opts.externalSorting !== void 0;
@@ -288,15 +300,13 @@ function useDataTable(opts) {
288
300
  const sorting = opts.externalSorting ?? internalSorting;
289
301
  const globalFilter = opts.externalGlobalFilter ?? internalGlobalFilter;
290
302
  const rowSelectionState = opts.externalRowSelection ?? internalRowSelection;
291
- const handleSortingChange = opts.onSortingChange ? (updater) => {
292
- opts.onSortingChange(updater(sorting));
293
- } : setInternalSorting;
303
+ const handleSortingChange = changeHandler(opts.onSortingChange, sorting, setInternalSorting);
294
304
  const handleGlobalFilterChange = opts.onGlobalFilterChange ?? setInternalGlobalFilter;
295
- const handleRowSelectionChange = opts.onRowSelectionChange ? (updater) => {
296
- opts.onRowSelectionChange(
297
- updater(rowSelectionState)
298
- );
299
- } : setInternalRowSelection;
305
+ const handleRowSelectionChange = changeHandler(
306
+ opts.onRowSelectionChange,
307
+ rowSelectionState,
308
+ setInternalRowSelection
309
+ );
300
310
  const tanstackColumns = React.useMemo(
301
311
  () => buildTanstackColumns(opts.columns, opts.selectable),
302
312
  [opts.columns, opts.selectable]
@@ -315,8 +325,7 @@ function useDataTable(opts) {
315
325
  onRowSelectionChange: handleRowSelectionChange,
316
326
  onColumnVisibilityChange: setColumnVisibility,
317
327
  getCoreRowModel: getCoreRowModel(),
318
- getSortedRowModel: isManualSorting ? void 0 : getSortedRowModel(),
319
- getFilteredRowModel: isManualFiltering ? void 0 : getFilteredRowModel(),
328
+ ...clientRowModels(isManualSorting, isManualFiltering),
320
329
  manualSorting: isManualSorting,
321
330
  manualFiltering: isManualFiltering,
322
331
  manualPagination: opts.pagination !== void 0,
@@ -326,6 +335,9 @@ function useDataTable(opts) {
326
335
  const selectedRows = opts.selectable ? table.getSelectedRowModel().rows.map((r) => r.original) : [];
327
336
  return { table, tanstackColumns, globalFilter, handleGlobalFilterChange, selectedRows };
328
337
  }
338
+ function toolbarVisible(searchable, toolbar, columnToggle, exportCsv, selectedRows) {
339
+ return Boolean(searchable || toolbar || columnToggle || exportCsv || selectedRows.length > 0);
340
+ }
329
341
  function DataTable({
330
342
  columns,
331
343
  data,
@@ -363,7 +375,7 @@ function DataTable({
363
375
  externalRowSelection: rowSelection,
364
376
  onRowSelectionChange
365
377
  });
366
- const showToolbar = searchable || toolbar || columnToggle || exportCsv || selectedRows.length > 0;
378
+ const showToolbar = toolbarVisible(searchable, toolbar, columnToggle, exportCsv, selectedRows);
367
379
  return /* @__PURE__ */ jsxs("div", { className: cn("space-y-4", className), children: [
368
380
  showToolbar && /* @__PURE__ */ jsx(
369
381
  Toolbar,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/data-table.tsx"],"sourcesContent":["/** Feature-complete admin data table built on TanStack Table. */\n\"use client\";\n\nimport * as React from \"react\";\nimport {\n flexRender,\n getCoreRowModel,\n getSortedRowModel,\n getFilteredRowModel,\n useReactTable,\n type ColumnDef as TanstackColumnDef,\n type SortingState,\n type RowSelectionState,\n type VisibilityState,\n type Table as TanstackTable,\n type Header,\n type Row,\n type Cell,\n} from \"@tanstack/react-table\";\nimport { cn } from \"@simpleapps-com/augur-utils/web\";\nimport { LuArrowDown, LuArrowUp, LuArrowUpDown, LuDownload, LuSettings2 } from \"react-icons/lu\";\nimport { Table, TableHeader, TableBody, TableRow, TableHead, TableCell } from \"./table\";\nimport { Input } from \"./input\";\nimport { Spinner } from \"./spinner\";\nimport { Checkbox } from \"./checkbox\";\nimport { Button } from \"./button\";\nimport { ListPagination } from \"./pagination\";\nimport { Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from \"./select\";\nimport {\n DropdownMenu,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuCheckboxItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n} from \"./dropdown-menu\";\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport interface ColumnDef<T> {\n key: keyof T & string;\n header: string;\n sortable?: boolean;\n render?: (row: T) => React.ReactNode;\n align?: \"left\" | \"center\" | \"right\";\n hideable?: boolean;\n}\n\nexport interface DataTablePagination {\n page: number;\n totalPages: number;\n getHref: (page: number) => string;\n onPageChange?: (page: number) => void;\n /** Current page size. Required when pageSizeOptions is set. */\n pageSize?: number;\n /** Available page size options. Renders a dropdown when provided. */\n pageSizeOptions?: number[];\n /** Called when the user selects a different page size. */\n onPageSizeChange?: (size: number) => void;\n}\n\nexport interface DataTableProps<T> {\n columns: ColumnDef<T>[];\n data: T[];\n searchable?: boolean;\n searchPlaceholder?: string;\n onRowClick?: (row: T) => void;\n loading?: boolean;\n emptyMessage?: string;\n toolbar?: React.ReactNode;\n className?: string;\n getRowId?: (row: T) => string;\n pagination?: DataTablePagination;\n globalFilter?: string;\n onGlobalFilterChange?: (value: string) => void;\n sortingState?: SortingState;\n onSortingChange?: (state: SortingState) => void;\n selectable?: boolean;\n rowSelection?: RowSelectionState;\n onRowSelectionChange?: (state: RowSelectionState) => void;\n bulkActions?: (selectedRows: T[]) => React.ReactNode;\n columnToggle?: boolean;\n exportCsv?: boolean;\n csvFilename?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nconst ALIGN_CLASS = { left: \"text-left\", center: \"text-center\", right: \"text-right\" } as const;\n\nfunction getAlignCn(meta: unknown): string {\n const align = (meta as { align?: string } | undefined)?.align ?? \"left\";\n return ALIGN_CLASS[align as keyof typeof ALIGN_CLASS];\n}\n\nfunction buildTanstackColumns<T>(\n columns: ColumnDef<T>[],\n selectable: boolean,\n): TanstackColumnDef<T, unknown>[] {\n const cols: TanstackColumnDef<T, unknown>[] = [];\n if (selectable) {\n cols.push({\n id: \"_select\",\n header: ({ table }) => (\n <Checkbox\n checked={table.getIsAllPageRowsSelected()}\n onCheckedChange={(v) => table.toggleAllPageRowsSelected(!!v)}\n aria-label=\"Select all\"\n />\n ),\n cell: ({ row }) => (\n <Checkbox\n checked={row.getIsSelected()}\n onCheckedChange={(v) => row.toggleSelected(!!v)}\n aria-label=\"Select row\"\n onClick={(e) => e.stopPropagation()}\n />\n ),\n enableSorting: false,\n enableHiding: false,\n meta: { align: \"center\" },\n });\n }\n for (const col of columns) {\n cols.push({\n id: col.key,\n accessorKey: col.key,\n header: col.header,\n enableSorting: col.sortable ?? false,\n enableHiding: col.hideable !== false,\n cell: col.render\n ? (info) => col.render!(info.row.original)\n : (info) => String(info.getValue() ?? \"\"),\n meta: { align: col.align },\n });\n }\n return cols;\n}\n\nfunction exportToCsv<T>(columns: ColumnDef<T>[], data: T[], filename: string) {\n const headers = columns.map((c) => c.header);\n const rows = data.map((row) =>\n columns.map((col) => {\n const str = String(row[col.key] ?? \"\");\n return str.includes(\",\") || str.includes('\"') || str.includes(\"\\n\")\n ? `\"${str.replace(/\"/g, '\"\"')}\"`\n : str;\n }),\n );\n const csv = [headers.join(\",\"), ...rows.map((r) => r.join(\",\"))].join(\"\\n\");\n const blob = new Blob([csv], { type: \"text/csv;charset=utf-8;\" });\n const url = URL.createObjectURL(blob);\n const link = document.createElement(\"a\");\n link.href = url;\n link.download = `${filename}.csv`;\n link.click();\n URL.revokeObjectURL(url);\n}\n\n// ---------------------------------------------------------------------------\n// Sub-components\n// ---------------------------------------------------------------------------\n\nfunction SortIndicator({ direction }: { direction: false | \"asc\" | \"desc\" }) {\n if (direction === \"asc\") return <LuArrowUp className=\"h-4 w-4\" />;\n if (direction === \"desc\") return <LuArrowDown className=\"h-4 w-4\" />;\n return <LuArrowUpDown className=\"text-muted-foreground/50 h-4 w-4\" />;\n}\n\nfunction ColumnToggle<T>({ table }: { table: TanstackTable<T> }) {\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"outline\" size=\"sm\">\n <LuSettings2 className=\"mr-2 h-4 w-4\" />\n Columns\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuLabel>Toggle columns</DropdownMenuLabel>\n <DropdownMenuSeparator />\n {table\n .getAllColumns()\n .filter((col) => col.getCanHide())\n .map((col) => (\n <DropdownMenuCheckboxItem\n key={col.id}\n checked={col.getIsVisible()}\n onCheckedChange={(v) => col.toggleVisibility(!!v)}\n >\n {col.columnDef.header as string}\n </DropdownMenuCheckboxItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n\nfunction HeaderCell<T>({ header }: { header: Header<T, unknown> }) {\n return (\n <TableHead\n className={cn(\n getAlignCn(header.column.columnDef.meta),\n header.column.getCanSort() && \"cursor-pointer select-none\",\n )}\n onClick={header.column.getToggleSortingHandler()}\n >\n <span className=\"inline-flex items-center gap-1\">\n {flexRender(header.column.columnDef.header, header.getContext())}\n {header.column.getCanSort() && <SortIndicator direction={header.column.getIsSorted()} />}\n </span>\n </TableHead>\n );\n}\n\nfunction DataCell<T>({ cell }: { cell: Cell<T, unknown> }) {\n return (\n <TableCell className={getAlignCn(cell.column.columnDef.meta)}>\n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n </TableCell>\n );\n}\n\nfunction DataRow<T>({ row, onRowClick }: { row: Row<T>; onRowClick?: (r: T) => void }) {\n return (\n <TableRow\n data-state={row.getIsSelected() ? \"selected\" : undefined}\n className={cn(onRowClick && \"cursor-pointer\")}\n onClick={onRowClick ? () => onRowClick(row.original) : undefined}\n >\n {row.getVisibleCells().map((cell) => (\n <DataCell key={cell.id} cell={cell} />\n ))}\n </TableRow>\n );\n}\n\nfunction ExportButton<T>({\n columns,\n data,\n csvFilename,\n}: {\n columns: ColumnDef<T>[];\n data: T[];\n csvFilename: string;\n}) {\n return (\n <Button variant=\"outline\" size=\"sm\" onClick={() => exportToCsv(columns, data, csvFilename)}>\n <LuDownload className=\"mr-2 h-4 w-4\" />\n Export\n </Button>\n );\n}\n\nfunction BulkActionsBar<T>({\n selectedRows,\n bulkActions,\n}: {\n selectedRows: T[];\n bulkActions: (rows: T[]) => React.ReactNode;\n}) {\n return (\n <div className=\"flex items-center gap-2\">\n <span className=\"text-muted-foreground text-sm\">{selectedRows.length} selected</span>\n {bulkActions(selectedRows)}\n </div>\n );\n}\n\nfunction Toolbar<T>({\n searchable,\n searchPlaceholder,\n globalFilter,\n onGlobalFilterChange,\n selectedRows,\n bulkActions,\n toolbar,\n exportCsv,\n columns,\n data,\n csvFilename,\n columnToggle,\n table,\n}: {\n searchable: boolean;\n searchPlaceholder: string;\n globalFilter: string;\n onGlobalFilterChange: (value: string) => void;\n selectedRows: T[];\n bulkActions?: (rows: T[]) => React.ReactNode;\n toolbar?: React.ReactNode;\n exportCsv: boolean;\n columns: ColumnDef<T>[];\n data: T[];\n csvFilename: string;\n columnToggle: boolean;\n table: TanstackTable<T>;\n}) {\n const hasSelection = selectedRows.length > 0;\n return (\n <div className=\"flex items-center gap-4\">\n {searchable && (\n <Input\n placeholder={searchPlaceholder}\n value={globalFilter}\n onChange={(e) => onGlobalFilterChange(e.target.value)}\n className=\"max-w-sm\"\n />\n )}\n {hasSelection && bulkActions && (\n <BulkActionsBar selectedRows={selectedRows} bulkActions={bulkActions} />\n )}\n <div className=\"ml-auto flex items-center gap-2\">\n {toolbar}\n {exportCsv && <ExportButton columns={columns} data={data} csvFilename={csvFilename} />}\n {columnToggle && <ColumnToggle table={table} />}\n </div>\n </div>\n );\n}\n\nfunction TableBodyContent<T>({\n loading,\n colSpan,\n emptyMessage,\n rows,\n onRowClick,\n}: {\n loading: boolean;\n colSpan: number;\n emptyMessage: string;\n rows: Row<T>[];\n onRowClick?: (r: T) => void;\n}) {\n if (loading) {\n return (\n <TableRow>\n <TableCell colSpan={colSpan} className=\"h-24 text-center\">\n <Spinner size=\"lg\" className=\"mx-auto\" />\n </TableCell>\n </TableRow>\n );\n }\n if (rows.length === 0) {\n return (\n <TableRow>\n <TableCell colSpan={colSpan} className=\"h-24 text-center\">\n {emptyMessage}\n </TableCell>\n </TableRow>\n );\n }\n return (\n <>\n {rows.map((row) => (\n <DataRow key={row.id} row={row} onRowClick={onRowClick} />\n ))}\n </>\n );\n}\n\nfunction PageSizeSelector({\n pageSize,\n options,\n onChange,\n}: {\n pageSize: number;\n options: number[];\n onChange: (size: number) => void;\n}) {\n return (\n <div className=\"flex items-center gap-2\">\n <span className=\"text-muted-foreground text-sm\">Rows per page</span>\n <Select value={String(pageSize)} onValueChange={(v) => onChange(Number(v))}>\n <SelectTrigger className=\"h-8 w-[70px]\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {options.map((size) => (\n <SelectItem key={size} value={String(size)}>\n {size}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n );\n}\n\nfunction PaginationFooter({ pagination }: { pagination?: DataTablePagination }) {\n if (!pagination) return null;\n const showPageSize =\n pagination.pageSizeOptions && pagination.pageSize !== undefined && pagination.onPageSizeChange;\n const showPages = pagination.totalPages > 1;\n if (!showPageSize && !showPages) return null;\n return (\n <div className=\"flex items-center justify-between\">\n {showPageSize ? (\n <PageSizeSelector\n pageSize={pagination.pageSize!}\n options={pagination.pageSizeOptions!}\n onChange={pagination.onPageSizeChange!}\n />\n ) : (\n <div />\n )}\n {showPages && (\n <ListPagination\n page={pagination.page}\n totalPages={pagination.totalPages}\n getHref={pagination.getHref}\n onPageChange={pagination.onPageChange}\n />\n )}\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Hook: encapsulates all state management and TanStack Table configuration\n// ---------------------------------------------------------------------------\n\ninterface UseDataTableOptions<T> {\n columns: ColumnDef<T>[];\n data: T[];\n selectable: boolean;\n getRowId?: (row: T) => string;\n pagination?: DataTablePagination;\n externalGlobalFilter?: string;\n onGlobalFilterChange?: (value: string) => void;\n externalSorting?: SortingState;\n onSortingChange?: (state: SortingState) => void;\n externalRowSelection?: RowSelectionState;\n onRowSelectionChange?: (state: RowSelectionState) => void;\n}\n\nfunction useDataTable<T>(opts: UseDataTableOptions<T>) {\n const isManualFiltering = opts.externalGlobalFilter !== undefined;\n const isManualSorting = opts.externalSorting !== undefined;\n\n const [internalSorting, setInternalSorting] = React.useState<SortingState>([]);\n const [internalGlobalFilter, setInternalGlobalFilter] = React.useState(\"\");\n const [internalRowSelection, setInternalRowSelection] = React.useState<RowSelectionState>({});\n const [columnVisibility, setColumnVisibility] = React.useState<VisibilityState>({});\n\n const sorting = opts.externalSorting ?? internalSorting;\n const globalFilter = opts.externalGlobalFilter ?? internalGlobalFilter;\n const rowSelectionState = opts.externalRowSelection ?? internalRowSelection;\n\n const handleSortingChange = opts.onSortingChange\n ? (updater: SortingState | ((prev: SortingState) => SortingState)) => {\n opts.onSortingChange!((updater as (prev: SortingState) => SortingState)(sorting));\n }\n : setInternalSorting;\n\n const handleGlobalFilterChange = opts.onGlobalFilterChange ?? setInternalGlobalFilter;\n\n const handleRowSelectionChange = opts.onRowSelectionChange\n ? (updater: RowSelectionState | ((prev: RowSelectionState) => RowSelectionState)) => {\n opts.onRowSelectionChange!(\n (updater as (prev: RowSelectionState) => RowSelectionState)(rowSelectionState),\n );\n }\n : setInternalRowSelection;\n\n const tanstackColumns = React.useMemo(\n () => buildTanstackColumns(opts.columns, opts.selectable),\n [opts.columns, opts.selectable],\n );\n\n const table = useReactTable({\n data: opts.data,\n columns: tanstackColumns,\n state: {\n sorting,\n globalFilter: isManualFiltering ? undefined : globalFilter,\n rowSelection: rowSelectionState,\n columnVisibility,\n },\n onSortingChange: handleSortingChange,\n onGlobalFilterChange: isManualFiltering ? undefined : setInternalGlobalFilter,\n onRowSelectionChange: handleRowSelectionChange,\n onColumnVisibilityChange: setColumnVisibility,\n getCoreRowModel: getCoreRowModel(),\n getSortedRowModel: isManualSorting ? undefined : getSortedRowModel(),\n getFilteredRowModel: isManualFiltering ? undefined : getFilteredRowModel(),\n manualSorting: isManualSorting,\n manualFiltering: isManualFiltering,\n manualPagination: opts.pagination !== undefined,\n enableRowSelection: opts.selectable,\n getRowId: opts.getRowId ? (row) => opts.getRowId!(row) : undefined,\n });\n\n const selectedRows = opts.selectable\n ? table.getSelectedRowModel().rows.map((r) => r.original)\n : [];\n\n return { table, tanstackColumns, globalFilter, handleGlobalFilterChange, selectedRows };\n}\n\n// ---------------------------------------------------------------------------\n// Main component\n// ---------------------------------------------------------------------------\n\nfunction DataTable<T>({\n columns,\n data,\n searchable = false,\n searchPlaceholder = \"Search...\",\n onRowClick,\n loading = false,\n emptyMessage = \"No results.\",\n toolbar,\n className,\n getRowId,\n pagination,\n globalFilter: externalGlobalFilter,\n onGlobalFilterChange,\n sortingState,\n onSortingChange,\n selectable = false,\n rowSelection,\n onRowSelectionChange,\n bulkActions,\n columnToggle = false,\n exportCsv = false,\n csvFilename = \"export\",\n}: DataTableProps<T>) {\n const { table, tanstackColumns, globalFilter, handleGlobalFilterChange, selectedRows } =\n useDataTable({\n columns,\n data,\n selectable,\n getRowId,\n pagination,\n externalGlobalFilter,\n onGlobalFilterChange,\n externalSorting: sortingState,\n onSortingChange,\n externalRowSelection: rowSelection,\n onRowSelectionChange,\n });\n\n const showToolbar = searchable || toolbar || columnToggle || exportCsv || selectedRows.length > 0;\n\n return (\n <div className={cn(\"space-y-4\", className)}>\n {showToolbar && (\n <Toolbar\n searchable={searchable}\n searchPlaceholder={searchPlaceholder}\n globalFilter={globalFilter}\n onGlobalFilterChange={handleGlobalFilterChange}\n selectedRows={selectedRows}\n bulkActions={bulkActions}\n toolbar={toolbar}\n exportCsv={exportCsv}\n columns={columns}\n data={data}\n csvFilename={csvFilename}\n columnToggle={columnToggle}\n table={table}\n />\n )}\n <Table>\n <TableHeader className=\"bg-background sticky top-0 z-10\">\n {table.getHeaderGroups().map((hg) => (\n <TableRow key={hg.id}>\n {hg.headers.map((h) => (\n <HeaderCell key={h.id} header={h} />\n ))}\n </TableRow>\n ))}\n </TableHeader>\n <TableBody>\n <TableBodyContent\n loading={loading}\n colSpan={tanstackColumns.length}\n emptyMessage={emptyMessage}\n rows={table.getRowModel().rows}\n onRowClick={onRowClick}\n />\n </TableBody>\n </Table>\n <PaginationFooter pagination={pagination} />\n </div>\n );\n}\nDataTable.displayName = \"DataTable\";\n\nexport { DataTable };\nexport type { SortingState, RowSelectionState, VisibilityState };\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/data-table.tsx"],"sourcesContent":["/** Feature-complete admin data table built on TanStack Table. */\n\"use client\";\n\nimport * as React from \"react\";\nimport {\n flexRender,\n functionalUpdate,\n getCoreRowModel,\n getSortedRowModel,\n getFilteredRowModel,\n useReactTable,\n type ColumnDef as TanstackColumnDef,\n type SortingState,\n type RowSelectionState,\n type Updater,\n type VisibilityState,\n type Table as TanstackTable,\n type Header,\n type Row,\n type Cell,\n} from \"@tanstack/react-table\";\nimport { cn } from \"@simpleapps-com/augur-utils/web\";\nimport { LuArrowDown, LuArrowUp, LuArrowUpDown, LuDownload, LuSettings2 } from \"react-icons/lu\";\nimport { Table, TableHeader, TableBody, TableRow, TableHead, TableCell } from \"./table\";\nimport { Input } from \"./input\";\nimport { Spinner } from \"./spinner\";\nimport { alignClass, ariaSortOf, bodyViewOf, csvField } from \"./rules\";\nimport { Checkbox } from \"./checkbox\";\nimport { Button } from \"./button\";\nimport { ListPagination } from \"./pagination\";\nimport { Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from \"./select\";\nimport {\n DropdownMenu,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuCheckboxItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n} from \"./dropdown-menu\";\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport interface ColumnDef<T> {\n key: keyof T & string;\n header: string;\n sortable?: boolean;\n render?: (row: T) => React.ReactNode;\n align?: \"left\" | \"center\" | \"right\";\n hideable?: boolean;\n}\n\nexport interface DataTablePagination {\n page: number;\n totalPages: number;\n getHref: (page: number) => string;\n onPageChange?: (page: number) => void;\n /** Current page size. Required when pageSizeOptions is set. */\n pageSize?: number;\n /** Available page size options. Renders a dropdown when provided. */\n pageSizeOptions?: number[];\n /** Called when the user selects a different page size. */\n onPageSizeChange?: (size: number) => void;\n}\n\nexport interface DataTableProps<T> {\n columns: ColumnDef<T>[];\n data: T[];\n searchable?: boolean;\n searchPlaceholder?: string;\n onRowClick?: (row: T) => void;\n loading?: boolean;\n emptyMessage?: string;\n toolbar?: React.ReactNode;\n className?: string;\n getRowId?: (row: T) => string;\n pagination?: DataTablePagination;\n globalFilter?: string;\n onGlobalFilterChange?: (value: string) => void;\n sortingState?: SortingState;\n onSortingChange?: (state: SortingState) => void;\n selectable?: boolean;\n rowSelection?: RowSelectionState;\n onRowSelectionChange?: (state: RowSelectionState) => void;\n bulkActions?: (selectedRows: T[]) => React.ReactNode;\n columnToggle?: boolean;\n exportCsv?: boolean;\n csvFilename?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nfunction getAlignCn(meta: unknown): string {\n return alignClass((meta as { align?: string } | undefined)?.align ?? \"left\");\n}\n\nfunction buildTanstackColumns<T>(\n columns: ColumnDef<T>[],\n selectable: boolean,\n): TanstackColumnDef<T, unknown>[] {\n const cols: TanstackColumnDef<T, unknown>[] = [];\n if (selectable) {\n cols.push({\n id: \"_select\",\n header: ({ table }) => (\n <Checkbox\n checked={table.getIsAllPageRowsSelected()}\n onCheckedChange={(v) => table.toggleAllPageRowsSelected(!!v)}\n aria-label=\"Select all\"\n />\n ),\n cell: ({ row }) => (\n <Checkbox\n checked={row.getIsSelected()}\n onCheckedChange={(v) => row.toggleSelected(!!v)}\n aria-label=\"Select row\"\n onClick={(e) => e.stopPropagation()}\n />\n ),\n enableSorting: false,\n enableHiding: false,\n meta: { align: \"center\" },\n });\n }\n for (const col of columns) {\n cols.push({\n id: col.key,\n accessorKey: col.key,\n header: col.header,\n enableSorting: col.sortable ?? false,\n enableHiding: col.hideable !== false,\n cell: col.render\n ? (info) => col.render!(info.row.original)\n : (info) => String(info.getValue() ?? \"\"),\n meta: { align: col.align },\n });\n }\n return cols;\n}\n\nfunction exportToCsv<T>(columns: ColumnDef<T>[], data: T[], filename: string) {\n const headers = columns.map((c) => c.header);\n const rows = data.map((row) => columns.map((col) => csvField(String(row[col.key] ?? \"\"))));\n const csv = [headers.join(\",\"), ...rows.map((r) => r.join(\",\"))].join(\"\\n\");\n const blob = new Blob([csv], { type: \"text/csv;charset=utf-8;\" });\n const url = URL.createObjectURL(blob);\n const link = document.createElement(\"a\");\n link.href = url;\n link.download = `${filename}.csv`;\n link.click();\n URL.revokeObjectURL(url);\n}\n\n// ---------------------------------------------------------------------------\n// Sub-components\n// ---------------------------------------------------------------------------\n\nfunction SortIndicator({ direction }: { direction: false | \"asc\" | \"desc\" }) {\n if (direction === \"asc\") return <LuArrowUp className=\"h-4 w-4\" />;\n if (direction === \"desc\") return <LuArrowDown className=\"h-4 w-4\" />;\n return <LuArrowUpDown className=\"text-muted-foreground/50 h-4 w-4\" />;\n}\n\nfunction ColumnToggle<T>({ table }: { table: TanstackTable<T> }) {\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"outline\" size=\"sm\">\n <LuSettings2 className=\"mr-2 h-4 w-4\" />\n Columns\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuLabel>Toggle columns</DropdownMenuLabel>\n <DropdownMenuSeparator />\n {table\n .getAllColumns()\n .filter((col) => col.getCanHide())\n .map((col) => (\n <DropdownMenuCheckboxItem\n key={col.id}\n checked={col.getIsVisible()}\n onCheckedChange={(v) => col.toggleVisibility(!!v)}\n >\n {col.columnDef.header as string}\n </DropdownMenuCheckboxItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n );\n}\n\nfunction HeaderCell<T>({ header }: { header: Header<T, unknown> }) {\n const canSort = header.column.getCanSort();\n const sorted = header.column.getIsSorted();\n // aria-sort announces sort state to screen readers; only meaningful on\n // sortable columns. Sorting is triggered by a real <button> so it is\n // keyboard-focusable and Enter/Space-activatable (a click handler on the\n // <th> alone is mouse-only).\n // ariaSortOf gives only \"ascending\", \"descending\", \"none\" or undefined.\n const ariaSort = ariaSortOf(canSort, sorted === false ? \"unsorted\" : sorted) as\n React.AriaAttributes[\"aria-sort\"] | undefined;\n\n return (\n <TableHead className={getAlignCn(header.column.columnDef.meta)} aria-sort={ariaSort}>\n {canSort ? (\n <button\n type=\"button\"\n onClick={header.column.getToggleSortingHandler()}\n className=\"inline-flex cursor-pointer select-none items-center gap-1\"\n >\n {flexRender(header.column.columnDef.header, header.getContext())}\n <SortIndicator direction={sorted} />\n </button>\n ) : (\n <span className=\"inline-flex items-center gap-1\">\n {flexRender(header.column.columnDef.header, header.getContext())}\n </span>\n )}\n </TableHead>\n );\n}\n\nfunction DataCell<T>({ cell }: { cell: Cell<T, unknown> }) {\n return (\n <TableCell className={getAlignCn(cell.column.columnDef.meta)}>\n {flexRender(cell.column.columnDef.cell, cell.getContext())}\n </TableCell>\n );\n}\n\nfunction DataRow<T>({ row, onRowClick }: { row: Row<T>; onRowClick?: (r: T) => void }) {\n return (\n <TableRow\n data-state={row.getIsSelected() ? \"selected\" : undefined}\n className={cn(onRowClick && \"cursor-pointer\")}\n onClick={onRowClick ? () => onRowClick(row.original) : undefined}\n >\n {row.getVisibleCells().map((cell) => (\n <DataCell key={cell.id} cell={cell} />\n ))}\n </TableRow>\n );\n}\n\nfunction ExportButton<T>({\n columns,\n data,\n csvFilename,\n}: {\n columns: ColumnDef<T>[];\n data: T[];\n csvFilename: string;\n}) {\n return (\n <Button variant=\"outline\" size=\"sm\" onClick={() => exportToCsv(columns, data, csvFilename)}>\n <LuDownload className=\"mr-2 h-4 w-4\" />\n Export\n </Button>\n );\n}\n\nfunction BulkActionsBar<T>({\n selectedRows,\n bulkActions,\n}: {\n selectedRows: T[];\n bulkActions: (rows: T[]) => React.ReactNode;\n}) {\n return (\n <div className=\"flex items-center gap-2\">\n <span className=\"text-muted-foreground text-sm\">{selectedRows.length} selected</span>\n {bulkActions(selectedRows)}\n </div>\n );\n}\n\nfunction Toolbar<T>({\n searchable,\n searchPlaceholder,\n globalFilter,\n onGlobalFilterChange,\n selectedRows,\n bulkActions,\n toolbar,\n exportCsv,\n columns,\n data,\n csvFilename,\n columnToggle,\n table,\n}: {\n searchable: boolean;\n searchPlaceholder: string;\n globalFilter: string;\n onGlobalFilterChange: (value: string) => void;\n selectedRows: T[];\n bulkActions?: (rows: T[]) => React.ReactNode;\n toolbar?: React.ReactNode;\n exportCsv: boolean;\n columns: ColumnDef<T>[];\n data: T[];\n csvFilename: string;\n columnToggle: boolean;\n table: TanstackTable<T>;\n}) {\n const hasSelection = selectedRows.length > 0;\n return (\n <div className=\"flex items-center gap-4\">\n {searchable && (\n <Input\n placeholder={searchPlaceholder}\n value={globalFilter}\n onChange={(e) => onGlobalFilterChange(e.target.value)}\n className=\"max-w-sm\"\n />\n )}\n {hasSelection && bulkActions && (\n <BulkActionsBar selectedRows={selectedRows} bulkActions={bulkActions} />\n )}\n <div className=\"ml-auto flex items-center gap-2\">\n {toolbar}\n {exportCsv && <ExportButton columns={columns} data={data} csvFilename={csvFilename} />}\n {columnToggle && <ColumnToggle table={table} />}\n </div>\n </div>\n );\n}\n\nfunction TableBodyContent<T>({\n loading,\n colSpan,\n emptyMessage,\n rows,\n onRowClick,\n}: {\n loading: boolean;\n colSpan: number;\n emptyMessage: string;\n rows: Row<T>[];\n onRowClick?: (r: T) => void;\n}) {\n const view = bodyViewOf(loading, rows.length);\n if (view === \"loading\") {\n return (\n <TableRow>\n <TableCell colSpan={colSpan} className=\"h-24 text-center\">\n <Spinner size=\"lg\" className=\"mx-auto\" />\n </TableCell>\n </TableRow>\n );\n }\n if (view === \"empty\") {\n return (\n <TableRow>\n <TableCell colSpan={colSpan} className=\"h-24 text-center\">\n {emptyMessage}\n </TableCell>\n </TableRow>\n );\n }\n return (\n <>\n {rows.map((row) => (\n <DataRow key={row.id} row={row} onRowClick={onRowClick} />\n ))}\n </>\n );\n}\n\nfunction PageSizeSelector({\n pageSize,\n options,\n onChange,\n}: {\n pageSize: number;\n options: number[];\n onChange: (size: number) => void;\n}) {\n return (\n <div className=\"flex items-center gap-2\">\n <span className=\"text-muted-foreground text-sm\">Rows per page</span>\n <Select value={String(pageSize)} onValueChange={(v) => onChange(Number(v))}>\n <SelectTrigger className=\"h-8 w-[70px]\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {options.map((size) => (\n <SelectItem key={size} value={String(size)}>\n {size}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n );\n}\n\nfunction PaginationFooter({ pagination }: { pagination?: DataTablePagination }) {\n if (!pagination) return null;\n const showPageSize =\n pagination.pageSizeOptions && pagination.pageSize !== undefined && pagination.onPageSizeChange;\n const showPages = pagination.totalPages > 1;\n if (!showPageSize && !showPages) return null;\n return (\n <div className=\"flex items-center justify-between\">\n {showPageSize ? (\n <PageSizeSelector\n pageSize={pagination.pageSize!}\n options={pagination.pageSizeOptions!}\n onChange={pagination.onPageSizeChange!}\n />\n ) : (\n <div />\n )}\n {showPages && (\n <ListPagination\n page={pagination.page}\n totalPages={pagination.totalPages}\n getHref={pagination.getHref}\n onPageChange={pagination.onPageChange}\n />\n )}\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Hook: encapsulates all state management and TanStack Table configuration\n// ---------------------------------------------------------------------------\n\ninterface UseDataTableOptions<T> {\n columns: ColumnDef<T>[];\n data: T[];\n selectable: boolean;\n getRowId?: (row: T) => string;\n pagination?: DataTablePagination;\n externalGlobalFilter?: string;\n onGlobalFilterChange?: (value: string) => void;\n externalSorting?: SortingState;\n onSortingChange?: (state: SortingState) => void;\n externalRowSelection?: RowSelectionState;\n onRowSelectionChange?: (state: RowSelectionState) => void;\n}\n\n/**\n * The change handler TanStack calls: the caller's (with TanStack's Updater<S> =\n * S | ((old: S) => S) resolved against the current value via functionalUpdate, so a plain\n * value from resetRowSelection()/setSorting(v) is not called as a function), or the internal\n * state setter when the state is uncontrolled.\n */\nfunction changeHandler<S>(\n onChange: ((state: S) => void) | undefined,\n current: S,\n setInternal: React.Dispatch<React.SetStateAction<S>>,\n): (updater: Updater<S>) => void {\n if (!onChange) return setInternal;\n return (updater) => onChange(functionalUpdate(updater, current));\n}\n\n/** TanStack's client-side models, left out when the caller sorts or filters on the server. */\nfunction clientRowModels(isManualSorting: boolean, isManualFiltering: boolean) {\n return {\n getSortedRowModel: isManualSorting ? undefined : getSortedRowModel(),\n getFilteredRowModel: isManualFiltering ? undefined : getFilteredRowModel(),\n };\n}\n\nfunction useDataTable<T>(opts: UseDataTableOptions<T>) {\n const isManualFiltering = opts.externalGlobalFilter !== undefined;\n const isManualSorting = opts.externalSorting !== undefined;\n\n const [internalSorting, setInternalSorting] = React.useState<SortingState>([]);\n const [internalGlobalFilter, setInternalGlobalFilter] = React.useState(\"\");\n const [internalRowSelection, setInternalRowSelection] = React.useState<RowSelectionState>({});\n const [columnVisibility, setColumnVisibility] = React.useState<VisibilityState>({});\n\n const sorting = opts.externalSorting ?? internalSorting;\n const globalFilter = opts.externalGlobalFilter ?? internalGlobalFilter;\n const rowSelectionState = opts.externalRowSelection ?? internalRowSelection;\n\n const handleSortingChange = changeHandler(opts.onSortingChange, sorting, setInternalSorting);\n\n const handleGlobalFilterChange = opts.onGlobalFilterChange ?? setInternalGlobalFilter;\n\n const handleRowSelectionChange = changeHandler(\n opts.onRowSelectionChange,\n rowSelectionState,\n setInternalRowSelection,\n );\n\n const tanstackColumns = React.useMemo(\n () => buildTanstackColumns(opts.columns, opts.selectable),\n [opts.columns, opts.selectable],\n );\n\n const table = useReactTable({\n data: opts.data,\n columns: tanstackColumns,\n state: {\n sorting,\n globalFilter: isManualFiltering ? undefined : globalFilter,\n rowSelection: rowSelectionState,\n columnVisibility,\n },\n onSortingChange: handleSortingChange,\n onGlobalFilterChange: isManualFiltering ? undefined : setInternalGlobalFilter,\n onRowSelectionChange: handleRowSelectionChange,\n onColumnVisibilityChange: setColumnVisibility,\n getCoreRowModel: getCoreRowModel(),\n ...clientRowModels(isManualSorting, isManualFiltering),\n manualSorting: isManualSorting,\n manualFiltering: isManualFiltering,\n manualPagination: opts.pagination !== undefined,\n enableRowSelection: opts.selectable,\n getRowId: opts.getRowId ? (row) => opts.getRowId!(row) : undefined,\n });\n\n const selectedRows = opts.selectable\n ? table.getSelectedRowModel().rows.map((r) => r.original)\n : [];\n\n return { table, tanstackColumns, globalFilter, handleGlobalFilterChange, selectedRows };\n}\n\n// ---------------------------------------------------------------------------\n// Main component\n// ---------------------------------------------------------------------------\n\n/** The toolbar shows when it has something to show: search, custom content, column toggle, CSV export, or a selection. */\nfunction toolbarVisible(\n searchable: boolean,\n toolbar: React.ReactNode,\n columnToggle: boolean,\n exportCsv: boolean,\n selectedRows: readonly unknown[],\n): boolean {\n return Boolean(searchable || toolbar || columnToggle || exportCsv || selectedRows.length > 0);\n}\n\nfunction DataTable<T>({\n columns,\n data,\n searchable = false,\n searchPlaceholder = \"Search...\",\n onRowClick,\n loading = false,\n emptyMessage = \"No results.\",\n toolbar,\n className,\n getRowId,\n pagination,\n globalFilter: externalGlobalFilter,\n onGlobalFilterChange,\n sortingState,\n onSortingChange,\n selectable = false,\n rowSelection,\n onRowSelectionChange,\n bulkActions,\n columnToggle = false,\n exportCsv = false,\n csvFilename = \"export\",\n}: DataTableProps<T>) {\n const { table, tanstackColumns, globalFilter, handleGlobalFilterChange, selectedRows } =\n useDataTable({\n columns,\n data,\n selectable,\n getRowId,\n pagination,\n externalGlobalFilter,\n onGlobalFilterChange,\n externalSorting: sortingState,\n onSortingChange,\n externalRowSelection: rowSelection,\n onRowSelectionChange,\n });\n\n const showToolbar = toolbarVisible(searchable, toolbar, columnToggle, exportCsv, selectedRows);\n\n return (\n <div className={cn(\"space-y-4\", className)}>\n {showToolbar && (\n <Toolbar\n searchable={searchable}\n searchPlaceholder={searchPlaceholder}\n globalFilter={globalFilter}\n onGlobalFilterChange={handleGlobalFilterChange}\n selectedRows={selectedRows}\n bulkActions={bulkActions}\n toolbar={toolbar}\n exportCsv={exportCsv}\n columns={columns}\n data={data}\n csvFilename={csvFilename}\n columnToggle={columnToggle}\n table={table}\n />\n )}\n <Table>\n <TableHeader className=\"bg-background sticky top-0 z-10\">\n {table.getHeaderGroups().map((hg) => (\n <TableRow key={hg.id}>\n {hg.headers.map((h) => (\n <HeaderCell key={h.id} header={h} />\n ))}\n </TableRow>\n ))}\n </TableHeader>\n <TableBody>\n <TableBodyContent\n loading={loading}\n colSpan={tanstackColumns.length}\n emptyMessage={emptyMessage}\n rows={table.getRowModel().rows}\n onRowClick={onRowClick}\n />\n </TableBody>\n </Table>\n <PaginationFooter pagination={pagination} />\n </div>\n );\n}\nDataTable.displayName = \"DataTable\";\n\nexport { DataTable };\nexport type { SortingState, RowSelectionState, VisibilityState };\n"],"mappings":"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","names":[]}
@@ -2,14 +2,14 @@
2
2
  "use client";
3
3
 
4
4
 
5
- var _chunkWJUDOEVBcjs = require('./chunk-WJUDOEVB.cjs');
6
-
7
-
8
5
  var _chunkZ57QBVUCcjs = require('./chunk-Z57QBVUC.cjs');
9
6
  require('./chunk-5ZITWMV4.cjs');
10
7
 
11
8
 
12
9
  var _chunk32XB3REYcjs = require('./chunk-32XB3REY.cjs');
10
+
11
+
12
+ var _chunkWJUDOEVBcjs = require('./chunk-WJUDOEVB.cjs');
13
13
  require('./chunk-BXMTQGKV.cjs');
14
14
  require('./chunk-76RSVRGB.cjs');
15
15
  require('./chunk-7EXXNELX.cjs');
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/runner/work/augur-packages/augur-packages/packages/augur-web/dist/detail-panel.cjs","../src/detail-panel.tsx"],"names":[],"mappings":"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","file":"/home/runner/work/augur-packages/augur-packages/packages/augur-web/dist/detail-panel.cjs","sourcesContent":[null,"/** Read/edit toggle panel for a single record. */\n\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"@simpleapps-com/augur-utils/web\";\nimport { Button } from \"./button\";\nimport { FormInput } from \"./form-input\";\nimport { FormSelect } from \"./form-select\";\nimport { FormTextarea } from \"./form-textarea\";\nimport { Spinner } from \"./spinner\";\n\nexport interface FieldDef<T> {\n /** Property key on the data object. */\n key: keyof T & string;\n /** Display label. */\n label: string;\n /** Field type determines the input component used in edit mode. */\n type: \"text\" | \"textarea\" | \"select\" | \"readonly\";\n /** Options for select fields. */\n options?: { label: string; value: string }[];\n /** Mark the field as required in edit mode. */\n required?: boolean;\n /** Custom read-mode renderer. Receives the field value. */\n render?: (value: T[keyof T]) => React.ReactNode;\n}\n\nexport interface DetailPanelProps<T extends object> {\n /** Field definitions describing each field. */\n fields: FieldDef<T>[];\n /** The record to display/edit. */\n data: T;\n /** Called with the updated record when the user saves. */\n onSave: (data: T) => void;\n /** Called when the user cancels editing. */\n onCancel?: () => void;\n /** Whether a save operation is in progress. */\n loading?: boolean;\n /** Optional title displayed above the fields. */\n title?: string;\n /** Additional class name for the root container. */\n className?: string;\n /** Start in edit mode. */\n defaultEditing?: boolean;\n}\n\n/**\n * Read/edit toggle panel for a single record. Renders field values in read\n * mode, and form inputs in edit mode based on field definitions.\n *\n * @example\n * ```tsx\n * const fields: FieldDef<Brand>[] = [\n * { key: \"brandsName\", label: \"Name\", type: \"text\", required: true },\n * { key: \"brandsDesc\", label: \"Description\", type: \"textarea\" },\n * { key: \"brandsUid\", label: \"UID\", type: \"readonly\" },\n * ];\n *\n * <DetailPanel fields={fields} data={brand} onSave={handleSave} />\n * ```\n */\nfunction DetailPanel<T extends object>({\n fields,\n data,\n onSave,\n onCancel,\n loading = false,\n title,\n className,\n defaultEditing = false,\n}: DetailPanelProps<T>) {\n const [editing, setEditing] = React.useState(defaultEditing);\n const [draft, setDraft] = React.useState<T>(data);\n\n React.useEffect(() => {\n setDraft(data);\n }, [data]);\n\n const handleEdit = () => {\n setDraft(data);\n setEditing(true);\n };\n\n const handleCancel = () => {\n setDraft(data);\n setEditing(false);\n onCancel?.();\n };\n\n const handleSave = () => {\n onSave(draft);\n };\n\n const updateField = (key: keyof T & string, value: unknown) => {\n setDraft((prev) => ({ ...prev, [key]: value }));\n };\n\n return (\n <div className={cn(\"space-y-6\", className)}>\n {(title || !editing) && (\n <div className=\"flex items-center justify-between\">\n {title && <h3 className=\"text-lg font-semibold\">{title}</h3>}\n {!editing && (\n <Button variant=\"outline\" size=\"sm\" onClick={handleEdit}>\n Edit\n </Button>\n )}\n </div>\n )}\n <div className=\"grid gap-4 sm:grid-cols-2\">\n {fields.map((field) =>\n editing ? (\n <EditField\n key={field.key}\n field={field}\n value={draft[field.key]}\n onChange={updateField}\n />\n ) : (\n <ReadField key={field.key} field={field} value={data[field.key]} />\n ),\n )}\n </div>\n {editing && (\n <div className=\"flex gap-2\">\n <Button onClick={handleSave} disabled={loading}>\n {loading && <Spinner size=\"sm\" className=\"mr-2\" />}\n Save\n </Button>\n <Button variant=\"outline\" onClick={handleCancel} disabled={loading}>\n Cancel\n </Button>\n </div>\n )}\n </div>\n );\n}\nDetailPanel.displayName = \"DetailPanel\";\n\nfunction ReadField<T>({ field, value }: { field: FieldDef<T>; value: T[keyof T] }) {\n const display = field.render ? field.render(value) : String(value ?? \"\");\n return (\n <div className=\"space-y-1\">\n <p className=\"text-muted-foreground text-sm font-medium\">{field.label}</p>\n <p className=\"text-sm\">{display}</p>\n </div>\n );\n}\n\nfunction EditField<T>({\n field,\n value,\n onChange,\n}: {\n field: FieldDef<T>;\n value: unknown;\n onChange: (key: keyof T & string, value: unknown) => void;\n}) {\n const strValue = String(value ?? \"\");\n\n if (field.type === \"readonly\") {\n return (\n <div className=\"space-y-1\">\n <p className=\"text-muted-foreground text-sm font-medium\">{field.label}</p>\n <p className=\"text-sm\">{field.render ? field.render(value as T[keyof T]) : strValue}</p>\n </div>\n );\n }\n\n if (field.type === \"select\") {\n return (\n <FormSelect\n label={field.label}\n name={field.key}\n required={field.required}\n options={field.options ?? []}\n value={strValue}\n onValueChange={(v) => onChange(field.key, v)}\n />\n );\n }\n\n if (field.type === \"textarea\") {\n return (\n <FormTextarea\n label={field.label}\n name={field.key}\n required={field.required}\n value={strValue}\n onChange={(e) => onChange(field.key, e.target.value)}\n />\n );\n }\n\n return (\n <FormInput\n label={field.label}\n name={field.key}\n required={field.required}\n value={strValue}\n onChange={(e) => onChange(field.key, e.target.value)}\n />\n );\n}\n\nexport { DetailPanel };\n"]}
1
+ {"version":3,"sources":["/Users/stuartjackson/Projects/simpleapps/atlas/repo/packages/augur-web/dist/detail-panel.cjs","../src/detail-panel.tsx"],"names":[],"mappings":"AAAA,+8BAAY;AACZ,YAAY;AACZ;AACE;AACF,wDAA6B;AAC7B,gCAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B,gCAA6B;AAC7B,gCAA6B;AAC7B,gCAA6B;AAC7B,gCAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACE;AACF,wDAA6B;AAC7B;AACA;ACpBA,2EAAuB;AACvB,sDAAmB;AA+FX,+CAAA;AAvCR,SAAS,WAAA,CAA8B;AAAA,EACrC,MAAA;AAAA,EACA,IAAA;AAAA,EACA,MAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA,EAAU,KAAA;AAAA,EACV,KAAA;AAAA,EACA,SAAA;AAAA,EACA,eAAA,EAAiB;AACnB,CAAA,EAAwB;AACtB,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,EAAA,EAAU,KAAA,CAAA,QAAA,CAAS,cAAc,CAAA;AAC3D,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,EAAA,EAAU,KAAA,CAAA,QAAA,CAAY,IAAI,CAAA;AAEhD,EAAM,KAAA,CAAA,SAAA,CAAU,CAAA,EAAA,GAAM;AACpB,IAAA,QAAA,CAAS,IAAI,CAAA;AAAA,EACf,CAAA,EAAG,CAAC,IAAI,CAAC,CAAA;AAET,EAAA,MAAM,WAAA,EAAa,CAAA,EAAA,GAAM;AACvB,IAAA,QAAA,CAAS,IAAI,CAAA;AACb,IAAA,UAAA,CAAW,IAAI,CAAA;AAAA,EACjB,CAAA;AAEA,EAAA,MAAM,aAAA,EAAe,CAAA,EAAA,GAAM;AACzB,IAAA,QAAA,CAAS,IAAI,CAAA;AACb,IAAA,UAAA,CAAW,KAAK,CAAA;AAChB,oBAAA,QAAA,wBAAA,CAAW,GAAA;AAAA,EACb,CAAA;AAEA,EAAA,MAAM,WAAA,EAAa,CAAA,EAAA,GAAM;AACvB,IAAA,MAAA,CAAO,KAAK,CAAA;AAAA,EACd,CAAA;AAEA,EAAA,MAAM,YAAA,EAAc,CAAC,GAAA,EAAuB,KAAA,EAAA,GAAmB;AAC7D,IAAA,QAAA,CAAS,CAAC,IAAA,EAAA,GAAA,CAAU,EAAE,GAAG,IAAA,EAAM,CAAC,GAAG,CAAA,EAAG,MAAM,CAAA,CAAE,CAAA;AAAA,EAChD,CAAA;AAEA,EAAA,uBACE,8BAAA,KAAC,EAAA,EAAI,SAAA,EAAW,qBAAA,WAAG,EAAa,SAAS,CAAA,EACrC,QAAA,EAAA;AAAA,IAAA,CAAA,MAAA,GAAS,CAAC,OAAA,EAAA,mBACV,8BAAA,KAAC,EAAA,EAAI,SAAA,EAAU,mCAAA,EACZ,QAAA,EAAA;AAAA,MAAA,MAAA,mBAAS,6BAAA,IAAC,EAAA,EAAG,SAAA,EAAU,uBAAA,EAAyB,QAAA,EAAA,MAAA,CAAM,CAAA;AAAA,MACtD,CAAC,QAAA,mBACA,6BAAA,wBAAC,EAAA,EAAO,OAAA,EAAQ,SAAA,EAAU,IAAA,EAAK,IAAA,EAAK,OAAA,EAAS,UAAA,EAAY,QAAA,EAAA,OAAA,CAEzD;AAAA,IAAA,EAAA,CAEJ,CAAA;AAAA,oBAEF,6BAAA,KAAC,EAAA,EAAI,SAAA,EAAU,2BAAA,EACZ,QAAA,EAAA,MAAA,CAAO,GAAA;AAAA,MAAI,CAAC,KAAA,EAAA,GACX,QAAA,kBACE,6BAAA;AAAA,QAAC,SAAA;AAAA,QAAA;AAAA,UAEC,KAAA;AAAA,UACA,KAAA,EAAO,KAAA,CAAM,KAAA,CAAM,GAAG,CAAA;AAAA,UACtB,QAAA,EAAU;AAAA,QAAA,CAAA;AAAA,QAHL,KAAA,CAAM;AAAA,MAIb,EAAA,kBAEA,6BAAA,SAAC,EAAA,EAA0B,KAAA,EAAc,KAAA,EAAO,IAAA,CAAK,KAAA,CAAM,GAAG,EAAA,CAAA,EAA9C,KAAA,CAAM,GAA2C;AAAA,IAErE,EAAA,CACF,CAAA;AAAA,IACC,QAAA,mBACC,8BAAA,KAAC,EAAA,EAAI,SAAA,EAAU,YAAA,EACb,QAAA,EAAA;AAAA,sBAAA,8BAAA,wBAAC,EAAA,EAAO,OAAA,EAAS,UAAA,EAAY,QAAA,EAAU,OAAA,EACpC,QAAA,EAAA;AAAA,QAAA,QAAA,mBAAW,6BAAA,yBAAC,EAAA,EAAQ,IAAA,EAAK,IAAA,EAAK,SAAA,EAAU,OAAA,CAAO,CAAA;AAAA,QAAG;AAAA,MAAA,EAAA,CAErD,CAAA;AAAA,sBACA,6BAAA,wBAAC,EAAA,EAAO,OAAA,EAAQ,SAAA,EAAU,OAAA,EAAS,YAAA,EAAc,QAAA,EAAU,OAAA,EAAS,QAAA,EAAA,SAAA,CAEpE;AAAA,IAAA,EAAA,CACF;AAAA,EAAA,EAAA,CAEJ,CAAA;AAEJ;AACA,WAAA,CAAY,YAAA,EAAc,aAAA;AAE1B,SAAS,SAAA,CAAa,EAAE,KAAA,EAAO,MAAM,CAAA,EAA8C;AACjF,EAAA,MAAM,QAAA,EAAU,KAAA,CAAM,OAAA,EAAS,KAAA,CAAM,MAAA,CAAO,KAAK,EAAA,EAAI,MAAA,kBAAO,KAAA,UAAS,IAAE,CAAA;AACvE,EAAA,uBACE,8BAAA,KAAC,EAAA,EAAI,SAAA,EAAU,WAAA,EACb,QAAA,EAAA;AAAA,oBAAA,6BAAA,GAAC,EAAA,EAAE,SAAA,EAAU,2CAAA,EAA6C,QAAA,EAAA,KAAA,CAAM,MAAA,CAAM,CAAA;AAAA,oBACtE,6BAAA,GAAC,EAAA,EAAE,SAAA,EAAU,SAAA,EAAW,QAAA,EAAA,QAAA,CAAQ;AAAA,EAAA,EAAA,CAClC,CAAA;AAEJ;AAEA,SAAS,SAAA,CAAa;AAAA,EACpB,KAAA;AAAA,EACA,KAAA;AAAA,EACA;AACF,CAAA,EAIG;AACD,EAAA,MAAM,SAAA,EAAW,MAAA,kBAAO,KAAA,UAAS,IAAE,CAAA;AAEnC,EAAA,GAAA,CAAI,KAAA,CAAM,KAAA,IAAS,UAAA,EAAY;AAC7B,IAAA,uBACE,8BAAA,KAAC,EAAA,EAAI,SAAA,EAAU,WAAA,EACb,QAAA,EAAA;AAAA,sBAAA,6BAAA,GAAC,EAAA,EAAE,SAAA,EAAU,2CAAA,EAA6C,QAAA,EAAA,KAAA,CAAM,MAAA,CAAM,CAAA;AAAA,sBACtE,6BAAA,GAAC,EAAA,EAAE,SAAA,EAAU,SAAA,EAAW,QAAA,EAAA,KAAA,CAAM,OAAA,EAAS,KAAA,CAAM,MAAA,CAAO,KAAmB,EAAA,EAAI,SAAA,CAAS;AAAA,IAAA,EAAA,CACtF,CAAA;AAAA,EAEJ;AAEA,EAAA,GAAA,CAAI,KAAA,CAAM,KAAA,IAAS,QAAA,EAAU;AAC3B,IAAA,uBACE,6BAAA;AAAA,MAAC,4BAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAO,KAAA,CAAM,KAAA;AAAA,QACb,IAAA,EAAM,KAAA,CAAM,GAAA;AAAA,QACZ,QAAA,EAAU,KAAA,CAAM,QAAA;AAAA,QAChB,OAAA,mBAAS,KAAA,CAAM,OAAA,UAAW,CAAC,GAAA;AAAA,QAC3B,KAAA,EAAO,QAAA;AAAA,QACP,aAAA,EAAe,CAAC,CAAA,EAAA,GAAM,QAAA,CAAS,KAAA,CAAM,GAAA,EAAK,CAAC;AAAA,MAAA;AAAA,IAC7C,CAAA;AAAA,EAEJ;AAEA,EAAA,GAAA,CAAI,KAAA,CAAM,KAAA,IAAS,UAAA,EAAY;AAC7B,IAAA,uBACE,6BAAA;AAAA,MAAC,8BAAA;AAAA,MAAA;AAAA,QACC,KAAA,EAAO,KAAA,CAAM,KAAA;AAAA,QACb,IAAA,EAAM,KAAA,CAAM,GAAA;AAAA,QACZ,QAAA,EAAU,KAAA,CAAM,QAAA;AAAA,QAChB,KAAA,EAAO,QAAA;AAAA,QACP,QAAA,EAAU,CAAC,CAAA,EAAA,GAAM,QAAA,CAAS,KAAA,CAAM,GAAA,EAAK,CAAA,CAAE,MAAA,CAAO,KAAK;AAAA,MAAA;AAAA,IACrD,CAAA;AAAA,EAEJ;AAEA,EAAA,uBACE,6BAAA;AAAA,IAAC,2BAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAO,KAAA,CAAM,KAAA;AAAA,MACb,IAAA,EAAM,KAAA,CAAM,GAAA;AAAA,MACZ,QAAA,EAAU,KAAA,CAAM,QAAA;AAAA,MAChB,KAAA,EAAO,QAAA;AAAA,MACP,QAAA,EAAU,CAAC,CAAA,EAAA,GAAM,QAAA,CAAS,KAAA,CAAM,GAAA,EAAK,CAAA,CAAE,MAAA,CAAO,KAAK;AAAA,IAAA;AAAA,EACrD,CAAA;AAEJ;ADhEA;AACE;AACF,kCAAC","file":"/Users/stuartjackson/Projects/simpleapps/atlas/repo/packages/augur-web/dist/detail-panel.cjs","sourcesContent":[null,"/** Read/edit toggle panel for a single record. */\n\"use client\";\n\nimport * as React from \"react\";\nimport { cn } from \"@simpleapps-com/augur-utils/web\";\nimport { Button } from \"./button\";\nimport { FormInput } from \"./form-input\";\nimport { FormSelect } from \"./form-select\";\nimport { FormTextarea } from \"./form-textarea\";\nimport { Spinner } from \"./spinner\";\n\nexport interface FieldDef<T> {\n /** Property key on the data object. */\n key: keyof T & string;\n /** Display label. */\n label: string;\n /** Field type determines the input component used in edit mode. */\n type: \"text\" | \"textarea\" | \"select\" | \"readonly\";\n /** Options for select fields. */\n options?: { label: string; value: string }[];\n /** Mark the field as required in edit mode. */\n required?: boolean;\n /** Custom read-mode renderer. Receives the field value. */\n render?: (value: T[keyof T]) => React.ReactNode;\n}\n\nexport interface DetailPanelProps<T extends object> {\n /** Field definitions describing each field. */\n fields: FieldDef<T>[];\n /** The record to display/edit. */\n data: T;\n /** Called with the updated record when the user saves. */\n onSave: (data: T) => void;\n /** Called when the user cancels editing. */\n onCancel?: () => void;\n /** Whether a save operation is in progress. */\n loading?: boolean;\n /** Optional title displayed above the fields. */\n title?: string;\n /** Additional class name for the root container. */\n className?: string;\n /** Start in edit mode. */\n defaultEditing?: boolean;\n}\n\n/**\n * Read/edit toggle panel for a single record. Renders field values in read\n * mode, and form inputs in edit mode based on field definitions.\n *\n * @example\n * ```tsx\n * const fields: FieldDef<Brand>[] = [\n * { key: \"brandsName\", label: \"Name\", type: \"text\", required: true },\n * { key: \"brandsDesc\", label: \"Description\", type: \"textarea\" },\n * { key: \"brandsUid\", label: \"UID\", type: \"readonly\" },\n * ];\n *\n * <DetailPanel fields={fields} data={brand} onSave={handleSave} />\n * ```\n */\nfunction DetailPanel<T extends object>({\n fields,\n data,\n onSave,\n onCancel,\n loading = false,\n title,\n className,\n defaultEditing = false,\n}: DetailPanelProps<T>) {\n const [editing, setEditing] = React.useState(defaultEditing);\n const [draft, setDraft] = React.useState<T>(data);\n\n React.useEffect(() => {\n setDraft(data);\n }, [data]);\n\n const handleEdit = () => {\n setDraft(data);\n setEditing(true);\n };\n\n const handleCancel = () => {\n setDraft(data);\n setEditing(false);\n onCancel?.();\n };\n\n const handleSave = () => {\n onSave(draft);\n };\n\n const updateField = (key: keyof T & string, value: unknown) => {\n setDraft((prev) => ({ ...prev, [key]: value }));\n };\n\n return (\n <div className={cn(\"space-y-6\", className)}>\n {(title || !editing) && (\n <div className=\"flex items-center justify-between\">\n {title && <h3 className=\"text-lg font-semibold\">{title}</h3>}\n {!editing && (\n <Button variant=\"outline\" size=\"sm\" onClick={handleEdit}>\n Edit\n </Button>\n )}\n </div>\n )}\n <div className=\"grid gap-4 sm:grid-cols-2\">\n {fields.map((field) =>\n editing ? (\n <EditField\n key={field.key}\n field={field}\n value={draft[field.key]}\n onChange={updateField}\n />\n ) : (\n <ReadField key={field.key} field={field} value={data[field.key]} />\n ),\n )}\n </div>\n {editing && (\n <div className=\"flex gap-2\">\n <Button onClick={handleSave} disabled={loading}>\n {loading && <Spinner size=\"sm\" className=\"mr-2\" />}\n Save\n </Button>\n <Button variant=\"outline\" onClick={handleCancel} disabled={loading}>\n Cancel\n </Button>\n </div>\n )}\n </div>\n );\n}\nDetailPanel.displayName = \"DetailPanel\";\n\nfunction ReadField<T>({ field, value }: { field: FieldDef<T>; value: T[keyof T] }) {\n const display = field.render ? field.render(value) : String(value ?? \"\");\n return (\n <div className=\"space-y-1\">\n <p className=\"text-muted-foreground text-sm font-medium\">{field.label}</p>\n <p className=\"text-sm\">{display}</p>\n </div>\n );\n}\n\nfunction EditField<T>({\n field,\n value,\n onChange,\n}: {\n field: FieldDef<T>;\n value: unknown;\n onChange: (key: keyof T & string, value: unknown) => void;\n}) {\n const strValue = String(value ?? \"\");\n\n if (field.type === \"readonly\") {\n return (\n <div className=\"space-y-1\">\n <p className=\"text-muted-foreground text-sm font-medium\">{field.label}</p>\n <p className=\"text-sm\">{field.render ? field.render(value as T[keyof T]) : strValue}</p>\n </div>\n );\n }\n\n if (field.type === \"select\") {\n return (\n <FormSelect\n label={field.label}\n name={field.key}\n required={field.required}\n options={field.options ?? []}\n value={strValue}\n onValueChange={(v) => onChange(field.key, v)}\n />\n );\n }\n\n if (field.type === \"textarea\") {\n return (\n <FormTextarea\n label={field.label}\n name={field.key}\n required={field.required}\n value={strValue}\n onChange={(e) => onChange(field.key, e.target.value)}\n />\n );\n }\n\n return (\n <FormInput\n label={field.label}\n name={field.key}\n required={field.required}\n value={strValue}\n onChange={(e) => onChange(field.key, e.target.value)}\n />\n );\n}\n\nexport { DetailPanel };\n"]}
@@ -1,7 +1,5 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import * as React from 'react';
3
-
4
- interface FieldDef<T> {
1
+ import * as React from "react";
2
+ export interface FieldDef<T> {
5
3
  /** Property key on the data object. */
6
4
  key: keyof T & string;
7
5
  /** Display label. */
@@ -18,7 +16,7 @@ interface FieldDef<T> {
18
16
  /** Custom read-mode renderer. Receives the field value. */
19
17
  render?: (value: T[keyof T]) => React.ReactNode;
20
18
  }
21
- interface DetailPanelProps<T extends object> {
19
+ export interface DetailPanelProps<T extends object> {
22
20
  /** Field definitions describing each field. */
23
21
  fields: FieldDef<T>[];
24
22
  /** The record to display/edit. */
@@ -51,9 +49,9 @@ interface DetailPanelProps<T extends object> {
51
49
  * <DetailPanel fields={fields} data={brand} onSave={handleSave} />
52
50
  * ```
53
51
  */
54
- declare function DetailPanel<T extends object>({ fields, data, onSave, onCancel, loading, title, className, defaultEditing, }: DetailPanelProps<T>): react_jsx_runtime.JSX.Element;
52
+ declare function DetailPanel<T extends object>({ fields, data, onSave, onCancel, loading, title, className, defaultEditing, }: DetailPanelProps<T>): React.JSX.Element;
55
53
  declare namespace DetailPanel {
56
54
  var displayName: string;
57
55
  }
58
-
59
- export { DetailPanel, type DetailPanelProps, type FieldDef };
56
+ export { DetailPanel };
57
+ //# sourceMappingURL=detail-panel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detail-panel.d.ts","sourceRoot":"","sources":["../src/detail-panel.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAQ/B,MAAM,WAAW,QAAQ,CAAC,CAAC;IACzB,uCAAuC;IACvC,GAAG,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC;IACtB,qBAAqB;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,mEAAmE;IACnE,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,QAAQ,GAAG,UAAU,CAAC;IAClD,iCAAiC;IACjC,OAAO,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC7C,+CAA+C;IAC/C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,2DAA2D;IAC3D,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,KAAK,CAAC,SAAS,CAAC;CACjD;AAED,MAAM,WAAW,gBAAgB,CAAC,CAAC,SAAS,MAAM;IAChD,+CAA+C;IAC/C,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;IACtB,kCAAkC;IAClC,IAAI,EAAE,CAAC,CAAC;IACR,0DAA0D;IAC1D,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC;IAC1B,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB,+CAA+C;IAC/C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,iDAAiD;IACjD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oDAAoD;IACpD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0BAA0B;IAC1B,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;;;;;;;;;;;;GAcG;AACH,iBAAS,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,EACrC,MAAM,EACN,IAAI,EACJ,MAAM,EACN,QAAQ,EACR,OAAe,EACf,KAAK,EACL,SAAS,EACT,cAAsB,GACvB,EAAE,gBAAgB,CAAC,CAAC,CAAC,qBAkErB;kBA3EQ,WAAW;;;AAgJpB,OAAO,EAAE,WAAW,EAAE,CAAC"}
@@ -1,8 +1,5 @@
1
1
  "use client";
2
2
  "use client";
3
- import {
4
- FormSelect
5
- } from "./chunk-WFMP6TZN.js";
6
3
  import {
7
4
  FormTextarea
8
5
  } from "./chunk-RGJT67PN.js";
@@ -10,6 +7,9 @@ import "./chunk-L3BT67EO.js";
10
7
  import {
11
8
  FormInput
12
9
  } from "./chunk-UB7HYAAC.js";
10
+ import {
11
+ FormSelect
12
+ } from "./chunk-WFMP6TZN.js";
13
13
  import "./chunk-MXSQYVCK.js";
14
14
  import "./chunk-RCUKSVMF.js";
15
15
  import "./chunk-HXQF6XTL.js";
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/runner/work/augur-packages/augur-packages/packages/augur-web/dist/dialog.cjs"],"names":[],"mappings":"AAAA,qFAAY;AACZ,YAAY;AACZ;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,wDAA6B;AAC7B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,qiBAAC","file":"/home/runner/work/augur-packages/augur-packages/packages/augur-web/dist/dialog.cjs"}
1
+ {"version":3,"sources":["/Users/stuartjackson/Projects/simpleapps/atlas/repo/packages/augur-web/dist/dialog.cjs"],"names":[],"mappings":"AAAA,qFAAY;AACZ,YAAY;AACZ;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,wDAA6B;AAC7B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,qiBAAC","file":"/Users/stuartjackson/Projects/simpleapps/atlas/repo/packages/augur-web/dist/dialog.cjs"}
package/dist/dialog.d.ts CHANGED
@@ -1,7 +1,5 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import * as React from 'react';
3
- import * as DialogPrimitive from '@radix-ui/react-dialog';
4
-
1
+ import * as React from "react";
2
+ import * as DialogPrimitive from "@radix-ui/react-dialog";
5
3
  declare const Dialog: React.FC<DialogPrimitive.DialogProps>;
6
4
  declare const DialogTrigger: React.ForwardRefExoticComponent<DialogPrimitive.DialogTriggerProps & React.RefAttributes<HTMLButtonElement>>;
7
5
  declare const DialogPortal: React.FC<DialogPrimitive.DialogPortalProps>;
@@ -9,14 +7,14 @@ declare const DialogClose: React.ForwardRefExoticComponent<DialogPrimitive.Dialo
9
7
  declare const DialogOverlay: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogOverlayProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
10
8
  declare const DialogContent: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
11
9
  declare const DialogHeader: {
12
- ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>): react_jsx_runtime.JSX.Element;
10
+ ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>): React.JSX.Element;
13
11
  displayName: string;
14
12
  };
15
13
  declare const DialogFooter: {
16
- ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>): react_jsx_runtime.JSX.Element;
14
+ ({ className, ...props }: React.HTMLAttributes<HTMLDivElement>): React.JSX.Element;
17
15
  displayName: string;
18
16
  };
19
17
  declare const DialogTitle: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogTitleProps & React.RefAttributes<HTMLHeadingElement>, "ref"> & React.RefAttributes<HTMLHeadingElement>>;
20
18
  declare const DialogDescription: React.ForwardRefExoticComponent<Omit<DialogPrimitive.DialogDescriptionProps & React.RefAttributes<HTMLParagraphElement>, "ref"> & React.RefAttributes<HTMLParagraphElement>>;
21
-
22
- export { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger };
19
+ export { Dialog, DialogPortal, DialogOverlay, DialogTrigger, DialogClose, DialogContent, DialogHeader, DialogFooter, DialogTitle, DialogDescription, };
20
+ //# sourceMappingURL=dialog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dialog.d.ts","sourceRoot":"","sources":["../src/dialog.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,eAAe,MAAM,wBAAwB,CAAC;AAI1D,QAAA,MAAM,MAAM,uCAAuB,CAAC;AAEpC,QAAA,MAAM,aAAa,8GAA0B,CAAC;AAE9C,QAAA,MAAM,YAAY,6CAAyB,CAAC;AAE5C,QAAA,MAAM,WAAW,4GAAwB,CAAC;AAE1C,QAAA,MAAM,aAAa,8JAYjB,CAAC;AAGH,QAAA,MAAM,aAAa,8JAqBjB,CAAC;AAGH,QAAA,MAAM,YAAY;8BAA6B,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;;CAElF,CAAC;AAGF,QAAA,MAAM,YAAY;8BAA6B,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;;CAKlF,CAAC;AAGF,QAAA,MAAM,WAAW,oKASf,CAAC;AAGH,QAAA,MAAM,iBAAiB,8KASrB,CAAC;AAGH,OAAO,EACL,MAAM,EACN,YAAY,EACZ,aAAa,EACb,aAAa,EACb,WAAW,EACX,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,iBAAiB,GAClB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/runner/work/augur-packages/augur-packages/packages/augur-web/dist/dropdown-menu.cjs"],"names":[],"mappings":"AAAA,qFAAY;AACZ,YAAY;AACZ;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,wDAA6B;AAC7B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,0gCAAC","file":"/home/runner/work/augur-packages/augur-packages/packages/augur-web/dist/dropdown-menu.cjs"}
1
+ {"version":3,"sources":["/Users/stuartjackson/Projects/simpleapps/atlas/repo/packages/augur-web/dist/dropdown-menu.cjs"],"names":[],"mappings":"AAAA,qFAAY;AACZ,YAAY;AACZ;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,wDAA6B;AAC7B;AACE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACF,0gCAAC","file":"/Users/stuartjackson/Projects/simpleapps/atlas/repo/packages/augur-web/dist/dropdown-menu.cjs"}
@@ -1,7 +1,5 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import * as React from 'react';
3
- import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
4
-
1
+ import * as React from "react";
2
+ import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
5
3
  declare const DropdownMenu: React.FC<DropdownMenuPrimitive.DropdownMenuProps>;
6
4
  declare const DropdownMenuTrigger: React.ForwardRefExoticComponent<DropdownMenuPrimitive.DropdownMenuTriggerProps & React.RefAttributes<HTMLButtonElement>>;
7
5
  declare const DropdownMenuGroup: React.ForwardRefExoticComponent<DropdownMenuPrimitive.DropdownMenuGroupProps & React.RefAttributes<HTMLDivElement>>;
@@ -23,8 +21,8 @@ declare const DropdownMenuLabel: React.ForwardRefExoticComponent<Omit<DropdownMe
23
21
  } & React.RefAttributes<HTMLDivElement>>;
24
22
  declare const DropdownMenuSeparator: React.ForwardRefExoticComponent<Omit<DropdownMenuPrimitive.DropdownMenuSeparatorProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
25
23
  declare const DropdownMenuShortcut: {
26
- ({ className, ...props }: React.HTMLAttributes<HTMLSpanElement>): react_jsx_runtime.JSX.Element;
24
+ ({ className, ...props }: React.HTMLAttributes<HTMLSpanElement>): React.JSX.Element;
27
25
  displayName: string;
28
26
  };
29
-
30
- export { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger };
27
+ export { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuCheckboxItem, DropdownMenuRadioItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuGroup, DropdownMenuPortal, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuRadioGroup, };
28
+ //# sourceMappingURL=dropdown-menu.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dropdown-menu.d.ts","sourceRoot":"","sources":["../src/dropdown-menu.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,qBAAqB,MAAM,+BAA+B,CAAC;AAIvE,QAAA,MAAM,YAAY,mDAA6B,CAAC;AAEhD,QAAA,MAAM,mBAAmB,0HAAgC,CAAC;AAE1D,QAAA,MAAM,iBAAiB,qHAA8B,CAAC;AAEtD,QAAA,MAAM,kBAAkB,yDAA+B,CAAC;AAExD,QAAA,MAAM,eAAe,sDAA4B,CAAC;AAElD,QAAA,MAAM,sBAAsB,0HAAmC,CAAC;AAEhE,QAAA,MAAM,sBAAsB;YAGhB,OAAO;wCAejB,CAAC;AAGH,QAAA,MAAM,sBAAsB,6KAY1B,CAAC;AAGH,QAAA,MAAM,mBAAmB,0KAevB,CAAC;AAGH,QAAA,MAAM,gBAAgB;YAGV,OAAO;wCAYjB,CAAC;AAGH,QAAA,MAAM,wBAAwB,+KAoB5B,CAAC;AAGH,QAAA,MAAM,qBAAqB,4KAmBzB,CAAC;AAGH,QAAA,MAAM,iBAAiB;YAGX,OAAO;wCAQjB,CAAC;AAGH,QAAA,MAAM,qBAAqB,4KASzB,CAAC;AAGH,QAAA,MAAM,oBAAoB;8BAA6B,KAAK,CAAC,cAAc,CAAC,eAAe,CAAC;;CAI3F,CAAC;AAGF,OAAO,EACL,YAAY,EACZ,mBAAmB,EACnB,mBAAmB,EACnB,gBAAgB,EAChB,wBAAwB,EACxB,qBAAqB,EACrB,iBAAiB,EACjB,qBAAqB,EACrB,oBAAoB,EACpB,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,sBAAsB,EACtB,sBAAsB,EACtB,sBAAsB,GACvB,CAAC"}
@@ -11,9 +11,7 @@ function injectTimePayment(vendorCode, onLoad) {
11
11
  script.src = `https://app.timepayment.com/js/apply-button.js?vendor=${encodeURIComponent(vendorCode)}`;
12
12
  script.async = true;
13
13
  script.defer = true;
14
- if (onLoad) {
15
- script.onload = onLoad;
16
- }
14
+ script.onload = onLoad;
17
15
  document.head.appendChild(script);
18
16
  }
19
17
  var injectors = {
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/runner/work/augur-packages/augur-packages/packages/augur-web/dist/financing-widget.cjs","../src/financing-widget.tsx"],"names":[],"mappings":"AAAA,ylBAAY;AACZ,YAAY;AACZ;AACA;ACDA,8BAA+C;AAyC/C,SAAS,iBAAA,CAAkB,UAAA,EAAoB,MAAA,EAA2B;AAExE,EAAA,GAAA,CAAI,OAAO,SAAA,IAAa,WAAA,EAAa,MAAA;AACrC,EAAA,GAAA,CAAI,QAAA,CAAS,cAAA,CAAe,kBAAkB,CAAA,EAAG,MAAA;AAEjD,EAAA,MAAM,OAAA,EAAS,QAAA,CAAS,aAAA,CAAc,QAAQ,CAAA;AAC9C,EAAA,MAAA,CAAO,GAAA,EAAK,kBAAA;AACZ,EAAA,MAAA,CAAO,IAAA,EAAM,CAAA,sDAAA,EAAyD,kBAAA,CAAmB,UAAU,CAAC,CAAA,CAAA;AACrF,EAAA;AACA,EAAA;AACH,EAAA;AACM,IAAA;AAClB,EAAA;AACgC,EAAA;AAClC;AAEgG;AACjF,EAAA;AACf;AAyBgC;AAC9B,EAAA;AACA,EAAA;AACW,EAAA;AACX,EAAA;AACuB;AACS,EAAA;AAEO,EAAA;AAC5B,oBAAA;AACA,EAAA;AAEK,EAAA;AACuB,IAAA;AACf,IAAA;AAEW,IAAA;AAGc,IAAA;AACa,MAAA;AACrD,IAAA;AAC+C,MAAA;AACtD,IAAA;AAC+C,EAAA;AAE1C,EAAA;AACT;ADtEuG;AACA;AACA","file":"/home/runner/work/augur-packages/augur-packages/packages/augur-web/dist/financing-widget.cjs","sourcesContent":[null,"\"use client\";\n\nimport { useEffect, useRef, useCallback } from \"react\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** Supported financing providers. */\nexport type FinancingProvider = \"timepayment\";\n\nexport interface FinancingWidgetProps {\n /** Financing provider. */\n provider: FinancingProvider;\n /** Vendor/merchant code from the provider. */\n vendorCode: string;\n /** Disable loading. Default: false. */\n disabled?: boolean;\n /** Called when the financing script has loaded. */\n onLoad?: () => void;\n}\n\nexport interface UseFinancingResult {\n /** Whether the financing script has loaded. */\n isLoaded: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Globals\n// ---------------------------------------------------------------------------\n\ndeclare global {\n interface Window {\n TimePayment?: {\n apply: (vendorCode: string) => void;\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Script injectors\n// ---------------------------------------------------------------------------\n\nfunction injectTimePayment(vendorCode: string, onLoad?: () => void): void {\n /* v8 ignore next */\n if (typeof document === \"undefined\") return;\n if (document.getElementById(\"financing-script\")) return;\n\n const script = document.createElement(\"script\");\n script.id = \"financing-script\";\n script.src = `https://app.timepayment.com/js/apply-button.js?vendor=${encodeURIComponent(vendorCode)}`;\n script.async = true;\n script.defer = true;\n if (onLoad) {\n script.onload = onLoad;\n }\n document.head.appendChild(script);\n}\n\nconst injectors: Record<FinancingProvider, (vendorCode: string, onLoad?: () => void) => void> = {\n timepayment: injectTimePayment,\n};\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\n/**\n * Loads a financing widget script on the pages where it's needed.\n * Renders nothing — this is a side-effect-only leaf component.\n *\n * Place this on product or checkout pages, NOT in the global layout.\n *\n * @example\n * ```tsx\n * // On a product page\n * <FinancingWidget provider=\"timepayment\" vendorCode=\"PVD5P\" />\n *\n * // With load callback\n * <FinancingWidget\n * provider=\"timepayment\"\n * vendorCode=\"PVD5P\"\n * onLoad={() => console.log(\"Financing ready\")}\n * />\n * ```\n */\nexport function FinancingWidget({\n provider,\n vendorCode,\n disabled = false,\n onLoad,\n}: FinancingWidgetProps) {\n const injectedRef = useRef(false);\n\n const stableOnLoad = useCallback(() => {\n onLoad?.();\n }, [onLoad]);\n\n useEffect(() => {\n if (disabled || injectedRef.current) return;\n injectedRef.current = true;\n\n const inject = injectors[provider];\n\n // Load during idle time\n if (typeof requestIdleCallback === \"function\") {\n requestIdleCallback(() => inject(vendorCode, stableOnLoad));\n } else {\n setTimeout(() => inject(vendorCode, stableOnLoad), 0);\n }\n }, [provider, vendorCode, disabled, stableOnLoad]);\n\n return null;\n}\n"]}
1
+ {"version":3,"sources":["/Users/stuartjackson/Projects/simpleapps/atlas/repo/packages/augur-web/dist/financing-widget.cjs","../src/financing-widget.tsx"],"names":[],"mappings":"AAAA,ylBAAY;AACZ,YAAY;AACZ;AACA;ACDA,8BAA+C;AA0C/C,SAAS,iBAAA,CAAkB,UAAA,EAAoB,MAAA,EAA0B;AACvE,EAAA,GAAA,CAAI,OAAO,SAAA,IAAa,WAAA,EAAa,MAAA;AACrC,EAAA,GAAA,CAAI,QAAA,CAAS,cAAA,CAAe,kBAAkB,CAAA,EAAG,MAAA;AAEjD,EAAA,MAAM,OAAA,EAAS,QAAA,CAAS,aAAA,CAAc,QAAQ,CAAA;AAC9C,EAAA,MAAA,CAAO,GAAA,EAAK,kBAAA;AACZ,EAAA,MAAA,CAAO,IAAA,EAAM,CAAA,sDAAA,EAAyD,kBAAA,CAAmB,UAAU,CAAC,CAAA,CAAA;AACrF,EAAA;AACA,EAAA;AACC,EAAA;AACgB,EAAA;AAClC;AAE+F;AAChF,EAAA;AACf;AAyBgC;AAC9B,EAAA;AACA,EAAA;AACW,EAAA;AACX,EAAA;AACuB;AACS,EAAA;AAEO,EAAA;AAC5B,oBAAA;AACA,EAAA;AAEK,EAAA;AACuB,IAAA;AACf,IAAA;AAEW,IAAA;AAGc,IAAA;AACa,MAAA;AACrD,IAAA;AAC+C,MAAA;AACtD,IAAA;AAC+C,EAAA;AAE1C,EAAA;AACT;ADtEuG;AACA;AACA","file":"/Users/stuartjackson/Projects/simpleapps/atlas/repo/packages/augur-web/dist/financing-widget.cjs","sourcesContent":[null,"\"use client\";\n\nimport { useEffect, useRef, useCallback } from \"react\";\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\n/** Supported financing providers. */\nexport type FinancingProvider = \"timepayment\";\n\nexport interface FinancingWidgetProps {\n /** Financing provider. */\n provider: FinancingProvider;\n /** Vendor/merchant code from the provider. */\n vendorCode: string;\n /** Disable loading. Default: false. */\n disabled?: boolean;\n /** Called when the financing script has loaded. */\n onLoad?: () => void;\n}\n\nexport interface UseFinancingResult {\n /** Whether the financing script has loaded. */\n isLoaded: boolean;\n}\n\n// ---------------------------------------------------------------------------\n// Globals\n// ---------------------------------------------------------------------------\n\ndeclare global {\n interface Window {\n TimePayment?: {\n apply: (vendorCode: string) => void;\n };\n }\n}\n\n// ---------------------------------------------------------------------------\n// Script injectors\n// ---------------------------------------------------------------------------\n\n// The widget always passes its (stable) onLoad wrapper, so the script always gets one.\nfunction injectTimePayment(vendorCode: string, onLoad: () => void): void {\n if (typeof document === \"undefined\") return;\n if (document.getElementById(\"financing-script\")) return;\n\n const script = document.createElement(\"script\");\n script.id = \"financing-script\";\n script.src = `https://app.timepayment.com/js/apply-button.js?vendor=${encodeURIComponent(vendorCode)}`;\n script.async = true;\n script.defer = true;\n script.onload = onLoad;\n document.head.appendChild(script);\n}\n\nconst injectors: Record<FinancingProvider, (vendorCode: string, onLoad: () => void) => void> = {\n timepayment: injectTimePayment,\n};\n\n// ---------------------------------------------------------------------------\n// Component\n// ---------------------------------------------------------------------------\n\n/**\n * Loads a financing widget script on the pages where it's needed.\n * Renders nothing — this is a side-effect-only leaf component.\n *\n * Place this on product or checkout pages, NOT in the global layout.\n *\n * @example\n * ```tsx\n * // On a product page\n * <FinancingWidget provider=\"timepayment\" vendorCode=\"PVD5P\" />\n *\n * // With load callback\n * <FinancingWidget\n * provider=\"timepayment\"\n * vendorCode=\"PVD5P\"\n * onLoad={() => console.log(\"Financing ready\")}\n * />\n * ```\n */\nexport function FinancingWidget({\n provider,\n vendorCode,\n disabled = false,\n onLoad,\n}: FinancingWidgetProps) {\n const injectedRef = useRef(false);\n\n const stableOnLoad = useCallback(() => {\n onLoad?.();\n }, [onLoad]);\n\n useEffect(() => {\n if (disabled || injectedRef.current) return;\n injectedRef.current = true;\n\n const inject = injectors[provider];\n\n // Load during idle time\n if (typeof requestIdleCallback === \"function\") {\n requestIdleCallback(() => inject(vendorCode, stableOnLoad));\n } else {\n setTimeout(() => inject(vendorCode, stableOnLoad), 0);\n }\n }, [provider, vendorCode, disabled, stableOnLoad]);\n\n return null;\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  /** Supported financing providers. */
2
- type FinancingProvider = "timepayment";
3
- interface FinancingWidgetProps {
2
+ export type FinancingProvider = "timepayment";
3
+ export interface FinancingWidgetProps {
4
4
  /** Financing provider. */
5
5
  provider: FinancingProvider;
6
6
  /** Vendor/merchant code from the provider. */
@@ -10,7 +10,7 @@ interface FinancingWidgetProps {
10
10
  /** Called when the financing script has loaded. */
11
11
  onLoad?: () => void;
12
12
  }
13
- interface UseFinancingResult {
13
+ export interface UseFinancingResult {
14
14
  /** Whether the financing script has loaded. */
15
15
  isLoaded: boolean;
16
16
  }
@@ -40,6 +40,5 @@ declare global {
40
40
  * />
41
41
  * ```
42
42
  */
43
- declare function FinancingWidget({ provider, vendorCode, disabled, onLoad, }: FinancingWidgetProps): null;
44
-
45
- export { type FinancingProvider, FinancingWidget, type FinancingWidgetProps, type UseFinancingResult };
43
+ export declare function FinancingWidget({ provider, vendorCode, disabled, onLoad, }: FinancingWidgetProps): null;
44
+ //# sourceMappingURL=financing-widget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"financing-widget.d.ts","sourceRoot":"","sources":["../src/financing-widget.tsx"],"names":[],"mappings":"AAQA,qCAAqC;AACrC,MAAM,MAAM,iBAAiB,GAAG,aAAa,CAAC;AAE9C,MAAM,WAAW,oBAAoB;IACnC,0BAA0B;IAC1B,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,8CAA8C;IAC9C,UAAU,EAAE,MAAM,CAAC;IACnB,uCAAuC;IACvC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,mDAAmD;IACnD,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,+CAA+C;IAC/C,QAAQ,EAAE,OAAO,CAAC;CACnB;AAMD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,WAAW,CAAC,EAAE;YACZ,KAAK,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;SACrC,CAAC;KACH;CACF;AA4BD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,eAAe,CAAC,EAC9B,QAAQ,EACR,UAAU,EACV,QAAgB,EAChB,MAAM,GACP,EAAE,oBAAoB,QAsBtB"}
@@ -11,9 +11,7 @@ function injectTimePayment(vendorCode, onLoad) {
11
11
  script.src = `https://app.timepayment.com/js/apply-button.js?vendor=${encodeURIComponent(vendorCode)}`;
12
12
  script.async = true;
13
13
  script.defer = true;
14
- if (onLoad) {
15
- script.onload = onLoad;
16
- }
14
+ script.onload = onLoad;
17
15
  document.head.appendChild(script);
18
16
  }
19
17
  var injectors = {