index.tsx 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. 'use client'
  2. import cn from 'classnames'
  3. import React, { useRef } from 'react'
  4. import { useRouter } from 'next/navigation'
  5. import { useHover } from 'ahooks'
  6. import s from './style.module.css'
  7. import ItemOperation from '@/app/components/explore/item-operation'
  8. import AppIcon from '@/app/components/base/app-icon'
  9. export type IAppNavItemProps = {
  10. name: string
  11. id: string
  12. icon: string
  13. icon_background: string
  14. isSelected: boolean
  15. isPinned: boolean
  16. togglePin: () => void
  17. uninstallable: boolean
  18. onDelete: (id: string) => void
  19. }
  20. export default function AppNavItem({
  21. name,
  22. id,
  23. icon,
  24. icon_background,
  25. isSelected,
  26. isPinned,
  27. togglePin,
  28. uninstallable,
  29. onDelete,
  30. }: IAppNavItemProps) {
  31. const router = useRouter()
  32. const url = `/explore/installed/${id}`
  33. const ref = useRef(null)
  34. const isHovering = useHover(ref)
  35. return (
  36. <div
  37. ref={ref}
  38. key={id}
  39. className={cn(
  40. s.item,
  41. isSelected ? s.active : 'hover:bg-gray-200',
  42. 'flex h-8 items-center justify-between px-2 rounded-lg text-sm font-normal ',
  43. )}
  44. onClick={() => {
  45. router.push(url) // use Link causes popup item always trigger jump. Can not be solved by e.stopPropagation().
  46. }}
  47. >
  48. <div className='flex items-center space-x-2 w-0 grow'>
  49. <AppIcon size='tiny' icon={icon} background={icon_background} />
  50. <div className='overflow-hidden text-ellipsis whitespace-nowrap'>{name}</div>
  51. </div>
  52. {
  53. <div className='shrink-0 h-6' onClick={e => e.stopPropagation()}>
  54. <ItemOperation
  55. isPinned={isPinned}
  56. isItemHovering={isHovering}
  57. togglePin={togglePin}
  58. isShowDelete={!uninstallable && !isSelected}
  59. onDelete={() => onDelete(id)}
  60. />
  61. </div>
  62. }
  63. </div>
  64. )
  65. }