Skip to content

Commit 610fa9f

Browse files
authored
Merge pull request mac-s-g#145 from mac-s-g/copy-everything
enable copy for all elements - closes mac-s-g#141
2 parents aa5c877 + 6b81fc2 commit 610fa9f

File tree

11 files changed

+689
-683
lines changed

11 files changed

+689
-683
lines changed

demo/dist/main.js

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package-lock.json

Lines changed: 359 additions & 420 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "react-json-view",
33
"description": "Interactive react component for displaying javascript arrays and JSON objects.",
4-
"version": "1.15.1",
4+
"version": "1.15.2",
55
"main": "dist/main.js",
66
"files": [
77
"dist/"
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import React from 'react'
2+
3+
//clibboard icon
4+
import { Clippy } from "./icons"
5+
6+
//theme
7+
import Theme from "./../themes/getStyle"
8+
9+
export default class extends React.Component {
10+
constructor(props) {
11+
super(props);
12+
this.copiedTimer = null;
13+
}
14+
15+
state = {copied: false}
16+
17+
componentWillUnmount() {
18+
if (this.copiedTimer) {
19+
clearTimeout(this.copiedTimer);
20+
this.copiedTimer = null;
21+
}
22+
}
23+
24+
handleCopy = () => {
25+
const container = document.createElement("textarea")
26+
const { clickCallback, src, namespace } = this.props
27+
28+
container.innerHTML = JSON.stringify(src, null, " ")
29+
30+
document.body.appendChild(container)
31+
container.select()
32+
document.execCommand("copy")
33+
34+
document.body.removeChild(container)
35+
36+
this.copiedTimer = setTimeout(() => {
37+
this.setState({
38+
copied: false
39+
})
40+
}, 5500)
41+
42+
this.setState({ copied: true }, () => {
43+
if (typeof clickCallback !== "function") {
44+
return
45+
}
46+
47+
clickCallback({
48+
src: src,
49+
namespace: namespace,
50+
name: namespace[namespace.length - 1]
51+
})
52+
})
53+
}
54+
55+
getClippyIcon = () => {
56+
const { theme } = this.props
57+
58+
if (this.state.copied) {
59+
return (
60+
<span>
61+
<Clippy class="copy-icon" {...Theme(theme, "copy-icon")} />
62+
<span {...Theme(theme, "copy-icon-copied")}></span>
63+
</span>
64+
)
65+
}
66+
67+
return <Clippy class="copy-icon" {...Theme(theme, "copy-icon")} />
68+
}
69+
70+
render() {
71+
const { src, theme, hidden } = this.props
72+
let style = Theme(theme, "copy-to-clipboard").style
73+
let display = "inline"
74+
75+
if (hidden) {
76+
display = "none"
77+
}
78+
79+
return (
80+
<span class="copy-to-clipboard-container">
81+
<span
82+
style={{
83+
...style,
84+
display: display
85+
}}
86+
onClick={this.handleCopy}
87+
>
88+
{this.getClippyIcon()}
89+
</span>
90+
</span>
91+
)
92+
}
93+
}

src/js/components/VariableEditor.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { toType } from "./../helpers/util"
55
import dispatcher from "./../helpers/dispatcher"
66
import parseInput from "./../helpers/parseInput"
77
import stringifyVariable from "./../helpers/stringifyVariable"
8+
import CopyToClipboard from './CopyToClipboard'
89

910
//data type components
1011
import {
@@ -39,11 +40,13 @@ class VariableEditor extends React.Component {
3940
render() {
4041
const {
4142
variable,
43+
src,
4244
singleIndent,
4345
type,
4446
theme,
4547
namespace,
4648
indentWidth,
49+
enableClipboard,
4750
onEdit,
4851
onDelete,
4952
onSelect,
@@ -107,6 +110,14 @@ class VariableEditor extends React.Component {
107110
>
108111
{this.getValue(variable, this.props, editMode)}
109112
</div>
113+
{enableClipboard
114+
? (<CopyToClipboard
115+
hidden={editMode}
116+
src={variable.value}
117+
clickCallback={enableClipboard}
118+
{...{theme, namespace}} />)
119+
: null
120+
}
110121
{onEdit !== false && editMode == false
111122
? this.getEditIcon()
112123
: null}

src/js/components/VariableMeta.js

Lines changed: 16 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,96 +1,19 @@
11
import React from 'react';
22
import dispatcher from './../helpers/dispatcher';
33

4+
import CopyToClipboard from './CopyToClipboard'
45
import {toType} from './../helpers/util';
56

67
//icons
78
import {
8-
Clippy, RemoveCircle as Remove, AddCircle as Add
9+
RemoveCircle as Remove, AddCircle as Add
910
} from './icons';
1011

1112
//theme
1213
import Theme from './../themes/getStyle';
1314

1415

1516
export default class extends React.Component {
16-
constructor(props) {
17-
super(props);
18-
19-
this.state = { copied: false };
20-
21-
this.copiedTimer = null;
22-
}
23-
24-
componentWillUnmount() {
25-
if (this.copiedTimer) {
26-
clearTimeout(this.copiedTimer);
27-
this.copiedTimer = null;
28-
}
29-
}
30-
31-
handleCopy = () => {
32-
const container = document.createElement('textarea');
33-
const {enableClipboard, src, namespace} = this.props;
34-
35-
container.innerHTML = JSON.stringify(src, null, ' ');
36-
37-
document.body.appendChild(container);
38-
container.select();
39-
document.execCommand('copy');
40-
41-
document.body.removeChild(container);
42-
43-
this.copiedTimer = setTimeout(() => {
44-
this.setState({
45-
copied: false
46-
});
47-
}, 5500)
48-
49-
this.setState({ copied: true }, () => {
50-
if (typeof enableClipboard !== "function") {
51-
return;
52-
}
53-
54-
enableClipboard({
55-
src:src,
56-
namespace: namespace,
57-
name: namespace[namespace.length - 1]
58-
});
59-
})
60-
}
61-
62-
getCopyComponent = () => {
63-
const {src, size, theme, enableClipboard} = this.props;
64-
let style = Theme(theme, 'copy-to-clipboard').style;
65-
66-
return (
67-
enableClipboard ?
68-
<span class="copy-to-clipboard-container" >
69-
<span
70-
style={{
71-
...style,
72-
display: 'inline-block'
73-
}}
74-
onClick={this.handleCopy}
75-
>{this.getClippyIcon()}</span>
76-
</span>
77-
: null
78-
);
79-
}
80-
81-
getClippyIcon = () => {
82-
const {theme} = this.props;
83-
84-
if (this.state.copied) {
85-
return (<span>
86-
<Clippy class="copy-icon" {...Theme(theme, 'copy-icon')} />
87-
<span {...Theme(theme, 'copy-icon-copied')}></span>
88-
</span>)
89-
}
90-
91-
return <Clippy class="copy-icon" {...Theme(theme, 'copy-icon')} />
92-
}
93-
9417
getObjectSize = () => {
9518
const {size, theme, displayObjectSize} = this.props;
9619
if (displayObjectSize) {
@@ -178,7 +101,14 @@ export default class extends React.Component {
178101
}
179102

180103
render = () => {
181-
const {theme, onDelete, onAdd} = this.props;
104+
const {
105+
theme,
106+
onDelete,
107+
onAdd,
108+
enableClipboard,
109+
src,
110+
namespace
111+
} = this.props;
182112
return (
183113
<div {...Theme(theme, 'object-meta-data')}
184114
class='object-meta-data'
@@ -188,7 +118,12 @@ export default class extends React.Component {
188118
{/* size badge display */}
189119
{this.getObjectSize()}
190120
{/* copy to clipboard icon */}
191-
{this.getCopyComponent()}
121+
{enableClipboard
122+
? (<CopyToClipboard
123+
clickCallback={enableClipboard}
124+
{...{src, theme, namespace}} />)
125+
: null
126+
}
192127
{/* copy add/remove icons */}
193128
{onAdd !== false ? this.getAddAttribute() : null}
194129
{onDelete !== false ? this.getRemoveObject() : null}

0 commit comments

Comments
 (0)