method-selector.tsx 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. import type { FC } from 'react'
  2. import { useState } from 'react'
  3. import { useTranslation } from 'react-i18next'
  4. import { RiArrowDownSLine } from '@remixicon/react'
  5. import cn from '@/utils/classnames'
  6. import {
  7. PortalToFollowElem,
  8. PortalToFollowElemContent,
  9. PortalToFollowElemTrigger,
  10. } from '@/app/components/base/portal-to-follow-elem'
  11. import { Check } from '@/app/components/base/icons/src/vender/line/general'
  12. type MethodSelectorProps = {
  13. value?: string
  14. onChange: (v: string) => void
  15. }
  16. const MethodSelector: FC<MethodSelectorProps> = ({
  17. value,
  18. onChange,
  19. }) => {
  20. const { t } = useTranslation()
  21. const [open, setOpen] = useState(false)
  22. return (
  23. <PortalToFollowElem
  24. open={open}
  25. onOpenChange={setOpen}
  26. placement='bottom-start'
  27. offset={4}
  28. >
  29. <div className='relative'>
  30. <PortalToFollowElemTrigger
  31. onClick={() => setOpen(v => !v)}
  32. className='block'
  33. >
  34. <div className={cn(
  35. 'flex items-center gap-1 min-h-[56px] px-3 py-2 h-9 bg-white cursor-pointer hover:bg-gray-100',
  36. open && '!bg-gray-100 hover:bg-gray-100',
  37. )}>
  38. <div className={cn('grow text-[13px] leading-[18px] text-gray-700 truncate')}>
  39. {value === 'llm' ? t('tools.createTool.toolInput.methodParameter') : t('tools.createTool.toolInput.methodSetting')}
  40. </div>
  41. <div className='shrink-0 ml-1 text-gray-700 opacity-60'>
  42. <RiArrowDownSLine className='h-4 w-4' />
  43. </div>
  44. </div>
  45. </PortalToFollowElemTrigger>
  46. <PortalToFollowElemContent className='z-[1040]'>
  47. <div className='relative w-[320px] bg-white rounded-lg border-[0.5px] border-gray-200 shadow-lg'>
  48. <div className='p-1'>
  49. <div className='pl-3 pr-2 py-2.5 rounded-lg hover:bg-gray-50 cursor-pointer' onClick={() => onChange('llm')}>
  50. <div className='flex item-center gap-1'>
  51. <div className='shrink-0 w-4 h-4'>
  52. {value === 'llm' && <Check className='shrink-0 w-4 h-4 text-primary-600' />}
  53. </div>
  54. <div className='text-[13px] text-gray-700 font-medium leading-[18px]'>{t('tools.createTool.toolInput.methodParameter')}</div>
  55. </div>
  56. <div className='pl-5 text-gray-500 text-[13px] leading-[18px]'>{t('tools.createTool.toolInput.methodParameterTip')}</div>
  57. </div>
  58. <div className='pl-3 pr-2 py-2.5 rounded-lg hover:bg-gray-50 cursor-pointer' onClick={() => onChange('form')}>
  59. <div className='flex item-center gap-1'>
  60. <div className='shrink-0 w-4 h-4'>
  61. {value === 'form' && <Check className='shrink-0 w-4 h-4 text-primary-600' />}
  62. </div>
  63. <div className='text-[13px] text-gray-700 font-medium leading-[18px]'>{t('tools.createTool.toolInput.methodSetting')}</div>
  64. </div>
  65. <div className='pl-5 text-gray-500 text-[13px] leading-[18px]'>{t('tools.createTool.toolInput.methodSettingTip')}</div>
  66. </div>
  67. </div>
  68. </div>
  69. </PortalToFollowElemContent>
  70. </div>
  71. </PortalToFollowElem>
  72. )
  73. }
  74. export default MethodSelector