@ai-matrx/design-system 0.18.4 → 0.18.5

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 (56) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/content-transfer.cjs +12 -5
  3. package/dist/content-transfer.cjs.map +1 -1
  4. package/dist/content-transfer.d.cts +4 -0
  5. package/dist/content-transfer.d.ts +4 -0
  6. package/dist/content-transfer.js +12 -5
  7. package/dist/content-transfer.js.map +1 -1
  8. package/dist/data-table/copy-helpers.cjs +53 -0
  9. package/dist/data-table/copy-helpers.cjs.map +1 -1
  10. package/dist/data-table/copy-helpers.d.cts +13 -2
  11. package/dist/data-table/copy-helpers.d.ts +13 -2
  12. package/dist/data-table/copy-helpers.js +55 -0
  13. package/dist/data-table/copy-helpers.js.map +1 -1
  14. package/dist/data-table/copy-types.cjs.map +1 -1
  15. package/dist/data-table/copy-types.d.cts +4 -0
  16. package/dist/data-table/copy-types.d.ts +4 -0
  17. package/dist/data-table/data-row-inspector.cjs +70 -50
  18. package/dist/data-table/data-row-inspector.cjs.map +1 -1
  19. package/dist/data-table/data-row-inspector.js +70 -50
  20. package/dist/data-table/data-row-inspector.js.map +1 -1
  21. package/dist/data-table/data-row-window.cjs +70 -50
  22. package/dist/data-table/data-row-window.cjs.map +1 -1
  23. package/dist/data-table/data-row-window.js +70 -50
  24. package/dist/data-table/data-row-window.js.map +1 -1
  25. package/dist/data-table/filter-engine.d.cts +1 -1
  26. package/dist/data-table/filter-engine.d.ts +1 -1
  27. package/dist/data-table/index.cjs +621 -422
  28. package/dist/data-table/index.cjs.map +1 -1
  29. package/dist/data-table/index.d.cts +2 -2
  30. package/dist/data-table/index.d.ts +2 -2
  31. package/dist/data-table/index.js +623 -422
  32. package/dist/data-table/index.js.map +1 -1
  33. package/dist/data-table/infer-filter.d.cts +1 -1
  34. package/dist/data-table/infer-filter.d.ts +1 -1
  35. package/dist/data-table/layered-filters.d.cts +1 -1
  36. package/dist/data-table/layered-filters.d.ts +1 -1
  37. package/dist/data-table/pagination.cjs +148 -90
  38. package/dist/data-table/pagination.cjs.map +1 -1
  39. package/dist/data-table/pagination.js +143 -85
  40. package/dist/data-table/pagination.js.map +1 -1
  41. package/dist/data-table/query-control.d.cts +1 -1
  42. package/dist/data-table/query-control.d.ts +1 -1
  43. package/dist/data-table/types.cjs.map +1 -1
  44. package/dist/data-table/types.d.cts +1 -1
  45. package/dist/data-table/types.d.ts +1 -1
  46. package/dist/data-table/url-state.d.cts +1 -1
  47. package/dist/data-table/url-state.d.ts +1 -1
  48. package/dist/data-table/uuid-cell.cjs +58 -45
  49. package/dist/data-table/uuid-cell.cjs.map +1 -1
  50. package/dist/data-table/uuid-cell.js +58 -45
  51. package/dist/data-table/uuid-cell.js.map +1 -1
  52. package/dist/data-table/xlsx.d.cts +1 -1
  53. package/dist/data-table/xlsx.d.ts +1 -1
  54. package/dist/{types-Bx9SfdJM.d.cts → types-0CNCWvdK.d.cts} +2 -2
  55. package/dist/{types-DyByb6tW.d.ts → types-cH8oLqUx.d.ts} +2 -2
  56. package/package.json +1 -1
