Skip to content

Model Selector

The model selector is a Claude-style pill that sits in the composer actions and opens an upward popover of models, each showing a name, a short description, and a check on the active option. It is built to sit on top of the composer’s ghost control, overriding the pill radius and lightening hover with a squared radius and a darkening hover. It is themed through the global --ds-* tokens, and the chevron and check are inline SVGs.

cmp-chat-model-select is the relative anchor. The trigger reuses cmp-chat-composer__control--ghost; the __menu lists __option buttons, each with __option-text (__name + __desc) and a trailing __check.

<div class="cmp-chat-model-select">
<button
type="button"
class="cmp-chat-composer__control cmp-chat-composer__control--ghost cmp-chat-model-select__trigger"
aria-haspopup="listbox"
aria-expanded="true"
aria-label="Model: GPT-5.5"
title="Model"
>
<span class="cmp-chat-model-select__trigger-label">GPT-5.5</span>
<svg
class="cmp-chat-model-select__chevron"
width="14"
height="14"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2.5"
stroke-linecap="round"
stroke-linejoin="round"
aria-hidden="true"
>
<polyline points="6 9 12 15 18 9"></polyline>
</svg>
</button>
<div class="cmp-chat-model-select__menu" role="listbox">
<button
type="button"
class="cmp-chat-model-select__option cmp-chat-model-select__option--selected"
role="option"
aria-selected="true"
>
<span class="cmp-chat-model-select__option-text">
<span class="cmp-chat-model-select__name">GPT-5.5</span>
<span class="cmp-chat-model-select__desc">
Balanced general-purpose model.
</span>
</span>
<svg
class="cmp-chat-model-select__check"
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2.5"
stroke-linecap="round"
stroke-linejoin="round"
aria-hidden="true"
>
<polyline points="20 6 9 17 4 12"></polyline>
</svg>
</button>
<button
type="button"
class="cmp-chat-model-select__option"
role="option"
aria-selected="false"
>
<span class="cmp-chat-model-select__option-text">
<span class="cmp-chat-model-select__name">Claude Opus 4.8</span>
<span class="cmp-chat-model-select__desc">
Deeper reasoning for complex tasks.
</span>
</span>
</button>
</div>
</div>
ClassElementPurpose
cmp-chat-model-selectdivRelative anchor wrapping the trigger and menu.
cmp-chat-model-select__triggerbuttonPill trigger (layered on the composer ghost control).
cmp-chat-model-select__trigger-labelspanCurrent model label.
cmp-chat-model-select__chevronsvgDisclosure chevron.
cmp-chat-model-select__menudivUpward popover list of models.
cmp-chat-model-select__optionbuttonA selectable model row.
cmp-chat-model-select__option--selectedbuttonCurrent model row.
cmp-chat-model-select__option-textspanColumn holding the name and description.
cmp-chat-model-select__namespanModel name.
cmp-chat-model-select__descspanMuted model description.
cmp-chat-model-select__checksvgTrailing check on the selected option.
  • Give the menu role="listbox" and each option role="option" with aria-selected reflecting the current model.
  • Mark the chevron and check <svg> icons aria-hidden="true".
  • Manage focus and keyboard selection (arrow keys, Enter, Escape) in script.

Uses --ds-surface, --ds-fg, --ds-fg-muted, --ds-border, --ds-hover-bg, --ds-accent, and --ds-shadow. Under data-theme="dark" the check switches to the foreground color for better legibility.