Skip to content

Commit 7d8c0aa

Browse files
emyarodjoshblack
authored andcommitted
refactor(CopyButton): inherit Copy component (#5006)
* refactor(CopyButton): inherit Copy component * refactor(code-snippet): unnest rules * test(CopyButton): full mount for button props test * docs(CodeSnippet): change default story feedback text
1 parent 0a5f18f commit 7d8c0aa

File tree

4 files changed

+33
-79
lines changed

4 files changed

+33
-79
lines changed

packages/components/src/components/code-snippet/_code-snippet.scss

+15-14
Original file line numberDiff line numberDiff line change
@@ -66,23 +66,24 @@
6666
display: none;
6767
}
6868
@include tooltip--placement('icon', 'bottom', 'center');
69+
}
6970

70-
&.#{$prefix}--copy-btn--animating::before,
71-
&.#{$prefix}--copy-btn--animating .#{$prefix}--copy-btn__feedback {
72-
display: block;
73-
}
71+
.#{$prefix}--snippet--inline.#{$prefix}--copy-btn--animating::before,
72+
.#{$prefix}--snippet--inline.#{$prefix}--copy-btn--animating
73+
.#{$prefix}--copy-btn__feedback {
74+
display: block;
75+
}
7476

75-
&.#{$prefix}--copy-btn--animating.#{$prefix}--copy-btn--fade-out::before,
76-
&.#{$prefix}--copy-btn--animating.#{$prefix}--copy-btn--fade-out
77-
.#{$prefix}--copy-btn__feedback {
78-
animation: $duration--fast-02 motion(standard, productive) hide-feedback;
79-
}
77+
.#{$prefix}--snippet--inline.#{$prefix}--copy-btn--animating.#{$prefix}--copy-btn--fade-out::before,
78+
.#{$prefix}--snippet--inline.#{$prefix}--copy-btn--animating.#{$prefix}--copy-btn--fade-out
79+
.#{$prefix}--copy-btn__feedback {
80+
animation: $duration--fast-02 motion(standard, productive) hide-feedback;
81+
}
8082

81-
&.#{$prefix}--copy-btn--animating.#{$prefix}--copy-btn--fade-in::before,
82-
&.#{$prefix}--copy-btn--animating.#{$prefix}--copy-btn--fade-in
83-
.#{$prefix}--copy-btn__feedback {
84-
animation: $duration--fast-02 motion(standard, productive) show-feedback;
85-
}
83+
.#{$prefix}--snippet--inline.#{$prefix}--copy-btn--animating.#{$prefix}--copy-btn--fade-in::before,
84+
.#{$prefix}--snippet--inline.#{$prefix}--copy-btn--animating.#{$prefix}--copy-btn--fade-in
85+
.#{$prefix}--copy-btn__feedback {
86+
animation: $duration--fast-02 motion(standard, productive) show-feedback;
8687
}
8788

8889
.#{$prefix}--snippet--inline code {

packages/react/src/components/CodeSnippet/CodeSnippet-story.js