@@ -2039,6 +2039,36 @@ function useTableNotice() {
2039
2039
 
2040
2040
  // src/data-table/pagination.tsx
2041
2041
  var import_jsx_runtime19 = require("react/jsx-runtime");
2042
+ function PageNavigationControl({
2043
+ label,
2044
+ disabledHint,
2045
+ visibilityClassName = "inline-flex",
2046
+ disabled,
2047
+ className,
2048
+ ...props
2049
+ }) {
2050
+ const button = /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2051
+ Button,
2052
+ {
2053
+ ...props,
2054
+ disabled,
2055
+ "aria-label": label,
2056
+ className: cn(visibilityClassName, className)
2057
+ }
2058
+ );
2059
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(Tooltip, { children: [
2060
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(TooltipTrigger, { asChild: true, children: disabled ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2061
+ "span",
2062
+ {
2063
+ className: cn(visibilityClassName, "rounded-md outline-none focus-visible:ring-2 focus-visible:ring-ring"),
2064
+ tabIndex: 0,
2065
+ "aria-label": `${label} \u2014 ${disabledHint.toLowerCase()}`,
2066
+ children: button
2067
+ }
2068
+ ) : button }),
2069
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(TooltipContent, { children: disabled ? disabledHint : label })
2070
+ ] });
2071
+ }
2042
2072
  function GenericTablePagination({
2043
2073
  totalItems,
2044
2074
  itemsPerPage,
@@ -2097,7 +2127,7 @@ function GenericTablePagination({
2097
2127
  className,
2098
2128
  containerClassName
2099
2129
  );
2100
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { "data-matrx-table-footer": true, className: containerClass, children: [
2130
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(TooltipProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { "data-matrx-table-footer": true, className: containerClass, children: [
2101
2131
  showItemsPerPageSelect && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2102
2132
  "div",
2103
2133
  {
@@ -2164,16 +2194,16 @@ function GenericTablePagination({
2164
2194
  ),
2165
2195
  children: [
2166
2196
  /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2167
- Button,
2197
+ PageNavigationControl,
2168
2198
  {
2169
2199
  variant: "outline",
2170
2200
  size: buttonSize,
2171
- "aria-label": "First page",
2172
- title: "First page",
2201
+ visibilityClassName: "hidden sm:inline-flex",
2202
+ label: "First page",
2203
+ disabledHint: "Already on the first page",
2173
2204
  onClick: () => onPageChange(1),
2174
2205
  disabled: isFirstPageDisabled,
2175
2206
  className: cn(
2176
- "hidden sm:inline-flex",
2177
2207
  compact ? compactButtonClass : "h-8 w-8 p-0",
2178
2208
  navButtonClassName
2179
2209
  ),
@@ -2181,12 +2211,12 @@ function GenericTablePagination({
2181
2211
  }
2182
2212
  ),
2183
2213
  /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2184
- Button,
2214
+ PageNavigationControl,
2185
2215
  {
2186
2216
  variant: "outline",
2187
2217
  size: buttonSize,
2188
- "aria-label": "Previous page",
2189
- title: "Previous page",
2218
+ label: "Previous page",
2219
+ disabledHint: "Already on the first page",
2190
2220
  onClick: () => onPageChange(currentPage - 1),
2191
2221
  disabled: isFirstPageDisabled,
2192
2222
  className: cn(
@@ -2234,12 +2264,12 @@ function GenericTablePagination({
2234
2264
  `desktop-${page}`
2235
2265
  )),
2236
2266
  /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2237
- Button,
2267
+ PageNavigationControl,
2238
2268
  {
2239
2269
  variant: "outline",
2240
2270
  size: buttonSize,
2241
- "aria-label": "Next page",
2242
- title: "Next page",
2271
+ label: "Next page",
2272
+ disabledHint: "Already on the last page",
2243
2273
  onClick: () => onPageChange(currentPage + 1),
2244
2274
  disabled: isLastPageDisabled,
2245
2275
  className: cn(
@@ -2250,16 +2280,16 @@ function GenericTablePagination({
2250
2280
  }
2251
2281
  ),
2252
2282
  /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2253
- Button,
2283
+ PageNavigationControl,
2254
2284
  {
2255
2285
  variant: "outline",
2256
2286
  size: buttonSize,
2257
- "aria-label": "Last page",
2258
- title: "Last page",
2287
+ visibilityClassName: "hidden sm:inline-flex",
2288
+ label: "Last page",
2289
+ disabledHint: "Already on the last page",
2259
2290
  onClick: () => onPageChange(totalPages),
2260
2291
  disabled: isLastPageDisabled,
2261
2292
  className: cn(
2262
- "hidden sm:inline-flex",
2263
2293
  compact ? compactButtonClass : "h-8 w-8 p-0",
2264
2294
  navButtonClassName
2265
2295
  ),
@@ -2269,7 +2299,7 @@ function GenericTablePagination({
2269
2299
  ]
2270
2300
  }
2271
2301
  )
2272
- ] });
2302
+ ] }) });
2273
2303
  }
2274
2304
 
2275
2305
  // src/content-transfer/matrx-copy.tsx
@@ -3382,14 +3412,21 @@ function MatrxCopyMenuSession(props) {
3382
3412
  ))
3383
3413
  throw new Error("Sheet rows must be JSON objects.");
3384
3414
  const rows = value;
3385
- const keys = [...new Set(rows.flatMap((row) => Object.keys(row)))];
3415
+ const suppliedColumns = props.export.sheetColumns?.();
3416
+ const columns = suppliedColumns ?? [...new Set(rows.flatMap((row) => Object.keys(row)))].map((id) => ({ id, label: id }));
3417
+ const ids = /* @__PURE__ */ new Set();
3418
+ for (const column of columns) {
3419
+ if (!column.id || !column.label || ids.has(column.id)) throw new Error("Sheet columns require unique nonempty ids and labels.");
3420
+ ids.add(column.id);
3421
+ }
3422
+ for (const row of rows) for (const key of Object.keys(row)) if (!ids.has(key)) throw new Error(`Sheet row key "${key}" is not declared in sheetColumns.`);
3386
3423
  return {
3387
3424
  kind: "rows",
3388
3425
  rows,
3389
- columns: keys.map((key) => ({
3390
- id: key,
3391
- label: key,
3392
- path: `/${key.replace(/~/g, "~0").replace(/\//g, "~1")}`,
3426
+ columns: columns.map((column) => ({
3427
+ id: column.id,
3428
+ label: column.label,
3429
+ path: `/${column.id.replace(/~/g, "~0").replace(/\//g, "~1")}`,
3393
3430
  visible: true
3394
3431
  }))
3395
3432
  };
@@ -3861,7 +3898,56 @@ var import_clipboard = require("@ai-matrx/kit/clipboard");
3861
3898
  init_filter_engine();
3862
3899
 
3863
3900
  // src/data-table/tableCopy.ts
3901
+ var import_content_transfer3 = require("@ai-matrx/kit/content-transfer");
3864
3902
  init_filter_engine();
3903
+ function projectDefaultTableCopyRow(row, columns) {
3904
+ const record = /* @__PURE__ */ Object.create(null);
3905
+ for (const column of columns) {
3906
+ const value = getCellValue(row, column);
3907
+ if (value !== void 0) record[columnId(column)] = value;
3908
+ }
3909
+ return (0, import_content_transfer3.normalizeTransferJson)(record, { omitUndefinedObjectProperties: true });
3910
+ }
3911
+ function buildDefaultTableViewAgentInput(config, rows, all, columns, meta) {
3912
+ const projected = rows.map((row) => projectDefaultTableCopyRow(row, columns));
3913
+ return {
3914
+ kind: config.listKind,
3915
+ location: config.location,
3916
+ description: meta?.scope === "selected" ? `${projected.length} selected ${projected.length === 1 ? config.label : config.listLabel ?? `${config.label} rows`}.` : config.listDescription ?? `${config.listLabel ?? config.label} \u2014 current filtered/sorted view.`,
3917
+ data: projected,
3918
+ summary: projected.map((record) => formatDefaultTableCopyRecord(record, columns)).join("\n---\n"),
3919
+ attributes: {
3920
+ visible_count: projected.length,
3921
+ total_count: all.length,
3922
+ search: meta?.search || void 0,
3923
+ search_match: meta?.search ? meta.searchMatchMode : void 0,
3924
+ any_of: meta?.anyOf || void 0,
3925
+ active_filters: meta?.filterCount ?? 0,
3926
+ sort: meta?.sort || void 0,
3927
+ scope: meta?.scope ?? "view",
3928
+ ...config.listAttributes?.(rows, all)
3929
+ },
3930
+ ...config.listContext ? { context: config.listContext(rows, all) } : {}
3931
+ };
3932
+ }
3933
+ function buildDefaultTableRowAgentInput(config, row, columns) {
3934
+ const projected = projectDefaultTableCopyRow(row, columns);
3935
+ return {
3936
+ kind: config.rowKind,
3937
+ location: config.location,
3938
+ description: config.rowDescription ?? `One ${config.label} row.`,
3939
+ data: projected,
3940
+ summary: formatDefaultTableCopyRecord(projected, columns),
3941
+ ...config.rowAttributes ? { attributes: config.rowAttributes(row) } : {}
3942
+ };
3943
+ }
3944
+ function formatDefaultTableCopyRecord(record, columns) {
3945
+ return columns.map((column) => {
3946
+ const id = columnId(column);
3947
+ const label = column.label ?? (typeof column.header === "string" ? column.header : id);
3948
+ return `${label}: ${stringifyCellValue(record[id])}`;
3949
+ }).join("\n");
3950
+ }
3865
3951
  function rowsToMarkdownTable(rows, columns) {
3866
3952
  const cols = columns.filter((c) => c.filter !== false || c.accessorKey);
3867
3953
  if (cols.length === 0) return "";
@@ -4404,6 +4490,18 @@ CommandShortcut.displayName = "CommandShortcut";
4404
4490
  // src/data-table/ColumnHeaderCell.tsx
4405
4491
  init_filter_engine();
4406
4492
  var import_jsx_runtime27 = require("react/jsx-runtime");
4493
+ var HeaderButton = (0, import_react7.forwardRef)(({ dragDescription, "aria-describedby": tooltipDescription, ...props }, ref) => {
4494
+ const descriptions = [tooltipDescription, dragDescription].filter((value) => Boolean(value)).join(" ");
4495
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4496
+ "button",
4497
+ {
4498
+ ref,
4499
+ ...props,
4500
+ ...descriptions ? { "aria-describedby": descriptions } : {}
4501
+ }
4502
+ );
4503
+ });
4504
+ HeaderButton.displayName = "HeaderButton";
4407
4505
  function ColumnHeaderCell({
4408
4506
  label,
4409
4507
  labelText,
@@ -4441,11 +4539,12 @@ function ColumnHeaderCell({
4441
4539
  }
4442
4540
  );
4443
4541
  const reorderLabel = reorderColumn?.label ?? labelText ?? "column";
4542
+ const { "aria-describedby": dragDescription, ...reorderAttributesWithoutDescription } = reorderAttributes;
4444
4543
  const reorderActivator = reorderEnabled ? {
4445
- ...reorderAttributes,
4544
+ ...reorderAttributesWithoutDescription,
4446
4545
  ...reorderListeners,
4447
4546
  ref: setNodeRef,
4448
- title: `Drag to reorder ${reorderLabel}.`,
4547
+ dragDescription,
4449
4548
  "aria-description": "Drag this column label to reorder it."
4450
4549
  } : void 0;
4451
4550
  const reorderClass = reorderEnabled ? "touch-none cursor-grab active:cursor-grabbing" : void 0;
@@ -4595,18 +4694,25 @@ function ColumnHeaderCell({
4595
4694
  if (!reorderEnabled) {
4596
4695
  return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: cn("flex items-center justify-center", className), children: label });
4597
4696
  }
4598
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: cn("flex items-center justify-center", className), children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4599
- "button",
4600
- {
4601
- type: "button",
4602
- ...reorderActivator,
4603
- className: cn(
4604
- "inline-flex items-center justify-center rounded p-0.5 text-muted-foreground transition-colors hover:text-foreground",
4605
- reorderClass
4606
- ),
4607
- children: label
4608
- }
4609
- ) });
4697
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("div", { className: cn("flex items-center justify-center", className), children: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(Tooltip, { children: [
4698
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4699
+ HeaderButton,
4700
+ {
4701
+ type: "button",
4702
+ ...reorderActivator,
4703
+ className: cn(
4704
+ "inline-flex items-center justify-center rounded p-0.5 text-muted-foreground transition-colors hover:text-foreground",
4705
+ reorderClass
4706
+ ),
4707
+ children: label
4708
+ }
4709
+ ) }),
4710
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(TooltipContent, { children: [
4711
+ "Drag to reorder ",
4712
+ reorderLabel,
4713
+ "."
4714
+ ] })
4715
+ ] }) });
4610
4716
  }
4611
4717
  return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4612
4718
  "div",
@@ -4617,34 +4723,36 @@ function ColumnHeaderCell({
4617
4723
  className
4618
4724
  ),
4619
4725
  children: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(Popover, { open: filterOpen, onOpenChange: setFilterOpen, children: [
4620
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
4621
- "button",
4622
- {
4623
- type: "button",
4624
- "aria-label": menuLabel,
4625
- title: menuLabel,
4626
- onClick: (event) => {
4627
- event.stopPropagation();
4628
- },
4629
- ...reorderActivator,
4630
- className: cn(
4631
- "relative inline-flex items-center justify-center rounded p-0.5 transition-colors",
4632
- reorderClass,
4633
- isSorted || filterActive ? "text-foreground" : "text-muted-foreground hover:text-foreground"
4634
- ),
4635
- children: [
4636
- label,
4637
- isSorted ? sortDirection === "asc" ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ArrowUp, { className: "absolute -top-1 right-0 h-2 w-2 text-primary" }) : /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ArrowDown, { className: "absolute -top-1 right-0 h-2 w-2 text-primary" }) : null,
4638
- filterActive ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4639
- "span",
4640
- {
4641
- "aria-hidden": true,
4642
- className: "absolute -bottom-0.5 right-0 h-1.5 w-1.5 rounded-full bg-primary"
4643
- }
4644
- ) : null
4645
- ]
4646
- }
4647
- ) }),
4726
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(Tooltip, { children: [
4727
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
4728
+ HeaderButton,
4729
+ {
4730
+ type: "button",
4731
+ "aria-label": menuLabel,
4732
+ onClick: (event) => {
4733
+ event.stopPropagation();
4734
+ },
4735
+ ...reorderActivator,
4736
+ className: cn(
4737
+ "relative inline-flex items-center justify-center rounded p-0.5 transition-colors",
4738
+ reorderClass,
4739
+ isSorted || filterActive ? "text-foreground" : "text-muted-foreground hover:text-foreground"
4740
+ ),
4741
+ children: [
4742
+ label,
4743
+ isSorted ? sortDirection === "asc" ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ArrowUp, { className: "absolute -top-1 right-0 h-2 w-2 text-primary" }) : /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ArrowDown, { className: "absolute -top-1 right-0 h-2 w-2 text-primary" }) : null,
4744
+ filterActive ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4745
+ "span",
4746
+ {
4747
+ "aria-hidden": true,
4748
+ className: "absolute -bottom-0.5 right-0 h-1.5 w-1.5 rounded-full bg-primary"
4749
+ }
4750
+ ) : null
4751
+ ]
4752
+ }
4753
+ ) }) }),
4754
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(TooltipContent, { children: menuLabel })
4755
+ ] }),
4648
4756
  menuContent
