Skip to content

Commit f9c9761

Browse files
fix(style): added copied success message for clipboard icon
Signed-off-by: Soumik Sarker <ronodhirsoumik@gmail.com>
1 parent 8d17c78 commit f9c9761

5 files changed

Lines changed: 88 additions & 6 deletions

File tree

src/core/components/copy-to-clipboard-btn.jsx

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,34 @@ import PropTypes from "prop-types"
88
* @constructor
99
*/
1010
export default class CopyToClipboardBtn extends React.Component {
11+
constructor(props) {
12+
super(props)
13+
this.state = { copied: false }
14+
this.timerRef = null
15+
}
16+
17+
handleCopy = () => {
18+
this.setState({ copied: true })
19+
if (this.timerRef) clearTimeout(this.timerRef)
20+
this.timerRef = setTimeout(() => this.setState({ copied: false }), 1500)
21+
}
22+
23+
componentWillUnmount() {
24+
if (this.timerRef) clearTimeout(this.timerRef)
25+
}
26+
1127
render() {
1228
let { getComponent } = this.props
29+
const { copied } = this.state
1330

1431
const CopyIcon = getComponent("CopyIcon")
1532

1633
return (
1734
<div className="view-line-link copy-to-clipboard" title="Copy to clipboard">
18-
<CopyToClipboard text={this.props.textToCopy}>
35+
<CopyToClipboard text={this.props.textToCopy} onCopy={this.handleCopy}>
1936
<CopyIcon />
2037
</CopyToClipboard>
38+
{copied && <span className="copy-to-clipboard__toast">Copied!</span>}
2139
</div>
2240
)
2341
}

src/core/components/curl.jsx

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,34 @@ export default class Curl extends React.Component {
99
request: PropTypes.object.isRequired
1010
}
1111

12+
constructor(props) {
13+
super(props)
14+
this.state = { copied: false }
15+
this.timerRef = null
16+
}
17+
18+
handleCopy = () => {
19+
this.setState({ copied: true })
20+
if (this.timerRef) clearTimeout(this.timerRef)
21+
this.timerRef = setTimeout(() => this.setState({ copied: false }), 1500)
22+
}
23+
24+
componentWillUnmount() {
25+
if (this.timerRef) clearTimeout(this.timerRef)
26+
}
27+
1228
render() {
1329
const { request, getComponent } = this.props
30+
const { copied } = this.state
1431
const curl = requestSnippetGenerator_curl_bash(request)
1532
const SyntaxHighlighter = getComponent("SyntaxHighlighter", true)
1633

1734
return (
1835
<div className="curl-command">
1936
<h4>Curl</h4>
2037
<div className="copy-to-clipboard">
21-
<CopyToClipboard text={curl}><button/></CopyToClipboard>
38+
<CopyToClipboard text={curl} onCopy={this.handleCopy}><button/></CopyToClipboard>
39+
{copied && <span className="copy-to-clipboard__toast">Copied!</span>}
2240
</div>
2341
<div>
2442
<SyntaxHighlighter

src/core/plugins/request-snippets/request-snippets.jsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useRef, useEffect, useState } from "react"
1+
import React, { useRef, useEffect, useState, useCallback } from "react"
22
import classNames from "classnames"
33
import PropTypes from "prop-types"
44
import { CopyToClipboard } from "react-copy-to-clipboard"
@@ -42,6 +42,14 @@ const RequestSnippets = ({ request, requestSnippetsSelectors, getComponent }) =>
4242

4343
const [activeLanguage, setActiveLanguage] = useState(requestSnippetsSelectors.getSnippetGenerators()?.keySeq().first())
4444
const [isExpanded, setIsExpanded] = useState(requestSnippetsSelectors?.getDefaultExpanded())
45+
const [copied, setCopied] = useState(false)
46+
const copyTimerRef = useRef(null)
47+
48+
const handleCopy = useCallback(() => {
49+
setCopied(true)
50+
if (copyTimerRef.current) clearTimeout(copyTimerRef.current)
51+
copyTimerRef.current = setTimeout(() => setCopied(false), 1500)
52+
}, [])
4553

4654
const snippetGenerators = requestSnippetsSelectors.getSnippetGenerators()
4755
const activeGenerator = snippetGenerators.get(activeLanguage)
@@ -132,9 +140,10 @@ const RequestSnippets = ({ request, requestSnippetsSelectors, getComponent }) =>
132140
}
133141
</div>
134142
<div className="copy-to-clipboard">
135-
<CopyToClipboard text={snippet}>
143+
<CopyToClipboard text={snippet} onCopy={handleCopy}>
136144
<button />
137145
</CopyToClipboard>
146+
{copied && <span className="copy-to-clipboard__toast">Copied!</span>}
138147
</div>
139148
<div>
140149
<SyntaxHighlighter

src/core/plugins/syntax-highlighting/components/HighlightCode.jsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/**
22
* @prettier
33
*/
4-
import React, { useRef, useEffect } from "react"
4+
import React, { useRef, useEffect, useState, useCallback } from "react"
55
import PropTypes from "prop-types"
66
import classNames from "classnames"
77
import saveAs from "js-file-download"
@@ -17,6 +17,14 @@ const HighlightCode = ({
1717
children,
1818
}) => {
1919
const rootRef = useRef(null)
20+
const [copied, setCopied] = useState(false)
21+
const copyTimerRef = useRef(null)
22+
23+
const handleCopy = useCallback(() => {
24+
setCopied(true)
25+
if (copyTimerRef.current) clearTimeout(copyTimerRef.current)
26+
copyTimerRef.current = setTimeout(() => setCopied(false), 1500)
27+
}, [])
2028
const SyntaxHighlighter = getComponent("SyntaxHighlighter", true)
2129

2230
const handleDownload = () => {
@@ -69,9 +77,10 @@ const HighlightCode = ({
6977
<div className="highlight-code" ref={rootRef}>
7078
{canCopy && (
7179
<div className="copy-to-clipboard">
72-
<CopyToClipboard text={children}>
80+
<CopyToClipboard text={children} onCopy={handleCopy}>
7381
<button />
7482
</CopyToClipboard>
83+
{copied && <span className="copy-to-clipboard__toast">Copied!</span>}
7584
</div>
7685
)}
7786

src/style/_buttons.scss

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,34 @@ button {
174174
background: #5e626f;
175175
}
176176

177+
.copy-to-clipboard__toast {
178+
position: absolute;
179+
right: calc(100% + 8px);
180+
top: 50%;
181+
transform: translateY(-50%);
182+
background: #333;
183+
color: #fff;
184+
font-size: 11px;
185+
font-family: sans-serif;
186+
line-height: 1;
187+
padding: 4px 8px;
188+
border-radius: 4px;
189+
white-space: nowrap;
190+
pointer-events: none;
191+
animation: copy-toast-fade-in 0.15s ease-out;
192+
}
193+
194+
@keyframes copy-toast-fade-in {
195+
from {
196+
opacity: 0;
197+
transform: translateY(-50%) translateX(4px);
198+
}
199+
to {
200+
opacity: 1;
201+
transform: translateY(-50%) translateX(0);
202+
}
203+
}
204+
177205
.opblock-control-arrow {
178206
border: none;
179207
text-align: center;

0 commit comments

Comments
 (0)