Skip to content

Commit ea08c07

Browse files
copy to clipboard button
1 parent ca7e6d0 commit ea08c07

File tree

3 files changed

+57
-11
lines changed

3 files changed

+57
-11
lines changed

demo/README.md

+2
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,5 @@
22

33
This is a small React application that demonstrates how to work with the
44
Request Converter library.
5+
6+
Try it out [here](https://elastic.github.io/request-converter).

demo/src/App.tsx

+37-4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ import Row from 'react-bootstrap/Row';
44
import Col from 'react-bootstrap/Col';
55
import Stack from 'react-bootstrap/Stack';
66
import Form from 'react-bootstrap/Form';
7+
import Button from 'react-bootstrap/Button';
8+
import ToastContainer from 'react-bootstrap/ToastContainer';
9+
import Toast from 'react-bootstrap/Toast';
710
import SyntaxHighlighter from 'react-syntax-highlighter';
811
import { atomOneLight } from 'react-syntax-highlighter/dist/esm/styles/hljs';
912
import { compareVersions } from 'compare-versions';
@@ -18,6 +21,7 @@ function App() {
1821
const [error, setError] = useState<string | null>(null);
1922
const [code, setCode] = useState<string>('Loading...');
2023
const [language, setLanguage] = useState<string>(formats[0]);
24+
const [showClipboardMsg, setShowClipboardMsg] = useState(false);
2125

2226
useEffect(() => {
2327
const sourceElem = document.getElementById("source");
@@ -71,15 +75,43 @@ function App() {
7175
})();
7276
}, [hasSchema, source, language]);
7377

74-
const onRequestChanged = (ev: React.ChangeEvent<HTMLSelectElement>) => {
78+
const onRequestChanged = (ev: React.ChangeEvent<HTMLSelectElement>): null => {
7579
setSource(ev.target.value);
7680
ev.target.style.height = ev.target.scrollHeight + "px";
7781
};
7882

83+
const copyToClipboard = async () => {
84+
await navigator.clipboard.writeText(code);
85+
setShowClipboardMsg(true);
86+
};
87+
7988
return (
8089
<Container id="main-container">
81-
<h1>Elasticsearch Request Converter Demo</h1>
82-
<p><a href="./docs/index.html">Library documentation</a></p>
90+
<div aria-live="polite" aria-atomic="true" className="position-relative">
91+
<ToastContainer className="clipboard-toast p-3" position="top-end" style={{ zIndex: 1 }}>
92+
<Toast onClose={() => setShowClipboardMsg(false)} show={showClipboardMsg} delay={2000} autohide>
93+
<Toast.Body>Copied to clipboard!</Toast.Body>
94+
</Toast>
95+
</ToastContainer>
96+
</div>
97+
<Row>
98+
<Col>
99+
<h1>Elasticsearch Request Converter Demo</h1>
100+
</Col>
101+
<Col sm="auto">
102+
<p>
103+
<small>
104+
<svg width="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><g id="SVGRepo_bgCarrier" strokeWidth="0"></g><g id="SVGRepo_tracerCarrier" strokeLinecap="round" strokeLinejoin="round"></g><g id="SVGRepo_iconCarrier"> <g id="Interface / External_Link"> <path id="Vector" d="M10.0002 5H8.2002C7.08009 5 6.51962 5 6.0918 5.21799C5.71547 5.40973 5.40973 5.71547 5.21799 6.0918C5 6.51962 5 7.08009 5 8.2002V15.8002C5 16.9203 5 17.4801 5.21799 17.9079C5.40973 18.2842 5.71547 18.5905 6.0918 18.7822C6.5192 19 7.07899 19 8.19691 19H15.8031C16.921 19 17.48 19 17.9074 18.7822C18.2837 18.5905 18.5905 18.2839 18.7822 17.9076C19 17.4802 19 16.921 19 15.8031V14M20 9V4M20 4H15M20 4L13 11" stroke="#000000" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"></path> </g> </g></svg>
105+
&nbsp;
106+
<a href="https://github.com/elastic/request-converter">GitHub project</a>
107+
<br />
108+
<svg width="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><g id="SVGRepo_bgCarrier" strokeWidth="0"></g><g id="SVGRepo_tracerCarrier" strokeLinecap="round" strokeLinejoin="round"></g><g id="SVGRepo_iconCarrier"> <g id="Interface / External_Link"> <path id="Vector" d="M10.0002 5H8.2002C7.08009 5 6.51962 5 6.0918 5.21799C5.71547 5.40973 5.40973 5.71547 5.21799 6.0918C5 6.51962 5 7.08009 5 8.2002V15.8002C5 16.9203 5 17.4801 5.21799 17.9079C5.40973 18.2842 5.71547 18.5905 6.0918 18.7822C6.5192 19 7.07899 19 8.19691 19H15.8031C16.921 19 17.48 19 17.9074 18.7822C18.2837 18.5905 18.5905 18.2839 18.7822 17.9076C19 17.4802 19 16.921 19 15.8031V14M20 9V4M20 4H15M20 4L13 11" stroke="#000000" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"></path> </g> </g></svg>
109+
&nbsp;
110+
<a href="./docs/index.html">Library documentation</a>
111+
</small>
112+
</p>
113+
</Col>
114+
</Row>
83115
<Row>
84116
<Col className="col-6">
85117
<Stack direction="horizontal" className="heading">
@@ -91,12 +123,13 @@ function App() {
91123
</Stack>
92124
</Col>
93125
<Col className="col-6">
94-
<Stack direction="horizontal" className="heading">
126+
<Stack direction="horizontal" className="heading" gap={1}>
95127
<p>Converted&nbsp;Code</p>
96128
<p className="spacer"></p>
97129
<Form.Select id="language-choice" size="sm" defaultValue={language} onChange={ev => setLanguage(ev.target.value)}>
98130
{formats.map(fmt => <option key={fmt} value={fmt}>{fmt}</option>)}
99131
</Form.Select>
132+
<Button className="copy-clipboard" size="sm" variant="outline-secondary" onClick={() => copyToClipboard()}>&#x2398;</Button>
100133
</Stack>
101134
</Col>
102135
</Row>

demo/src/index.css

+18-7
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,3 @@
1-
html, body, #root {
2-
margin-top: 0;
3-
margin-bottom: 0;
4-
height: 100%;
5-
min-height: 100%;
6-
}
7-
81
body {
92
color: #444;
103
}
@@ -22,6 +15,10 @@ textarea.form-control {
2215
font-size: 14px;
2316
}
2417

18+
#main-container {
19+
margin-top: 10px;
20+
}
21+
2522
.heading {
2623
align-items: baseline;
2724
}
@@ -41,4 +38,18 @@ pre {
4138
white-space: pre-wrap;
4239
}
4340

41+
.copy-clipboard {
42+
line-height: 0.5em;
43+
padding-bottom: 11px;
44+
font-size: 150%;
45+
border: 1px solid #ddd;
46+
}
47+
48+
.clipboard-toast {
49+
margin-top: 90px;
50+
width: 200px;
51+
}
4452

53+
.clipboard-toast .toast {
54+
background-color: #eee;
55+
}

0 commit comments

Comments
 (0)