# Model Picker

> Model pickers grouped by provider with monogram marks — a searchable popover with keyboard selection, or a provider rail beside selectable model cards — with springy indicators and blurred crossfades.

- Collection: AI Agents
- Tier: pro
- Docs: https://geturui.com/docs/model-picker
- Install: `npx shadcn@latest add @geturui-pro/model-picker`
- Dependencies: motion, lucide-react

## Variants

### Provider catalog

Searchable popover grouped by provider, with badges, match highlighting and the search field pinned to the bottom.

Install: `npx shadcn@latest add @geturui-pro/model-picker-provider-catalog`

```tsx
import { ProviderCatalogPicker } from "@/components/ai/model-picker/provider-catalog";

export function ModelSwitch() {
  const [model, setModel] = React.useState("atlas-3");
  return (
    <ProviderCatalogPicker
      value={model}
      onValueChange={setModel}
      providers={[{ id: "northwind", name: "Northwind Labs", monogram: "Nw", tone: "volt" }]}
      models={[{ id: "atlas-3", providerId: "northwind", name: "Atlas 3", context: "200K", badges: ["reasoning"] }]}
    />
  );
}
```

| Prop | Type | Default | Description |
|---|---|---|---|
| providers | `CatalogProvider[]` | CATALOG_PROVIDERS | Groups in order: { id, name, monogram, tone? }. |
| models | `CatalogModel[]` | CATALOG_MODELS | { id, providerId, name, description?, context?, badges? }. |
| value / defaultValue | `string` | — | Controlled or initial model id. |
| onValueChange | `(id: string) => void` | — | Called when a model is picked. |
| side | `"top" | "bottom"` | "top" | Open above the trigger (search next to it) or below. |
| align | `"start" | "end"` | "start" | Horizontal alignment of the popover. |
| searchPlaceholder | `string` | "Search models or providers" | Placeholder of the pinned search field. |
| disabled | `boolean` | — | Disables the trigger. |

### Provider rail

Provider rail on the left with a sliding indicator; that provider's models as selectable cards with speed and depth meters on the right.

Install: `npx shadcn@latest add @geturui-pro/model-picker-provider-rail`

```tsx
import { ProviderRailPicker } from "@/components/ai/model-picker/provider-rail";

export function DefaultModelSetting() {
  return <ProviderRailPicker defaultValue="atlas-3" onConfirm={(id) => saveDefaultModel(id)} />;
}
```

| Prop | Type | Default | Description |
|---|---|---|---|
| providers | `RailProvider[]` | RAIL_PROVIDERS | { id, name, monogram, tone?, tagline? }. |
| models | `RailModel[]` | RAIL_MODELS | { id, providerId, name, description?, context?, speed?, intelligence?, price?, isNew? }. |
| value / defaultValue | `string` | — | Controlled or initial model id. |
| onValueChange | `(id: string) => void` | — | Called when a model card is selected. |
| onConfirm | `(id: string) => void` | — | Shows a Use model button in the footer. |

## Accessibility

- Catalog: the search field is a combobox that drives aria-activedescendant on a grouped listbox; arrows move, Enter picks, Escape clears then closes and restores focus.
- Rail: providers are a vertical tablist with roving focus; models are a radiogroup where arrow keys move the selection.
- Provider monograms are decorative; names, context sizes and meters are exposed as text.

## Source

Pro item — send `Authorization: Bearer <registry token>` to include the source.
