key-value-item.tsx 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. 'use client'
  2. import type { FC } from 'react'
  3. import React, { useCallback, useEffect, useState } from 'react'
  4. import copy from 'copy-to-clipboard'
  5. import {
  6. RiClipboardLine,
  7. } from '@remixicon/react'
  8. import { useTranslation } from 'react-i18next'
  9. import { ClipboardCheck } from '../../base/icons/src/vender/line/files'
  10. import Tooltip from '../../base/tooltip'
  11. import cn from '@/utils/classnames'
  12. import ActionButton from '@/app/components/base/action-button'
  13. type Props = {
  14. label: string
  15. labelWidthClassName?: string
  16. value: string
  17. maskedValue?: string
  18. valueMaxWidthClassName?: string
  19. }
  20. const KeyValueItem: FC<Props> = ({
  21. label,
  22. labelWidthClassName = 'w-10',
  23. value,
  24. maskedValue,
  25. valueMaxWidthClassName = 'max-w-[162px]',
  26. }) => {
  27. const { t } = useTranslation()
  28. const [isCopied, setIsCopied] = useState(false)
  29. const handleCopy = useCallback(() => {
  30. copy(value)
  31. setIsCopied(true)
  32. }, [value])
  33. useEffect(() => {
  34. if (isCopied) {
  35. const timer = setTimeout(() => {
  36. setIsCopied(false)
  37. }, 2000)
  38. return () => {
  39. clearTimeout(timer)
  40. }
  41. }
  42. }, [isCopied])
  43. const CopyIcon = isCopied ? ClipboardCheck : RiClipboardLine
  44. return (
  45. <div className='flex items-center gap-1'>
  46. <span className={cn('flex flex-col justify-center items-start text-text-tertiary system-xs-medium', labelWidthClassName)}>{label}</span>
  47. <div className='flex justify-center items-center gap-0.5'>
  48. <span className={cn(valueMaxWidthClassName, ' truncate system-xs-medium text-text-secondary')}>
  49. {maskedValue || value}
  50. </span>
  51. <Tooltip popupContent={t(`common.operation.${isCopied ? 'copied' : 'copy'}`)} position='top'>
  52. <ActionButton onClick={handleCopy}>
  53. <CopyIcon className='shrink-0 w-3.5 h-3.5 text-text-tertiary' />
  54. </ActionButton>
  55. </Tooltip>
  56. </div>
  57. </div>
  58. )
  59. }
  60. export default React.memo(KeyValueItem)