item.tsx 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. 'use client'
  2. import type { FC } from 'react'
  3. import React, { useRef } from 'react'
  4. import cn from 'classnames'
  5. import { ChatBubbleOvalLeftEllipsisIcon as ChatBubbleOvalLeftEllipsisSolidIcon } from '@heroicons/react/24/solid'
  6. import {
  7. ChatBubbleOvalLeftEllipsisIcon,
  8. } from '@heroicons/react/24/outline'
  9. import { useHover } from 'ahooks'
  10. import ItemOperation from '@/app/components/explore/item-operation'
  11. import type { ConversationItem } from '@/models/share'
  12. export type IItemProps = {
  13. onClick: (id: string) => void
  14. item: ConversationItem
  15. isCurrent: boolean
  16. isPinned: boolean
  17. togglePin: (id: string) => void
  18. onDelete: (id: string) => void
  19. onRenameConversation: (item: ConversationItem) => void
  20. }
  21. const Item: FC<IItemProps> = ({
  22. isCurrent,
  23. item,
  24. onClick,
  25. isPinned,
  26. togglePin,
  27. onDelete,
  28. onRenameConversation,
  29. }) => {
  30. const ItemIcon = isCurrent ? ChatBubbleOvalLeftEllipsisSolidIcon : ChatBubbleOvalLeftEllipsisIcon
  31. const ref = useRef(null)
  32. const isHovering = useHover(ref)
  33. return (
  34. <div
  35. ref={ref}
  36. onClick={() => onClick(item.id)}
  37. key={item.id}
  38. className={cn(
  39. isCurrent
  40. ? 'bg-primary-50 text-primary-600'
  41. : 'text-gray-700 hover:bg-gray-200 hover:text-gray-700',
  42. 'group flex justify-between items-center rounded-md px-2 py-2 text-sm font-medium cursor-pointer',
  43. )}
  44. >
  45. <div className='flex items-center w-0 grow'>
  46. <ItemIcon
  47. className={cn(
  48. isCurrent
  49. ? 'text-primary-600'
  50. : 'text-gray-400 group-hover:text-gray-500',
  51. 'mr-3 h-5 w-5 flex-shrink-0',
  52. )}
  53. aria-hidden="true"
  54. />
  55. <span>{item.name}</span>
  56. </div>
  57. {item.id !== '-1' && (
  58. <div className='shrink-0 h-6' onClick={e => e.stopPropagation()}>
  59. <ItemOperation
  60. isPinned={isPinned}
  61. isItemHovering={isHovering}
  62. togglePin={() => togglePin(item.id)}
  63. isShowDelete
  64. isShowRenameConversation
  65. onRenameConversation={() => onRenameConversation(item)}
  66. onDelete={() => onDelete(item.id)}
  67. />
  68. </div>
  69. )}
  70. </div>
  71. )
  72. }
  73. export default React.memo(Item)