Components / AI Chat Interfaces
AI Model Selector
A dropdown model selector for choosing between AI models (GPT-4, Claude, Gemini) with model info badges and capability indicators.
Components / AI Chat Interfaces
A dropdown model selector for choosing between AI models (GPT-4, Claude, Gemini) with model info badges and capability indicators.
"use client";
import React, { useState } from "react";
import { ChevronDown, Sparkles, Zap, Brain, Check } from "lucide-react";
interface AIModel {
id: string;
name: string;
provider: string;
description: string;
icon: React.ReactNode;
badge?: string;
}
const models: AIModel[] = [
{ id: "gpt-4", name: "GPT-4o", provider: "OpenAI", description: "Most capable model", icon: <Sparkles className="h-4 w-4" />, badge: "Popular" },
{ id: "claude-3", name: "Claude 3.5", provider: "Anthropic", description: "Best for analysis", icon: <Brain className="h-4 w-4" /> },
{ id: "gemini-pro", name: "Gemini Pro", provider: "Google", description: "Fast & efficient", icon: <Zap className="h-4 w-4" />, badge: "Fast" },
];
export default function AIModelSelector() {
const [selected, setSelected] = useState(models[0]);
const [open, setOpen] = useState(false);
return (
<div className="relative w-72">
<button
onClick={() => setOpen(!open)}
className="w-full flex items-center justify-between rounded-lg border border-zinc-200 dark:border-zinc-700 bg-white dark:bg-zinc-900 px-3 py-2.5 text-sm hover:bg-zinc-50 dark:hover:bg-zinc-800 transition-colors"
>
<div className="flex items-center gap-2">
<div className="text-violet-500">{selected.icon}</div>
<div className="text-left">
<p className="font-medium text-zinc-900 dark:text-zinc-100">{selected.name}</p>
<p className="text-xs text-zinc-500">{selected.provider}</p>
</div>
</div>
<ChevronDown className={`h-4 w-4 text-zinc-400 transition-transform ${open ? "rotate-180" : ""}`} />
</button>
{open && (
<div className="absolute top-full left-0 right-0 mt-1 rounded-lg border border-zinc-200 dark:border-zinc-700 bg-white dark:bg-zinc-900 shadow-lg z-10 overflow-hidden">
{models.map((model) => (
<button
key={model.id}
onClick={() => { setSelected(model); setOpen(false); }}
className="w-full flex items-center justify-between px-3 py-2.5 hover:bg-zinc-50 dark:hover:bg-zinc-800 transition-colors"
>
<div className="flex items-center gap-2">
<div className="text-violet-500">{model.icon}</div>
<div className="text-left">
<div className="flex items-center gap-1.5">
<p className="text-sm font-medium text-zinc-900 dark:text-zinc-100">{model.name}</p>
{model.badge && (
<span className="text-[10px] px-1.5 py-0.5 rounded-full bg-violet-100 dark:bg-violet-900/30 text-violet-600 dark:text-violet-400 font-medium">
{model.badge}
</span>
)}
</div>
<p className="text-xs text-zinc-500">{model.description}</p>
</div>
</div>
{selected.id === model.id && <Check className="h-4 w-4 text-violet-500" />}
</button>
))}
</div>
)}
</div>
);
}react lucide-react npm install react lucide-react