ModelSelector.tsx (2446B)
1 import { getModelColor } from "../lib/colors"; 2 3 interface ModelSelectorProps { 4 allModels: string[]; 5 selectedModels: Set<string>; 6 onChange: (models: Set<string>) => void; 7 } 8 9 export default function ModelSelector({ 10 allModels, 11 selectedModels, 12 onChange, 13 }: ModelSelectorProps) { 14 const allSelected = allModels.length > 0 && allModels.every((m) => selectedModels.has(m)); 15 const noneSelected = allModels.length > 0 && allModels.every((m) => !selectedModels.has(m)); 16 17 const toggleModel = (model: string) => { 18 const next = new Set(selectedModels); 19 if (next.has(model)) { 20 next.delete(model); 21 } else { 22 next.add(model); 23 } 24 onChange(next); 25 }; 26 27 const toggleAll = () => { 28 if (allSelected) { 29 onChange(new Set()); 30 } else { 31 onChange(new Set(allModels)); 32 } 33 }; 34 35 return ( 36 <div 37 style={{ 38 display: "flex", 39 gap: "8px", 40 justifyContent: "center", 41 flexWrap: "wrap", 42 }} 43 > 44 <button 45 onClick={toggleAll} 46 style={{ 47 padding: "4px 10px", 48 borderRadius: "0", 49 border: `1px solid var(--border, hsl(217 17% 28%))`, 50 background: allSelected 51 ? "rgba(255, 255, 255, 0.08)" 52 : "transparent", 53 color: allSelected 54 ? "var(--text-primary, hsl(213 14% 80%))" 55 : "var(--text-muted, hsl(213 14% 55%))", 56 opacity: noneSelected ? 0.4 : 1, 57 cursor: "pointer", 58 fontSize: "0.75rem", 59 fontFamily: "var(--font-mono, 'JetBrains Mono', monospace)", 60 }} 61 > 62 {allSelected ? "None" : "All"} 63 </button> 64 {allModels.map((model) => { 65 const color = getModelColor(model); 66 const active = selectedModels.has(model); 67 return ( 68 <button 69 key={model} 70 onClick={() => toggleModel(model)} 71 style={{ 72 padding: "4px 10px", 73 borderRadius: "0", 74 border: `1px solid ${color}`, 75 background: active ? `${color}22` : "transparent", 76 color: active ? color : "var(--text-muted, hsl(213 14% 55%))", 77 opacity: active ? 1 : 0.4, 78 cursor: "pointer", 79 fontSize: "0.75rem", 80 fontFamily: "var(--font-mono, 'JetBrains Mono', monospace)", 81 }} 82 > 83 {model} 84 </button> 85 ); 86 })} 87 </div> 88 ); 89 }