FrameworkSelector.tsx 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. import { Box, Check, ChevronDown } from 'lucide-react'
  2. import { useState } from 'react'
  3. import {
  4. Button,
  5. cn,
  6. Command,
  7. CommandEmpty,
  8. CommandGroup,
  9. CommandInput,
  10. CommandItem,
  11. CommandList,
  12. Popover,
  13. PopoverContent,
  14. PopoverTrigger,
  15. } from 'ui'
  16. import { ConnectionType } from '@/components/interfaces/ConnectSheet/Connect.constants'
  17. import { ConnectionIcon } from '@/components/interfaces/ConnectSheet/ConnectionIcon'
  18. interface FrameworkSelectorProps {
  19. value: string
  20. onChange: (value: string) => void
  21. items: ConnectionType[]
  22. className?: string
  23. size?: 'tiny' | 'small'
  24. }
  25. export const FrameworkSelector = ({
  26. value,
  27. onChange,
  28. items,
  29. className,
  30. size = 'tiny',
  31. }: FrameworkSelectorProps) => {
  32. const [open, setOpen] = useState(false)
  33. const selectedItem = items.find((item) => item.key === value)
  34. function handleSelect(key: string) {
  35. onChange(key)
  36. setOpen(false)
  37. }
  38. return (
  39. <Popover open={open} onOpenChange={setOpen} modal={false}>
  40. <div className={cn('flex', className)}>
  41. <PopoverTrigger asChild>
  42. <Button
  43. size={size}
  44. type="default"
  45. className={cn('gap-0 justify-between', className?.includes('w-full') && 'w-full')}
  46. iconRight={<ChevronDown strokeWidth={1.5} />}
  47. >
  48. <div className="flex items-center gap-2">
  49. {selectedItem?.icon ? <ConnectionIcon icon={selectedItem.icon} /> : <Box size={12} />}
  50. {selectedItem?.label}
  51. </div>
  52. </Button>
  53. </PopoverTrigger>
  54. </div>
  55. <PopoverContent
  56. className="p-0 w-radix-popover-trigger-width min-w-48"
  57. side="bottom"
  58. align="start"
  59. onOpenAutoFocus={(e) => e.preventDefault()}
  60. >
  61. <Command>
  62. <CommandInput placeholder="Search..." />
  63. <CommandList>
  64. <CommandEmpty>No results found.</CommandEmpty>
  65. <CommandGroup>
  66. {items.map((item) => (
  67. <CommandItem
  68. key={item.key}
  69. value={item.key}
  70. onSelect={() => handleSelect(item.key)}
  71. className="flex gap-2 items-center"
  72. >
  73. {item.icon ? <ConnectionIcon icon={item.icon} /> : <Box size={12} />}
  74. {item.label}
  75. <Check
  76. size={15}
  77. className={cn('ml-auto', item.key === value ? 'opacity-100' : 'opacity-0')}
  78. />
  79. </CommandItem>
  80. ))}
  81. </CommandGroup>
  82. </CommandList>
  83. </Command>
  84. </PopoverContent>
  85. </Popover>
  86. )
  87. }