4649
4757
  ] })
4650
4758
  }
@@ -4660,71 +4768,85 @@ function ColumnHeaderCell({
4660
4768
  className
4661
4769
  ),
4662
4770
  children: [
4663
- sortable ? /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
4664
- "button",
4665
- {
4666
- type: "button",
4667
- onClick: onHeaderSortClick,
4668
- ...reorderActivator,
4669
- className: cn(
4670
- "inline-flex min-w-0 items-center gap-1 rounded px-0.5 py-0.5 text-left text-xs font-semibold uppercase tracking-wide transition-colors",
4671
- reorderClass,
4672
- isSorted ? "text-foreground" : "text-muted-foreground hover:text-foreground"
4673
- ),
4674
- children: [
4675
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "truncate", children: label }),
4676
- isSorted ? sortDirection === "asc" ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ArrowUp, { className: "h-3 w-3 shrink-0 text-primary" }) : /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ArrowDown, { className: "h-3 w-3 shrink-0 text-primary" }) : /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ArrowUpDown, { className: "h-3 w-3 shrink-0 opacity-40" })
4677
- ]
4678
- }
4679
- ) : reorderEnabled ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4680
- "button",
4681
- {
4682
- type: "button",
4683
- ...reorderActivator,
4684
- className: cn(
4685
- "min-w-0 truncate rounded px-0.5 py-0.5 text-left text-xs font-semibold uppercase tracking-wide text-muted-foreground hover:text-foreground",
4686
- reorderClass
4687
- ),
4688
- children: label
4689
- }
4690
- ) : /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "truncate text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: label }),
4771
+ sortable ? /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(Tooltip, { children: [
4772
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(
4773
+ HeaderButton,
4774
+ {
4775
+ type: "button",
4776
+ onClick: onHeaderSortClick,
4777
+ ...reorderActivator,
4778
+ className: cn(
4779
+ "inline-flex min-w-0 items-center gap-1 rounded px-0.5 py-0.5 text-left text-xs font-semibold uppercase tracking-wide transition-colors",
4780
+ reorderClass,
4781
+ isSorted ? "text-foreground" : "text-muted-foreground hover:text-foreground"
4782
+ ),
4783
+ children: [
4784
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "truncate", children: label }),
4785
+ isSorted ? sortDirection === "asc" ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ArrowUp, { className: "h-3 w-3 shrink-0 text-primary" }) : /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ArrowDown, { className: "h-3 w-3 shrink-0 text-primary" }) : /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(ArrowUpDown, { className: "h-3 w-3 shrink-0 opacity-40" })
4786
+ ]
4787
+ }
4788
+ ) }),
4789
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(TooltipContent, { children: reorderEnabled ? `Drag to reorder ${reorderLabel}.` : labelText ?? "Sort column" })
4790
+ ] }) : reorderEnabled ? /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(Tooltip, { children: [
4791
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4792
+ HeaderButton,
4793
+ {
4794
+ type: "button",
4795
+ ...reorderActivator,
4796
+ className: cn(
4797
+ "min-w-0 truncate rounded px-0.5 py-0.5 text-left text-xs font-semibold uppercase tracking-wide text-muted-foreground hover:text-foreground",
4798
+ reorderClass
4799
+ ),
4800
+ children: label
4801
+ }
4802
+ ) }),
4803
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(TooltipContent, { children: [
4804
+ "Drag to reorder ",
4805
+ reorderLabel,
4806
+ "."
4807
+ ] })
4808
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { className: "truncate text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: label }),
4691
4809
  filterKind ? /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { className: "inline-flex items-center", children: [
4692
4810
  /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(Popover, { open: filterOpen, onOpenChange: setFilterOpen, children: [
4693
- /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4811
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(Tooltip, { children: [
4812
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4813
+ "button",
4814
+ {
4815
+ type: "button",
4816
+ "aria-label": menuLabel,
4817
+ onClick: (e) => e.stopPropagation(),
4818
+ className: cn(
4819
+ "rounded p-0.5 transition-colors",
4820
+ filterActive ? "text-primary hover:text-primary/80" : "text-muted-foreground/40 hover:text-muted-foreground"
4821
+ ),
4822
+ children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4823
+ ListFilter,
4824
+ {
4825
+ className: cn("h-3 w-3", filterActive && "fill-primary/20")
4826
+ }
4827
+ )
4828
+ }
4829
+ ) }) }),
4830
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(TooltipContent, { children: menuLabel })
4831
+ ] }),
4832
+ menuContent
4833
+ ] }),
4834
+ filterActive ? /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(Tooltip, { children: [
4835
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4694
4836
  "button",
4695
4837
  {
4696
4838
  type: "button",
4697
- "aria-label": menuLabel,
4698
- title: "Sort or filter column",
4699
- onClick: (e) => e.stopPropagation(),
4700
- className: cn(
4701
- "rounded p-0.5 transition-colors",
4702
- filterActive ? "text-primary hover:text-primary/80" : "text-muted-foreground/40 hover:text-muted-foreground"
4703
- ),
4704
- children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4705
- ListFilter,
4706
- {
4707
- className: cn("h-3 w-3", filterActive && "fill-primary/20")
4708
- }
4709
- )
4839
+ "aria-label": labelText ? `Clear ${labelText} filter` : "Clear this filter",
4840
+ onClick: (e) => {
4841
+ e.stopPropagation();
4842
+ onFilterChange(void 0);
4843
+ },
4844
+ className: "rounded p-0.5 text-primary hover:bg-muted hover:text-foreground",
4845
+ children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(X, { className: "h-3 w-3" })
4710
4846
  }
4711
4847
  ) }),
4712
- menuContent
4713
- ] }),
4714
- filterActive ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4715
- "button",
4716
- {
4717
- type: "button",
4718
- "aria-label": labelText ? `Clear ${labelText} filter` : "Clear this filter",
4719
- title: "Clear this filter",
4720
- onClick: (e) => {
4721
- e.stopPropagation();
4722
- onFilterChange(void 0);
4723
- },
4724
- className: "rounded p-0.5 text-primary hover:bg-muted hover:text-foreground",
4725
- children: /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(X, { className: "h-3 w-3" })
4726
- }
4727
- ) : null
4848
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(TooltipContent, { children: labelText ? `Clear ${labelText} filter` : "Clear this filter" })
4849
+ ] }) : null
4728
4850
  ] }) : null
4729
4851
  ]
4730
4852
  }
@@ -5338,7 +5460,7 @@ function MatrxUuidCell({
5338
5460
  }
5339
5461
  return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "min-w-0 truncate font-mono text-xs text-muted-foreground tabular-nums select-all", children: display });
5340
5462
  })();
