Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions docs-ui/components/textCopyInput.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from 'react';
import {storiesOf} from '@storybook/react';
import {withInfo} from '@storybook/addon-info';
import {action} from '@storybook/addon-actions';

import TextCopyInput from 'application-root/views/settings/components/forms/textCopyInput';

storiesOf('TextCopyInput', module).add(
'default',
withInfo('Description')(() => (
<TextCopyInput onCopy={action('Copied!')}>Value to be copied </TextCopyInput>
))
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import {Flex} from 'grid-emotion';
import PropTypes from 'prop-types';
import React from 'react';
import ReactDOM from 'react-dom';
import styled from 'react-emotion';

import {inputStyles} from './styled/styles';
import {selectText} from '../../../../utils/selectText';
import AutoSelectText from '../../../../components/autoSelectText';
import Button from '../../../../components/buttons/button';
import Clipboard from '../../../../components/clipboard';
import InlineSvg from '../../../../components/inlineSvg';

const StyledAutoSelectText = styled(AutoSelectText)`
${inputStyles};
display: inline-block;
width: auto;
padding: 0;
`;

const OverflowContainer = styled(Flex)`
overflow: hidden;
text-overflow: ellipsis;
`;

const Wrapper = styled(Flex)`
overflow: hidden;
`;

class TextCopyInput extends React.Component {
static propTypes = {
/**
* Text to copy
*/
children: PropTypes.string.isRequired,
/**
* CSS style object
*/
style: PropTypes.object,
onCopy: PropTypes.func,
};

static defaultProps = {
onCopy: () => {},
};

constructor(props) {
super(props);
}

// Select text when copy button is clicked
handleCopyClick = e => {
if (!this.textRef) return;

let {onCopy} = this.props;

// We use findDOMNode here because `this.textRef` is not a dom node,
// it's a ref to AutoSelectText
// eslint-disable-next-line react/no-find-dom-node
selectText(ReactDOM.findDOMNode(this.textRef));

onCopy(this.props.children, e);

e.stopPropagation();
};

handleAutoMount = ref => {
this.textRef = ref;
};

render() {
let {style, children} = this.props;

return (
<Wrapper>
<OverflowContainer flex="1">
<StyledAutoSelectText innerRef={this.handleAutoMount} style={style}>
{children}
</StyledAutoSelectText>
</OverflowContainer>
<Clipboard hideUnsupported onClick={this.handleCopyClick} value={children}>
<Flex shrink="0">
<Button borderless size="xsmall" onClick={this.handleCopyClick}>
<InlineSvg src="icon-copy" />
</Button>
</Flex>
</Clipboard>
</Wrapper>
);
}
}

export default TextCopyInput;
38 changes: 38 additions & 0 deletions tests/js/spec/components/__snapshots__/textCopyInput.spec.jsx.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`TextCopyInput renders 1`] = `
<Styled(Base)>
<Styled(Base)
flex="1"
>
<Styled(AutoSelectText)
innerRef={[Function]}
>
Text to Copy
</Styled(AutoSelectText)>
</Styled(Base)>
<Clipboard
errorMessage="Error copying to clipboard"
hideMessages={false}
hideUnsupported={true}
onClick={[Function]}
successMessage="Copied to clipboard"
value="Text to Copy"
>
<Flex
shrink="0"
>
<Button
borderless={true}
disabled={false}
onClick={[Function]}
size="xsmall"
>
<InlineSvg
src="icon-copy"
/>
</Button>
</Flex>
</Clipboard>
</Styled(Base)>
`;
10 changes: 10 additions & 0 deletions tests/js/spec/components/textCopyInput.spec.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import React from 'react';
import {shallow} from 'enzyme';
import TextCopyInput from 'app/views/settings/components/forms/textCopyInput';

describe('TextCopyInput', function() {
it('renders', function() {
let wrapper = shallow(<TextCopyInput>Text to Copy</TextCopyInput>);
expect(wrapper).toMatchSnapshot();
});
});