@ai-matrx/rich-content 0.2.9 → 0.2.10
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.
- package/CHANGELOG.md +9 -0
- package/dist/display/blocks/json/json-tabular-utils.d.ts +7 -5
- package/dist/display/blocks/json/json-tabular-utils.js +26 -17
- package/dist/display/blocks/table/StreamingTableRenderer.js +11 -16
- package/dist/display/chat-markdown/BasicMarkdownContent.js +8 -6
- package/dist/display/chat-markdown/ConfigurableMarkdownContent.js +8 -6
- package/dist/display/tables/MarkdownTable.js +11 -16
- package/dist/display/tables/TableWithSeparatedControls.js +11 -16
- package/dist/display/tables/table-csv.d.ts +7 -0
- package/dist/display/tables/table-csv.js +19 -0
- package/dist/host/app-bindings.d.ts +2 -0
- package/dist/host/app-bindings.js +2 -0
- package/package.json +7 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.2.10
|
|
4
|
+
|
|
5
|
+
- Markdown copy goes through the host's `app.CopyButtons` (the copy menu; matrx-frontend ALC-19).
|
|
6
|
+
- Table CSV/TSV and workbook export through Alchemy (`toDelimitedText`, `buildFile`); `display/tables/table-csv`.
|
|
7
|
+
|
|
8
|
+
### Consumer action
|
|
9
|
+
|
|
10
|
+
- Register `app.CopyButtons` (matrx-frontend: `components/agent-copy/CopyButtons`).
|
|
11
|
+
|
|
3
12
|
## 0.2.9
|
|
4
13
|
|
|
5
14
|
AP-2 (2026-10-07) — the kit and Alchemy doors are the only doors in this package (aidream guard `apps/shared/scripts/check-shared-doors.mjs`). New dependency `@ai-matrx/alchemy`; `html2canvas` dependency removed. Every table/code/SVG/JSON/mermaid/diagram download saves through `@ai-matrx/kit/download` (`downloadFile` / `downloadUrl`) — the tables' "Download Again" toast action now really downloads again (it clicked a revoked URL before). Link/URL/mermaid copies go through `@ai-matrx/kit/clipboard` `copyText` (copied state from its boolean; `copyMermaidSource`/`copyMermaidSvg` throw when refused, as before); ImageBlock's image copy uses `useClipboard().copyImage`. The diagram PNG export captures through `@ai-matrx/alchemy/operate/capture` `captureElement` with `safeColors` (the local getComputedStyle patch is gone). No consumer action.
|
|
@@ -49,16 +49,18 @@ export declare function detectTabular(value: unknown): TabularShape;
|
|
|
49
49
|
* `null` and `undefined` become empty strings (Excel-friendly).
|
|
50
50
|
*/
|
|
51
51
|
export declare function cellToCsv(value: unknown): string;
|
|
52
|
+
/**
|
|
53
|
+
* Rows -> CSV/TSV text through Alchemy's one writer (quoting, line breaks, `'` before a leading
|
|
54
|
+
* = + - @ text; real numbers stay numbers, so -5 is never altered).
|
|
55
|
+
*/
|
|
52
56
|
export declare function rowsToCsv(rows: Record<string, unknown>[], columns: string[], delimiter?: string): string;
|
|
53
57
|
export declare function rowsToNdjson(rows: unknown[]): string;
|
|
54
58
|
/** Browser file-download for a text payload. */
|
|
55
59
|
export declare function downloadText(filename: string, content: string, mime?: string): void;
|
|
56
60
|
/**
|
|
57
|
-
* XLSX export
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
* Cell values are pre-stringified for objects/arrays so spreadsheets
|
|
61
|
-
* receive plain text instead of "[object Object]".
|
|
61
|
+
* XLSX export through Alchemy's workbook format (the one spreadsheet engine).
|
|
62
|
+
* Header row = `columns`; object/array cells are pre-stringified so
|
|
63
|
+
* spreadsheets receive plain text instead of "[object Object]".
|
|
62
64
|
*/
|
|
63
65
|
export declare function rowsToXlsx(rows: Record<string, unknown>[], columns: string[], filename: string): Promise<void>;
|
|
64
66
|
/** Default filename helper (no extension). */
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { buildFile } from "@ai-matrx/alchemy/operate";
|
|
2
|
+
import { toDelimitedText } from "@ai-matrx/alchemy/operate/read";
|
|
1
3
|
import { downloadFile } from "@ai-matrx/kit/download";
|
|
2
|
-
import { announceBareHost, hostCapability } from "../../../host/registry.js";
|
|
3
4
|
function parseJsonSafe(text) {
|
|
4
5
|
if (!text || !text.trim()) {
|
|
5
6
|
return { ok: false, error: "Empty input" };
|
|
@@ -73,30 +74,38 @@ function cellToCsv(value) {
|
|
|
73
74
|
}
|
|
74
75
|
return String(value);
|
|
75
76
|
}
|
|
76
|
-
function escapeCsv(value, delimiter) {
|
|
77
|
-
const needsQuote = value.includes(delimiter) || value.includes('"') || value.includes("\n") || value.includes("\r");
|
|
78
|
-
if (!needsQuote) return value;
|
|
79
|
-
return `"${value.replace(/"/g, '""')}"`;
|
|
80
|
-
}
|
|
81
77
|
function rowsToCsv(rows, columns, delimiter = ",") {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
(row) => columns.map((c) =>
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
78
|
+
return toDelimitedText(
|
|
79
|
+
columns,
|
|
80
|
+
rows.map((row) => columns.map((c) => cellToCsvValue(row[c]))),
|
|
81
|
+
{ format: delimiter === " " ? "tsv" : "csv", spreadsheetSafe: true }
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
function cellToCsvValue(value) {
|
|
85
|
+
if (value === null || value === void 0) return "";
|
|
86
|
+
if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") return value;
|
|
87
|
+
return cellToCsv(value);
|
|
88
88
|
}
|
|
89
89
|
function rowsToNdjson(rows) {
|
|
90
90
|
return rows.map((r) => JSON.stringify(r)).join("\n");
|
|
91
91
|
}
|
|
92
92
|
function downloadText(filename, content, mime = "text/plain") {
|
|
93
|
-
|
|
93
|
+
const blob = new Blob([content], { type: `${mime};charset=utf-8` });
|
|
94
|
+
downloadFile(filename, blob, blob.type);
|
|
94
95
|
}
|
|
95
96
|
async function rowsToXlsx(rows, columns, filename) {
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
97
|
+
const cell = (v) => v === null || v === void 0 ? null : typeof v === "object" ? JSON.stringify(v) : typeof v === "string" || typeof v === "number" || typeof v === "boolean" ? v : String(v);
|
|
98
|
+
const built = await buildFile(
|
|
99
|
+
{
|
|
100
|
+
kind: "registered",
|
|
101
|
+
format: "workbook",
|
|
102
|
+
value: { sheets: [{ name: "Data", rows: [columns, ...rows.map((row) => columns.map((c) => cell(row[c])))] }] }
|
|
103
|
+
},
|
|
104
|
+
"xlsx-workbook",
|
|
105
|
+
{ filename }
|
|
106
|
+
);
|
|
107
|
+
const blob = built.blob();
|
|
108
|
+
downloadFile(built.filename, blob, blob.type);
|
|
100
109
|
}
|
|
101
110
|
function defaultJsonFilename() {
|
|
102
111
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19);
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { downloadFile } from "@ai-matrx/kit/download";
|
|
4
3
|
import { useClipboard } from "@ai-matrx/kit/clipboard";
|
|
5
4
|
import { toast as copyToast } from "../../../host/toast.js";
|
|
6
5
|
import { rewriteTableSource } from "../../../utils/table-source.js";
|
|
@@ -77,6 +76,8 @@ import {
|
|
|
77
76
|
parseMarkdownTable,
|
|
78
77
|
cleanTableHeaderKey
|
|
79
78
|
} from "./parseMarkdownTable.js";
|
|
79
|
+
import { downloadFile } from "@ai-matrx/kit/download";
|
|
80
|
+
import { tableToCsv } from "../../tables/table-csv.js";
|
|
80
81
|
const NO_HIDDEN_COLUMNS = /* @__PURE__ */ new Set();
|
|
81
82
|
const ExportDropdownMenu = ({
|
|
82
83
|
tableData,
|
|
@@ -292,21 +293,13 @@ const StreamingTableRendererCore = ({
|
|
|
292
293
|
};
|
|
293
294
|
const downloadCSV = () => {
|
|
294
295
|
try {
|
|
295
|
-
const csvContent =
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
(row) => row.map((cell) => {
|
|
299
|
-
const escaped = cell.replace(/"/g, '""');
|
|
300
|
-
return cell.includes(",") ? `"${escaped}"` : escaped;
|
|
301
|
-
}).join(",")
|
|
302
|
-
)
|
|
303
|
-
].join("\n");
|
|
304
|
-
const saveCsv = () => downloadFile("table_data.csv", csvContent, "text/csv;charset=utf-8");
|
|
305
|
-
saveCsv();
|
|
296
|
+
const csvContent = tableToCsv(headers, rows);
|
|
297
|
+
const blob = new Blob([csvContent], { type: "text/csv;charset=utf-8;" });
|
|
298
|
+
downloadFile("table_data.csv", blob, blob.type);
|
|
306
299
|
toast.success("Table exported to CSV", {
|
|
307
300
|
action: {
|
|
308
301
|
label: "Download Again",
|
|
309
|
-
onClick:
|
|
302
|
+
onClick: () => downloadFile("table_data.csv", blob, blob.type),
|
|
310
303
|
className: "font-medium"
|
|
311
304
|
}
|
|
312
305
|
});
|
|
@@ -320,12 +313,14 @@ const StreamingTableRendererCore = ({
|
|
|
320
313
|
try {
|
|
321
314
|
const markdownContent = content || "";
|
|
322
315
|
const fileName = headers && headers[0] ? `${headers[0].replace(/[^a-z0-9]/gi, "_").toLowerCase()}.md` : "table_data.md";
|
|
323
|
-
const
|
|
324
|
-
|
|
316
|
+
const blob = new Blob([markdownContent], {
|
|
317
|
+
type: "text/markdown;charset=utf-8"
|
|
318
|
+
});
|
|
319
|
+
downloadFile(fileName, blob, blob.type);
|
|
325
320
|
toast.success("Markdown file downloaded", {
|
|
326
321
|
action: {
|
|
327
322
|
label: "Download Again",
|
|
328
|
-
onClick:
|
|
323
|
+
onClick: () => downloadFile(fileName, blob, blob.type),
|
|
329
324
|
className: "font-medium"
|
|
330
325
|
}
|
|
331
326
|
});
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
reportDelimiterViolations
|
|
8
8
|
} from "@ai-matrx/kit/delimiter-guard";
|
|
9
9
|
import { captureError } from "../../host/diagnostics.js";
|
|
10
|
-
import {
|
|
10
|
+
import { CopyButtons } from "../../host/app-bindings.js";
|
|
11
11
|
import {
|
|
12
12
|
TableRenderPathDiagnostic
|
|
13
13
|
} from "../blocks/table/TableRenderPathDiagnostic.js";
|
|
@@ -102,12 +102,14 @@ const BasicMarkdownContentBody = ({
|
|
|
102
102
|
/* @__PURE__ */ jsx("style", { dangerouslySetInnerHTML: { __html: PROSE_FRAME_CSS } }),
|
|
103
103
|
/* @__PURE__ */ jsx(MarkdownCore, { preset: "chat", components, children: processedContent }),
|
|
104
104
|
!isStreamActive && isHovering && /* @__PURE__ */ jsx("div", { className: "absolute top-0 right-0 p-1 opacity-0 group-hover:opacity-100 transition-opacity duration-200", children: showCopyButton && /* @__PURE__ */ jsx(
|
|
105
|
-
|
|
105
|
+
CopyButtons,
|
|
106
106
|
{
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
107
|
+
label: "Content",
|
|
108
|
+
human: content,
|
|
109
|
+
contentFlavor: "markdown",
|
|
110
|
+
stripThinking: true,
|
|
111
|
+
size: "sm",
|
|
112
|
+
className: "absolute top-1 right-1 z-10 mt-1 mr-1"
|
|
111
113
|
}
|
|
112
114
|
) })
|
|
113
115
|
]
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
} from "@ai-matrx/kit/delimiter-guard";
|
|
13
13
|
import { captureError } from "../../host/diagnostics.js";
|
|
14
14
|
import { LinkComponent } from "../blocks/links/LinkComponent.js";
|
|
15
|
-
import {
|
|
15
|
+
import { CopyButtons } from "../../host/app-bindings.js";
|
|
16
16
|
import {
|
|
17
17
|
useMediaBlob,
|
|
18
18
|
useMediaLoadRecovery
|
|
@@ -614,12 +614,14 @@ const ConfigurableMarkdownContentBody = ({
|
|
|
614
614
|
/* @__PURE__ */ jsx(MarkdownCore, { preset: "rich", components, children: processedContent }),
|
|
615
615
|
!isStreamActive && isHovering && /* @__PURE__ */ jsxs("div", { className: "absolute top-0 right-0 p-1 opacity-0 group-hover:opacity-100 transition-opacity duration-200", children: [
|
|
616
616
|
showCopyButton && /* @__PURE__ */ jsx(
|
|
617
|
-
|
|
617
|
+
CopyButtons,
|
|
618
618
|
{
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
619
|
+
label: "Content",
|
|
620
|
+
human: content,
|
|
621
|
+
contentFlavor: "markdown",
|
|
622
|
+
stripThinking: true,
|
|
623
|
+
size: "sm",
|
|
624
|
+
className: "absolute top-1 right-1 z-10 mt-1 mr-1"
|
|
623
625
|
}
|
|
624
626
|
),
|
|
625
627
|
onEditRequest && /* @__PURE__ */ jsx(
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { downloadFile } from "@ai-matrx/kit/download";
|
|
4
3
|
import { useClipboard } from "@ai-matrx/kit/clipboard";
|
|
5
4
|
import { toast as copyToast } from "../../host/toast.js";
|
|
6
5
|
import { rewriteTableSource } from "../../utils/table-source.js";
|
|
@@ -61,6 +60,8 @@ import {
|
|
|
61
60
|
clearColumn,
|
|
62
61
|
duplicateColumn
|
|
63
62
|
} from "./editing/tableMutations.js";
|
|
63
|
+
import { downloadFile } from "@ai-matrx/kit/download";
|
|
64
|
+
import { tableToCsv } from "./table-csv.js";
|
|
64
65
|
const ExportDropdownMenu = ({
|
|
65
66
|
tableData,
|
|
66
67
|
content,
|
|
@@ -291,21 +292,13 @@ const MarkdownTable = ({
|
|
|
291
292
|
};
|
|
292
293
|
const downloadCSV = () => {
|
|
293
294
|
try {
|
|
294
|
-
const csvContent =
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
(row) => row.map((cell) => {
|
|
298
|
-
const escaped = cell.replace(/"/g, '""');
|
|
299
|
-
return cell.includes(",") ? `"${escaped}"` : escaped;
|
|
300
|
-
}).join(",")
|
|
301
|
-
)
|
|
302
|
-
].join("\n");
|
|
303
|
-
const saveCsv = () => downloadFile("table_data.csv", csvContent, "text/csv;charset=utf-8");
|
|
304
|
-
saveCsv();
|
|
295
|
+
const csvContent = tableToCsv(internalTableData.headers, internalTableData.rows);
|
|
296
|
+
const blob = new Blob([csvContent], { type: "text/csv;charset=utf-8;" });
|
|
297
|
+
downloadFile("table_data.csv", blob, blob.type);
|
|
305
298
|
toast.success("Table exported to CSV", {
|
|
306
299
|
action: {
|
|
307
300
|
label: "Download Again",
|
|
308
|
-
onClick:
|
|
301
|
+
onClick: () => downloadFile("table_data.csv", blob, blob.type),
|
|
309
302
|
className: "font-medium"
|
|
310
303
|
}
|
|
311
304
|
});
|
|
@@ -317,12 +310,14 @@ const MarkdownTable = ({
|
|
|
317
310
|
try {
|
|
318
311
|
const markdownContent = content || "";
|
|
319
312
|
const fileName = internalTableData.headers && internalTableData.headers[0] ? `${internalTableData.headers[0].replace(/[^a-z0-9]/gi, "_").toLowerCase()}.md` : "table_data.md";
|
|
320
|
-
const
|
|
321
|
-
|
|
313
|
+
const blob = new Blob([markdownContent], {
|
|
314
|
+
type: "text/markdown;charset=utf-8"
|
|
315
|
+
});
|
|
316
|
+
downloadFile(fileName, blob, blob.type);
|
|
322
317
|
toast.success("Markdown file downloaded", {
|
|
323
318
|
action: {
|
|
324
319
|
label: "Download Again",
|
|
325
|
-
onClick:
|
|
320
|
+
onClick: () => downloadFile(fileName, blob, blob.type),
|
|
326
321
|
className: "font-medium"
|
|
327
322
|
}
|
|
328
323
|
});
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { downloadFile } from "@ai-matrx/kit/download";
|
|
4
3
|
import { useClipboard } from "@ai-matrx/kit/clipboard";
|
|
5
4
|
import { toast as copyToast } from "../../host/toast.js";
|
|
6
5
|
import { rewriteTableSource } from "../../utils/table-source.js";
|
|
@@ -31,6 +30,8 @@ import {
|
|
|
31
30
|
import { useToastManager } from "../../utils/lifted/useToastManager.js";
|
|
32
31
|
import { THEMES } from "../themes.js";
|
|
33
32
|
import { useOpenSaveToTable } from "../../host/tables.js";
|
|
33
|
+
import { downloadFile } from "@ai-matrx/kit/download";
|
|
34
|
+
import { tableToCsv } from "./table-csv.js";
|
|
34
35
|
function useDebounce(value, delay) {
|
|
35
36
|
const [debouncedValue, setDebouncedValue] = useState(value);
|
|
36
37
|
useEffect(() => {
|
|
@@ -108,21 +109,13 @@ const TableControls = ({
|
|
|
108
109
|
}, [content, copyTableToClipboard, toast]);
|
|
109
110
|
const downloadCSV = useCallback(() => {
|
|
110
111
|
try {
|
|
111
|
-
const csvContent =
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
(row) => row.map((cell) => {
|
|
115
|
-
const escaped = cell.replace(/"/g, '""');
|
|
116
|
-
return cell.includes(",") ? `"${escaped}"` : escaped;
|
|
117
|
-
}).join(",")
|
|
118
|
-
)
|
|
119
|
-
].join("\n");
|
|
120
|
-
const saveCsv = () => downloadFile("table_data.csv", csvContent, "text/csv;charset=utf-8");
|
|
121
|
-
saveCsv();
|
|
112
|
+
const csvContent = tableToCsv(tableData.headers, tableData.rows);
|
|
113
|
+
const blob = new Blob([csvContent], { type: "text/csv;charset=utf-8;" });
|
|
114
|
+
downloadFile("table_data.csv", blob, blob.type);
|
|
122
115
|
toast.success("Table exported to CSV", {
|
|
123
116
|
action: {
|
|
124
117
|
label: "Download Again",
|
|
125
|
-
onClick:
|
|
118
|
+
onClick: () => downloadFile("table_data.csv", blob, blob.type),
|
|
126
119
|
className: "font-medium"
|
|
127
120
|
}
|
|
128
121
|
});
|
|
@@ -134,12 +127,14 @@ const TableControls = ({
|
|
|
134
127
|
try {
|
|
135
128
|
const markdownContent = content || "";
|
|
136
129
|
const fileName = tableData.headers && tableData.headers[0] ? `${tableData.headers[0].replace(/[^a-z0-9]/gi, "_").toLowerCase()}.md` : "table_data.md";
|
|
137
|
-
const
|
|
138
|
-
|
|
130
|
+
const blob = new Blob([markdownContent], {
|
|
131
|
+
type: "text/markdown;charset=utf-8"
|
|
132
|
+
});
|
|
133
|
+
downloadFile(fileName, blob, blob.type);
|
|
139
134
|
toast.success("Markdown file downloaded", {
|
|
140
135
|
action: {
|
|
141
136
|
label: "Download Again",
|
|
142
|
-
onClick:
|
|
137
|
+
onClick: () => downloadFile(fileName, blob, blob.type),
|
|
143
138
|
className: "font-medium"
|
|
144
139
|
}
|
|
145
140
|
});
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The CSV text of a markdown/streaming table, written by Alchemy's one writer. Quotes, commas and
|
|
3
|
+
* line breaks are quoted; text that opens with = + - @ is prefixed `'` so a spreadsheet never runs
|
|
4
|
+
* it (alchemy `spreadsheetSafe`, on). A cell that is a plain number is written as a number, so a
|
|
5
|
+
* negative amount stays `-5`.
|
|
6
|
+
*/
|
|
7
|
+
export declare function tableToCsv(headers: readonly string[], rows: readonly (readonly string[])[]): string;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { toDelimitedText } from "@ai-matrx/alchemy/operate/read";
|
|
2
|
+
const PLAIN_NUMBER = /^-?\d+(\.\d+)?$/;
|
|
3
|
+
function cellValue(cell) {
|
|
4
|
+
if (PLAIN_NUMBER.test(cell)) {
|
|
5
|
+
const n = Number(cell);
|
|
6
|
+
if (String(n) === cell) return n;
|
|
7
|
+
}
|
|
8
|
+
return cell;
|
|
9
|
+
}
|
|
10
|
+
function tableToCsv(headers, rows) {
|
|
11
|
+
return toDelimitedText(
|
|
12
|
+
headers,
|
|
13
|
+
rows.map((row) => row.map(cellValue)),
|
|
14
|
+
{ spreadsheetSafe: true }
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
export {
|
|
18
|
+
tableToCsv
|
|
19
|
+
};
|
|
@@ -47,6 +47,7 @@ export interface RichContentAppBindings {
|
|
|
47
47
|
MarkdownStream: HostComponent;
|
|
48
48
|
CitationMarkerInline: HostComponent;
|
|
49
49
|
InlineCopyButton: HostComponent;
|
|
50
|
+
CopyButtons: HostComponent;
|
|
50
51
|
AdvancedMenu: HostComponent;
|
|
51
52
|
useAdvancedMenu: HostFn;
|
|
52
53
|
EntityRef: HostComponent;
|
|
@@ -129,6 +130,7 @@ export declare const kindHasRecordChrome: HostFn;
|
|
|
129
130
|
export declare const KindFixItBar: HostComponent;
|
|
130
131
|
export declare const MarkdownStream: HostComponent;
|
|
131
132
|
export declare const CitationMarkerInline: HostComponent;
|
|
133
|
+
export declare const CopyButtons: HostComponent;
|
|
132
134
|
export declare const InlineCopyButton: HostComponent;
|
|
133
135
|
export declare const AdvancedMenu: HostComponent;
|
|
134
136
|
export declare const useAdvancedMenu: HostFn;
|
|
@@ -70,6 +70,7 @@ const kindHasRecordChrome = fn("kindHasRecordChrome", () => false, "kind records
|
|
|
70
70
|
const KindFixItBar = component("KindFixItBar", null, "no fix-it bar on broken kinds");
|
|
71
71
|
const MarkdownStream = component("MarkdownStream", null, "the full renderer is not registered");
|
|
72
72
|
const CitationMarkerInline = component("CitationMarkerInline", TextOnly, "citation markers show as text");
|
|
73
|
+
const CopyButtons = component("CopyButtons", null, "no copy menu on rendered content");
|
|
73
74
|
const InlineCopyButton = component("InlineCopyButton", null, "no inline copy button");
|
|
74
75
|
const AdvancedMenu = component("AdvancedMenu", null, "no block menus");
|
|
75
76
|
const useAdvancedMenu = fn("useAdvancedMenu", () => ({ isOpen: false, open: noop, close: noop, toggle: noop, menuProps: {} }), "no block menus");
|
|
@@ -105,6 +106,7 @@ export {
|
|
|
105
106
|
ArtifactRender,
|
|
106
107
|
CitationMarkerInline,
|
|
107
108
|
CodeBlockWithContextAttach,
|
|
109
|
+
CopyButtons,
|
|
108
110
|
EntityRef,
|
|
109
111
|
IconInputWithValidation,
|
|
110
112
|
InlineCopyButton,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-matrx/rich-content",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.10",
|
|
4
4
|
"description": "The AI Matrx formatted-text engine: the one markdown renderer, streaming markdown, the block splitter and renderer, the generic blocks, <RichContent> levels, the rich-document action registry and menus, copy, and the selection toolbar — as portable React.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -115,20 +115,20 @@
|
|
|
115
115
|
"unist-util-visit": "^5.1.0",
|
|
116
116
|
"unist-util-visit-parents": "^6.0.2",
|
|
117
117
|
"yaml": "^2.9.1",
|
|
118
|
-
"@ai-matrx/agents": "latest",
|
|
119
118
|
"@ai-matrx/alchemy": "latest",
|
|
120
|
-
"@ai-matrx/canvas": "latest",
|
|
121
|
-
"@ai-matrx/content-ir-react": "latest",
|
|
122
119
|
"@ai-matrx/content-ir": "latest",
|
|
120
|
+
"@ai-matrx/content-ir-react": "latest",
|
|
123
121
|
"@ai-matrx/data": "latest",
|
|
122
|
+
"@ai-matrx/agents": "latest",
|
|
124
123
|
"@ai-matrx/design-system": "latest",
|
|
125
|
-
"@ai-matrx/diff": "latest",
|
|
126
124
|
"@ai-matrx/icons": "latest",
|
|
125
|
+
"@ai-matrx/canvas": "latest",
|
|
126
|
+
"@ai-matrx/kit": "latest",
|
|
127
127
|
"@ai-matrx/print": "latest",
|
|
128
128
|
"@ai-matrx/records": "latest",
|
|
129
|
-
"@ai-matrx/tap-target": "latest",
|
|
130
129
|
"@ai-matrx/media": "latest",
|
|
131
|
-
"@ai-matrx/
|
|
130
|
+
"@ai-matrx/tap-target": "latest",
|
|
131
|
+
"@ai-matrx/diff": "latest"
|
|
132
132
|
},
|
|
133
133
|
"peerDependencies": {
|
|
134
134
|
"react": ">=19.0.0",
|