@@ -17,6 +17,7 @@ export default class Clipboard extends React.Component {
17
17
constructor ( props ) {
18
18
super ( props ) ;
19
19
this . copyToClipboard = this . copyToClipboard . bind ( this ) ;
20
+ this . onClickHandler = this . onClickHandler . bind ( this ) ;
20
21
this . copySuccess = this . copySuccess . bind ( this ) ;
21
22
this . getTargetText = this . getTargetText . bind ( this ) ;
22
23
this . loading = this . loading . bind ( this ) ;
@@ -26,6 +27,22 @@ export default class Clipboard extends React.Component {
26
27
} ;
27
28
}
28
29
30
+ onClickHandler ( ) {
31
+ this . props . setProps ( { n_clicks : this . props . n_clicks + 1 } ) ;
32
+ }
33
+
34
+ componentDidUpdate ( prevProps ) {
35
+ // If the clicks has not changed, do nothing
36
+ if (
37
+ ! this . props . n_clicks ||
38
+ this . props . n_clicks === prevProps . n_clicks
39
+ ) {
40
+ return ;
41
+ }
42
+ // If the clicks has changed, copy to clipboard
43
+ this . copyToClipboard ( ) ;
44
+ }
45
+
29
46
// stringifies object ids used in pattern matching callbacks
30
47
stringifyId ( id ) {
31
48
if ( typeof id !== 'object' ) {
@@ -38,9 +55,23 @@ export default class Clipboard extends React.Component {
38
55
return '{' + parts . join ( ',' ) + '}' ;
39
56
}
40
57
41
- async copySuccess ( content ) {
58
+ async copySuccess ( content , htmlContent ) {
42
59
const showCopiedIcon = 1000 ;
43
- await clipboardAPI . writeText ( content ) ;
60
+ if ( htmlContent ) {
61
+ const blobHtml = new Blob ( [ htmlContent ] , { type : 'text/html' } ) ;
62
+ const blobText = new Blob ( [ content ?? htmlContent ] , {
63
+ type : 'text/plain' ,
64
+ } ) ;
65
+ const data = [
66
+ new ClipboardItem ( {
67
+ [ 'text/plain' ] : blobText ,
68
+ [ 'text/html' ] : blobHtml ,
69
+ } ) ,
70
+ ] ;
71
+ await navigator . clipboard . write ( data ) ;
72
+ } else {
73
+ await clipboardAPI . writeText ( content ) ;
74
+ }
44
75
this . setState ( { copied : true } ) ;
45
76
await wait ( showCopiedIcon ) ;
46
77
this . setState ( { copied : false } ) ;
@@ -71,20 +102,18 @@ export default class Clipboard extends React.Component {
71
102
}
72
103
73
104
async copyToClipboard ( ) {
74
- this . props . setProps ( {
75
- n_clicks : this . props . n_clicks + 1 ,
76
- } ) ;
77
-
78
105
let content ;
106
+ let htmlContent ;
79
107
if ( this . props . target_id ) {
80
108
content = this . getTargetText ( ) ;
81
109
} else {
82
110
await wait ( 100 ) ; // gives time for callback to start
83
111
await this . loading ( ) ;
84
112
content = this . props . content ;
113
+ htmlContent = this . props . html_content ;
85
114
}
86
- if ( content ) {
87
- this . copySuccess ( content ) ;
115
+ if ( content || htmlContent ) {
116
+ this . copySuccess ( content , htmlContent ) ;
88
117
}
89
118
}
90
119
@@ -106,7 +135,7 @@ export default class Clipboard extends React.Component {
106
135
title = { title }
107
136
style = { style }
108
137
className = { className }
109
- onClick = { this . copyToClipboard }
138
+ onClick = { this . onClickHandler }
110
139
data-dash-is-loading = {
111
140
( loading_state && loading_state . is_loading ) || undefined
112
141
}
@@ -119,6 +148,7 @@ export default class Clipboard extends React.Component {
119
148
120
149
Clipboard . defaultProps = {
121
150
content : null ,
151
+ html_content : null ,
122
152
target_id : null ,
123
153
n_clicks : 0 ,
124
154
} ;
@@ -137,7 +167,7 @@ Clipboard.propTypes = {
137
167
target_id : PropTypes . oneOfType ( [ PropTypes . string , PropTypes . object ] ) ,
138
168
139
169
/**
140
- * The text to be copied to the clipboard if the `target_id` is None.
170
+ * The text to be copied to the clipboard if the `target_id` is None.
141
171
*/
142
172
content : PropTypes . string ,
143
173
@@ -146,6 +176,11 @@ Clipboard.propTypes = {
146
176
*/
147
177
n_clicks : PropTypes . number ,
148
178
179
+ /**
180
+ * The clipboard html text be copied to the clipboard if the `target_id` is None.
181
+ */
182
+ html_content : PropTypes . string ,
183
+
149
184
/**
150
185
* The text shown as a tooltip when hovering over the copy icon.
151
186
*/
0 commit comments