<ModelSelector />

A cross-platform model picker for AI interfaces, with built-in provider logos, model labels, and compact trigger patterns for web and mobile.

<ModelSelector /> gives you a polished way to let users switch models without rebuilding the same provider-and-model UI every time. It wraps the lower-level select primitives in a shape that already feels right for AI products.

Web

The web version is built for compact dropdown usage in chat toolbars, composer controls, and settings surfaces. It keeps the trigger small and lets the selected model label carry most of the visual weight.

ModelSelector component demo

Mobile

The mobile version follows the same mental model, but it gives the trigger a little more visual context by including the provider or model logo directly inside the trigger. That makes model switching easier to scan in touch-first layouts.

ModelSelector component demo

Why it matters

Model choice is often one of the most important controls in an AI product, but it can also become visually messy very quickly. This component helps you present that choice in a way that feels intentional instead of improvised.

Designed for AI workflows

The component already understands provider logos, model names, and the kind of compact trigger most chat products need.

Reusable beyond the dropdown

The logo and name helpers are useful on their own in places like usage panels, model badges, and message metadata.

Consistent across surfaces

Whether the selector appears in a composer, a settings area, or a context panel, it keeps the visual language of model choice consistent.

Building blocks

<ModelSelector /> is best thought of as a small family of parts rather than one monolithic control. You can use the default composition, or pull out the logo and name helpers when you need them elsewhere.

The exported parts are:

  • <ModelSelector />
  • <ModelSelectorTrigger />
  • <ModelSelectorContent />
  • <ModelSelectorItem />
  • <ModelSelectorLogo />
  • <ModelSelectorName />

Basic usage

The usual pattern is a root selector with a trigger and a list of items. The exact select state wiring depends on your app, but the visual composition is the same across platforms.

import {
  ModelSelector,
  ModelSelectorContent,
  ModelSelectorItem,
  ModelSelectorTrigger,
} from "@workspace/ui-web/ai-elements/model-selector";

export function ChatModelSelector() {
  return (
    <ModelSelector value="gpt-4.1-mini">
      <ModelSelectorTrigger />
      <ModelSelectorContent>
        <ModelSelectorItem value="gpt-4.1-mini">GPT-4.1 Mini</ModelSelectorItem>
        <ModelSelectorItem value="claude-4-sonnet">
          Claude 4 Sonnet
        </ModelSelectorItem>
        <ModelSelectorItem value="gemini-2.5-flash">
          Gemini 2.5 Flash
        </ModelSelectorItem>
      </ModelSelectorContent>
    </ModelSelector>
  );
}

Logo and name helpers

One of the most useful details in this component family is that the branding logic is reusable. You do not need to duplicate provider-logo matching in other parts of the interface.

import {
  ModelSelectorLogo,
  ModelSelectorName,
} from "@workspace/ui-web/ai-elements/model-selector";

export function ModelMeta() {
  return (
    <div className="flex items-center gap-2">
      <ModelSelectorLogo provider="anthropic" model="claude-4-sonnet" />
      <ModelSelectorName>Claude 4 Sonnet</ModelSelectorName>
    </div>
  );
}

The helpers first try to match model-specific icons for names like claude, gemini, grok, or nano-banana. If no model-specific icon matches, they fall back to the provider icon, and then finally to an external logo from models.dev.

Platform differences

The two versions stay close in spirit, but there are a few differences worth knowing when you design around them.

AreaWebMobile
TriggerCompact text-first triggerTrigger includes logo by default
Logo fallbackimg fallback from models.devexpo-image fallback from models.dev
Name helperspan-based text helpernative Text-based helper
Visual feeltighter desktop toolbar fiteasier scanning in touch layouts

What to customize

Most customization happens through composition and styling rather than through a long prop list. In practice, the main knobs are:

  • the selected value and state wiring from the underlying select primitive
  • className on trigger, item, logo, or name helpers
  • the provider and model values used to resolve the right logo
  • size on the mobile logo helper when you need a larger or smaller icon

That makes the component easy to adapt without turning it into a configuration-heavy abstraction.

<ModelSelector /> tends to live near other model-aware pieces of the UI. These are the most natural companion pages in this docs set.

How is this guide?

Last updated on

On this page

Make AI your edge, not replacement.Get TurboStarter AI