CopyButton.tsx 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. import React, { useState, FC } from 'react';
  2. import { Theme } from '@mui/material';
  3. import { makeStyles } from '@mui/styles';
  4. import { CopyButtonProps } from './Types';
  5. import icons from '../icons/Icons';
  6. import CustomIconButton from '../customButton/CustomIconButton';
  7. import { useTranslation } from 'react-i18next';
  8. const CopyIcon = icons.copyExpression;
  9. const CopyButton: FC<CopyButtonProps> = props => {
  10. const { label, icon, className, value = '', ...others } = props;
  11. const classes = useStyles();
  12. const { t: commonTrans } = useTranslation();
  13. const copyTrans = commonTrans('copy');
  14. const [tooltipTitle, setTooltipTitle] = useState('Copy');
  15. const unsecuredCopyToClipboard = (v: string) => {
  16. const textArea = document.createElement('textarea');
  17. textArea.style.position = 'fixed';
  18. textArea.style.opacity = '0';
  19. textArea.style.zIndex = '-1000';
  20. textArea.value = v;
  21. document.body.appendChild(textArea);
  22. textArea.focus();
  23. textArea.select();
  24. try {
  25. document.execCommand('copy');
  26. } catch (err) {
  27. console.error('Unable to copy to clipboard', err);
  28. }
  29. document.body.removeChild(textArea);
  30. };
  31. const handleClick = (event: React.MouseEvent<HTMLElement>, v: string) => {
  32. event.stopPropagation();
  33. if (typeof v === 'object') {
  34. v = JSON.stringify(v);
  35. }
  36. setTooltipTitle(copyTrans.copied);
  37. navigator.clipboard?.writeText(v) ?? unsecuredCopyToClipboard(v);
  38. setTimeout(() => {
  39. setTooltipTitle(copyTrans.copy);
  40. }, 1000);
  41. };
  42. return (
  43. <CustomIconButton
  44. tooltip={tooltipTitle}
  45. aria-label={label}
  46. className={`${classes.button} ${className}`}
  47. onClick={event => handleClick(event, value || '')}
  48. {...others}
  49. >
  50. {icon || <CopyIcon />}
  51. </CustomIconButton>
  52. );
  53. };
  54. CopyButton.displayName = 'CopyButton';
  55. const useStyles = makeStyles((theme: Theme) => ({
  56. root: {},
  57. button: {},
  58. tooltip: {},
  59. }));
  60. export default CopyButton;