Prompt area
<PromptInput />The box a prompt is written in, and everything that rides on it: suggestions, attachments, the crew of agents it goes to, mentions and commands, how full the context is, and prompts queued while the agents are busy.
Install
bash
npx shadcn@latest add https://orbeez-kit.vercel.app/r/prompt-input.jsonUsage
tsx
<PromptInput value={draft} onValueChange={setDraft} onSubmit={send} loading={answering} onFiles={addFiles}>
<Attachments>{files.map((f) => <Attachment key={f.id} {...f} />)}</Attachments>
<PromptInputTextarea placeholder="Ask your agents..." />
<PromptInputActions>
<PromptInputAction tooltip="Attach files">
<IconButton label="Attach files"><PaperclipIcon /></IconButton>
</PromptInputAction>
<PromptInputCrew />
<PromptInputSubmit onStop={stop} />
</PromptInputActions>
</PromptInput>Good to know
- Moods. The lead bead is sleepy while the box is empty, thinking while you type, and working once sent.
- The field grows with what is written up to maxHeight, then scrolls. Enter sends; Shift+Enter breaks the line.
- PromptInputCrew splits the prompt into parts after a colon, one per agent, and shows a bead for each. Pass split to split it your own way.
- While loading, the send bead turns into stop if you give it onStop.
- Give it uploading, the number of files still on their way up, and send waits till there are none, so the prompt and its files go together. The crew says what it is waiting on.
- Give it onFiles and a paste can come in as a file: files on the clipboard, like a screenshot, and text longer than pasteAsFile characters (10,000 by default), which becomes "Pasted text.txt". onFiles is told which, as "clipboard" or "long-paste". For a long paste, give its Attachment onInsert and the chip offers to put it back in the field as text, with file.text(). pasteAsFile={false} keeps every paste as text. Only pastes count; typing past the limit never turns into a file.
Behaviour
- Grows upward: the bottom edge stays put while text is written, pasted or deleted, and the top edge moves by whole lines.
- Stops at maxHeight and scrolls inside. However long the prompt, nothing outside the box moves.
- Typing keeps the field scrolled where it was: the caret stays in view and the text never jumps to the top.
- A paste over pasteAsFile characters never reaches the field. It goes to onFiles as one .txt file.
- Send is disabled while there is nothing written, and while any file is still uploading. Enter does nothing then too.
- The crew label changes only its words, never its height, and is announced politely to screen readers.
- Attachments, the queue tab and the mention list never push the field: the chips take a row of their own, and the tab and the list float over the tray.
- Tooltips on the tray's buttons are never cut off by a row that scrolls or a box that clips.
Compact
<PromptInput />The same box in one row, the field between the tools and the send button, for tight spots like a side panel or a reply under a message.
tsx
<PromptInput compact value={draft} onValueChange={setDraft} onSubmit={send}>
<PromptInputMentions triggers={triggers} />
<Attachments>{files.map((f) => <Attachment key={f.id} {...f} />)}</Attachments>
<PromptInputActions>
<IconButton label="Attach a file"><PaperclipIcon /></IconButton>
</PromptInputActions>
<PromptInputTextarea />
<PromptInputActions>
<PromptInputCrew />
<PromptInputSubmit onStop={stop} />
</PromptInputActions>
</PromptInput>- Put a PromptInputActions on either side of the field, or only after it. Everything else, like mentions, the queue and the context meter, works the same.
- The field grows as it wraps, and the buttons keep to its last line.
- Attachments take a row of their own over the field.
- The crew perches on the top edge of the tray, at the right, half out of it, so it takes no room from the field. It shows its beads alone; what it would say is still read out to screen readers. Put it anywhere in the actions; it finds its own place.
Behaviour
- One row while the prompt fits on one line: the field's line sits level with the buttons beside it.
- Grows only as the field wraps, upward, and the buttons stay on its last line.
- Attachments take a row of their own over the field and never squeeze it.
- The crew sits on the top edge at the right and takes no room in the row. Its lead bead stays put as parts pop in to its left.
- With a crew on the edge, the queue tab on that edge stops short of it rather than running under it.
- The crew shows beads alone. Its label is still read to screen readers.
Prompt suggestion
<PromptSuggestion />Pills to start a conversation from, or, with highlight, lines that complete what is being typed.
bash
npx shadcn@latest add https://orbeez-kit.vercel.app/r/prompt-suggestion.jsontsx
<PromptSuggestion onClick={() => setDraft('Plan the launch')}>Plan the launch</PromptSuggestion>
// completing what is typed
{matches.map((m) => (
<PromptSuggestion key={m} highlight={typed} onClick={() => setTyped(m)}>{m}</PromptSuggestion>
))}Mentions and commands
<PromptInputMentions />Type @ to mention a file or an agent, or / for a command. The list comes up over the tray, driven by the keyboard, and what is picked is written into the prompt.
Click into the box and type @ or /. Arrows move, Enter or Tab picks, Escape closes.
bash
npx shadcn@latest add https://orbeez-kit.vercel.app/r/mentions.jsontsx
<PromptInput value={draft} onValueChange={setDraft} onSubmit={send}>
<PromptInputMentions
triggers={[
{ char: '@', title: 'Files and agents', items: files },
{ char: '/', title: 'Commands', items: commands },
]}
/>
<PromptInputTextarea />
...
</PromptInput>- The list floats over the tray instead of taking room in it, so opening it moves nothing.
- Arrow keys move through it, Enter or Tab picks, Escape closes; the focus never leaves the field, and the field says which option is active for screen readers.
- Give an item a hue to show it as an agent, with its bead, or an icon of its own.
Behaviour
- A mention moves no letter of the prompt: the chip adds colour and a ring, never padding or weight, so the caret always lands where the text is drawn.
- An agent's bead takes the place of the @ and is never wider than it. The chip reaches further left to make room round it, with a box-shadow that takes no space.
- The chip is in the agent's own colour, written out in full, never a colour variable that resolves to another hue.
- The list floats over the tray: opening and closing it moves nothing.
- The focus stays in the field the whole time. Arrows move, Enter or Tab picks, Escape closes.
- A whole mention goes with one Backspace.
Queue
<Queue />Prompts lined up while the agents are busy, as a tab on the prompt itself that pulls out into a drawer. Pressing Enter mid-answer queues instead of waiting.
Working on: Ship dark mode
bash
npx shadcn@latest add https://orbeez-kit.vercel.app/r/queue.jsontsx
<PromptInput value={draft} onValueChange={setDraft} onSubmit={send} loading={busy} onQueue={(text) => enqueue(text)}>
<Queue items={queue} onRemove={remove} onReorder={setOrder} onEdit={rename} />
<PromptInputTextarea />
...
</PromptInput>
// when the current answer is done, send what is next
useEffect(() => { if (!busy && queue.length) send(dequeue()) }, [busy, queue])- Give PromptInput onQueue and sending while loading hands the prompt to it rather than doing nothing. The crew says "Enter to queue it" while you type.
- It belongs to the prompt: a tab on the tray's top edge, with a heap of waiting beads and a count, that pulls out into a drawer of the queued prompts.
- It takes no room. The tab is the same height however many are waiting, and the drawer's rows stand on it with transforms, stacked from the bottom, so when the front prompt is picked up it lifts off and the rest stay exactly where they were.
- Leave room at the foot of the conversation for the tab (ChatContainerContent with some bottom padding), so it never covers the latest message.
- Pull a row by its grip to change the order; the others make way as you drag, and all of it moves by transform. The grip also takes the up and down arrow keys, for anyone not using a pointer.
- The pencil edits a prompt in place: Enter saves, Escape puts it back. The row keeps its height while you edit.
- The drawer shows four prompts at most and scrolls the rest, next up at the top and newest at the bottom, with a fade at an edge there is more past. A long queue never climbs over the conversation, and a prompt you just queued is scrolled into view.
- Each prompt keeps its bead colour however the line moves.
Context meter
<ContextMeter />How full the model's context is: a bead in a ring that fills and turns from green to amber to red.
19%· 200k71%· 200k94%· 200k
bash
npx shadcn@latest add https://orbeez-kit.vercel.app/r/context-meter.jsontsx
<ContextMeter used={usage.totalTokens} max={200_000} />- Moods. Past 85% the bead switches to angry.