Sunflower UI
Search
Copy Code
Light Mode
dropdown-menu-demo.tsx
dropdown-menu.tsx
Collapse
Reset
Copy Code
Download
Run
1
"use client"
2
3
import * as React from "react"
4
import { ChevronDown, Sun, Hexagon, Sparkles, Globe, BrainCircuit, Box, Command, Zap, Image, Video, PenTool } from "lucide-react"
5
6
import {
7
DropdownMenu,
8
DropdownMenuCheckboxItem,
9
DropdownMenuContent,
10
DropdownMenuPortal,
11
DropdownMenuSub,
12
DropdownMenuSubContent,
13
DropdownMenuSubTrigger,
14
DropdownMenuTrigger,
15
} from "@/components/ui/dropdown-menu"
16
17
type ModelType = {
18
id: string
19
name: string
20
icon: React.ElementType
21
colorClass: string
22
}
23
24
const mainModels: ModelType[] = [
25
{ id: "claude", name: "Claude Opus 5.5", icon: Sun, colorClass: "text-[#D97757]" },
26
{ id: "gpt6", name: "GPT 6 Astra", icon: Hexagon, colorClass: "text-zinc-500" },
27
{ id: "gemini", name: "Gemini 3.0 Flash", icon: Sparkles, colorClass: "text-[#8E8DFA]" },
28
{ id: "deepseek", name: "DeepSeek V4.1", icon: Globe, colorClass: "text-[#4D6BFE]" },
29
]
30
31
const openWeightModels: ModelType[] = [
32
{ id: "llama", name: "Llama 4 Maverick", icon: BrainCircuit, colorClass: "text-[#2563EB]" },
33
{ id: "qwen", name: "Qwen3 Max", icon: Box, colorClass: "text-[#7C3AED]" },
34
{ id: "kimi", name: "Kimi K3", icon: Command, colorClass: "text-zinc-500" },
35
{ id: "mistral", name: "Mistral Large 3", icon: Zap, colorClass: "text-[#EA580C]" },
36
]
37
38
const mediaModels: ModelType[] = [
39
{ id: "gptimg", name: "GPT Image 2.5", icon: Image, colorClass: "text-zinc-500" },
40
{ id: "geminiimg", name: "Gemini 3 Pro Image", icon: PenTool, colorClass: "text-[#8E8DFA]" },
41
{ id: "veo", name: "Veo 3.1", icon: Video, colorClass: "text-[#3B82F6]" },
42
]
43
44
const allModels = [...mainModels, ...openWeightModels, ...mediaModels]
45
46
export default function DropdownMenuDemo() {
47
const [selectedIds, setSelectedIds] = React.useState<string[]>([])
48
49
const toggleModel = (id: string) => {
50
setSelectedIds((prev) =>
51
prev.includes(id) ? prev.filter((i) => i !== id) : [...prev, id]
52
)
53
}
54
55
const selectedModelsList = selectedIds.map(id => allModels.find(m => m.id === id)!)
56
57
return (
58
<div className="w-full min-h-[400px] flex items-center justify-center p-8">
59
<DropdownMenu>
60
<DropdownMenuTrigger asChild>
61
<button className="inline-flex h-8 items-center justify-center rounded-full border border-black/10 bg-transparent px-3 text-[13px] font-medium transition-colors hover:bg-black/5 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-zinc-950 dark:border-white/10 dark:text-zinc-50 dark:hover:bg-white/5 dark:focus-visible:ring-white/20">
62
{selectedIds.length === 0 ? (
63
<span className="px-1">No models</span>
64
) : (
65
<div className="flex items-center gap-2">
66
<div className="flex -space-x-1">
67
{selectedModelsList.slice(0, 4).map((model, i) => {
68
const Icon = model.icon
69
return (
70
<div
71
key={model.id}
72
className="flex h-[18px] w-[18px] items-center justify-center rounded-full border border-white bg-zinc-100 dark:border-[#111111] dark:bg-zinc-800 relative z-[1]"
73
style={{ zIndex: 4 - i }}
74
>
75
<Icon className={`h-2.5 w-2.5 ${model.colorClass}`} />
76
</div>
77
)
78
})}
79
</div>
80
<span>{selectedIds.length} models</span>
81
</div>
82
)}
83
<ChevronDown className="ml-1 h-3.5 w-3.5 opacity-50" />
84
</button>
85
</DropdownMenuTrigger>
86
<DropdownMenuContent className="w-64" align="center">
87
{mainModels.map((model) => {
88
const Icon = model.icon
89
return (
90
<DropdownMenuCheckboxItem
91
key={model.id}
92
checked={selectedIds.includes(model.id)}
93
onCheckedChange={() => toggleModel(model.id)}
94
onSelect={(e) => e.preventDefault()}
95
>
96
<Icon className={`mr-2 h-4 w-4 ${model.colorClass}`} />
97
{model.name}
98
</DropdownMenuCheckboxItem>
99
)
100
})}
101
102
<DropdownMenuSub>
103
<DropdownMenuSubTrigger>
104
Open weights
105
</DropdownMenuSubTrigger>
106
<DropdownMenuPortal>
107
<DropdownMenuSubContent className="w-56">
108
{openWeightModels.map((model) => {
109
const Icon = model.icon
110
return (
111
<DropdownMenuCheckboxItem
112
key={model.id}
113
checked={selectedIds.includes(model.id)}
114
onCheckedChange={() => toggleModel(model.id)}
115
onSelect={(e) => e.preventDefault()}
116
>
117
<Icon className={`mr-2 h-4 w-4 ${model.colorClass}`} />
118
{model.name}
119
</DropdownMenuCheckboxItem>
120
)
121
})}
122
</DropdownMenuSubContent>
123
</DropdownMenuPortal>
124
</DropdownMenuSub>
125
126
<DropdownMenuSub>
127
<DropdownMenuSubTrigger>
128
Media
129
</DropdownMenuSubTrigger>
130
<DropdownMenuPortal>
131
<DropdownMenuSubContent className="w-56">
132
{mediaModels.map((model) => {
133
const Icon = model.icon
134
return (
135
<DropdownMenuCheckboxItem
136
key={model.id}
137
checked={selectedIds.includes(model.id)}
138
onCheckedChange={() => toggleModel(model.id)}
139
onSelect={(e) => e.preventDefault()}
140
>
141
<Icon className={`mr-2 h-4 w-4 ${model.colorClass}`} />
142
{model.name}
143
</DropdownMenuCheckboxItem>
144
)
145
})}
146
</DropdownMenuSubContent>
147
</DropdownMenuPortal>
148
</DropdownMenuSub>
149
150
</DropdownMenuContent>
151
</DropdownMenu>
152
</div>
153
)
154
}