KQ-1293 · PROMPT/DOCK
Prompt Dock
A prompt box with its context around it: a tray of pinned files and snippets that collapses into a count as each chip's icon flies into a stack on glide, files dropped on the dock flying from the drop point into the tray (x on glide, y on snap, so the path bows), and an @ menu whose chosen row flies in the same way. A model pill opens in place into every model with a highlight sliding on snap, the token meter fills and warms toward the limit and bumps on recoil as it crosses 90% and the limit, and Send's arrow folds into a stop square on snap while a reply is written. The box is a real textarea and combobox: arrows walk the @ menu, Enter or Tab attaches, Escape closes it or stops a reply, and Backspace in an empty box removes the last chip.
ready · 3 in context · 4.5k of 8k
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/prompt-dock
Props
- value / defaultValue
- string
- default — / ""
- The prompt text.
- onValueChange
- (text: string) => void
- default —
- Fires from the keystroke, the @ choice or the send that changed the text.
- context / defaultContext
- DockItem[]
- default — / defaultContext
- The items in the tray: id, kind, name, tokens and an optional detail.
- onContextChange
- (items: DockItem[]) => void
- default —
- Fires from the drop, the attach, the @ choice or the remove that changed the tray.
- sources
- DockItem[]
- default defaultSources
- What the @ menu offers, filtered as you type.
- models
- DockModel[]
- default defaultModels
- The models the pill switches between: id, name, short name, note.
- model
- string
- default the first model
- The selected model's id. A new value slides the pill to it; the visitor's own switch is reported through onModelChange.
- onModelChange
- (id: string) => void
- default —
- The visitor chose a model.
- tray
- "open" | "count" | "auto"
- default "open"
- The tray starts open, starts collapsed into a count, or collapses itself while there is text in the box.
- limit
- number
- default 8000
- The context budget in tokens: the meter warms toward it and Send stops past it.
- generating / defaultGenerating
- boolean
- default — / false
- A reply is being written, so Send is Stop. Uncontrolled, Send turns it on and Stop off.
- onGeneratingChange
- (generating: boolean) => void
- default —
- Send or Stop changed it.
- onSend
- (message: { text, context, model }) => void
- default —
- Send or Enter, with what was sent. The box clears.
- onStop
- () => void
- default —
- Stop was pressed, or Escape while a reply is written.
- onFilesAdd
- (files: File[]) => void
- default —
- Files dropped on the dock or picked with Attach.
- accept
- string
- default —
- File types the Attach picker offers, as for an input's accept.
- placeholder
- string
- default "Ask anything, or type @ to add context"
- The empty box's hint.
- maxRows
- number
- default 6
- How many lines the box grows to before it scrolls.
- label
- string
- default "Prompt"
- The dock's and the box's accessible name.
- sound
- boolean
- default false
- Play the chip landings, the switches, Stop and the send.
- disabled
- boolean
- default false
- Disables the box, the tray, the picker and Send.
- className
- string
- default —
- Classes for the dock's outer box.
| Prop | Type | Default | Description |
|---|---|---|---|
| value / defaultValue | string | — / "" | The prompt text. |
| onValueChange | (text: string) => void | — | Fires from the keystroke, the @ choice or the send that changed the text. |
| context / defaultContext | DockItem[] | — / defaultContext | The items in the tray: id, kind, name, tokens and an optional detail. |
| onContextChange | (items: DockItem[]) => void | — | Fires from the drop, the attach, the @ choice or the remove that changed the tray. |
| sources | DockItem[] | defaultSources | What the @ menu offers, filtered as you type. |
| models | DockModel[] | defaultModels | The models the pill switches between: id, name, short name, note. |
| model | string | the first model | The selected model's id. A new value slides the pill to it; the visitor's own switch is reported through onModelChange. |
| onModelChange | (id: string) => void | — | The visitor chose a model. |
| tray | "open" | "count" | "auto" | "open" | The tray starts open, starts collapsed into a count, or collapses itself while there is text in the box. |
| limit | number | 8000 | The context budget in tokens: the meter warms toward it and Send stops past it. |
| generating / defaultGenerating | boolean | — / false | A reply is being written, so Send is Stop. Uncontrolled, Send turns it on and Stop off. |
| onGeneratingChange | (generating: boolean) => void | — | Send or Stop changed it. |
| onSend | (message: { text, context, model }) => void | — | Send or Enter, with what was sent. The box clears. |
| onStop | () => void | — | Stop was pressed, or Escape while a reply is written. |
| onFilesAdd | (files: File[]) => void | — | Files dropped on the dock or picked with Attach. |
| accept | string | — | File types the Attach picker offers, as for an input's accept. |
| placeholder | string | "Ask anything, or type @ to add context" | The empty box's hint. |
| maxRows | number | 6 | How many lines the box grows to before it scrolls. |
| label | string | "Prompt" | The dock's and the box's accessible name. |
| sound | boolean | false | Play the chip landings, the switches, Stop and the send. |
| disabled | boolean | false | Disables the box, the tray, the picker and Send. |
| className | string | — | Classes for the dock's outer box. |