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