Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pterodactyl
GitHub Repository: pterodactyl/panel
Path: blob/1.0-develop/resources/scripts/components/elements/CopyOnClick.tsx
10276 views
1
import React, { useEffect, useState } from 'react';
2
import Fade from '@/components/elements/Fade';
3
import Portal from '@/components/elements/Portal';
4
import copy from 'copy-to-clipboard';
5
import classNames from 'classnames';
6
7
interface CopyOnClickProps {
8
text: string | number | null | undefined;
9
showInNotification?: boolean;
10
children: React.ReactNode;
11
}
12
13
const CopyOnClick = ({ text, showInNotification = true, children }: CopyOnClickProps) => {
14
const [copied, setCopied] = useState(false);
15
16
useEffect(() => {
17
if (!copied) return;
18
19
const timeout = setTimeout(() => {
20
setCopied(false);
21
}, 2500);
22
23
return () => {
24
clearTimeout(timeout);
25
};
26
}, [copied]);
27
28
if (!React.isValidElement(children)) {
29
throw new Error('Component passed to <CopyOnClick/> must be a valid React element.');
30
}
31
32
const child = !text
33
? React.Children.only(children)
34
: React.cloneElement(React.Children.only(children), {
35
// @ts-expect-error todo: check on this
36
className: classNames(children.props.className || '', 'cursor-pointer'),
37
onClick: (e: React.MouseEvent<HTMLElement>) => {
38
copy(String(text));
39
setCopied(true);
40
if (typeof children.props.onClick === 'function') {
41
children.props.onClick(e);
42
}
43
},
44
});
45
46
return (
47
<>
48
{copied && (
49
<Portal>
50
<Fade in appear timeout={250} key={copied ? 'visible' : 'invisible'}>
51
<div className={'fixed z-50 bottom-0 right-0 m-4'}>
52
<div className={'rounded-md py-3 px-4 text-gray-200 bg-neutral-600/95 shadow'}>
53
<p>
54
{showInNotification
55
? `Copied "${String(text)}" to clipboard.`
56
: 'Copied text to clipboard.'}
57
</p>
58
</div>
59
</div>
60
</Fade>
61
</Portal>
62
)}
63
{child}
64
</>
65
);
66
};
67
68
export default CopyOnClick;
69
70