Copy generated code to clipboard

Summary: Generated code modal now has a copy to clipboard button

Reviewed By: emilsjolander

Differential Revision: D7009716

fbshipit-source-id: 7a9b083d7067aa66ffa5b9d9c23741321547c4f6
This commit is contained in:
Daniel Büchele
2018-02-16 06:10:06 -08:00
committed by Facebook Github Bot
parent 01ffe10c2f
commit 1822bc5eaf
2 changed files with 72 additions and 14 deletions

View File

@@ -0,0 +1,20 @@
.CodeGeneratorsTitle {
display: flex;
justify-content: space-between;
}
.CodeGeneratorsTitle a {
font-size: 13px;
font-weight: normal;
margin-right: 20px;
}
.CodeGeneratorsCopyText {
position: absolute;
top: -9999em;
left: -9999em;
pointer-events: none;
width: 0;
height: 0;
}

View File

@@ -11,7 +11,7 @@
*/ */
import React, {Component} from 'react'; import React, {Component} from 'react';
import {Menu, Button, Row, Col, Dropdown, Icon, Modal} from 'antd'; import {Menu, Button, Row, Col, Dropdown, Icon, Modal, Tooltip} from 'antd';
import SyntaxHighlighter, { import SyntaxHighlighter, {
registerLanguage, registerLanguage,
} from 'react-syntax-highlighter/prism-light'; } from 'react-syntax-highlighter/prism-light';
@@ -29,6 +29,8 @@ registerLanguage('jsx', jsx);
registerLanguage('java', java); registerLanguage('java', java);
registerLanguage('objectivec', objectivec); registerLanguage('objectivec', objectivec);
import './CodeGenerators.css';
import type {LayoutRecordT} from './LayoutRecord'; import type {LayoutRecordT} from './LayoutRecord';
import type {Yoga$Direction} from 'yoga-layout'; import type {Yoga$Direction} from 'yoga-layout';
@@ -38,6 +40,7 @@ type Props = {
}; };
type State = { type State = {
showModal: ?string, showModal: ?string,
copied: boolean,
}; };
const LANGUAGES = { const LANGUAGES = {
@@ -62,10 +65,19 @@ const LANGUAGES = {
export default class CodeGenerators extends Component<Props, State> { export default class CodeGenerators extends Component<Props, State> {
state = { state = {
showModal: null, showModal: null,
copied: false,
}; };
onClick = ({key}: {key: string}) => this.setState({showModal: key}); onClick = ({key}: {key: string}) => this.setState({showModal: key});
onCopy = () => {
if (this._ref) {
this._ref.select();
document.execCommand('Copy');
this.setState({copied: true});
}
};
render() { render() {
const {showModal} = this.state; const {showModal} = this.state;
@@ -77,27 +89,53 @@ export default class CodeGenerators extends Component<Props, State> {
</Menu> </Menu>
); );
const code = showModal
? LANGUAGES[showModal].generator(
this.props.layoutDefinition,
this.props.direction,
)
: '';
return [ return [
<Modal <Modal
key="modal" key="modal"
title={showModal ? LANGUAGES[showModal].title : ''} title={
showModal ? (
<div className="CodeGeneratorsTitle">
{LANGUAGES[showModal].title}
<Tooltip
title={this.state.copied ? 'Copied!' : 'Click to copy'}
onVisibleChange={() => this.setState({copied: false})}>
<a onClick={this.onCopy}>copy to clipboard</a>
</Tooltip>
</div>
) : (
''
)
}
visible={Boolean(showModal)} visible={Boolean(showModal)}
footer={null} footer={null}
bodyStyle={{padding: 0}} bodyStyle={{padding: 0}}
onCancel={() => this.setState({showModal: null})}> onCancel={() => this.setState({showModal: null})}>
{showModal && ( {showModal && (
<SyntaxHighlighter <div>
language={LANGUAGES[showModal].syntax} <textarea
style={styles} className="CodeGeneratorsCopyText"
customStyle={{fontSize: '13px', backgroundColor: 'white'}} value={code}
lineNumberStyle={{userSelect: 'none', opacity: 0.5}} ref={ref => {
codeTagProps={{style: {tabSize: 4}}} this._ref = ref;
showLineNumbers> }}
{LANGUAGES[showModal].generator( />
this.props.layoutDefinition, <SyntaxHighlighter
this.props.direction, language={LANGUAGES[showModal].syntax}
)} style={styles}
</SyntaxHighlighter> customStyle={{fontSize: '13px', backgroundColor: 'white'}}
lineNumberStyle={{userSelect: 'none', opacity: 0.5}}
codeTagProps={{style: {tabSize: 4}}}
showLineNumbers>
{code}
</SyntaxHighlighter>
</div>
)} )}
</Modal>, </Modal>,
<Dropdown overlay={menu} key="dropdown"> <Dropdown overlay={menu} key="dropdown">