@ai-matrx/design-system 0.18.0 → 0.18.2

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.
@@ -427,7 +427,7 @@ import {
427
427
  PointerSensor,
428
428
  pointerWithin,
429
429
  useDndMonitor as useDndMonitor2,
430
- useDraggable as useDraggable2,
430
+ useDraggable as useDraggable3,
431
431
  useDroppable as useDroppable2,
432
432
  useSensor,
433
433
  useSensors
@@ -2423,7 +2423,12 @@ async function buildArtifact(draft, format, label) {
2423
2423
  const extension = format === "plain" ? "txt" : format === "compact-json" ? "json" : format;
2424
2424
  return serialize(draft, format, { spreadsheetSafe: format === "csv" || format === "tsv", filename: `${filenameFor(label)}.${extension}` });
2425
2425
  }
2426
- function ContentTransferMenu({ source, surface, label, projection, sections, preferences, table, formatSources, variants = EMPTY_VARIANTS, actions = [], capabilities: local, disabled, enabled = true, className, stopPropagation = true, hide = [], controllerRef }) {
2426
+ function ContentTransferMenu(props) {
2427
+ const inherited = React12.useContext(CapabilityContext);
2428
+ const identityKey = props.capabilities?.identityKey ?? inherited.identityKey;
2429
+ return /* @__PURE__ */ jsx19(ContentTransferMenuSession, { ...props }, identityKey ?? "anonymous");
2430
+ }
2431
+ function ContentTransferMenuSession({ source, surface, label, projection, sections, preferences, table, formatSources, variants = EMPTY_VARIANTS, actions = [], capabilities: local, disabled, enabled = true, className, stopPropagation = true, hide = [], controllerRef }) {
2427
2432
  const triggerRef = React12.useRef(null);
2428
2433
  const inherited = React12.useContext(CapabilityContext);
2429
2434
  const nearestSurface = React12.useContext(SurfaceContext);
@@ -2716,6 +2721,9 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
2716
2721
  const [instruction, setInstruction] = React12.useState("");
2717
2722
  const [busy, setBusy] = React12.useState(null);
2718
2723
  const [aiFailed, setAiFailed] = React12.useState(false);
2724
+ React12.useEffect(() => {
2725
+ setAiFailed(false);
2726
+ }, [state.snapshot.id, state.draft.revision]);
2719
2727
  const activeAi = React12.useRef(null);
2720
2728
  const activeCapture = React12.useRef(null);
2721
2729
  React12.useEffect(() => {
@@ -3026,7 +3034,7 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
3026
3034
  activeCapture.current = null;
3027
3035
  setBusy(null);
3028
3036
  }, children: "Stop loading rows" }) : null,
3029
- ai && aiSession.current?.recover && busy !== "ai" ? /* @__PURE__ */ jsx19(Button, { type: "button", variant: "outline", onClick: () => void runAi(true), children: aiFailed ? "Retry or rejoin AI run" : "Rejoin AI run" }) : null,
3037
+ ai && aiFailed && aiSession.current?.recover && busy !== "ai" ? /* @__PURE__ */ jsx19(Button, { type: "button", variant: "outline", onClick: () => void runAi(true), children: aiFailed ? "Retry or rejoin AI run" : "Rejoin AI run" }) : null,
3030
3038
  ai ? /* @__PURE__ */ jsx19("p", { className: "matrx-alchemy-meta", children: "AI creates a preview. It never copies automatically. Closing detaches this view without cancelling server work." }) : null,
3031
3039
  state.error ? /* @__PURE__ */ jsx19("p", { role: "alert", className: "matrx-alchemy-error", children: state.error }) : null
3032
3040
  ] }) : null
@@ -3153,7 +3161,17 @@ var sourceFor = (id, label, build) => ({
3153
3161
  }
3154
3162
  });
3155
3163
  function MatrxCopyMenu(props) {
3156
- return /* @__PURE__ */ jsx20(MatrxCopyMenuSession, { ...props }, props.sourceId ?? props.label);
3164
+ const inherited = useContentTransferCapabilities();
3165
+ return /* @__PURE__ */ jsx20(
3166
+ MatrxCopyMenuSession,
3167
+ {
3168
+ ...props
3169
+ },
3170
+ JSON.stringify([
3171
+ inherited.identityKey ?? null,
3172
+ props.sourceId ?? props.label
3173
+ ])
3174
+ );
3157
3175
  }
3158
3176
  function MatrxCopyMenuSession(props) {
3159
3177
  const instance = React13.useId();
@@ -3181,7 +3199,7 @@ function MatrxCopyMenuSession(props) {
3181
3199
  })) : void 0;