5341
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
5463
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(TooltipProvider, { delayDuration: 200, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
5342
5464
  "span",
5343
5465
  {
5344
5466
  "data-matrx-cell-control": true,
@@ -5348,51 +5470,64 @@ function MatrxUuidCell({
5348
5470
  ),
5349
5471
  onClick: stop,
5350
5472
  children: [
5351
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(TooltipProvider, { delayDuration: 200, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(Tooltip, { children: [
5473
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(Tooltip, { children: [
5352
5474
  /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "inline-flex min-w-0 max-w-full items-center", children: idNode }) }),
5353
5475
  /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(TooltipContent, { side: "top", className: "max-w-sm break-all font-mono", children: forbidden ? `No access \xB7 ${tip}` : tip })
5354
- ] }) }),
5355
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
5356
- "button",
5357
- {
5358
- type: "button",
5359
- onClick: onCopy,
5360
- "aria-label": copied ? "Copied" : `Copy ${label ?? "id"}`,
5361
- title: `Copy ${label ?? "id"}: ${value}`,
5362
- className: cn(
5363
- "inline-flex h-4 w-4 shrink-0 items-center justify-center rounded text-muted-foreground transition-colors hover:text-foreground focus:outline-none",
5364
- copied && "text-primary"
5365
- ),
5366
- children: copied ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Check, { className: "h-3 w-3" }) : /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Copy, { className: "h-3 w-3" })
5367
- }
5368
- ),
5369
- canPeek ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
5370
- "button",
5371
- {
5372
- type: "button",
5373
- onClick: (e) => {
5374
- stop(e);
5375
- setPeekOpen(true);
5376
- },
5377
- "aria-label": `Quick look at ${label ?? "record"}`,
5378
- title: `Quick look at ${label ?? "record"}`,
5379
- className: "inline-flex h-4 w-4 shrink-0 items-center justify-center rounded text-muted-foreground transition-colors hover:text-foreground focus:outline-none",
5380
- children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Lightbulb, { className: "h-3 w-3" })
5381
- }
5382
- ) : null,
5383
- onOpen && resolvedHref && !forbidden ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
5384
- "a",
5385
- {
5386
- href: resolvedHref,
5387
- target: "_blank",
5388
- rel: "noopener noreferrer",
5389
- onClick: stop,
5390
- "aria-label": `Open ${label ?? "record"} in a new tab`,
5391
- title: `Open ${label ?? "record"} in a new tab`,
5392
- className: "inline-flex h-4 w-4 shrink-0 items-center justify-center rounded text-muted-foreground transition-colors hover:text-foreground focus:outline-none",
5393
- children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(ExternalLink, { className: "h-3 w-3" })
5394
- }
5395
- ) : null,
5476
+ ] }),
5477
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(Tooltip, { children: [
5478
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
5479
+ "button",
5480
+ {
5481
+ type: "button",
5482
+ onClick: onCopy,
5483
+ "aria-label": copied ? "Copied" : `Copy ${label ?? "id"}`,
5484
+ className: cn(
5485
+ "inline-flex h-4 w-4 shrink-0 items-center justify-center rounded text-muted-foreground transition-colors hover:text-foreground focus:outline-none",
5486
+ copied && "text-primary"
5487
+ ),
5488
+ children: copied ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Check, { className: "h-3 w-3" }) : /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Copy, { className: "h-3 w-3" })
5489
+ }
5490
+ ) }),
5491
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(TooltipContent, { side: "top", children: copied ? "Copied" : `Copy ${label ?? "id"}: ${value}` })
5492
+ ] }),
5493
+ canPeek ? /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(Tooltip, { children: [
5494
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
5495
+ "button",
5496
+ {
5497
+ type: "button",
5498
+ onClick: (e) => {
5499
+ stop(e);
5500
+ setPeekOpen(true);
5501
+ },
5502
+ "aria-label": `Quick look at ${label ?? "record"}`,
5503
+ className: "inline-flex h-4 w-4 shrink-0 items-center justify-center rounded text-muted-foreground transition-colors hover:text-foreground focus:outline-none",
5504
+ children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Lightbulb, { className: "h-3 w-3" })
5505
+ }
5506
+ ) }),
5507
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(TooltipContent, { side: "top", children: [
5508
+ "Quick look at ",
5509
+ label ?? "record"
5510
+ ] })
5511
+ ] }) : null,
5512
+ onOpen && resolvedHref && !forbidden ? /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(Tooltip, { children: [
5513
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
5514
+ "a",
5515
+ {
5516
+ href: resolvedHref,
5517
+ target: "_blank",
5518
+ rel: "noopener noreferrer",
5519
+ onClick: stop,
5520
+ "aria-label": `Open ${label ?? "record"} in a new tab`,
5521
+ className: "inline-flex h-4 w-4 shrink-0 items-center justify-center rounded text-muted-foreground transition-colors hover:text-foreground focus:outline-none",
5522
+ children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(ExternalLink, { className: "h-3 w-3" })
5523
+ }
5524
+ ) }),
5525
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(TooltipContent, { side: "top", children: [
5526
+ "Open ",
5527
+ label ?? "record",
5528
+ " in a new tab"
5529
+ ] })
5530
+ ] }) : null,
5396
5531
  trailing,
5397
5532
  notice,
5398
5533
  canPeek && peekOpen && ResourcePeek ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
@@ -5406,7 +5541,7 @@ function MatrxUuidCell({
5406
5541
  ) : null
5407
5542
  ]
5408
5543
  }
5409
- );
5544
+ ) });
5410
5545
  }
5411
5546
 
5412
5547
  // src/data-table/entity.ts
@@ -5750,35 +5885,39 @@ function EditableTableCell({
5750
5885
  display,
5751
5886
  ...dirty === void 0 ? {} : { dirty },
5752
5887
  ...className === void 0 ? {} : { className },
5753
- editButton: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
5754
- "button",
5755
- {
5756
- type: "button",
5757
- "aria-label": "Edit",
5758
- title: "Edit",
5759
- onClick: (e) => e.stopPropagation(),
5760
- className: CELL_PENCIL_CLASS,
5761
- children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Pencil, { className: "h-3 w-3" })
5762
- }
5763
- ) })
5764
- }
5765
- ) : /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
5766
- "button",
5767
- {
5768
- type: "button",
5769
- onClick: (e) => e.stopPropagation(),
5770
- className: cn(
5771
- "group/cell-select flex w-full items-center gap-1 rounded px-0.5 text-left hover:bg-muted/60",
5772
- dirty && "ring-1 ring-primary/40 bg-primary/5",
5773
- className
5774
- ),
5775
- title: "Edit",
5776
- children: [
5777
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "min-w-0 flex-1 overflow-hidden", children: display }),
5778
- editType === "select" ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ChevronDown, { className: "h-3 w-3 shrink-0 text-muted-foreground/70 transition-colors group-hover/cell-select:text-foreground" }) : null
5779
- ]
5888
+ editButton: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(Tooltip, { children: [
5889
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
5890
+ "button",
5891
+ {
5892
+ type: "button",
5893
+ "aria-label": "Edit",
5894
+ onClick: (e) => e.stopPropagation(),
5895
+ className: CELL_PENCIL_CLASS,
5896
+ children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Pencil, { className: "h-3 w-3" })
5897
+ }
5898
+ ) }) }),
5899
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(TooltipContent, { children: "Edit" })
5900
+ ] })
5780
5901
  }
5781
- ) }),
5902
+ ) : /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(Tooltip, { children: [
5903
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
5904
+ "button",
5905
+ {
5906
+ type: "button",
5907
+ onClick: (e) => e.stopPropagation(),
5908
+ className: cn(
5909
+ "group/cell-select flex w-full items-center gap-1 rounded px-0.5 text-left hover:bg-muted/60",
5910
+ dirty && "ring-1 ring-primary/40 bg-primary/5",
5911
+ className
5912
+ ),
5913
+ children: [
5914
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "min-w-0 flex-1 overflow-hidden", children: display }),
5915
+ editType === "select" ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ChevronDown, { className: "h-3 w-3 shrink-0 text-muted-foreground/70 transition-colors group-hover/cell-select:text-foreground" }) : null
5916
+ ]
5917
+ }
5918
+ ) }) }),
5919
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(TooltipContent, { children: "Edit value" })
5920
+ ] }),
5782
5921
  /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
5783
5922
  PopoverContent,
5784
5923
  {
@@ -5822,42 +5961,46 @@ function InlineStringEditor({
5822
5961
  display,
5823
5962
  ...dirty === void 0 ? {} : { dirty },
5824
5963
  ...className === void 0 ? {} : { className },
5825
- editButton: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
5826
- "button",
5827
- {
5828
- type: "button",
5829
- "aria-label": "Edit",
5830
- title: "Edit",
5831
- onClick: (e) => {
5832
- e.stopPropagation();
5833
- setDraft(value);
5834
- setEditing(true);
5835
- },
5836
- className: CELL_PENCIL_CLASS,
5837
- children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Pencil, { className: "h-3 w-3" })
5838
- }
5839
- )
5964
+ editButton: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(Tooltip, { children: [
5965
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
5966
+ "button",
5967
+ {
5968
+ type: "button",
5969
+ "aria-label": "Edit",
5970
+ onClick: (e) => {
5971
+ e.stopPropagation();
5972
+ setDraft(value);
5973
+ setEditing(true);
5974
+ },
5975
+ className: CELL_PENCIL_CLASS,
5976
+ children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Pencil, { className: "h-3 w-3" })
5977
+ }
5978
+ ) }),
5979
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(TooltipContent, { children: "Edit" })
5980
+ ] })
5840
5981
  }
5841
5982
  );
5842
5983
  }
5843
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
5844
- "button",
5845
- {
5846
- type: "button",
5847
- onClick: (e) => {
5848
- e.stopPropagation();
5849
- setDraft(value);
5850
- setEditing(true);
5851
- },
5852
- className: cn(
5853
- "w-full rounded px-0.5 text-left hover:bg-muted/60",
5854
- dirty && "ring-1 ring-primary/40 bg-primary/5",
5855
- className
5856
- ),
5857
- title: "Click to edit",
5858
- children: display
5859
- }
5860
- );
5984
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(Tooltip, { children: [
5985
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
5986
+ "button",
5987
+ {
5988
+ type: "button",
5989
+ onClick: (e) => {
5990
+ e.stopPropagation();
5991
+ setDraft(value);
5992
+ setEditing(true);
5993
+ },
5994
+ className: cn(
5995
+ "w-full rounded px-0.5 text-left hover:bg-muted/60",
5996
+ dirty && "ring-1 ring-primary/40 bg-primary/5",
5997
+ className
5998
+ ),
5999
+ children: display
6000
+ }
6001
+ ) }),
6002
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(TooltipContent, { children: "Click to edit" })
6003
+ ] });
5861
6004
  }
5862
6005
  return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
5863
6006
  Input,
