index.tsx 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. import { useState } from 'react'
  2. import { ChevronDownIcon, ChevronRightIcon } from '@heroicons/react/24/outline'
  3. import classNames from '@/utils/classnames'
  4. export type IItem = {
  5. key: string
  6. name: string
  7. }
  8. type ICollapse = {
  9. title: string | undefined
  10. items: IItem[]
  11. renderItem: (item: IItem) => React.ReactNode
  12. onSelect?: (item: IItem) => void
  13. wrapperClassName?: string
  14. }
  15. const Collapse = ({
  16. title,
  17. items,
  18. renderItem,
  19. onSelect,
  20. wrapperClassName,
  21. }: ICollapse) => {
  22. const [open, setOpen] = useState(false)
  23. const toggle = () => setOpen(!open)
  24. return (
  25. <div className={classNames('border border-gray-200 bg-gray-50 rounded-lg', wrapperClassName)}>
  26. <div className='flex items-center justify-between leading-[18px] px-3 py-2 text-xs font-medium text-gray-800 cursor-pointer' onClick={toggle}>
  27. {title}
  28. {
  29. open
  30. ? <ChevronDownIcon className='w-3 h-3 text-gray-400' />
  31. : <ChevronRightIcon className='w-3 h-3 text-gray-400' />
  32. }
  33. </div>
  34. {
  35. open && (
  36. <div className='py-2 border-t border-t-gray-100'>
  37. {
  38. items.map(item => (
  39. <div key={item.key} onClick={() => onSelect && onSelect(item)}>
  40. {renderItem(item)}
  41. </div>
  42. ))
  43. }
  44. </div>
  45. )
  46. }
  47. </div>
  48. )
  49. }
  50. export default Collapse