diff --git a/src/core/components/copy-to-clipboard-btn.jsx b/src/core/components/copy-to-clipboard-btn.jsx
index 9c44487e2c5..cf3d066733e 100644
--- a/src/core/components/copy-to-clipboard-btn.jsx
+++ b/src/core/components/copy-to-clipboard-btn.jsx
@@ -8,16 +8,34 @@ import PropTypes from "prop-types"
* @constructor
*/
export default class CopyToClipboardBtn extends React.Component {
+ constructor(props) {
+ super(props)
+ this.state = { copied: false }
+ this.timerRef = null
+ }
+
+ handleCopy = () => {
+ this.setState({ copied: true })
+ if (this.timerRef) clearTimeout(this.timerRef)
+ this.timerRef = setTimeout(() => this.setState({ copied: false }), 1500)
+ }
+
+ componentWillUnmount() {
+ if (this.timerRef) clearTimeout(this.timerRef)
+ }
+
render() {
let { getComponent } = this.props
+ const { copied } = this.state
const CopyIcon = getComponent("CopyIcon")
return (
-
+
+ {copied && Copied!}
)
}
diff --git a/src/core/components/curl.jsx b/src/core/components/curl.jsx
index 618b21b9e6b..66f4b05dbf3 100644
--- a/src/core/components/curl.jsx
+++ b/src/core/components/curl.jsx
@@ -9,8 +9,25 @@ export default class Curl extends React.Component {
request: PropTypes.object.isRequired
}
+ constructor(props) {
+ super(props)
+ this.state = { copied: false }
+ this.timerRef = null
+ }
+
+ handleCopy = () => {
+ this.setState({ copied: true })
+ if (this.timerRef) clearTimeout(this.timerRef)
+ this.timerRef = setTimeout(() => this.setState({ copied: false }), 1500)
+ }
+
+ componentWillUnmount() {
+ if (this.timerRef) clearTimeout(this.timerRef)
+ }
+
render() {
const { request, getComponent } = this.props
+ const { copied } = this.state
const curl = requestSnippetGenerator_curl_bash(request)
const SyntaxHighlighter = getComponent("SyntaxHighlighter", true)
@@ -18,7 +35,8 @@ export default class Curl extends React.Component {
Curl
-
+
+ {copied && Copied!}
const [activeLanguage, setActiveLanguage] = useState(requestSnippetsSelectors.getSnippetGenerators()?.keySeq().first())
const [isExpanded, setIsExpanded] = useState(requestSnippetsSelectors?.getDefaultExpanded())
+ const [copied, setCopied] = useState(false)
+ const copyTimerRef = useRef(null)
+
+ const handleCopy = useCallback(() => {
+ setCopied(true)
+ if (copyTimerRef.current) clearTimeout(copyTimerRef.current)
+ copyTimerRef.current = setTimeout(() => setCopied(false), 1500)
+ }, [])
const snippetGenerators = requestSnippetsSelectors.getSnippetGenerators()
const activeGenerator = snippetGenerators.get(activeLanguage)
@@ -132,9 +140,10 @@ const RequestSnippets = ({ request, requestSnippetsSelectors, getComponent }) =>
}
-
+
+ {copied && Copied!}
{
const rootRef = useRef(null)
+ const [copied, setCopied] = useState(false)
+ const copyTimerRef = useRef(null)
+
+ const handleCopy = useCallback(() => {
+ setCopied(true)
+ if (copyTimerRef.current) clearTimeout(copyTimerRef.current)
+ copyTimerRef.current = setTimeout(() => setCopied(false), 1500)
+ }, [])
const SyntaxHighlighter = getComponent("SyntaxHighlighter", true)
const handleDownload = () => {
@@ -69,9 +77,10 @@ const HighlightCode = ({
{canCopy && (
-
+
+ {copied && Copied!}
)}
diff --git a/src/style/_buttons.scss b/src/style/_buttons.scss
index 7806d17ee1d..987f919748c 100644
--- a/src/style/_buttons.scss
+++ b/src/style/_buttons.scss
@@ -174,6 +174,34 @@ button {
background: #5e626f;
}
+.copy-to-clipboard__toast {
+ position: absolute;
+ right: calc(100% + 8px);
+ top: 50%;
+ transform: translateY(-50%);
+ background: #333;
+ color: #fff;
+ font-size: 11px;
+ font-family: sans-serif;
+ line-height: 1;
+ padding: 4px 8px;
+ border-radius: 4px;
+ white-space: nowrap;
+ pointer-events: none;
+ animation: copy-toast-fade-in 0.15s ease-out;
+}
+
+@keyframes copy-toast-fade-in {
+ from {
+ opacity: 0;
+ transform: translateY(-50%) translateX(4px);
+ }
+ to {
+ opacity: 1;
+ transform: translateY(-50%) translateX(0);
+ }
+}
+
.opblock-control-arrow {
border: none;
text-align: center;