@@ -5973,20 +6116,25 @@ function TagsEditor({
5973
6116
  return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "space-y-2", onClick: (e) => e.stopPropagation(), children: [
5974
6117
  /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "flex flex-wrap gap-1", children: [
5975
6118
  tags.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "text-xs text-muted-foreground", children: "No tags" }),
5976
- tags.map((tag) => /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
5977
- "button",
5978
- {
5979
- type: "button",
5980
- onClick: () => setTags(tags.filter((t) => t !== tag)),
5981
- className: "inline-flex items-center gap-1 rounded-full border border-border px-2 py-0.5 text-[11px] hover:border-destructive hover:text-destructive",
5982
- title: `Remove ${tag}`,
5983
- children: [
5984
- tag,
5985
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(X, { className: "h-2.5 w-2.5" })
5986
- ]
5987
- },
5988
- tag
5989
- ))
6119
+ tags.map((tag) => /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(Tooltip, { children: [
6120
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
6121
+ "button",
6122
+ {
6123
+ type: "button",
6124
+ onClick: () => setTags(tags.filter((t) => t !== tag)),
6125
+ "aria-label": `Remove ${tag}`,
6126
+ className: "inline-flex items-center gap-1 rounded-full border border-border px-2 py-0.5 text-[11px] hover:border-destructive hover:text-destructive",
6127
+ children: [
6128
+ tag,
6129
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(X, { className: "h-2.5 w-2.5" })
6130
+ ]
6131
+ }
6132
+ ) }),
6133
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(TooltipContent, { children: [
6134
+ "Remove ",
6135
+ tag
6136
+ ] })
6137
+ ] }, tag))
5990
6138
  ] }),
5991
6139
  /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
5992
6140
  Input,
@@ -6134,28 +6282,30 @@ function ToolbarFacets({ facets }) {
6134
6282
  children: [
6135
6283
  opt.icon,
6136
6284
  opt.label,
6137
- active && isNonDefault ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
6138
- "span",
6139
- {
6140
- role: "button",
6141
- tabIndex: 0,
6142
- "aria-label": `Clear ${facet.label ?? opt.label} filter`,
6143
- title: "Clear this filter",
6144
- className: "ml-0.5 inline-flex rounded-sm p-0.5 hover:bg-primary-foreground/20",
6145
- onClick: (e) => {
6146
- e.stopPropagation();
6147
- facet.onChange(defaultValue);
6148
- },
6149
- onKeyDown: (e) => {
6150
- if (e.key === "Enter" || e.key === " ") {
6151
- e.preventDefault();
6285
+ active && isNonDefault ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(TooltipProvider, { delayDuration: 200, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(Tooltip, { children: [
6286
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
6287
+ "span",
6288
+ {
6289
+ role: "button",
6290
+ tabIndex: 0,
6291
+ "aria-label": `Clear ${facet.label ?? opt.label} filter`,
6292
+ className: "ml-0.5 inline-flex rounded-sm p-0.5 hover:bg-primary-foreground/20",
6293
+ onClick: (e) => {
6152
6294
  e.stopPropagation();
6153
6295
  facet.onChange(defaultValue);
6154
- }
6155
- },
6156
- children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(X, { className: "h-3 w-3" })
6157
- }
6158
- ) : null
6296
+ },
6297
+ onKeyDown: (e) => {
6298
+ if (e.key === "Enter" || e.key === " ") {
6299
+ e.preventDefault();
6300
+ e.stopPropagation();
6301
+ facet.onChange(defaultValue);
6302
+ }
6303
+ },
6304
+ children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(X, { className: "h-3 w-3" })
6305
+ }
6306
+ ) }),
6307
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(TooltipContent, { side: "top", children: "Clear this filter" })
6308
+ ] }) }) : null
6159
6309
  ]
6160
6310
  },
6161
6311
  opt.value
@@ -6668,7 +6818,8 @@ function TableRowCopyControl({
6668
6818
  copy,
6669
6819
  row,
6670
6820
  size,
6671
- sourceId
6821
+ sourceId,
6822
+ defaultColumns
6672
6823
  }) {
6673
6824
  return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
6674
6825
  CopyButtons,
@@ -6678,7 +6829,7 @@ function TableRowCopyControl({
6678
6829
  label: copy.label,
6679
6830
  human: () => copy.humanRow(row),
6680
6831
  json: () => copy.agentRow ? copy.agentRow(row) : row,
6681
- agent: () => buildRowAgentInput(copy, row),
6832
+ agent: () => defaultColumns ? buildDefaultTableRowAgentInput(copy, row, defaultColumns) : buildRowAgentInput(copy, row),
6682
6833
  ...copy.rowAiVariants?.(row) === void 0 ? {} : { aiVariants: copy.rowAiVariants?.(row) }
6683
6834
  }
6684
6835
  );
@@ -7069,7 +7220,7 @@ function MatrxDataTableCore({
7069
7220
  });
7070
7221
  const rootRef = (0, import_react13.useRef)(null);
7071
7222
  useClippedContentGuard(rootRef, {
7072
- label: copy?.listLabel ? `Table: ${copy.listLabel}` : "MatrxDataTable"
7223
+ label: typeof copy === "object" && copy.listLabel ? `Table: ${copy.listLabel}` : "MatrxDataTable"
7073
7224
  });
7074
7225
  const [scrollHintRight, setScrollHintRight] = (0, import_react13.useState)(false);
7075
7226
  const [scrollHintLeft, setScrollHintLeft] = (0, import_react13.useState)(false);
@@ -7181,23 +7332,45 @@ function MatrxDataTableCore({
7181
7332
  (column) => column !== void 0 && !effectiveHiddenColumnIds.has(columnId(column))
7182
7333
  );
7183
7334
  }, [columns, effectiveColumnOrder, effectiveHiddenColumnIds]);
7335
+ const declaredVisibleCopyColumns = (0, import_react13.useMemo)(
7336
+ () => visibleColumns.filter((column) => column.accessorFn !== void 0 || column.accessorKey !== void 0),
7337
+ [visibleColumns]
7338
+ );
7339
+ const tableCopySourceNamespace = (0, import_react13.useId)();
7340
+ const defaultCopyTitle = toolbar?.title || "Table";
7341
+ const defaultCopy = (0, import_react13.useMemo)(() => ({
7342
+ label: defaultCopyTitle,
7343
+ listLabel: defaultCopyTitle,
7344
+ location: defaultCopyTitle,
7345
+ rowKind: "table-row",
7346
+ listKind: "table-view",
7347
+ listDescription: `${defaultCopyTitle} \u2014 ${remoteQuery ? "current filtered/sorted loaded view" : "current filtered/sorted view"}.`,
7348
+ listAttributes: (_visible, loaded) => remoteQuery ? { coverage: "loaded-current-view", loaded_count: loaded.length } : { coverage: "current-view" },
7349
+ humanRow: (row) => formatDefaultTableCopyRecord(
7350
+ projectDefaultTableCopyRow(row, declaredVisibleCopyColumns),
7351
+ declaredVisibleCopyColumns
7352
+ ),
7353
+ agentRow: (row) => projectDefaultTableCopyRow(row, declaredVisibleCopyColumns)
7354
+ }), [defaultCopyTitle, declaredVisibleCopyColumns, remoteQuery]);
7355
+ const effectiveCopy = copy === false ? void 0 : copy ?? defaultCopy;
7356
+ const effectiveCopyColumns = copy === void 0 ? declaredVisibleCopyColumns : visibleColumns;
7184
7357
  const copySubsetVariant = useCopySubsetVariant();
