Skip to content

Commit

Permalink
feat: add copy to clipboard component
Browse files Browse the repository at this point in the history
  • Loading branch information
welingtonms committed Feb 21, 2021
1 parent 563a196 commit 914049e
Show file tree
Hide file tree
Showing 7 changed files with 150 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/atoms/icon/assets/ic_content_copy_48px.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions src/atoms/icon/icon-mapping.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import CloseFullscreen from './assets/ic_close_fullscreen_48px.svg';
import Cloud from './assets/ic_cloud_48px.svg';
import CloudDone from './assets/ic_cloud_done_48px.svg';
import CloudQueue from './assets/ic_cloud_queue_48px.svg';
import ContentCopy from './assets/ic_content_copy_48px.svg'
import Create from './assets/ic_create_48px.svg';
import DoubleChevronLeft from './assets/ic_double_chevron_left_48px.svg';
import DoubleChevronRight from './assets/ic_double_chevron_right_48px.svg';
Expand Down Expand Up @@ -52,6 +53,7 @@ export default {
'check-circle': CheckCircle,
'chevron-left': ChevronLeft,
'chevron-right': ChevronRight,
'content-copy': ContentCopy,
'double-chevron-left': DoubleChevronLeft,
'double-chevron-right': DoubleChevronRight,
'expand-less': ExpandLess,
Expand Down
61 changes: 61 additions & 0 deletions src/molecules/copy/copy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import React, { useCallback } from 'react';
import PropTypes from 'prop-types';
import clsx from 'clsx';

import { Box } from '../../atoms/box';
import { Button, Emphasis } from '../../atoms/button';
import { Input } from '../../atoms/input';
import { useID } from '../../hooks/id';

import './copy.scss';

function Copy({ className, value, editable = false, onCopy, ...others }) {
const id = useID(others);

const handleClick = useCallback(function handleClick() {
// based on https://www.w3schools.com/howto/howto_js_copy_clipboard.asp

/* Get the text field */
var copyText = document.getElementById(id);

/* Select the text field */
copyText.select();
copyText.setSelectionRange(0, 99999); /* For mobile devices */

/* Copy the text inside the text field */
document.execCommand('copy');

navigator?.clipboard?.readText?.().then(text => {
onCopy?.(text);
});
});

return (
<Box
borderless
paddingless
className={clsx('cb-copy', className)}
trailing={
<Button
emphasis={Emphasis.ghost}
icon="content-copy"
onClick={handleClick}
data-testid="cb-copy-button"
/>
}
>
<Input
id={id}
{...(editable ? { value } : { defaultValue: value })}
readOnly={!editable}
/>
</Box>
);
}

Copy.propTypes = {
editable: PropTypes.bool,
onCopy: PropTypes.func,
};

export default Copy;
21 changes: 21 additions & 0 deletions src/molecules/copy/copy.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
@import '../../styles/tools/_tools.mixins';

.cb-copy {
@include transition(all);

@include disableable;
@include font;

@include px(spacing-4);
@include py(spacing-4);

display: inline-flex;
flex-direction: row;

// box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1),
// 0 2px 4px -1px rgba(0, 0, 0, 0.06);

// @include hoverable {
// box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);
// }
}
29 changes: 29 additions & 0 deletions src/molecules/copy/copy.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React from 'react';

import generator from '../../../test/data-generator';
import Copy from './copy';

export default {
title: 'Molecules/Copy',
component: Copy,
docs: {
description: {
story: 'some story *a*markdown**',
},
},
};

const Template = args => {
return (
<div className="block">
<p className="mb-2">
This is me, a cool Copy to Clipboard ready to be played around. Try me
:)
</p>

<Copy value={generator.animal()} {...args} className="" />
</div>
);
};

export const Playground = Template.bind({});
35 changes: 35 additions & 0 deletions src/molecules/copy/copy.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React from 'react';

import { render, userEvent, mount, asTestAttr } from '../../../test/helpers';
import { Copy } from './index';
import generator from '../../../test/data-generator';

describe('Copy', () => {
it('renders correctly', () => {
const props = {
value: generator.animal(),
};

const { getByTestId } = render(<Copy {...props} />);

expect(getByTestId('cb-copy-button')).toBeTruthy();
expect(getByTestId('cb-input')).toBeTruthy();
});

it('copies content', () => {
document.execCommand = jest.fn();

const props = {
value: generator.animal(),
onCopy: jest.fn(),
};

const { getByTestId } = render(<Copy {...props} />);

userEvent.click(getByTestId('cb-copy-button'));

expect(document.execCommand).toHaveBeenCalledWith('copy');
});

// TODO: test paste
});
1 change: 1 addition & 0 deletions src/molecules/copy/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as Copy } from './copy';

0 comments on commit 914049e

Please sign in to comment.