@ai-matrx/design-system 0.18.1 → 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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/data-table/copy-types.ts"],"sourcesContent":["import type { ComponentType, ReactNode } from \"react\";\n\nexport type CopyResolvable<T> = T | (() => T);\nexport type CopyScalar = string | number | boolean | null | undefined;\nexport interface AgentPayloadInput { kind: string; location: string; description: string; data: unknown; summary?: string; context?: Record<string, CopyScalar>; attributes?: Record<string, CopyScalar>; }\nexport type AiIcon = ComponentType<{ className?: string }>;\nexport interface AiVariant { id: string; label: string; hint?: string; icon?: AiIcon; section?: \"copy\" | \"ai\"; ariaLabel?: string; successMessage?: string; build?: () => AgentPayloadInput | string | Promise<AgentPayloadInput | string>; onSelect?: () => void; modal?: (props: { open: boolean; onOpenChange: (open: boolean) => void }) => ReactNode; }\nexport type AiCustomOption =\n | { kind: \"toggle\"; key: string; label: string; hint?: string; default: boolean }\n | { kind: \"preset\"; key: string; label: string; options: { label: string; value: number }[]; default: number }\n | { kind: \"slider\"; key: string; label: string; hint?: string; stops: number[]; default: number; formatValue: (value: number) => string }\n | { kind: \"number\"; key: string; label: string; hint?: string; min?: number; step?: number; presets?: { label: string; value: number }[]; default: number };\nexport type AiOptionValues = Record<string, boolean | number>;\nexport interface AiCustomSource { label?: string; hint?: string; options: AiCustomOption[]; build: (options: AiOptionValues) => { text: string; meta?: Record<string, string | number | boolean | undefined> }; wrap: (text: string, options: AiOptionValues, meta?: Record<string, string | number | boolean | undefined>) => AgentPayloadInput; dialogTitle?: string; dialogDescription?: string; }\nexport interface ExportItem { id: string; label: string; build?: () => { content: BlobPart; extension: string; mime: string }; onSelect?: () => void | Promise<void>; }\nexport interface CopyExportConfig { items: ExportItem[]; sheetRows?: () => Array<Record<string, unknown>>; }\n/** Exact portable table-copy API. Host adapters import this, never recreate it. */\nexport interface CopyControlProps {\n /** Changes reset the preparation session when a mounted control changes record. */\n sourceId?: string;\n human?: CopyResolvable<string>;\n agent?: CopyResolvable<AgentPayloadInput | string>;\n json?: CopyResolvable<unknown>;\n label: string;\n size?: \"xs\" | \"icon\" | \"sm\";\n /** Accepted for direct compatibility; package chrome has no application groomer engine. */\n appearance?: \"segmented\" | \"bare\";\n disabled?: boolean;\n stopPropagation?: boolean;\n className?: string;\n /** Legacy source compatibility; controls are already grouped by default. */\n grouped?: boolean;\n aiVariants?: AiVariant[];\n agentVariant?: { id?: string; label?: string; hint?: string; position?: \"first\" | \"last\" };\n aiCustom?: AiCustomSource;\n export?: CopyExportConfig;\n hide?: Array<\"copy\" | \"ai\" | \"export\">;\n}\nexport interface CopySubsetColumn<T> { id: string; header: string; accessorKey?: keyof T & string; accessorFn?: (row: T) => unknown; hidden?: boolean; }\nexport interface CopySubsetSource<T> { label: string; location: string; kind: string; rows: T[]; columns: CopySubsetColumn<T>[]; getRowId: (row: T) => string; serializer?: (rows: T[]) => AgentPayloadInput; }\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
1
+ {"version":3,"sources":["../../src/data-table/copy-types.ts"],"sourcesContent":["import type { ComponentType, ReactNode } from \"react\";\n\nexport type CopyResolvable<T> = T | (() => T);\nexport type CopyScalar = string | number | boolean | null | undefined;\nexport interface AgentPayloadInput { kind: string; location: string; description: string; data: unknown; summary?: string; context?: Record<string, CopyScalar>; attributes?: Record<string, CopyScalar>; }\nexport type AiIcon = ComponentType<{ className?: string }>;\nexport interface AiVariant { id: string; label: string; hint?: string; icon?: AiIcon; section?: \"copy\" | \"ai\"; ariaLabel?: string; successMessage?: string; build?: () => AgentPayloadInput | string | Promise<AgentPayloadInput | string>; onSelect?: () => void; modal?: (props: { open: boolean; onOpenChange: (open: boolean) => void }) => ReactNode; }\nexport type AiCustomOption =\n | { kind: \"toggle\"; key: string; label: string; hint?: string; default: boolean }\n | { kind: \"preset\"; key: string; label: string; options: { label: string; value: number }[]; default: number }\n | { kind: \"slider\"; key: string; label: string; hint?: string; stops: number[]; default: number; formatValue: (value: number) => string }\n | { kind: \"number\"; key: string; label: string; hint?: string; min?: number; step?: number; presets?: { label: string; value: number }[]; default: number };\nexport type AiOptionValues = Record<string, boolean | number>;\nexport interface AiCustomSource { label?: string; hint?: string; options: AiCustomOption[]; build: (options: AiOptionValues) => { text: string; meta?: Record<string, string | number | boolean | undefined> }; wrap: (text: string, options: AiOptionValues, meta?: Record<string, string | number | boolean | undefined>) => AgentPayloadInput; dialogTitle?: string; dialogDescription?: string; }\nexport interface ExportItem { id: string; label: string; build?: () => { content: BlobPart; extension: string; mime: string }; onSelect?: () => void | Promise<void>; }\nexport interface CopyExportConfig { items: ExportItem[]; sheetRows?: () => Array<Record<string, unknown>>; }\n/** Exact portable table-copy API. Host adapters import this, never recreate it. */\nexport interface CopyControlProps {\n /** Changes reset the preparation session when a mounted control changes record. */\n sourceId?: string;\n /** Canonical table controls opt into row preparation when sheet rows exist. */\n primarySource?: \"table\";\n human?: CopyResolvable<string>;\n agent?: CopyResolvable<AgentPayloadInput | string>;\n json?: CopyResolvable<unknown>;\n label: string;\n size?: \"xs\" | \"icon\" | \"sm\";\n /** Accepted for direct compatibility; package chrome has no application groomer engine. */\n appearance?: \"segmented\" | \"bare\";\n disabled?: boolean;\n stopPropagation?: boolean;\n className?: string;\n /** Legacy source compatibility; controls are already grouped by default. */\n grouped?: boolean;\n aiVariants?: AiVariant[];\n agentVariant?: { id?: string; label?: string; hint?: string; position?: \"first\" | \"last\" };\n aiCustom?: AiCustomSource;\n export?: CopyExportConfig;\n hide?: Array<\"copy\" | \"ai\" | \"export\">;\n}\nexport interface CopySubsetColumn<T> { id: string; header: string; accessorKey?: keyof T & string; accessorFn?: (row: T) => unknown; hidden?: boolean; }\nexport interface CopySubsetSource<T> { label: string; location: string; kind: string; rows: T[]; columns: CopySubsetColumn<T>[]; getRowId: (row: T) => string; serializer?: (rows: T[]) => AgentPayloadInput; }\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
@@ -96,6 +96,8 @@ interface CopyExportConfig {
96
96
  interface CopyControlProps {
97
97
  /** Changes reset the preparation session when a mounted control changes record. */
98
98
  sourceId?: string;
99
+ /** Canonical table controls opt into row preparation when sheet rows exist. */
100
+ primarySource?: "table";
99
101
  human?: CopyResolvable<string>;
100
102
  agent?: CopyResolvable<AgentPayloadInput | string>;
101
103
  json?: CopyResolvable<unknown>;
@@ -96,6 +96,8 @@ interface CopyExportConfig {
96
96
  interface CopyControlProps {
97
97
  /** Changes reset the preparation session when a mounted control changes record. */
98
98
  sourceId?: string;
99
+ /** Canonical table controls opt into row preparation when sheet rows exist. */
100
+ primarySource?: "table";
99
101
  human?: CopyResolvable<string>;
100
102
  agent?: CopyResolvable<AgentPayloadInput | string>;
101
103
  json?: CopyResolvable<unknown>;
@@ -705,7 +705,12 @@ async function buildArtifact(draft, format, label) {
705
705
  const extension = format === "plain" ? "txt" : format === "compact-json" ? "json" : format;
706
706
  return (0, import_content_transfer.serialize)(draft, format, { spreadsheetSafe: format === "csv" || format === "tsv", filename: `${filenameFor(label)}.${extension}` });
707
707
  }
708
- function ContentTransferMenu({ source, surface, label, projection, sections, preferences, table, formatSources, variants = EMPTY_VARIANTS, actions = [], capabilities: local, disabled, enabled = true, className, stopPropagation = true, hide = [], controllerRef }) {
708
+ function ContentTransferMenu(props) {
709
+ const inherited = React7.useContext(CapabilityContext);
710
+ const identityKey = props.capabilities?.identityKey ?? inherited.identityKey;
711
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ContentTransferMenuSession, { ...props }, identityKey ?? "anonymous");
712
+ }
713
+ function ContentTransferMenuSession({ source, surface, label, projection, sections, preferences, table, formatSources, variants = EMPTY_VARIANTS, actions = [], capabilities: local, disabled, enabled = true, className, stopPropagation = true, hide = [], controllerRef }) {
709
714
  const triggerRef = React7.useRef(null);
710
715
  const inherited = React7.useContext(CapabilityContext);
711
716
  const nearestSurface = React7.useContext(SurfaceContext);
@@ -998,6 +1003,9 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
998
1003
  const [instruction, setInstruction] = React7.useState("");
999
1004
  const [busy, setBusy] = React7.useState(null);
1000
1005
  const [aiFailed, setAiFailed] = React7.useState(false);
1006
+ React7.useEffect(() => {
1007
+ setAiFailed(false);
1008
+ }, [state.snapshot.id, state.draft.revision]);
1001
1009
  const activeAi = React7.useRef(null);
1002
1010
  const activeCapture = React7.useRef(null);
1003
1011
  React7.useEffect(() => {
@@ -1308,7 +1316,7 @@ function PreparationWorkspace({ restoreFocus, open, state, scopes, onClose, onCh
1308
1316
  activeCapture.current = null;
1309
1317
  setBusy(null);
1310
1318
  }, children: "Stop loading rows" }) : null,
1311
- ai && aiSession.current?.recover && busy !== "ai" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Button, { type: "button", variant: "outline", onClick: () => void runAi(true), children: aiFailed ? "Retry or rejoin AI run" : "Rejoin AI run" }) : null,
1319
+ ai && aiFailed && aiSession.current?.recover && busy !== "ai" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Button, { type: "button", variant: "outline", onClick: () => void runAi(true), children: aiFailed ? "Retry or rejoin AI run" : "Rejoin AI run" }) : null,
1312
1320
  ai ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "matrx-alchemy-meta", children: "AI creates a preview. It never copies automatically. Closing detaches this view without cancelling server work." }) : null,
1313
1321
  state.error ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { role: "alert", className: "matrx-alchemy-error", children: state.error }) : null
1314
1322
  ] }) : null