7185
- const copySubsetColumns = () => visibleColumns.filter((c) => c.filter !== false || c.accessorKey || c.accessorFn).map((c) => ({
7358
+ const copySubsetColumns = () => effectiveCopyColumns.filter((c) => c.filter !== false || c.accessorKey || c.accessorFn).map((c) => ({
7186
7359
  id: columnId(c),
7187
7360
  header: typeof c.header === "string" ? c.header : columnId(c),
7188
7361
  ...c.accessorKey === void 0 ? {} : { accessorKey: c.accessorKey },
7189
7362
  ...c.accessorFn === void 0 ? {} : { accessorFn: c.accessorFn },
7190
7363
  ...c.filter === void 0 ? {} : { filter: c.filter }
7191
7364
  }));
7192
- const copySubsetVariantFor = (rows, scope) => copy && !remoteQuery ? [
7365
+ const copySubsetVariantFor = (rows, scope) => effectiveCopy && !remoteQuery ? [
7193
7366
  copySubsetVariant(() => ({
7194
- label: scope === "selected" ? `${rows().length} selected ${selectionNoun}${rows().length === 1 ? "" : "s"}` : copy.listLabel ?? `${copy.label} view`,
7195
- location: copy.location,
7196
- kind: copy.listKind,
7367
+ label: scope === "selected" ? `${rows().length} selected ${selectionNoun}${rows().length === 1 ? "" : "s"}` : effectiveCopy.listLabel ?? `${effectiveCopy.label} view`,
7368
+ location: effectiveCopy.location,
7369
+ kind: effectiveCopy.listKind,
7197
7370
  rows: rows(),
7198
7371
  columns: copySubsetColumns(),
7199
7372
  getRowId,
7200
- serializer: (shaped) => buildViewAgentInput(copy, shaped, data, { scope: "custom" })
7373
+ serializer: (shaped) => buildViewAgentInput(effectiveCopy, shaped, data, { scope: "custom" })
7201
7374
  }))
7202
7375
  ] : [];
7203
7376
  const filterMeta = (0, import_react13.useMemo)(() => {
@@ -7311,9 +7484,8 @@ function MatrxDataTableCore({
7311
7484
  windowEnabled && windowConfig?.openOnRowClick
7312
7485
  );
7313
7486
  const editEnabled = Boolean(edit?.enabled && edit.onSave);
7314
- const copyEnabled = Boolean(copy);
7315
- const showRowCopy = copyEnabled && copy?.showRow !== false;
7316
- const showToolbarCopy = copyEnabled && copy?.showToolbar !== false;
7487
+ const showRowCopy = effectiveCopy !== void 0 && effectiveCopy.showRow !== false;
7488
+ const showToolbarCopy = effectiveCopy !== void 0 && effectiveCopy.showToolbar !== false;
7317
7489
  const activeFilterCount = countActiveColumnFilters(columnFilters);
7318
7490
  const facetActive = (toolbar?.facets ?? []).some((f) => {
7319
7491
  if (f.type !== "button-group") return false;
@@ -7695,7 +7867,7 @@ function MatrxDataTableCore({
7695
7867
  }
7696
7868
  } : facet
7697
7869
  ) : toolbar?.facets;
7698
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
7870
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(TooltipProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
7699
7871
  import_core3.DndContext,
7700
7872
  {
7701
7873
  sensors: hierarchySensors,
@@ -7786,7 +7958,7 @@ function MatrxDataTableCore({
7786
7958
  ),
7787
7959
  children: [
7788
7960
  notice,
7789
- !hideToolbar && (toolbar?.title || showSearch || toolbar?.anyOf || toolbar?.layeredFilters || toolbar?.facets && toolbar.facets.length > 0 || toolbar?.leading || toolbar?.actions || hasActiveFilters || showToolbarCopy || columns.length > 0) && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(TooltipProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
7961
+ !hideToolbar && (toolbar?.title || showSearch || toolbar?.anyOf || toolbar?.layeredFilters || toolbar?.facets && toolbar.facets.length > 0 || toolbar?.leading || toolbar?.actions || hasActiveFilters || showToolbarCopy || columns.length > 0) && /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
7790
7962
  TableTitleRow,
7791
7963
  {
7792
7964
  ...toolbar?.title === void 0 ? {} : { title: toolbar.title },
@@ -7828,25 +8000,27 @@ function MatrxDataTableCore({
7828
8000
  /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(TooltipContent, { children: "Clear search" })
7829
8001
  ] }) : null
7830
8002
  ] }),
7831
- toolbar?.searchMatch ? /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
7832
- Button,
7833
- {
7834
- type: "button",
7835
- variant: searchMatchMode === "whole_words" ? "secondary" : "outline",
7836
- size: "sm",
7837
- className: "h-8 shrink-0 gap-1 rounded-l-none border-l-0 px-2 text-xs",
7838
- "aria-pressed": searchMatchMode === "whole_words",
7839
- "aria-label": `Search match: ${searchMatchMode === "whole_words" ? "whole words" : "contains text"}`,
7840
- title: searchMatchMode === "whole_words" ? "Whole words \u2014 click to match text anywhere" : "Contains text \u2014 click to require whole words",
7841
- onClick: () => setSearchMatchMode(
7842
- searchMatchMode === "whole_words" ? "contains" : "whole_words"
7843
- ),
7844
- children: [
7845
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(WholeWord, { className: "h-3.5 w-3.5" }),
7846
- searchMatchMode === "whole_words" ? "Whole words" : "Contains"
7847
- ]
7848
- }
7849
- ) : null
8003
+ toolbar?.searchMatch ? /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(Tooltip, { children: [
8004
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
8005
+ Button,
8006
+ {
8007
+ type: "button",
8008
+ variant: searchMatchMode === "whole_words" ? "secondary" : "outline",
8009
+ size: "sm",
8010
+ className: "h-8 shrink-0 gap-1 rounded-l-none border-l-0 px-2 text-xs",
8011
+ "aria-pressed": searchMatchMode === "whole_words",
8012
+ "aria-label": `Search match: ${searchMatchMode === "whole_words" ? "whole words" : "contains text"}`,
8013
+ onClick: () => setSearchMatchMode(
8014
+ searchMatchMode === "whole_words" ? "contains" : "whole_words"
8015
+ ),
8016
+ children: [
8017
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(WholeWord, { className: "h-3.5 w-3.5" }),
8018
+ searchMatchMode === "whole_words" ? "Whole words" : "Contains"
8019
+ ]
8020
+ }
8021
+ ) }),
8022
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(TooltipContent, { children: searchMatchMode === "whole_words" ? "Whole words \u2014 click to match text anywhere" : "Contains text \u2014 click to require whole words" })
8023
+ ] }) : null
7850
8024
  ]
7851
8025
  }
7852
8026
  ) : null,
@@ -7930,14 +8104,23 @@ function MatrxDataTableCore({
7930
8104
  ) }),
7931
8105
  /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(TooltipContent, { children: "Clear search and filters; keep columns and sort" })
7932
8106
  ] }) : null,
7933
- showToolbarCopy && copy ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
8107
+ showToolbarCopy && effectiveCopy ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
7934
8108
  CopyButtons,
