Mode Picker

Ask / Plan / Agent switch with customizable labels and a 36px phone touch target that returns to its compact desktop size at sm, built on the shadcn dropdown menu with a short description under each mode.

Open in

Selected mode: agent

Installation

npx shadcn@latest add miskibin/chat-components/mode-picker

Also installs dropdown-menu.

Usage

"use client"

import { useState } from "react"
import { ModePicker, type ChatMode } from "@/components/ui/mode-picker"

export function Picker() {
  const [mode, setMode] = useState<ChatMode>("agent")
  return <ModePicker value={mode} onChange={setMode} />
}

Examples

Use application-specific modes

Pass modes to describe what this host actually supports, without modifying the copied component. Localize label and triggerLabel alongside the rows.

Restyle the trigger, flip the side

className merges onto the trigger and side decides which way the menu opens — top for a composer, bottom for a navbar. All three below share one selection.

API reference

ModePicker

modesChatModeOption[] = CHAT_MODES
Mode labels, descriptions and optional icons for this host. IDs remain ask / plan / agent; permissions are enforced by the host.
labelstring = "Mode"
Menu heading and empty-selection placeholder.
triggerLabelstring = "Change mode"
Accessible label and hover title of the trigger.
valueChatMode
Controlled selection.
defaultValueChatMode = "agent"
Initial selection when uncontrolled.
onChange(mode: ChatMode) => void
Fired on pick.
side"top" | "bottom" = "top"
Which way the menu opens.
disabledboolean = false
Disables the trigger.

Data slots

Every part below is addressable from a parent, so you can restyle internals without forking the component.

mode-picker-triggermode-picker-contentmode-picker-item