copy-to-clipboard.tsx 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. import { memo, useCallback, useState } from 'react'
  2. import { useTranslation } from 'react-i18next'
  3. import OLButton from '@/shared/components/ol/ol-button'
  4. import OLTooltip from '@/shared/components/ol/ol-tooltip'
  5. import OLIconButton from '@/shared/components/ol/ol-icon-button'
  6. import MaterialIcon from '@/shared/components/material-icon'
  7. export const CopyToClipboard = memo<{
  8. content: string
  9. tooltipId: string
  10. kind?: 'text' | 'icon' | 'button'
  11. unfilled?: boolean
  12. onClick?: () => void
  13. }>(({ content, tooltipId, kind = 'icon', unfilled = false, onClick }) => {
  14. const { t } = useTranslation()
  15. const [copied, setCopied] = useState(false)
  16. const handleClick = useCallback(() => {
  17. navigator.clipboard.writeText(content).then(() => {
  18. setCopied(true)
  19. window.setTimeout(() => {
  20. setCopied(false)
  21. }, 1500)
  22. })
  23. if (onClick) {
  24. onClick()
  25. }
  26. }, [content, onClick])
  27. if (!navigator.clipboard?.writeText) {
  28. return null
  29. }
  30. return (
  31. <OLTooltip
  32. id={tooltipId}
  33. description={copied ? `${t('copied')}!` : t('copy')}
  34. overlayProps={{ delay: copied ? 1000 : 250 }}
  35. >
  36. {kind === 'text' ? (
  37. <OLButton
  38. onClick={handleClick}
  39. size="sm"
  40. variant="secondary"
  41. className="copy-button"
  42. >
  43. {t('copy')}
  44. </OLButton>
  45. ) : kind === 'button' ? (
  46. <OLButton
  47. onClick={handleClick}
  48. size="sm"
  49. variant="ghost"
  50. className="copy-button copy-button-ghost"
  51. >
  52. {copied ? (
  53. <MaterialIcon type="check" />
  54. ) : (
  55. <MaterialIcon type="content_copy" unfilled />
  56. )}
  57. {t('copy')}
  58. </OLButton>
  59. ) : (
  60. <OLIconButton
  61. onClick={handleClick}
  62. variant="link"
  63. size="sm"
  64. accessibilityLabel={t('copy')}
  65. className="copy-button"
  66. icon={copied ? 'check' : 'content_copy'}
  67. unfilled={unfilled}
  68. />
  69. )}
  70. </OLTooltip>
  71. )
  72. })
  73. CopyToClipboard.displayName = 'CopyToClipboard'