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

-
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 }) => }
- +
{ 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 && (
- +
)} 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;