3182
3200
  const agent = aiVisible && props.agent !== void 0 ? make("agent", () => asPayload(resolve(props.agent))) : void 0;
3183
3201
  const structuredAgent = aiVisible && props.agent !== void 0 ? make("structured-agent", () => structuredPayload(resolve(props.agent))) : void 0;
3184
- const table = exportVisible && props.export?.sheetRows ? make("rows", () => {
3202
+ const table = (exportVisible || props.primarySource === "table") && props.export?.sheetRows ? make("rows", () => {
3185
3203
  const value = normalizeTransferJson(props.export.sheetRows());
3186
3204
  if (!Array.isArray(value) || value.some(
3187
3205
  (row) => row === null || typeof row !== "object" || Array.isArray(row)
@@ -3328,7 +3346,7 @@ function MatrxCopyMenuSession(props) {
3328
3346
  return props.sendToSheet(draft.payload.rows, props.label);
3329
3347
  }
3330
3348
  });
3331
- const source = json ?? table ?? structuredAgent ?? human ?? builderVariants[0]?.source;
3349
+ const source = (props.primarySource === "table" ? table : void 0) ?? json ?? table ?? structuredAgent ?? human ?? builderVariants[0]?.source;
3332
3350
  if (!source && !actions.length) return null;
3333
3351
  const target = source ?? make("actions", () => ({ kind: "text", text: props.label }));
3334
3352
  return /* @__PURE__ */ jsxs14(Fragment3, { children: [
@@ -3348,7 +3366,7 @@ function MatrxCopyMenuSession(props) {
3348
3366
  formatSources: {
3349
3367
  ...human ? { plain: human, markdown: humanMarkdown, html: humanMarkdown } : {},
3350
3368
  ...json ? { json, "compact-json": json } : {},
3351
- ...table ? { csv: table, tsv: table } : {}
3369
+ ...table && exportVisible ? { csv: table, tsv: table } : {}
3352
3370
  },
3353
3371
  ...props.disabled !== void 0 ? { disabled: props.disabled } : {},
3354
3372
  className: cn(
@@ -3648,8 +3666,9 @@ ${JSON.stringify(value.data, null, 2)}
3648
3666
  import { jsx as jsx21 } from "react/jsx-runtime";
3649
3667
  function CopyButtons(props) {
3650
3668
  const { CopyControls } = useMatrxDataTableHost();
3651
- if (CopyControls) return /* @__PURE__ */ jsx21(CopyControls, { ...props });
3652
- return /* @__PURE__ */ jsx21(MatrxCopyMenu, { ...props });
3669
+ const copyProps = props.export?.sheetRows ? { ...props, primarySource: "table" } : props;
3670
+ if (CopyControls) return /* @__PURE__ */ jsx21(CopyControls, { ...copyProps });
3671
+ return /* @__PURE__ */ jsx21(MatrxCopyMenu, { ...copyProps });
3653
3672
  }
3654
3673
  function jsonExportItem(build, label) {
3655
3674
  return { id: "json", label, build: () => ({ content: JSON.stringify(build(), null, 2), extension: "json", mime: "application/json" }) };
@@ -4022,7 +4041,12 @@ import {
4022
4041
  } from "@ai-matrx/kit/url-state";
4023
4042
 
4024
4043
  // src/data-table/ColumnHeaderCell.tsx
4025
- import { useEffect as useEffect6, useMemo as useMemo3, useState as useState9 } from "react";
4044
+ import {
4045
+ useEffect as useEffect6,
4046
+ useMemo as useMemo3,
4047
+ useState as useState9
4048
+ } from "react";
4049
+ import { useDraggable } from "@dnd-kit/core";
4026
4050
 
4027
4051
  // src/popover.tsx
4028
4052
  import * as PopoverPrimitive from "@radix-ui/react-popover";
@@ -4232,8 +4256,29 @@ function ColumnHeaderCell({
4232
4256
  filterShowCancel = false,
4233
4257
  filterFooterHint,
4234
4258
  allowNegation = false,
4235
- allowNullModes = false
4259
+ allowNullModes = false,
4260
+ reorderColumn
4236
4261
  }) {
4262
+ const reorderEnabled = reorderColumn !== void 0;
4263
+ const { attributes: reorderAttributes, listeners: reorderListeners, setNodeRef } = useDraggable(
4264
+ reorderColumn ? {
4265
+ id: `matrx-column-header:${reorderColumn.id}`,
4266
+ data: { matrxDragKind: "column-header", columnId: reorderColumn.id },
4267
+ disabled: false
4268
+ } : {
4269
+ id: `matrx-column-header:inactive:${labelText ?? "column"}`,
4270
+ disabled: true
4271
+ }
4272
+ );
4273
+ const reorderLabel = reorderColumn?.label ?? labelText ?? "column";
4274
+ const reorderActivator = reorderEnabled ? {
4275
+ ...reorderAttributes,
4276
+ ...reorderListeners,
4277
+ ref: setNodeRef,
4278
+ title: `Drag to reorder ${reorderLabel}.`,
4279
+ "aria-description": "Drag this column label to reorder it."
4280
+ } : void 0;
4281
+ const reorderClass = reorderEnabled ? "touch-none cursor-grab active:cursor-grabbing" : void 0;
4237
4282
  const filterActive = isColumnFilterActive(filterValue);
4238
4283
  const deferredFilter = filterApplyLabel !== void 0 || filterShowCancel || filterFooterHint !== void 0;
4239
4284
  const [filterOpen, setFilterOpen] = useState9(false);
@@ -4377,7 +4422,21 @@ function ColumnHeaderCell({
4377
4422
  );
4378
4423
  if (compact) {
4379
4424
  if (!sortable && !filterKind) {
4380
- return /* @__PURE__ */ jsx25("div", { className: cn("flex items-center justify-center", className), children: label });
4425
+ if (!reorderEnabled) {
4426
+ return /* @__PURE__ */ jsx25("div", { className: cn("flex items-center justify-center", className), children: label });
4427
+ }
4428
+ return /* @__PURE__ */ jsx25("div", { className: cn("flex items-center justify-center", className), children: /* @__PURE__ */ jsx25(
4429
+ "button",
4430
+ {
4431
+ type: "button",
4432
+ ...reorderActivator,
4433
+ className: cn(
4434
+ "inline-flex items-center justify-center rounded p-0.5 text-muted-foreground transition-colors hover:text-foreground",
4435
+ reorderClass
4436
+ ),
4437
+ children: label
4438
+ }
4439
+ ) });
4381
4440
  }
4382
4441
  return /* @__PURE__ */ jsx25(
4383
4442
  "div",
@@ -4394,9 +4453,13 @@ function ColumnHeaderCell({
4394
4453
  type: "button",
4395
4454
  "aria-label": menuLabel,
4396
4455
  title: menuLabel,
4397
- onClick: (e) => e.stopPropagation(),
4456
+ onClick: (event) => {
4457
+ event.stopPropagation();
4458
+ },
4459
+ ...reorderActivator,
4398
4460
  className: cn(
4399
4461
  "relative inline-flex items-center justify-center rounded p-0.5 transition-colors",
4462
+ reorderClass,
4400
4463
  isSorted || filterActive ? "text-foreground" : "text-muted-foreground hover:text-foreground"
4401
4464
  ),
4402
4465
  children: [
@@ -4432,8 +4495,10 @@ function ColumnHeaderCell({
4432
4495
  {
4433
4496
  type: "button",
4434
4497
  onClick: onHeaderSortClick,
4498
+ ...reorderActivator,
4435
4499
  className: cn(
4436
4500
  "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",
4501
+ reorderClass,
4437
4502
  isSorted ? "text-foreground" : "text-muted-foreground hover:text-foreground"
4438
4503
  ),
4439
4504
  children: [
@@ -4441,6 +4506,17 @@ function ColumnHeaderCell({
4441
4506
  isSorted ? sortDirection === "asc" ? /* @__PURE__ */ jsx25(ArrowUp, { className: "h-3 w-3 shrink-0 text-primary" }) : /* @__PURE__ */ jsx25(ArrowDown, { className: "h-3 w-3 shrink-0 text-primary" }) : /* @__PURE__ */ jsx25(ArrowUpDown, { className: "h-3 w-3 shrink-0 opacity-40" })
4442
4507
  ]
4443
4508
  }
4509
+ ) : reorderEnabled ? /* @__PURE__ */ jsx25(
4510
+ "button",
4511
+ {
4512
+ type: "button",
4513
+ ...reorderActivator,
4514
+ className: cn(
4515
+ "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",
4516
+ reorderClass
4517
+ ),
4518
+ children: label
4519
+ }
4444
4520
  ) : /* @__PURE__ */ jsx25("span", { className: "truncate text-xs font-semibold uppercase tracking-wide text-muted-foreground", children: label }),
4445
4521
  filterKind ? /* @__PURE__ */ jsxs17("div", { className: "inline-flex items-center", children: [
4446
4522
  /* @__PURE__ */ jsxs17(Popover, { open: filterOpen, onOpenChange: setFilterOpen, children: [
@@ -4763,7 +4839,7 @@ function parseOptionalNumber(raw) {
4763
4839
 
4764
4840
  // src/data-table/ColumnManager.tsx
4765
4841
  import { useEffect as useEffect7, useMemo as useMemo4, useState as useState10 } from "react";
4766
- import { useDndMonitor, useDraggable, useDroppable } from "@dnd-kit/core";
4842
+ import { useDndMonitor, useDraggable as useDraggable2, useDroppable } from "@dnd-kit/core";
4767
4843
  init_filter_engine();
4768
4844
  import { jsx as jsx26, jsxs as jsxs18 } from "react/jsx-runtime";
4769
4845
  function ColumnManager({
@@ -4938,7 +5014,7 @@ function ColumnManagerDropTarget({
4938
5014
  return /* @__PURE__ */ jsx26("div", { ref: setNodeRef, "data-matrx-column-manager-drop-target": id, className, children });
4939
5015
  }
4940
5016
  function ColumnManagerDragHandle({ id, label }) {
4941
- const { attributes, listeners, setNodeRef } = useDraggable({
5017
+ const { attributes, listeners, setNodeRef } = useDraggable2({
4942
5018
  id: `matrx-column-manager:${id}`,
4943
5019
  data: { matrxDragKind: "column-manager", columnId: id }
4944
5020
  });
@@ -6566,6 +6642,7 @@ function MatrxDataTableWithUrlState({
6566
6642
  }
6567
6643
  );
6568
6644
  }
6645
+ var COLUMN_REORDER_ACTIVATION_DISTANCE = 6;
6569
6646
  function MatrxDataTableCore({
6570
6647
  data: suppliedData,
6571
6648
  columns,
@@ -6638,7 +6715,9 @@ function MatrxDataTableCore({
6638
6715
  const [internalSearch, setInternalSearch] = useState15("");
6639
6716
  const [draggedRowId, setDraggedRowId] = useState15(null);
6640
6717
  const hierarchySensors = useSensors(
6641
- useSensor(PointerSensor, { activationConstraint: { distance: 6 } })
6718
+ useSensor(PointerSensor, {
6719
+ activationConstraint: { distance: COLUMN_REORDER_ACTIVATION_DISTANCE }
6720
+ })
6642
6721
  );
6643
6722
  const toolbarSearchControlled = toolbar?.searchValue !== void 0;
6644
6723
  const searchValue = controlledQuery ? controlledQuery.state.search : toolbarSearchControlled ? toolbar?.searchValue ?? "" : internalSearch;
@@ -7696,6 +7775,7 @@ function MatrxDataTableCore({
7696
7775
  size: "sm",
7697
7776
  className: "h-7 gap-1 px-2 text-xs text-muted-foreground",
7698
7777
  onClick: clearAllFilters,
7778
+ "aria-label": "Clear all filters",
7699
7779
  title: "Clear all filters",
7700
7780
  children: [
7701
7781
  /* @__PURE__ */ jsx35(Eraser, { className: "h-3.5 w-3.5" }),
@@ -8054,45 +8134,43 @@ function MatrxDataTableCore({
8054
8134
  col.align === "right" && "text-right"
8055
8135
  ),
8056
8136
  style: columnWidthVar(col.width),
8057
- children: /* @__PURE__ */ jsxs26(ColumnHeaderDropZone, { id, enabled: reorderableColumns, children: [
8058
- reorderableColumns ? /* @__PURE__ */ jsx35(ColumnReorderHandle, { id, label: headerLabel }) : null,
8059
- /* @__PURE__ */ jsx35(
8060
- ColumnHeaderCell,
8061
- {
8062
- label: col.header,
8063
- labelText: headerLabel,
8064
- sortable: col.sortable !== false,
8065
- isSorted: Boolean(isSorted),
8066
- sortDirection: sort?.direction ?? defaultSortDirection,
8067
- onSortAsc: () => setSort({ id, direction: "asc" }),
8068
- onSortDesc: () => setSort({ id, direction: "desc" }),
8069
- onClearSort: () => setSort(null),
8070
- onHeaderSortClick: () => {
8071
- if (!isSorted) {
8072
- setSort({ id, direction: defaultSortDirection });
8073
- return;
8074
- }
8075
- if (sort?.direction === "asc") {
8076
- setSort({ id, direction: "desc" });
8077
- return;
8078
- }
8079
- setSort(null);
8080
- },
8081
- filterKind: meta?.kind ?? null,
8082
- filterValue: columnFilters[id],
8083
- onFilterChange: (next) => setColumnFilter(id, next),
8084
- selectOptions: meta?.options,
8085
- selectSingle: col.filterSingle,
8086
- filterApplyLabel: filterUi?.applyLabel,
8087
- filterShowCancel: filterUi?.showCancel,
8088
- filterFooterHint: filterUi?.footerHint,
8089
- allowNegation: filterUi?.allowNegation,
8090
- allowNullModes: filterUi?.allowNullModes,
8091
- align: col.align,
8092
- compact: col.compact
8093
- }
8094
- )
8095
- ] })
8137
+ children: /* @__PURE__ */ jsx35(ColumnHeaderDropZone, { id, enabled: reorderableColumns, children: /* @__PURE__ */ jsx35(
8138
+ ColumnHeaderCell,
8139
+ {
8140
+ label: col.header,
8141
+ labelText: headerLabel,
8142
+ sortable: col.sortable !== false,
8143
+ isSorted: Boolean(isSorted),
8144
+ sortDirection: sort?.direction ?? defaultSortDirection,
8145
+ onSortAsc: () => setSort({ id, direction: "asc" }),
8146
+ onSortDesc: () => setSort({ id, direction: "desc" }),
8147
+ onClearSort: () => setSort(null),
8148
+ onHeaderSortClick: () => {
8149
+ if (!isSorted) {
8150
+ setSort({ id, direction: defaultSortDirection });
8151
+ return;
8152
+ }
8153
+ if (sort?.direction === "asc") {
8154
+ setSort({ id, direction: "desc" });
8155
+ return;
8156
+ }
8157
+ setSort(null);
8158
+ },
8159
+ filterKind: meta?.kind ?? null,
8160
+ filterValue: columnFilters[id],
8161
+ onFilterChange: (next) => setColumnFilter(id, next),
8162
+ selectOptions: meta?.options,
8163
+ selectSingle: col.filterSingle,
8164
+ filterApplyLabel: filterUi?.applyLabel,
8165
+ filterShowCancel: filterUi?.showCancel,
8166
+ filterFooterHint: filterUi?.footerHint,
8167
+ allowNegation: filterUi?.allowNegation,
8168
+ allowNullModes: filterUi?.allowNullModes,
8169
+ align: col.align,
8170
+ compact: col.compact,
8171
+ reorderColumn: reorderableColumns ? { id, label: headerLabel } : void 0
8172
+ }
8173
+ ) })
8096
8174
  },
8097
8175
  id
8098
8176
  );
@@ -8683,7 +8761,7 @@ function HierarchyDragHandle({
8683
8761
  label,
8684
8762
  disabled
8685
8763
  }) {
8686
- const { attributes, listeners, setNodeRef } = useDraggable2({
8764
+ const { attributes, listeners, setNodeRef } = useDraggable3({
8687
8765
  id,
8688
8766
  disabled
8689
8767
  });
@@ -8851,26 +8929,6 @@ function ColumnHeaderDropZone({
8851
8929
  });
8852
8930
  return /* @__PURE__ */ jsx35("div", { ref: setNodeRef, className: "flex min-w-0 items-center", children });
8853
8931
  }
8854
- function ColumnReorderHandle({ id, label }) {
8855
- const { attributes, listeners, setNodeRef } = useDraggable2({
8856
- id: `matrx-column-header:${id}`,
8857
- data: { matrxDragKind: "column-header", columnId: id }
8858
- });
8859
- return /* @__PURE__ */ jsx35(
8860
- "button",
8861
- {
8862
- ref: setNodeRef,
8863
- type: "button",
8864
- className: "mr-1 flex h-7 w-5 shrink-0 touch-none cursor-grab items-center justify-center text-muted-foreground hover:text-foreground active:cursor-grabbing",
8865
- "aria-label": `Reorder ${label}`,
8866
- title: `Drag to reorder ${label}`,
8867
- onClick: (event) => event.stopPropagation(),
8868
- ...attributes,
8869
- ...listeners,
8870
- children: /* @__PURE__ */ jsx35(GripVertical, { className: "h-3.5 w-3.5" })
8871
- }
8872
- );
8873
- }
8874
8932
  function columnWidthVar(width) {
8875
8933
  if (width === void 0) return void 0;
8876
8934
  return {