Spotlight chatPro
A command bar that answers: one line that grows into suggested actions as you type, then into an answer panel that follows the reply as it streams.
On this page
Installation
Usage
import { SpotlightChat } from "@/components/ui/chatcn/pro/spotlight-chat"
<SpotlightChat
messages={chat.chatcnMessages}
status={chat.status}
onSend={(text) => chat.sendMessage({ text })}
onStop={chat.stop}
actions={[{ id: "brief", label: "Summarize this week's feedback" }]}
followUps={["Which of these change the budget?"]}
context="Halden Studio workspace"
/>The bar has three sizes and one surface. Closed it is a single line with its shortcut. Typing opens a list: the first row asks exactly what you typed, the rest are your actions filtered by label and keywords. Asking grows it again into the answer, and the panel height follows the reply token by token, so it never jumps when a tool call or a source list arrives. Escape steps back one level at a time and the footer always names what it will do next: stop, collapse, clear, close. Collapsing keeps the thread behind a Show answer button, so a follow up starts where you left off. Actions with onSelect run instead of asking. onContinue and onNewChat add their buttons to the answer footer.
Examples
States
Props
| Prop | Type | Notes |
|---|---|---|
messages | ChatcnMessage[] | The thread. Pass useChatcnChat().chatcnMessages |
status | "ready" | "submitted" | "streaming" | "error" | Same as AI SDK useChat |
error | ReactNode | Shown with a retry. Say how to fix it |
onSend, onStop, onRetry | (text) => void, () => void, () => void | Wire to your chat |
actions | { id, label, prompt?, icon?, hint?, keywords?, onSelect? }[] | Suggested rows |
followUps | string[] | Offered under the finished answer, arrow keys reach them |
context | ReactNode | What answers come from, at the start of the footer |
onContinue, onNewChat | () => void | Continue in chat and New question buttons |
value, defaultValue, onValueChange | string | The input, controlled or not |
open, defaultOpen, onOpenChange | boolean | Closed shows the one line trigger |
expanded, defaultExpanded, onExpandedChange | boolean | The answer panel is showing |
hotkey, hotkeyTarget | string | null, RefObject | Default mod+k; scope it to one pane |
trigger | boolean | Render the closed line. Default true |
maxAnswerHeight | string | Before the answer scrolls. Default min(24rem, 56dvh) |
disabled | boolean | |
labels | Partial<SpotlightChatLabels> | Every string, for translation |
Keyboard
| Key | Action |
|---|---|
| Cmd K or Ctrl K | Open or close the bar |
| Up and Down | Move through actions or follow ups; Down on the bar shows the kept answer |
| Enter | Ask, or run the highlighted row |
| Escape | Stop, then collapse, then clear, then close: one level per press |
Accessibility
- The input is a combobox; rows are options reached with
aria-activedescendant, so focus never leaves the input. - The bar is a labelled region and the shortcut is announced with
aria-keyshortcuts. - Closing hands focus back to the trigger line.
- The panel content is inert while it is collapsing, so hidden rows are never reachable.
Motion
The panel opens in 280 ms and closes in 210 ms on the kit's ease out, following the content height as it streams; its contents fade in 150 ms. Reduced motion snaps the height and keeps the fade.