7935
8109
  {
7936
8110
  size: "icon",
7937
- label: copy.listLabel ?? `${copy.label} view`,
7938
- human: () => buildViewHuman(copy, processed, visibleColumns),
7939
- json: () => processed.map((r) => copy.agentRow ? copy.agentRow(r) : r),
7940
- agent: () => buildViewAgentInput(copy, processed, data, {
8111
+ sourceId: `${tableCopySourceNamespace}:view`,
8112
+ label: effectiveCopy.listLabel ?? `${effectiveCopy.label} view`,
8113
+ ...copy === void 0 ? {} : {
8114
+ human: () => buildViewHuman(effectiveCopy, processed, effectiveCopyColumns),
8115
+ json: () => processed.map((r) => effectiveCopy.agentRow ? effectiveCopy.agentRow(r) : r)
8116
+ },
8117
+ agent: () => copy === void 0 ? buildDefaultTableViewAgentInput(effectiveCopy, processed, data, declaredVisibleCopyColumns, {
8118
+ search: searchValue,
8119
+ searchMatchMode,
8120
+ anyOf: anyOfValue,
8121
+ filterCount: activeFilterCount + completeLayeredFilterRules(layeredFilters).length,
8122
+ sort: sort ? `${sort.id}:${sort.direction}` : null
8123
+ }) : buildViewAgentInput(effectiveCopy, processed, data, {
7941
8124
  search: searchValue,
7942
8125
  searchMatchMode,
7943
8126
  anyOf: anyOfValue,
@@ -7945,15 +8128,15 @@ function MatrxDataTableCore({
7945
8128
  sort: sort ? `${sort.id}:${sort.direction}` : null
7946
8129
  }),
7947
8130
  aiVariants: [
7948
- ...copy.aiVariants?.(processed, data) ?? [],
8131
+ ...effectiveCopy.aiVariants?.(processed, data) ?? [],
7949
8132
  ...copySubsetVariantFor(() => processed, "view")
7950
8133
  ],
7951
- ...copy.aiCustom ? { aiCustom: copy.aiCustom(processed, data) } : {},
8134
+ ...effectiveCopy.aiCustom ? { aiCustom: effectiveCopy.aiCustom(processed, data) } : {},
7952
8135
  export: {
7953
- items: [
8136
+ items: copy === void 0 ? [] : [
7954
8137
  jsonExportItem(
7955
8138
  () => processed.map(
7956
- (r) => copy.agentRow ? copy.agentRow(r) : r
8139
+ (r) => effectiveCopy.agentRow ? effectiveCopy.agentRow(r) : r
7957
8140
  ),
7958
8141
  "JSON (rows, raw)"
7959
8142
  ),
@@ -7961,7 +8144,7 @@ function MatrxDataTableCore({
7961
8144
  id: "csv",
7962
8145
  label: "CSV (current view)",
7963
8146
  build: () => ({
7964
- content: rowsToCsvFromColumns(processed, visibleColumns),
8147
+ content: rowsToCsvFromColumns(processed, effectiveCopyColumns),
7965
8148
  extension: "csv",
7966
8149
  mime: "text/csv"
7967
8150
  })
@@ -7973,13 +8156,14 @@ function MatrxDataTableCore({
7973
8156
  const { downloadTableAsXlsx: downloadTableAsXlsx2 } = await Promise.resolve().then(() => (init_tableXlsx(), tableXlsx_exports));
7974
8157
  downloadTableAsXlsx2({
7975
8158
  rows: processed,
7976
- columns: visibleColumns,
7977
- label: copy.listLabel ?? copy.label
8159
+ columns: effectiveCopyColumns,
8160
+ label: effectiveCopy.listLabel ?? effectiveCopy.label
7978
8161
  });
7979
8162
  }
7980
8163
  }
7981
8164
  ],
7982
- sheetRows: () => rowsToRecordsFromColumns(processed, visibleColumns)
8165
+ sheetRows: () => copy === void 0 ? processed.map((row) => projectDefaultTableCopyRow(row, declaredVisibleCopyColumns)) : rowsToRecordsFromColumns(processed, effectiveCopyColumns),
8166
+ ...copy === void 0 ? { sheetColumns: () => declaredVisibleCopyColumns.map((column) => ({ id: columnId(column), label: column.label ?? (typeof column.header === "string" ? column.header : columnId(column)) })) } : {}
7983
8167
  }
7984
8168
  }
7985
8169
  ) : null,
@@ -8010,7 +8194,7 @@ function MatrxDataTableCore({
8010
8194
  )
8011
8195
  ]
8012
8196
  }
8013
- ) }),
8197
+ ),
8014
8198
  selection && selectionCount > 0 ? /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "flex shrink-0 flex-wrap items-center gap-2 rounded-md border border-primary/30 bg-primary/5 px-2 py-1.5", children: [
8015
8199
  /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("span", { className: "text-xs font-medium text-foreground", children: [
8016
8200
  selectionCount.toLocaleString(),
@@ -8037,27 +8221,26 @@ function MatrxDataTableCore({
8037
8221
  }
8038
8222
  ),
8039
8223
  /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "ml-auto flex flex-wrap items-center gap-1.5", children: [
8040
- copy && selectedRows.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
8224
+ effectiveCopy && selectedRows.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
8041
8225
  CopyButtons,
8042
8226
  {
8043
8227
  size: "icon",
8228
+ sourceId: `${tableCopySourceNamespace}:selection`,
8044
8229
  label: `${selectedRows.length} selected ${selectionNoun}${selectedRows.length === 1 ? "" : "s"}`,
8045
- human: () => buildViewHuman(copy, selectedRows, visibleColumns),
8046
- json: () => selectedRows.map(
8047
- (row) => copy.agentRow ? copy.agentRow(row) : row
8048
- ),
8049
- agent: () => buildViewAgentInput(copy, selectedRows, data, {
8050
- scope: "selected"
8051
- }),
8230
+ ...copy === void 0 ? {} : {
8231
+ human: () => buildViewHuman(effectiveCopy, selectedRows, effectiveCopyColumns),
8232
+ json: () => selectedRows.map((row) => effectiveCopy.agentRow ? effectiveCopy.agentRow(row) : row)
8233
+ },
8234
+ agent: () => copy === void 0 ? buildDefaultTableViewAgentInput(effectiveCopy, selectedRows, data, declaredVisibleCopyColumns, { scope: "selected" }) : buildViewAgentInput(effectiveCopy, selectedRows, data, { scope: "selected" }),
8052
8235
  aiVariants: copySubsetVariantFor(
8053
8236
  () => selectedRows,
8054
8237
  "selected"
8055
8238
  ),
8056
8239
  export: {
8057
- items: [
8240
+ items: copy === void 0 ? [] : [
8058
8241
  jsonExportItem(
8059
8242
  () => selectedRows.map(
8060
- (row) => copy.agentRow ? copy.agentRow(row) : row
8243
+ (row) => effectiveCopy.agentRow ? effectiveCopy.agentRow(row) : row
8061
8244
  ),
8062
8245
  "JSON (selected rows)"
8063
8246
  ),
@@ -8067,7 +8250,7 @@ function MatrxDataTableCore({
8067
8250
  build: () => ({
8068
8251
  content: rowsToCsvFromColumns(
8069
8252
  selectedRows,
8070
- visibleColumns
8253
+ effectiveCopyColumns
8071
8254
  ),
8072
8255
  extension: "csv",
8073
8256
  mime: "text/csv"
@@ -8080,13 +8263,14 @@ function MatrxDataTableCore({
8080
8263
  const { downloadTableAsXlsx: downloadTableAsXlsx2 } = await Promise.resolve().then(() => (init_tableXlsx(), tableXlsx_exports));
8081
8264
  downloadTableAsXlsx2({
8082
8265
  rows: selectedRows,
8083
- columns: visibleColumns,
8084
- label: `${copy.listLabel ?? copy.label} selected`
8266
+ columns: effectiveCopyColumns,
8267
+ label: `${effectiveCopy.listLabel ?? effectiveCopy.label} selected`
8085
8268
  });
8086
8269
  }
8087
8270
  }
8088
8271
  ],
8089
- sheetRows: () => rowsToRecordsFromColumns(selectedRows, visibleColumns)
8272
+ sheetRows: () => copy === void 0 ? selectedRows.map((row) => projectDefaultTableCopyRow(row, declaredVisibleCopyColumns)) : rowsToRecordsFromColumns(selectedRows, effectiveCopyColumns),
8273
+ ...copy === void 0 ? { sheetColumns: () => declaredVisibleCopyColumns.map((column) => ({ id: columnId(column), label: column.label ?? (typeof column.header === "string" ? column.header : columnId(column)) })) } : {}
8090
8274
  }
8091
8275
  }
8092
8276
  ) : null,
@@ -8151,13 +8335,14 @@ function MatrxDataTableCore({
8151
8335
  className: "inline-flex items-center gap-1",
8152
8336
  onClick: (event) => event.stopPropagation(),
8153
8337
  children: [
8154
- showRowCopy && copy ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
8338
+ showRowCopy && effectiveCopy ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
8155
8339
  TableRowCopyControl,
8156
8340
  {
8157
8341
  size: "xs",
8158
- copy,
8342
+ copy: effectiveCopy,
8159
8343
  row: displayRow,
8160
- sourceId: getRowId(displayRow)
8344
+ sourceId: `${tableCopySourceNamespace}:row:${getRowId(displayRow)}`,
8345
+ ...copy === void 0 ? { defaultColumns: declaredVisibleCopyColumns } : {}
8161
8346
  }
8162
8347
  ) : null,
8163
8348
  rowActions?.(displayRow, {
@@ -8478,13 +8663,14 @@ function MatrxDataTableCore({
8478
8663
  className: "inline-flex items-center justify-end gap-0.5",
8479
8664
  onClick: (e) => e.stopPropagation(),
8480
8665
  children: [
8481
- showRowCopy && copy ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
8666
+ showRowCopy && effectiveCopy ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
8482
8667
  TableRowCopyControl,
8483
8668
  {
8484
8669
  size: "xs",
8485
- copy,
8670
+ copy: effectiveCopy,
8486
8671
  row: displayRow,
8487
- sourceId: getRowId(displayRow)
8672
+ sourceId: `${tableCopySourceNamespace}:row:${getRowId(displayRow)}`,
8673
+ ...copy === void 0 ? { defaultColumns: declaredVisibleCopyColumns } : {}
8488
8674
  }
8489
8675
  ) : null,
8490
8676
  rowActions?.(displayRow, {
@@ -8495,26 +8681,28 @@ function MatrxDataTableCore({
8495
8681
  hasPendingEdits: Boolean(rowEdits),
8496
8682
  discardPendingEdits: () => discardRowEdits(id)
8497
8683
  }),
8498
- windowEnabled ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
8499
- Button,
8500
- {
8501
- type: "button",
8502
- variant: "ghost",
8503
- size: "icon",
8504
- className: "h-11 w-11 text-muted-foreground hover:text-foreground lg:h-5 lg:w-5 [&_svg]:size-3",
8505
- "aria-label": opensWindowOnRowClick ? "Open in side panel" : "Open in window",
8506
- title: opensWindowOnRowClick ? "Open in side panel" : "Open in window",
8507
- onClick: (e) => {
8508
- e.stopPropagation();
8509
- if (opensWindowOnRowClick) {
8510
- openDetail(row);
8511
- } else {
8512
- openWindow(row);
8513
- }
8514
- },
8515
- children: opensWindowOnRowClick ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(PanelRightOpen, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(PanelRight, { className: "h-3.5 w-3.5" })
8516
- }
8517
- ) : null
8684
+ windowEnabled ? /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(Tooltip, { children: [
8685
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
8686
+ Button,
8687
+ {
8688
+ type: "button",
8689
+ variant: "ghost",
8690
+ size: "icon",
8691
+ className: "h-11 w-11 text-muted-foreground hover:text-foreground lg:h-5 lg:w-5 [&_svg]:size-3",
8692
+ "aria-label": opensWindowOnRowClick ? "Open in side panel" : "Open in window",
8693
+ onClick: (e) => {
8694
+ e.stopPropagation();
8695
+ if (opensWindowOnRowClick) {
8696
+ openDetail(row);
8697
+ } else {
8698
+ openWindow(row);
8699
+ }
8700
+ },
8701
+ children: opensWindowOnRowClick ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(PanelRightOpen, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(PanelRight, { className: "h-3.5 w-3.5" })
8702
+ }
8703
+ ) }),
8704
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(TooltipContent, { children: opensWindowOnRowClick ? "Open in side panel" : "Open in window" })
8705
+ ] }) : null
8518
8706
  ]
8519
8707
  }
8520
8708
  ) })
@@ -8582,34 +8770,38 @@ function MatrxDataTableCore({
8582
8770
  ]
8583
8771
  }
8584
8772
  ),
8585
- scrollHintLeft ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
8586
- Button,
8587
- {
8588
- type: "button",
8589
- variant: "ghost",
8590
- size: "icon",
8591
- "aria-label": "Scroll table left",
8592
- title: "More columns to the left",
8593
- "data-matrx-table-scroll-control": "left",
8594
- className: "absolute left-1.5 top-1/2 z-30 hidden h-11 w-11 -translate-y-1/2 rounded-full border border-glass-edge bg-glass p-0 text-foreground shadow-glass backdrop-blur-glass backdrop-saturate-glass hover:bg-glass-hover active:bg-glass-active sm:inline-flex",
8595
- onClick: () => scrollTableHorizontally("left"),
8596
- children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ChevronLeft, { className: "h-5 w-5" })
8597
- }
8598
- ) : null,
8599
- scrollHintRight ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
8600
- Button,
8601
- {
8602
- type: "button",
8603
- variant: "ghost",
8604
- size: "icon",
8605
- "aria-label": "Scroll table right",
8606
- title: "More columns to the right",
8607
- "data-matrx-table-scroll-control": "right",
8608
- className: "absolute right-1.5 top-1/2 z-30 hidden h-11 w-11 -translate-y-1/2 rounded-full border border-glass-edge bg-glass p-0 text-foreground shadow-glass backdrop-blur-glass backdrop-saturate-glass hover:bg-glass-hover active:bg-glass-active sm:inline-flex",
8609
- onClick: () => scrollTableHorizontally("right"),
8610
- children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ChevronRight, { className: "h-5 w-5" })
8611
- }
8612
- ) : null
8773
+ scrollHintLeft ? /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(Tooltip, { children: [
8774
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
8775
+ Button,
8776
+ {
8777
+ type: "button",
8778
+ variant: "ghost",
8779
+ size: "icon",
8780
+ "aria-label": "Scroll table left",
8781
+ "data-matrx-table-scroll-control": "left",
8782
+ className: "absolute left-1.5 top-1/2 z-30 hidden h-11 w-11 -translate-y-1/2 rounded-full border border-glass-edge bg-glass p-0 text-foreground shadow-glass backdrop-blur-glass backdrop-saturate-glass hover:bg-glass-hover active:bg-glass-active sm:inline-flex",
8783
+ onClick: () => scrollTableHorizontally("left"),
8784
+ children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ChevronLeft, { className: "h-5 w-5" })
8785
+ }
8786
+ ) }),
8787
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(TooltipContent, { children: "More columns to the left" })
8788
+ ] }) : null,
8789
+ scrollHintRight ? /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(Tooltip, { children: [
8790
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
8791
+ Button,
8792
+ {
8793
+ type: "button",
8794
+ variant: "ghost",
8795
+ size: "icon",
8796
+ "aria-label": "Scroll table right",
8797
+ "data-matrx-table-scroll-control": "right",
8798
+ className: "absolute right-1.5 top-1/2 z-30 hidden h-11 w-11 -translate-y-1/2 rounded-full border border-glass-edge bg-glass p-0 text-foreground shadow-glass backdrop-blur-glass backdrop-saturate-glass hover:bg-glass-hover active:bg-glass-active sm:inline-flex",
8799
+ onClick: () => scrollTableHorizontally("right"),
8800
+ children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(ChevronRight, { className: "h-5 w-5" })
8801
+ }
8802
+ ) }),
8803
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(TooltipContent, { children: "More columns to the right" })
8804
+ ] }) : null
8613
8805
  ] }),
