Locara
← All components AI affordances

ModelSelector

Cursor-style model picker with optional download flow per row, capability badges, provider tags, RAM-based disabling.

Inspired by Cursor model picker, t3.chat multi-provider dropdown, OpenRouter.

Preview

What it looks like.

Cursor-style model picker. Models with status: 'needs-download' get a download button (click one to see the simulated progress).

Live — the real component, scoped to this frame.

Usage

Drop it into your app.

import { ModelSelector } from '@locara/components'

<ModelSelector
  value={modelId}
  onChange={setModelId}
  onDownload={(id) => models.download(id)}
  options={[
    { id: 'qwen2.5-7b', label: 'Qwen 2.5 7B', hint: '4.9 GB · Q4_K_M', provider: 'Local',
      badges: ['fast'], status: 'ready' },
    { id: 'llama-3-8b', label: 'Llama 3 8B', hint: '4.9 GB · Q4_K_M', provider: 'Local',
      status: 'ready' },
    { id: 'llama-3-70b', label: 'Llama 3 70B', hint: '42.8 GB · Q4_K_M', provider: 'Local',
      badges: ['heavy'], status: 'needs-download', sizeLabel: '42.8 GB' },
    { id: 'llama-3-405b', label: 'Llama 3.1 405B', hint: '248 GB · Q4_K_M',
      disabled: true, disabledReason: 'Needs 256 GB+ Mac Studio' },
  ]}
/>

Or copy the source into your repo: locara add model-selector

Design notes

Why it works this way.

Per-row download is the differentiator vs a generic dropdown. The consumer owns the actual download lifecycle: on click, you call into your SDK, then update the option's `status` to `'downloading'` and stream `progress` (0..1). Once verification finishes, flip to `'ready'`. Rows marked `disabled` with a `disabledReason` are visible but un-selectable — useful for surfacing 'this model needs more RAM than you have' instead of silently hiding it.

Props

The API surface.

NameTypeDescription
options required ModelOption[] The available models, with status and metadata.
value required string Currently selected model id.
onChange required (id: string) => void Called when the user picks a model.
onDownload (id: string) => void Wired to your model-download SDK; enables the per-row Download button.
size 'sm' | 'md' Trigger height. Default md.
prefix string Label prefix on the trigger. Default "Model".