From 26bf6abbbdd9942189a451253fb7ea8f78fb46e5 Mon Sep 17 00:00:00 2001 From: Lex Date: Tue, 3 Oct 2023 20:16:28 +1000 Subject: [PATCH] Clipboard support for text/html MIME type --- .../src/components/Clipboard.react.js | 32 ++++++++++++++++--- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/components/dash-core-components/src/components/Clipboard.react.js b/components/dash-core-components/src/components/Clipboard.react.js index 22002b83a6..26b5ec729f 100644 --- a/components/dash-core-components/src/components/Clipboard.react.js +++ b/components/dash-core-components/src/components/Clipboard.react.js @@ -47,9 +47,23 @@ export default class Clipboard extends React.Component { return '{' + parts.join(',') + '}'; } - async copySuccess(content) { + async copySuccess(content, htmlContent) { const showCopiedIcon = 1000; - await clipboardAPI.writeText(content); + if (htmlContent) { + const blobHtml = new Blob([htmlContent], {type: 'text/html'}); + const blobText = new Blob([content ?? htmlContent], { + type: 'text/plain', + }); + const data = [ + new ClipboardItem({ + ['text/plain']: blobText, + ['text/html']: blobHtml, + }), + ]; + await navigator.clipboard.write(data); + } else { + await clipboardAPI.writeText(content); + } this.setState({copied: true}); await wait(showCopiedIcon); this.setState({copied: false}); @@ -85,15 +99,17 @@ export default class Clipboard extends React.Component { }); let content; + let htmlContent; if (this.props.target_id) { content = this.getTargetText(); } else { await wait(100); // gives time for callback to start await this.loading(); content = this.props.content; + htmlContent = this.props.html_content; } - if (content) { - this.copySuccess(content); + if (content || htmlContent) { + this.copySuccess(content, htmlContent); } } @@ -128,6 +144,7 @@ export default class Clipboard extends React.Component { Clipboard.defaultProps = { content: null, + html_content: null, target_id: null, n_clicks: 0, }; @@ -146,7 +163,7 @@ Clipboard.propTypes = { target_id: PropTypes.oneOfType([PropTypes.string, PropTypes.object]), /** - * The text to be copied to the clipboard if the `target_id` is None. + * The text to be copied to the clipboard if the `target_id` is None. */ content: PropTypes.string, @@ -155,6 +172,11 @@ Clipboard.propTypes = { */ n_clicks: PropTypes.number, + /** + * The clipboard html text be copied to the clipboard if the `target_id` is None. + */ + html_content: PropTypes.string, + /** * The text shown as a tooltip when hovering over the copy icon. */