AI Input

Chat-style AI composer with agent and model chips and an Apple Intelligence-style gradient wave on send.

Installation

npx shadcn@latest add @iconiq/ai-input

File Structure

Usage

"use client";

import { Archive, Camera, LayoutGrid, Paperclip, Plug } from "lucide-react";

import {
  AIInput,
  type AIInputMenuItem,
  type PromptSettingGroup,
} from "@/components/ui/ai-input";

// Featured row for the selected model, submenu for effort level.
const settingGroups: PromptSettingGroup[] = [
  {
    id: "model",
    label: "Model",
    display: "featured",
    options: [
      { value: "claude-5", label: "Claude 5", description: "Most capable" },
      { value: "claude-5-fast", label: "Claude 5 Fast", description: "Faster" },
    ],
  },
  {
    id: "effort",
    label: "Effort",
    display: "submenu",
    options: [
      { value: "high", label: "High" },
      { value: "medium", label: "Medium" },
      { value: "low", label: "Low" },
    ],
  },
];

// Use `shortcut` to show a keyboard hint. Pass `items` for a one-level submenu.
const menuItems: AIInputMenuItem[] = [
  { value: "add-files", label: "Add files or photos", icon: Paperclip, shortcut: "⌘U" },
  { value: "screenshot", label: "Take a screenshot", icon: Camera },
  {
    value: "add-to-project",
    label: "Add to project",
    icon: Archive,
    items: [
      { value: "new-project", label: "New project" },
      { value: "existing-project", label: "Existing project" },
    ],
  },
  { value: "sep-1", type: "separator" },
  {
    value: "skills",
    label: "Skills",
    icon: LayoutGrid,
    items: [
      { value: "skill-creator", label: "skill-creator" },
      { value: "manage-skills", label: "Manage skills" },
      { value: "browse-skills", label: "Browse skills" },
    ],
  },
  { value: "add-connector", label: "Add connector", icon: Plug },
];

export function AIInputPreview() {
  return (
    <div className="mx-auto w-full max-w-2xl px-4 py-10">
      <AIInput
        menuItems={menuItems}
        settingGroups={settingGroups}
        onMenuSelect={(value) => console.log("menu:", value)}
        onSettingsChange={(settings) => console.log("settings:", settings)}
        onSend={(message, meta) => console.log(message, meta)}
        placeholder="Ask for follow-up changes"
      />
    </div>
  );
}

Props

Props
Description

AIInput

agents

Options for the agent chip on the left of the footer. Each option has `value` and `label`. Omit to hide the chip.

Type AIInputOption[]

defaultAgent

Initially selected agent value. Falls back to the first agent option.

Type string

models

Options for the model chip on the right of the footer. Omit to hide the chip.

Type AIInputOption[]

defaultModel

Initially selected model value. Falls back to the first model option.

Type string

menuItems

Items for the plus menu. Each item has `value`, `label`, and optional `icon`. Set `type` to `"toggle"` for a switch row (with optional `defaultChecked`) or `"separator"` for a divider. Action items accept a per-item `onClick` and toggles a per-item `onCheckedChange`, firing alongside the component-level callbacks. Pass nested `items` to turn an action into a one-level submenu with a slide transition and back button. Omit to make the plus button a plain attachment button.

Type AIInputMenuItem[]

placeholder

Placeholder copy for the textarea.

Type string·Default "Ask for follow-up changes"

showMessages

Render sent messages as right-aligned chat bubbles above the composer. Disable when you render your own thread.

Type boolean·Default true

onSend

Called with the trimmed message and the current agent and model picks when the user presses Enter or clicks send.

Type (message: string, meta: { agent: string; model: string }) => void

onMicClick

Called when the microphone button is clicked.

Type () => void

onPlusClick

Called when the plus button is clicked and no `menuItems` are provided.

Type () => void

onMenuSelect

Called with the item's `value` when an action item — top-level or inside a submenu — is selected in the plus menu.

Type (value: string) => void

onMenuToggle

Called when a toggle item in the plus menu is switched on or off.

Type (value: string, checked: boolean) => void

onAgentChange

Called with the new agent value when the agent chip selection changes.

Type (value: string) => void

onModelChange

Called with the new model value when the model chip selection changes.

Type (value: string) => void

className

Extra classes for the outer wrapper.

Type string

Registry bundle

Install the exact registry entry shown on the right when you want the component file and its declared runtime dependencies together.

Dependencies: motion, lucide-react.

Contact

Additionally, if you find any bug or issue, feel free to raise an issue.