feat: add showCopyCodeButton to CodeSnippet component

This allows to easiy copy the content of the code snippet.
This commit is contained in:
Oliver Sand
2020-09-09 14:50:54 +02:00
parent 72c097f57f
commit 2615cafd5d
4 changed files with 38 additions and 11 deletions
@@ -86,3 +86,9 @@ export const Languages = () => (
<CodeSnippet text={PYTHON} language="python" showLineNumbers />
</InfoCard>
);
export const CopyCode = () => (
<InfoCard title="Copy Code">
<CodeSnippet text={JAVASCRIPT} language="javascript" showCopyCodeButton />
</InfoCard>
);
@@ -15,7 +15,7 @@
*/
import React from 'react';
import { render } from '@testing-library/react';
import { render, fireEvent } from '@testing-library/react';
import { wrapInTestApp } from '@backstage/test-utils';
import { CodeSnippet } from './CodeSnippet';
@@ -55,4 +55,14 @@ describe('<CodeSnippet />', () => {
expect(queryByText(/2/)).toBeInTheDocument();
expect(queryByText(/3/)).toBeInTheDocument();
});
it('copy code using button', async () => {
document.execCommand = jest.fn();
const rendered = render(
wrapInTestApp(<CodeSnippet {...minProps} showCopyCodeButton />),
);
const button = rendered.getByTitle('Text copied to clipboard');
fireEvent.click(button);
expect(document.execCommand).toHaveBeenCalled();
});
});
@@ -20,19 +20,22 @@ import SyntaxHighlighter from 'react-syntax-highlighter';
import { docco, dark } from 'react-syntax-highlighter/dist/cjs/styles/hljs';
import { useTheme } from '@material-ui/core';
import { BackstageTheme } from '@backstage/theme';
import { CopyTextButton } from '../CopyTextButton';
type Props = {
text: string;
language: string;
showLineNumbers?: boolean;
showCopyCodeButton?: boolean;
};
const defaultProps = {
showLineNumbers: false,
showCopyCodeButton: false,
};
export const CodeSnippet: FC<Props> = props => {
const { text, language, showLineNumbers } = {
const { text, language, showLineNumbers, showCopyCodeButton } = {
...defaultProps,
...props,
};
@@ -41,13 +44,20 @@ export const CodeSnippet: FC<Props> = props => {
const mode = theme.palette.type === 'dark' ? dark : docco;
return (
<SyntaxHighlighter
language={language}
style={mode}
showLineNumbers={showLineNumbers}
>
{text}
</SyntaxHighlighter>
<div style={{ position: 'relative' }}>
<SyntaxHighlighter
language={language}
style={mode}
showLineNumbers={showLineNumbers}
>
{text}
</SyntaxHighlighter>
{showCopyCodeButton && (
<div style={{ position: 'absolute', top: 0, right: 0 }}>
<CopyTextButton text={text} />
</div>
)}
</div>
);
};
@@ -56,4 +66,5 @@ CodeSnippet.propTypes = {
text: PropTypes.string.isRequired,
language: PropTypes.string.isRequired,
showLineNumbers: PropTypes.bool,
showCopyCodeButton: PropTypes.bool,
};
@@ -15,7 +15,7 @@
*/
import React from 'react';
import { render } from '@testing-library/react';
import { render, fireEvent } from '@testing-library/react';
import { wrapInTestApp } from '@backstage/test-utils';
import { CopyTextButton } from './CopyTextButton';
import {
@@ -76,7 +76,7 @@ describe('<CopyTextButton />', () => {
),
);
const button = rendered.getByTitle('mockTooltip');
button.click();
fireEvent.click(button);
expect(document.execCommand).toHaveBeenCalled();
rendered.getByText('mockTooltip');
});