ConnectDropdown.tsx113 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 './Connect.constants'
18import { ConnectionIcon } from './ConnectionIcon'
19
20interface ConnectDropdownProps {
21 state: string
22 updateState: (state: string) => void
23 label: string
24 items: ConnectionType[]
25 iconFolder?: string
26 supportsDarkMode?: boolean
27}
28
29export const ConnectDropdown = ({
30 state,
31 updateState,
32 label,
33
34 items,
35 iconFolder,
36 supportsDarkMode,
37}: ConnectDropdownProps) => {
38 const [open, setOpen] = useState(false)
39
40 function onSelectLib(key: string) {
41 updateState(key)
42 setOpen(false)
43 }
44
45 const selectedItem = items.find((item) => item.key === state)
46
47 return (
48 <Popover open={open} onOpenChange={setOpen} modal={false}>
49 <div className="flex ">
50 <span className="flex items-center text-foreground-lighter px-3 rounded-lg rounded-r-none text-xs border border-button border-r-0">
51 {label}
52 </span>
53 <PopoverTrigger asChild>
54 <Button
55 size="small"
56 type="default"
57 className="gap-0 rounded-l-none"
58 iconRight={<ChevronDown strokeWidth={1.5} />}
59 >
60 <div className="flex items-center gap-2">
61 {selectedItem?.icon ? (
62 <ConnectionIcon
63 icon={selectedItem.icon}
64 iconFolder={iconFolder}
65 supportsDarkMode={supportsDarkMode}
66 />
67 ) : (
68 <Box size={12} />
69 )}
70 {selectedItem?.label}
71 </div>
72 </Button>
73 </PopoverTrigger>
74 </div>
75 <PopoverContent className="p-0 max-w-48" side="bottom" align="start">
76 <Command>
77 <CommandInput placeholder="Search..." />
78 <CommandList>
79 <CommandEmpty>No results found.</CommandEmpty>
80 <CommandGroup>
81 {items.map((item) => (
82 <CommandItem
83 key={item.key}
84 value={item.key}
85 onSelect={() => {
86 onSelectLib(item.key)
87 setOpen(false)
88 }}
89 className="flex gap-2 items-center"
90 >
91 {item.icon ? (
92 <ConnectionIcon
93 icon={item.icon}
94 iconFolder={iconFolder}
95 supportsDarkMode={supportsDarkMode}
96 />
97 ) : (
98 <Box size={12} />
99 )}
100 {item.label}
101 <Check
102 size={15}
103 className={cn('ml-auto ', item.key === state ? 'opacity-100' : 'opacity-0')}
104 />
105 </CommandItem>
106 ))}
107 </CommandGroup>
108 </CommandList>
109 </Command>
110 </PopoverContent>
111 </Popover>
112 )
113}