index.tsx 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. 'use client'
  2. import React, { FC, useState } from 'react'
  3. import PortalToFollowElem from '../portal-to-follow-elem'
  4. import { ChevronDownIcon, CheckIcon } from '@heroicons/react/24/outline'
  5. import cn from 'classnames'
  6. export interface ISelectProps<T> {
  7. value: T
  8. items: { value: T, name: string }[]
  9. onChange: (value: T) => void
  10. }
  11. const Select: FC<ISelectProps<string | number>> = ({
  12. value,
  13. items,
  14. onChange
  15. }) => {
  16. const [controlHide, setControlHide] = useState(0)
  17. const itemsElement = items.map(item => {
  18. const isSelected = item.value === value
  19. return (
  20. <div
  21. key={item.value}
  22. className={cn('relative h-9 leading-9 px-10 rounded-lg text-sm text-gray-700 hover:bg-gray-100')}
  23. onClick={() => {
  24. onChange(item.value)
  25. setControlHide(Date.now())
  26. }}
  27. >
  28. {isSelected && (
  29. <div className='absolute left-4 top-1/2 translate-y-[-50%] flex items-center justify-center w-4 h-4 text-primary-600'>
  30. <CheckIcon width={16} height={16}></CheckIcon>
  31. </div>
  32. )}
  33. {item.name}
  34. </div>
  35. )
  36. })
  37. return (
  38. <div>
  39. <PortalToFollowElem
  40. portalElem={(
  41. <div
  42. className='p-1 rounded-lg bg-white cursor-pointer'
  43. style={{
  44. boxShadow: '0px 10px 15px -3px rgba(0, 0, 0, 0.1), 0px 4px 6px rgba(0, 0, 0, 0.05)'
  45. }}
  46. >
  47. {itemsElement}
  48. </div>
  49. )}
  50. controlHide={controlHide}
  51. >
  52. <div className='relative '>
  53. <div className='flex items-center h-9 px-3 gap-1 cursor-pointer hover:bg-gray-50'>
  54. <div className='text-sm text-gray-700'>{items.find(i => i.value === value)?.name}</div>
  55. <ChevronDownIcon width={16} height={16} />
  56. </div>
  57. {/* <div
  58. className='absolute z-50 left-0 top-9 p-1 w-[112px] rounded-lg bg-white'
  59. style={{
  60. boxShadow: '0px 10px 15px -3px rgba(0, 0, 0, 0.1), 0px 4px 6px rgba(0, 0, 0, 0.05)'
  61. }}
  62. >
  63. {itemsElement}
  64. </div> */}
  65. </div>
  66. </PortalToFollowElem>
  67. </div>
  68. )
  69. }
  70. export default React.memo(Select)