+6-6
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import CodeSnippetSkeleton from './CodeSnippet.Skeleton';
1515
const props = {
1616
inline: () => ({
1717
light: boolean('Light variant (light)', false),
18-
feedback: text('Feedback text (feedback)', 'Feedback Enabled 👍'),
18+
feedback: text('Feedback text (feedback)', 'Copied to clipboard'),
1919
onClick: action('onClick'),
2020
copyLabel: text(
2121
'ARIA label for the snippet/copy button (copyLabel)',
@@ -24,7 +24,7 @@ const props = {
2424
}),
2525
single: () => ({
2626
light: boolean('Light variant (light)', false),
27-
feedback: text('Feedback text (feedback)', 'Feedback Enabled 👍'),
27+
feedback: text('Feedback text (feedback)', 'Copied to clipboard'),
2828
copyButtonDescription: text(
2929
'Copy icon description (copyButtonDescription)',
3030
'copyable code snippet'
@@ -37,7 +37,7 @@ const props = {
3737
}),
3838
multiline: () => ({
3939
light: boolean('Light variant (light)', false),
40-
feedback: text('Feedback text (feedback)', 'Feedback Enabled 👍'),
40+
feedback: text('Feedback text (feedback)', 'Copied to clipboard'),
4141
showMoreText: text(
4242
'Text for "show more" button (showMoreText)',
4343
'Show more'
@@ -86,7 +86,7 @@ storiesOf('CodeSnippet', module)
8686
info: {
8787
text: `
8888
Code snippets are small blocks of reusable code that can be inserted in a code file.
89-
89+
9090
The Inline style is for code used within a block of text.
9191
`,
9292
},
@@ -108,7 +108,7 @@ storiesOf('CodeSnippet', module)
108108
info: {
109109
text: `
110110
Code snippets are small blocks of reusable code that can be inserted in a code file.
111-
111+
112112
The Code style is for larger, multi-line code snippets.
113113
`,
114114
},
@@ -165,7 +165,7 @@ $z-indexes: (
165165
info: {
166166
text: `
167167
Code snippets are small blocks of reusable code that can be inserted in a code file.
168-
168+
169169
The Terminal style is for single-line .
170170
`,
171171
},

packages/react/src/components/CopyButton/CopyButton-test.js

+6-3
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,14 @@ describe('CopyButton', () => {
3131
});
3232

3333
describe('Renders button props as expected', () => {
34-
const wrapper = shallow(<CopyButton />);
34+
let wrapper;
35+
36+
beforeEach(() => {
37+
wrapper = mount(<CopyButton />);
38+
});
3539

3640
it('Renders children as expected', () => {
37-
expect(wrapper.is('button')).toBe(true);
38-
expect(wrapper.hasClass(`${prefix}--copy-btn`)).toBe(true);
41+
expect(wrapper.find('button').hasClass(`${prefix}--copy-btn`)).toBe(true);
3942
expect(wrapper.find(`.${prefix}--copy-btn__feedback`).length).toBe(1);
4043
expect(wrapper.find(Copy16).length).toBe(1);
4144
});

packages/react/src/components/CopyButton/CopyButton.js

+6-56
Original file line numberDiff line numberDiff line change
@@ -6,73 +6,23 @@
66
*/
77

88
import PropTypes from 'prop-types';
9-
import React, { useState, useEffect, useCallback } from 'react';
9+
import React from 'react';
1010
import classnames from 'classnames';
11-
import debounce from 'lodash.debounce';
1211
import { settings } from 'carbon-components';
1312
import { Copy16 } from '@carbon/icons-react';
13+
import Copy from '../Copy';
1414

1515
const { prefix } = settings;
1616

17-
export default function CopyButton({
18-
iconDescription,
19-
className,
20-
feedback,
21-
feedbackTimeout,
22-
onAnimationEnd,
23-
onClick,
24-
...other
25-
}) {
26-
const [animation, setAnimation] = useState('');
27-
const classNames = classnames(`${prefix}--copy-btn`, className, {
28-
[`${prefix}--copy-btn--animating`]: animation,
29-
[`${prefix}--copy-btn--${animation}`]: animation,
30-
});
31-
const handleFadeOut = useCallback(
32-
debounce(() => {
33-
setAnimation('fade-out');
34-
}, feedbackTimeout),
35-
[feedbackTimeout]
36-
);
37-
const handleClick = useCallback(
38-
event => {
39-
setAnimation('fade-in');
40-
onClick(event);
41-
handleFadeOut();
42-
},
43-
[onClick, handleFadeOut]
44-
);
45-
const handleAnimationEnd = event => {
46-
if (event.animationName === 'hide-feedback') {
47-
setAnimation('');
48-
}
49-
if (onAnimationEnd) {
50-
onAnimationEnd(event);
51-
}
52-
};
53-
54-
useEffect(
55-
() => () => {
56-
handleFadeOut.cancel();
57-
},
58-
[handleFadeOut]
59-
);
60-
17+
export default function CopyButton({ iconDescription, className, ...other }) {
6118
return (
62-
<button
63-
type="button"
64-
className={classNames}
65-
onClick={handleClick}
19+
<Copy
20+
className={classnames(className, `${prefix}--copy-btn`)}
6621
aria-label={iconDescription}
6722
title={iconDescription}
68-
onAnimationEnd={handleAnimationEnd}
6923
{...other}>
70-
<span
71-
className={`${prefix}--assistive-text ${prefix}--copy-btn__feedback`}>
72-
{feedback}
73-
</span>
7424
<Copy16 className={`${prefix}--snippet__icon`} />
75-
</button>
25+
</Copy>
7626
);
7727
}
7828

0 commit comments

Comments
 (0)