Skip to content

Commit 5d438ca

Browse files
authored
feat: support copying table data as Markdown in TableCopyDropdown (#396)
* Add support for copying table data as Markdown in TableCopyDropdown * Refactor content generation in TableCopyDropdown to use formatters for cleaner code * docs: add changeset
1 parent 13fc824 commit 5d438ca

File tree

2 files changed

+26
-6
lines changed

2 files changed

+26
-6
lines changed

.changeset/five-points-brake.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"streamdown": minor
3+
---
4+
5+
Add support for copying table data as Markdown in TableCopyDropdown.
6+
Introduces a Markdown copy option alongside existing formats.
7+
Allows users to quickly copy tables in valid Markdown format.

packages/streamdown/lib/table/copy-dropdown.tsx

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@ import { cn } from "../utils";
55
import {
66
extractTableDataFromElement,
77
tableDataToCSV,
8+
tableDataToMarkdown,
89
tableDataToTSV,
910
} from "./utils";
1011

1112
export interface TableCopyDropdownProps {
1213
children?: React.ReactNode;
1314
className?: string;
14-
onCopy?: (format: "csv" | "tsv") => void;
15+
onCopy?: (format: "csv" | "tsv" | "md") => void;
1516
onError?: (error: Error) => void;
1617
timeout?: number;
1718
}
@@ -29,7 +30,7 @@ export const TableCopyDropdown = ({
2930
const timeoutRef = useRef(0);
3031
const { isAnimating } = useContext(StreamdownContext);
3132

32-
const copyTableData = async (format: "csv" | "tsv") => {
33+
const copyTableData = async (format: "csv" | "tsv" | "md") => {
3334
if (typeof window === "undefined" || !navigator?.clipboard?.write) {
3435
onError?.(new Error("Clipboard API not available"));
3536
return;
@@ -49,10 +50,14 @@ export const TableCopyDropdown = ({
4950
}
5051

5152
const tableData = extractTableDataFromElement(tableElement);
52-
const content =
53-
format === "csv"
54-
? tableDataToCSV(tableData)
55-
: tableDataToTSV(tableData);
53+
54+
const formatters = {
55+
csv: tableDataToCSV,
56+
tsv: tableDataToTSV,
57+
md: tableDataToMarkdown,
58+
};
59+
const formatter = formatters[format] || tableDataToMarkdown;
60+
const content = formatter(tableData)
5661

5762
const clipboardItemData = new ClipboardItem({
5863
"text/plain": new Blob([content], { type: "text/plain" }),
@@ -104,6 +109,14 @@ export const TableCopyDropdown = ({
104109
</button>
105110
{isOpen ? (
106111
<div className="absolute top-full right-0 z-10 mt-1 min-w-[120px] overflow-hidden rounded-md border border-border bg-background shadow-lg">
112+
<button
113+
className="w-full px-3 py-2 text-left text-sm transition-colors hover:bg-muted/40"
114+
onClick={() => copyTableData("md")}
115+
title="Copy table as Markdown"
116+
type="button"
117+
>
118+
Markdown
119+
</button>
107120
<button
108121
className="w-full px-3 py-2 text-left text-sm transition-colors hover:bg-muted/40"
109122
onClick={() => copyTableData("csv")}

0 commit comments

Comments
 (0)