Skip to content

Commit 5fbbc67

Browse files
committed
Feat: Copy pathline to clipboard button
Most of the code from #485 by @SaraVieira, close #471.
1 parent a4eed71 commit 5fbbc67

File tree

8 files changed

+84
-33
lines changed

8 files changed

+84
-33
lines changed

package-lock.json

+5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
"chalk": "^1.1.3",
3636
"classnames": "^2.2.5",
3737
"clean-webpack-plugin": "^0.1.16",
38+
"clipboard-copy": "^1.2.0",
3839
"codemirror": "^5.26.0",
3940
"common-dir": "^1.0.1",
4041
"css-loader": "^0.28.4",
+16-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,21 @@
11
import React from 'react';
2-
import { PathlineRenderer } from './PathlineRenderer';
2+
import copy from 'clipboard-copy';
3+
import { PathlineRenderer, styles } from './PathlineRenderer';
34

4-
it('renderer should a path line', () => {
5-
const pathline = 'foo/bar';
6-
const actual = shallow(<PathlineRenderer classes={{}}>{pathline}</PathlineRenderer>);
5+
jest.mock('clipboard-copy');
6+
7+
const pathline = 'foo/bar';
8+
const props = {
9+
classes: classes(styles),
10+
};
711

12+
it('renderer should a path line', () => {
13+
const actual = shallow(<PathlineRenderer {...props}>{pathline}</PathlineRenderer>);
814
expect(actual).toMatchSnapshot();
915
});
16+
17+
test('should copy text on click', () => {
18+
const actual = mount(<PathlineRenderer {...props}>{pathline}</PathlineRenderer>);
19+
actual.find('button').simulate('click');
20+
expect(copy).toBeCalledWith(pathline);
21+
});
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,40 @@
11
import React from 'react';
22
import PropTypes from 'prop-types';
3+
import copy from 'clipboard-copy';
4+
import MdContentCopy from 'react-icons/lib/md/content-copy';
5+
import ToolbarButton from 'rsg-components/ToolbarButton';
36
import Styled from 'rsg-components/Styled';
47

5-
const styles = ({ fontFamily, fontSize, color }) => ({
8+
export const styles = ({ space, fontFamily, fontSize, color }) => ({
69
pathline: {
710
fontFamily: fontFamily.monospace,
811
fontSize: fontSize.small,
912
color: color.light,
1013
},
14+
copyButton: {
15+
marginLeft: space[0],
16+
},
1117
});
1218

1319
export function PathlineRenderer({ classes, children }) {
14-
return <div className={classes.pathline}>{children}</div>;
20+
return (
21+
<div className={classes.pathline}>
22+
{children}
23+
<ToolbarButton
24+
small
25+
className={classes.copyButton}
26+
onClick={() => copy(children)}
27+
title="Copy to clipboard"
28+
>
29+
<MdContentCopy />
30+
</ToolbarButton>
31+
</div>
32+
);
1533
}
1634

1735
PathlineRenderer.propTypes = {
1836
classes: PropTypes.object.isRequired,
19-
children: PropTypes.node,
37+
children: PropTypes.string,
2038
};
2139

2240
export default Styled(styles)(PathlineRenderer);
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,17 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

33
exports[`renderer should a path line 1`] = `
4-
<div>
4+
<div
5+
className="pathline"
6+
>
57
foo/bar
8+
<Styled(ToolbarButton)
9+
className="copyButton"
10+
onClick={[Function]}
11+
small={true}
12+
title="Copy to clipboard"
13+
>
14+
<MdContentCopy />
15+
</Styled(ToolbarButton)>
616
</div>
717
`;

src/rsg-components/ToolbarButton/ToolbarButton.spec.js

+10-2
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ it('should pass a class name to a button', () => {
2929
</ToolbarButtonRenderer>
3030
);
3131

32-
expect(actual).toMatchSnapshot();
32+
expect(actual.prop('className')).toBe('button foo-class');
3333
});
3434

3535
it('should pass a class name to a link', () => {
@@ -39,5 +39,13 @@ it('should pass a class name to a link', () => {
3939
</ToolbarButtonRenderer>
4040
);
4141

42-
expect(actual).toMatchSnapshot();
42+
expect(actual.prop('className')).toBe('button foo-class');
43+
});
44+
45+
it('should render a button with small styles', () => {
46+
const actual = shallow(
47+
<ToolbarButtonRenderer {...props} onClick={() => {}} small>butterbrot</ToolbarButtonRenderer>
48+
);
49+
50+
expect(actual.prop('className')).toBe('button isSmall');
4351
});

src/rsg-components/ToolbarButton/ToolbarButtonRenderer.js

+20-2
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,29 @@ export const styles = ({ space, color }) => ({
2828
width: space[3],
2929
height: space[3],
3030
color: 'currentColor',
31+
cursor: 'inherit',
32+
},
33+
},
34+
isSmall: {
35+
'& svg': {
36+
width: 14,
37+
height: 14,
3138
},
3239
},
3340
});
3441

35-
export function ToolbarButtonRenderer({ classes, className, onClick, href, title, children }) {
36-
const classNames = cx(classes.button, className);
42+
export function ToolbarButtonRenderer({
43+
classes,
44+
className,
45+
onClick,
46+
href,
47+
title,
48+
small,
49+
children,
50+
}) {
51+
const classNames = cx(classes.button, className, {
52+
[classes.isSmall]: small,
53+
});
3754

3855
if (href !== undefined) {
3956
return (
@@ -56,6 +73,7 @@ ToolbarButtonRenderer.propTypes = {
5673
href: PropTypes.string,
5774
onClick: PropTypes.func,
5875
title: PropTypes.string,
76+
small: PropTypes.bool,
5977
children: PropTypes.node,
6078
};
6179

src/rsg-components/ToolbarButton/__snapshots__/ToolbarButton.spec.js.snap

-21
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,5 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3-
exports[`should pass a class name to a button 1`] = `
4-
<button
5-
className="button foo-class"
6-
onClick={[Function]}
7-
title="Pizza button"
8-
type="button"
9-
>
10-
pizza
11-
</button>
12-
`;
13-
14-
exports[`should pass a class name to a link 1`] = `
15-
<a
16-
className="button foo-class"
17-
href="/foo"
18-
title="Pizza button"
19-
>
20-
pizza
21-
</a>
22-
`;
23-
243
exports[`should render a button 1`] = `
254
<button
265
className="button"

0 commit comments

Comments
 (0)