@@ -1435,7 +1443,17 @@ var sourceFor = (id, label, build) => ({
1435
1443
  }
1436
1444
  });
1437
1445
  function MatrxCopyMenu(props) {
1438
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(MatrxCopyMenuSession, { ...props }, props.sourceId ?? props.label);
1446
+ const inherited = useContentTransferCapabilities();
1447
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1448
+ MatrxCopyMenuSession,
1449
+ {
1450
+ ...props
1451
+ },
1452
+ JSON.stringify([
1453
+ inherited.identityKey ?? null,
1454
+ props.sourceId ?? props.label
1455
+ ])
1456
+ );
1439
1457
  }
1440
1458
  function MatrxCopyMenuSession(props) {
1441
1459
  const instance = React8.useId();
@@ -1463,7 +1481,7 @@ function MatrxCopyMenuSession(props) {
1463
1481
  })) : void 0;
1464
1482
  const agent = aiVisible && props.agent !== void 0 ? make("agent", () => asPayload(resolve(props.agent))) : void 0;
1465
1483
  const structuredAgent = aiVisible && props.agent !== void 0 ? make("structured-agent", () => structuredPayload(resolve(props.agent))) : void 0;
1466
- const table = exportVisible && props.export?.sheetRows ? make("rows", () => {
1484
+ const table = (exportVisible || props.primarySource === "table") && props.export?.sheetRows ? make("rows", () => {
1467
1485
  const value = (0, import_content_transfer2.normalizeTransferJson)(props.export.sheetRows());
1468
1486
  if (!Array.isArray(value) || value.some(
1469
1487
  (row) => row === null || typeof row !== "object" || Array.isArray(row)
@@ -1610,7 +1628,7 @@ function MatrxCopyMenuSession(props) {
1610
1628
  return props.sendToSheet(draft.payload.rows, props.label);
1611
1629
  }
1612
1630
  });
1613
- const source = json ?? table ?? structuredAgent ?? human ?? builderVariants[0]?.source;
1631
+ const source = (props.primarySource === "table" ? table : void 0) ?? json ?? table ?? structuredAgent ?? human ?? builderVariants[0]?.source;
1614
1632
  if (!source && !actions.length) return null;
1615
1633
  const target = source ?? make("actions", () => ({ kind: "text", text: props.label }));
1616
1634
  return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
@@ -1630,7 +1648,7 @@ function MatrxCopyMenuSession(props) {
1630
1648
  formatSources: {
1631
1649
  ...human ? { plain: human, markdown: humanMarkdown, html: humanMarkdown } : {},
1632
1650
  ...json ? { json, "compact-json": json } : {},
1633
- ...table ? { csv: table, tsv: table } : {}
1651
+ ...table && exportVisible ? { csv: table, tsv: table } : {}
1634
1652
  },
1635
1653
  ...props.disabled !== void 0 ? { disabled: props.disabled } : {},
1636
1654
  className: cn(
@@ -1913,8 +1931,9 @@ function useMatrxDataTableHost() {
1913
1931
  var import_jsx_runtime10 = require("react/jsx-runtime");
1914
1932
  function CopyButtons(props) {
1915
1933
  const { CopyControls } = useMatrxDataTableHost();
1916
- if (CopyControls) return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(CopyControls, { ...props });
1917
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(MatrxCopyMenu, { ...props });
1934
+ const copyProps = props.export?.sheetRows ? { ...props, primarySource: "table" } : props;
1935
+ if (CopyControls) return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(CopyControls, { ...copyProps });
1936
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(MatrxCopyMenu, { ...copyProps });
1918
1937
  }
1919
1938
 
1920
1939
  // src/data-table/MatrxUuidCell.tsx