Download frontend/src/components/ModelSelector.tsx from dmpantiu/Eurus: direct link, hf CLI and curl.
- Browser
- Download file 2.52 kB
-
https://huggingface.co/spaces/dmpantiu/Eurus/resolve/main/frontend/src/components/ModelSelector.tsx
- Command line
-
hf download hf://spaces/dmpantiu/Eurus/frontend/src/components/ModelSelector.tsx
-
curl -L -o ModelSelector.tsx https://huggingface.co/spaces/dmpantiu/Eurus/resolve/main/frontend/src/components/ModelSelector.tsx
2.52 kB
| import { useState, useEffect, useRef } from 'react'; | |
| import { ChevronDown } from 'lucide-react'; | |
| import './ModelSelector.css'; | |
| interface ModelOption { | |
| id: string; | |
| label: string; | |
| provider: string; | |
| } | |
| interface ModelSelectorProps { | |
| send: (payload: Record<string, unknown>) => void; | |
| } | |
| export default function ModelSelector({ send }: ModelSelectorProps) { | |
| const [current, setCurrent] = useState('gpt-5.4'); | |
| const [open, setOpen] = useState(false); | |
| const ref = useRef<HTMLDivElement>(null); | |
| const models: ModelOption[] = [ | |
| { id: 'gpt-5.4', label: 'GPT-5.4', provider: 'openai' }, | |
| { id: 'gpt-4.1', label: 'GPT-4.1', provider: 'openai' }, | |
| { id: 'o3', label: 'o3', provider: 'openai' }, | |
| { id: 'gemini-3.1-pro-preview', label: 'Gemini 3.1 Pro', provider: 'google' }, | |
| ]; | |
| // Close on click outside | |
| useEffect(() => { | |
| if (!open) return; | |
| const handleClick = (e: MouseEvent) => { | |
| if (ref.current && !ref.current.contains(e.target as Node)) { | |
| setOpen(false); | |
| } | |
| }; | |
| document.addEventListener('mousedown', handleClick); | |
| return () => document.removeEventListener('mousedown', handleClick); | |
| }, [open]); | |
| const handleSelect = (modelId: string) => { | |
| setCurrent(modelId); | |
| setOpen(false); | |
| send({ type: 'set_provider', model: modelId }); | |
| }; | |
| const currentLabel = models.find(m => m.id === current)?.label ?? current; | |
| return ( | |
| <div className="model-selector" ref={ref}> | |
| <button | |
| className="model-selector-btn" | |
| onClick={() => setOpen(v => !v)} | |
| title="Switch AI model" | |
| > | |
| <span className="model-label">{currentLabel}</span> | |
| <ChevronDown size={13} className={`chevron ${open ? 'open' : ''}`} /> | |
| </button> | |
| {open && ( | |
| <div className="model-dropdown"> | |
| {models.map(m => ( | |
| <button | |
| key={m.id} | |
| className={`model-option ${m.id === current ? 'active' : ''}`} | |
| onClick={() => handleSelect(m.id)} | |
| > | |
| <span>{m.label}</span> | |
| {m.id === current && <span className="check">✓</span>} | |
| </button> | |
| ))} | |
| </div> | |
| )} | |
| </div> | |
| ); | |
| } | |