diff --git a/docs-ui/components/textCopyInput.stories.js b/docs-ui/components/textCopyInput.stories.js new file mode 100644 index 00000000000000..2b8507234a8678 --- /dev/null +++ b/docs-ui/components/textCopyInput.stories.js @@ -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')(() => ( + Value to be copied + )) +); diff --git a/src/sentry/static/sentry/app/views/settings/components/forms/textCopyInput.jsx b/src/sentry/static/sentry/app/views/settings/components/forms/textCopyInput.jsx new file mode 100644 index 00000000000000..0de9f99a761748 --- /dev/null +++ b/src/sentry/static/sentry/app/views/settings/components/forms/textCopyInput.jsx @@ -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 ( + + + + {children} + + + + + + + + + ); + } +} + +export default TextCopyInput; diff --git a/tests/js/spec/components/__snapshots__/textCopyInput.spec.jsx.snap b/tests/js/spec/components/__snapshots__/textCopyInput.spec.jsx.snap new file mode 100644 index 00000000000000..1902342e4be3d2 --- /dev/null +++ b/tests/js/spec/components/__snapshots__/textCopyInput.spec.jsx.snap @@ -0,0 +1,38 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`TextCopyInput renders 1`] = ` + + + + Text to Copy + + + + + + + + +`; diff --git a/tests/js/spec/components/textCopyInput.spec.jsx b/tests/js/spec/components/textCopyInput.spec.jsx new file mode 100644 index 00000000000000..55a2f6ad2a3d97 --- /dev/null +++ b/tests/js/spec/components/textCopyInput.spec.jsx @@ -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(Text to Copy); + expect(wrapper).toMatchSnapshot(); + }); +});