diff --git a/.changeset/kind-deer-create.md b/.changeset/kind-deer-create.md new file mode 100644 index 000000000000..d5dcc03d738c --- /dev/null +++ b/.changeset/kind-deer-create.md @@ -0,0 +1,6 @@ +--- +"@gradio/markdown": minor +"gradio": minor +--- + +feat:Add copy button to `gr.Markdown` diff --git a/gradio/components/markdown.py b/gradio/components/markdown.py index 8abcf5e58070..265d65d68bd1 100644 --- a/gradio/components/markdown.py +++ b/gradio/components/markdown.py @@ -45,6 +45,7 @@ def __init__( line_breaks: bool = False, header_links: bool = False, height: int | str | None = None, + show_copy_button: bool = False, ): """ Parameters: @@ -64,6 +65,7 @@ def __init__( line_breaks: If True, will enable Github-flavored Markdown line breaks in chatbot messages. If False (default), single new lines will be ignored. header_links: If True, will automatically create anchors for headings, displaying a link icon on hover. height: An optional maximum height of this component, specified in pixels if a number is passed, or in CSS units (e.g., '200px') if a stirng is passed in. If context exceeds this height, a scrollbar is added. + show_copy_button: If True, includes a copy button to copy the text in the Markdown component. Default is False. """ self.rtl = rtl if latex_delimiters is None: @@ -73,6 +75,7 @@ def __init__( self.line_breaks = line_breaks self.header_links = header_links self.height = height + self.show_copy_button = show_copy_button super().__init__( label=label, diff --git a/js/markdown/Index.svelte b/js/markdown/Index.svelte index 036557bad76a..c3a0ea2dbb5a 100644 --- a/js/markdown/Index.svelte +++ b/js/markdown/Index.svelte @@ -32,6 +32,7 @@ }[]; export let header_links = false; export let height: number | string | undefined = undefined; + export let show_copy_button = false; $: label, gradio.dispatch("change"); @@ -63,6 +64,7 @@ {line_breaks} {header_links} {height} + {show_copy_button} /> diff --git a/js/markdown/Markdown.stories.svelte b/js/markdown/Markdown.stories.svelte index 5fa82a4c1734..3684bdaf4601 100644 --- a/js/markdown/Markdown.stories.svelte +++ b/js/markdown/Markdown.stories.svelte @@ -84,3 +84,12 @@ in two separate lines.` height: "200px" }} /> + + diff --git a/js/markdown/package.json b/js/markdown/package.json index d88fc293b9cb..95cd1f837992 100644 --- a/js/markdown/package.json +++ b/js/markdown/package.json @@ -15,6 +15,7 @@ }, "dependencies": { "@gradio/atoms": "workspace:^", + "@gradio/icons": "workspace:^", "@gradio/statustracker": "workspace:^", "@gradio/utils": "workspace:^", "@types/dompurify": "^3.0.2", diff --git a/js/markdown/shared/Markdown.svelte b/js/markdown/shared/Markdown.svelte index 4f9f9f5646f9..8f58ab904b05 100644 --- a/js/markdown/shared/Markdown.svelte +++ b/js/markdown/shared/Markdown.svelte @@ -1,8 +1,10 @@
+ {#if show_copy_button} + {#if copied} + + {:else} + + {/if} + {/if} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e1a64b398020..7b69d1bec7e2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1434,6 +1434,9 @@ importers: '@gradio/atoms': specifier: workspace:^ version: link:../atoms + '@gradio/icons': + specifier: workspace:^ + version: link:../icons '@gradio/statustracker': specifier: workspace:^ version: link:../statustracker diff --git a/test/components/test_markdown.py b/test/components/test_markdown.py index 2ffe05b4345e..d88afad67590 100644 --- a/test/components/test_markdown.py +++ b/test/components/test_markdown.py @@ -5,6 +5,7 @@ class TestMarkdown: def test_component_functions(self): markdown_component = gr.Markdown("# Let's learn about $x$", label="Markdown") assert markdown_component.get_config()["value"] == "# Let's learn about $x$" + assert not markdown_component.get_config()["show_copy_button"] def test_in_interface(self): """ @@ -14,3 +15,9 @@ def test_in_interface(self): input_data = " Here's an [image](https://gradio.app/images/gradio_logo.png)" output_data = iface(input_data) assert output_data == input_data.strip() + + def test_show_copy_button(self): + markdown_component = gr.Markdown( + "# Let's learn about $x$", show_copy_button=True + ) + assert markdown_component.get_config()["show_copy_button"]