8614
8806
  appendQuery ? /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
8615
8807
  "div",
@@ -8750,29 +8942,32 @@ function MatrxDataTableCore({
8750
8942
  onClose: () => setSelectedId(null),
8751
8943
  defaultWidth: detail?.defaultWidth ?? 480,
8752
8944
  headerActions: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "flex items-center gap-1", children: [
8753
- copy && showRowCopy ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
8945
+ effectiveCopy && showRowCopy ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
8754
8946
  TableRowCopyControl,
8755
8947
  {
8756
8948
  size: "icon",
8757
- copy,
8758
- sourceId: getRowId(selectedRow),
8759
- row: selectedRow
8949
+ copy: effectiveCopy,
8950
+ sourceId: `${tableCopySourceNamespace}:row:${getRowId(selectedRow)}`,
8951
+ row: selectedRow,
8952
+ ...copy === void 0 ? { defaultColumns: declaredVisibleCopyColumns } : {}
8760
8953
  }
8761
8954
  ) : null,
8762
8955
  detail?.headerActions?.(selectedRow),
8763
- windowEnabled ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
8764
- Button,
8765
- {
8766
- type: "button",
8767
- variant: "ghost",
8768
- size: "icon",
8769
- className: "h-7 w-7",
8770
- "aria-label": "Open in window",
8771
- title: "Open in window",
8772
- onClick: () => openWindow(selectedRow),
8773
- children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(PanelRight, { className: "h-3.5 w-3.5" })
8774
- }
8775
- ) : null
8956
+ windowEnabled ? /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(Tooltip, { children: [
8957
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
8958
+ Button,
8959
+ {
8960
+ type: "button",
8961
+ variant: "ghost",
8962
+ size: "icon",
8963
+ className: "h-7 w-7",
8964
+ "aria-label": "Open in window",
8965
+ onClick: () => openWindow(selectedRow),
8966
+ children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(PanelRight, { className: "h-3.5 w-3.5" })
8967
+ }
8968
+ ) }),
8969
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(TooltipContent, { children: "Open in window" })
8970
+ ] }) : null
8776
8971
  ] }),
8777
8972
  children: detail?.render ? (
8778
8973
  // The panel hands children a `min-h-0 flex-1 overflow-hidden` cell
@@ -8794,9 +8989,9 @@ function MatrxDataTableCore({
8794
8989
  DataRowInspector,
8795
8990
  {
8796
8991
  row: selectedRow,
8797
- ...copy?.rowKind === void 0 ? {} : { recordKind: copy?.rowKind },
8798
- ...copy?.label === void 0 ? {} : { recordLabel: copy?.label },
8799
- ...copy?.location === void 0 ? {} : { location: copy?.location },
8992
+ ...effectiveCopy?.rowKind === void 0 ? {} : { recordKind: effectiveCopy?.rowKind },
8993
+ ...effectiveCopy?.label === void 0 ? {} : { recordLabel: effectiveCopy?.label },
8994
+ ...effectiveCopy?.location === void 0 ? {} : { location: effectiveCopy?.location },
8800
8995
  ...detail?.tokenForField === void 0 ? {} : { tokenForField: detail?.tokenForField }
8801
8996
  }
8802
8997
  )
@@ -8814,29 +9009,32 @@ function MatrxDataTableCore({
8814
9009
  windowId: `matrx-data-row-${urlState?.id ?? "local"}-${getRowId(windowRow)}`,
8815
9010
  defaultTab: windowConfig?.defaultTab,
8816
9011
  headerActions: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: "flex items-center gap-1", children: [
8817
- opensWindowOnRowClick && detailEnabled ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
8818
- Button,
8819
- {
8820
- type: "button",
8821
- variant: "ghost",
8822
- size: "icon",
8823
- className: "h-7 w-7",
8824
- "aria-label": "Open in side panel",
8825
- title: "Open in side panel",
8826
- onClick: () => {
8827
- closeWindow();
8828
- openDetail(windowRow);
8829
- },
8830
- children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(PanelRightOpen, { className: "h-3.5 w-3.5" })
8831
- }
8832
- ) : null,
8833
- copy ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
9012
+ opensWindowOnRowClick && detailEnabled ? /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(Tooltip, { children: [
9013
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
9014
+ Button,
9015
+ {
9016
+ type: "button",
9017
+ variant: "ghost",
9018
+ size: "icon",
9019
+ className: "h-7 w-7",
9020
+ "aria-label": "Open in side panel",
9021
+ onClick: () => {
9022
+ closeWindow();
9023
+ openDetail(windowRow);
9024
+ },
9025
+ children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(PanelRightOpen, { className: "h-3.5 w-3.5" })
9026
+ }
9027
+ ) }),
9028
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(TooltipContent, { children: "Open in side panel" })
9029
+ ] }) : null,
9030
+ effectiveCopy && showRowCopy ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
8834
9031
  TableRowCopyControl,
8835
9032
  {
8836
9033
  size: "icon",
8837
- copy,
8838
- sourceId: getRowId(windowRow),
8839
- row: windowRow
9034
+ copy: effectiveCopy,
9035
+ sourceId: `${tableCopySourceNamespace}:row:${getRowId(windowRow)}`,
9036
+ row: windowRow,
9037
+ ...copy === void 0 ? { defaultColumns: declaredVisibleCopyColumns } : {}
8840
9038
  }
8841
9039
  ) : null
8842
9040
  ] }),
@@ -8847,16 +9045,17 @@ function MatrxDataTableCore({
8847
9045
  closeWindow,
8848
9046
  hasPendingEdits: Boolean(edits[getRowId(windowRow)]),
8849
9047
  discardPendingEdits: () => discardRowEdits(getRowId(windowRow))
8850
- }) ?? (copy ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
9048
+ }) ?? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
8851
9049
  DataRowInspector,
8852
9050
  {
8853
9051
  row: windowRow,
8854
- recordKind: copy.rowKind,
8855
- recordLabel: copy.label,
8856
- location: copy.location,
9052
+ recordKind: effectiveCopy?.rowKind ?? "record",
9053
+ recordLabel: effectiveCopy?.label ?? "Record",
9054
+ location: effectiveCopy?.location ?? "Table",
9055
+ fieldCopy: copy !== false,
8857
9056
  ...detail?.tokenForField === void 0 ? {} : { tokenForField: detail?.tokenForField }
8858
9057
  }
8859
- ) : void 0),
9058
+ ),
8860
9059
  editContent: windowConfig?.renderEdit === false ? void 0 : windowConfig?.renderEdit ? windowConfig.renderEdit(windowRow, {
8861
9060
  closeDetail: () => setSelectedId(null),
8862
9061
  openDetail: () => openDetail(windowRow),
@@ -8944,7 +9143,7 @@ function MatrxDataTableCore({
8944
9143
  ) : null })
8945
9144
  ]
8946
9145
  }
8947
- );
9146
+ ) });
8948
9147
  }
8949
9148
  function HierarchyDragHandle({
8950
9149
  id,