copy-to-clipboard.tsx 1.5 KB

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