Skip to content

Commit

Permalink
refactor(CopyButton): inherit Copy component (#5006)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
emyarod authored and joshblack committed Jan 23, 2020
1 parent 0a5f18f commit 7d8c0aa
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 79 deletions.
29 changes: 15 additions & 14 deletions packages/components/src/components/code-snippet/_code-snippet.scss
Original file line number Diff line number Diff line change
Expand Up @@ -66,23 +66,24 @@
display: none;
}
@include tooltip--placement('icon', 'bottom', 'center');
}

&.#{$prefix}--copy-btn--animating::before,
&.#{$prefix}--copy-btn--animating .#{$prefix}--copy-btn__feedback {
display: block;
}
.#{$prefix}--snippet--inline.#{$prefix}--copy-btn--animating::before,
.#{$prefix}--snippet--inline.#{$prefix}--copy-btn--animating
.#{$prefix}--copy-btn__feedback {
display: block;
}

&.#{$prefix}--copy-btn--animating.#{$prefix}--copy-btn--fade-out::before,
&.#{$prefix}--copy-btn--animating.#{$prefix}--copy-btn--fade-out
.#{$prefix}--copy-btn__feedback {
animation: $duration--fast-02 motion(standard, productive) hide-feedback;
}
.#{$prefix}--snippet--inline.#{$prefix}--copy-btn--animating.#{$prefix}--copy-btn--fade-out::before,
.#{$prefix}--snippet--inline.#{$prefix}--copy-btn--animating.#{$prefix}--copy-btn--fade-out
.#{$prefix}--copy-btn__feedback {
animation: $duration--fast-02 motion(standard, productive) hide-feedback;
}

&.#{$prefix}--copy-btn--animating.#{$prefix}--copy-btn--fade-in::before,
&.#{$prefix}--copy-btn--animating.#{$prefix}--copy-btn--fade-in
.#{$prefix}--copy-btn__feedback {
animation: $duration--fast-02 motion(standard, productive) show-feedback;
}
.#{$prefix}--snippet--inline.#{$prefix}--copy-btn--animating.#{$prefix}--copy-btn--fade-in::before,
.#{$prefix}--snippet--inline.#{$prefix}--copy-btn--animating.#{$prefix}--copy-btn--fade-in
.#{$prefix}--copy-btn__feedback {
animation: $duration--fast-02 motion(standard, productive) show-feedback;
}

.#{$prefix}--snippet--inline code {
Expand Down
12 changes: 6 additions & 6 deletions packages/react/src/components/CodeSnippet/CodeSnippet-story.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import CodeSnippetSkeleton from './CodeSnippet.Skeleton';
const props = {
inline: () => ({
light: boolean('Light variant (light)', false),
feedback: text('Feedback text (feedback)', 'Feedback Enabled 👍'),
feedback: text('Feedback text (feedback)', 'Copied to clipboard'),
onClick: action('onClick'),
copyLabel: text(
'ARIA label for the snippet/copy button (copyLabel)',
Expand All @@ -24,7 +24,7 @@ const props = {
}),
single: () => ({
light: boolean('Light variant (light)', false),
feedback: text('Feedback text (feedback)', 'Feedback Enabled 👍'),
feedback: text('Feedback text (feedback)', 'Copied to clipboard'),
copyButtonDescription: text(
'Copy icon description (copyButtonDescription)',
'copyable code snippet'
Expand All @@ -37,7 +37,7 @@ const props = {
}),
multiline: () => ({
light: boolean('Light variant (light)', false),
feedback: text('Feedback text (feedback)', 'Feedback Enabled 👍'),
feedback: text('Feedback text (feedback)', 'Copied to clipboard'),
showMoreText: text(
'Text for "show more" button (showMoreText)',
'Show more'
Expand Down Expand Up @@ -86,7 +86,7 @@ storiesOf('CodeSnippet', module)
info: {
text: `
Code snippets are small blocks of reusable code that can be inserted in a code file.
The Inline style is for code used within a block of text.
`,
},
Expand All @@ -108,7 +108,7 @@ storiesOf('CodeSnippet', module)
info: {
text: `
Code snippets are small blocks of reusable code that can be inserted in a code file.
The Code style is for larger, multi-line code snippets.
`,
},
Expand Down Expand Up @@ -165,7 +165,7 @@ $z-indexes: (
info: {
text: `
Code snippets are small blocks of reusable code that can be inserted in a code file.
The Terminal style is for single-line .
`,
},
Expand Down
9 changes: 6 additions & 3 deletions packages/react/src/components/CopyButton/CopyButton-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,14 @@ describe('CopyButton', () => {
});

describe('Renders button props as expected', () => {
const wrapper = shallow(<CopyButton />);
let wrapper;

beforeEach(() => {
wrapper = mount(<CopyButton />);
});

it('Renders children as expected', () => {
expect(wrapper.is('button')).toBe(true);
expect(wrapper.hasClass(`${prefix}--copy-btn`)).toBe(true);
expect(wrapper.find('button').hasClass(`${prefix}--copy-btn`)).toBe(true);
expect(wrapper.find(`.${prefix}--copy-btn__feedback`).length).toBe(1);
expect(wrapper.find(Copy16).length).toBe(1);
});
Expand Down
62 changes: 6 additions & 56 deletions packages/react/src/components/CopyButton/CopyButton.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,73 +6,23 @@
*/

import PropTypes from 'prop-types';
import React, { useState, useEffect, useCallback } from 'react';
import React from 'react';
import classnames from 'classnames';
import debounce from 'lodash.debounce';
import { settings } from 'carbon-components';
import { Copy16 } from '@carbon/icons-react';
import Copy from '../Copy';

const { prefix } = settings;

export default function CopyButton({
iconDescription,
className,
feedback,
feedbackTimeout,
onAnimationEnd,
onClick,
...other
}) {
const [animation, setAnimation] = useState('');
const classNames = classnames(`${prefix}--copy-btn`, className, {
[`${prefix}--copy-btn--animating`]: animation,
[`${prefix}--copy-btn--${animation}`]: animation,
});
const handleFadeOut = useCallback(
debounce(() => {
setAnimation('fade-out');
}, feedbackTimeout),
[feedbackTimeout]
);
const handleClick = useCallback(
event => {
setAnimation('fade-in');
onClick(event);
handleFadeOut();
},
[onClick, handleFadeOut]
);
const handleAnimationEnd = event => {
if (event.animationName === 'hide-feedback') {
setAnimation('');
}
if (onAnimationEnd) {
onAnimationEnd(event);
}
};

useEffect(
() => () => {
handleFadeOut.cancel();
},
[handleFadeOut]
);

export default function CopyButton({ iconDescription, className, ...other }) {
return (
<button
type="button"
className={classNames}
onClick={handleClick}
<Copy
className={classnames(className, `${prefix}--copy-btn`)}
aria-label={iconDescription}
title={iconDescription}
onAnimationEnd={handleAnimationEnd}
{...other}>
<span
className={`${prefix}--assistive-text ${prefix}--copy-btn__feedback`}>
{feedback}
</span>
<Copy16 className={`${prefix}--snippet__icon`} />
</button>
</Copy>
);
}

Expand Down

0 comments on commit 7d8c0aa

Please sign in to comment.