About
AI model selector dropdown for React chat apps. A Radix menu that scales out of its trigger and glides the selection pill to the model you pick.
Built with React and Tailwind. Copy the prompt and paste it into Claude Code, Cursor or Lovable: your agent adds Model Context Switcher to your project and fits it to your theme.
Code
How Model Context Switcher is used: the demo's code. The component's own source comes with a free account.
Usage.tsx
"use client";
import * as React from "react";
import { DEFAULT_OPTIONS, ModelContextSwitcher, type ModelOption } from "@/components/ui/model-context-switcher";
const settings = {
showMenu: true,
compactTrigger: false,
showDescriptions: true,
triggerLabel: "Model",
};
const descriptions: Record<string, string> = {
fast: "Quick everyday answers",
thinking: "Reason through tough questions",
creative: "Explore new ideas",
research: "Read longer context",
};
const modelOptions: ModelOption[] = DEFAULT_OPTIONS.map((option) => ({
...option,
description: descriptions[option.id] ?? option.description,
}));
export default function Demo(props: Partial<typeof settings>) {
const s = { ...settings, ...props };
const [selected, setSelected] = React.useState("thinking");
const options = s.showDescriptions
? modelOptions
: modelOptions.map(({ description: _description, ...option }) => option);
const active = modelOptions.find((option) => option.id === selected);
return (
<div className="flex min-h-[450px] w-full items-start justify-center bg-background px-6 pt-20 text-foreground">
<div className="min-h-[360px] w-full max-w-2xl rounded-3xl border border-border bg-card p-6 shadow-sm sm:p-8">
<div className="mb-8 flex flex-wrap items-start justify-between gap-4">
<div className="max-w-[250px]">
<p className="mb-2 text-xs font-semibold uppercase tracking-[0.18em] text-muted-foreground">AI workspace</p>
<h2 className="text-2xl font-semibold tracking-tight">Choose how to think</h2>
<p className="mt-2 max-w-xs text-sm text-muted-foreground">Switch models without leaving the conversation.</p>
</div>
<ModelContextSwitcher
key={String(s.showMenu)}
options={options}
value={selected}
onChange={setSelected}
defaultOpen={s.showMenu}
size={s.compactTrigger ? "sm" : "md"}
triggerLabel={s.triggerLabel}
/>
</div>
<div className="mt-48 flex items-center gap-2 border-t border-border pt-4 text-xs text-muted-foreground">
<span className="inline-flex size-2 rounded-full bg-emerald-500" aria-hidden="true" />
{active?.label} is selected
</div>
</div>
</div>
);
}
















