Skip to content
Sign in
ConversationPaste chipMenu

Paste chipPro

A long paste becomes an attachment chip with its line count, a language guess and a preview, in the composer and in the sent message.

ProA 38 line paste folds into a chip, goes out with the message and opens as a preview. Paste your own long text after it.

Installation

$ pnpm dlx shadcn@latest add @chatcn-pro/paste-chip

Usage

tsx
import { PasteChipGroup, PasteChipTray, usePasteChips } from "@/components/ui/chatcn/pro/paste-chip"

const chips = usePasteChips({ minLines: 10 })

<PromptInput onSubmit={({ text }) => send(text, chips.take())}>
  <PasteChipTray pastes={chips.pastes} onRemove={chips.remove} />
  <PromptInputTextarea onPaste={chips.onPaste} />
</PromptInput>

<Message from="user">
  <PasteChipGroup pastes={message.pastes} />
  <MessageContent>{message.text}</MessageContent>
</Message>

Wire onPaste to the composer textarea: short pastes go through as text, and anything over minLines lines or minChars characters folds into a chip instead of a wall of text. The chip draws a silhouette of the paste, one hairline per line with its indentation, names it by its most telling line (a leading comment, else the first line that says something) and guesses the language from its shape. Click it for a preview with line numbers, Copy, Insert as text and Remove. Insert as text puts the paste back where it was pasted and selects it, so one keystroke can still replace it. take() returns the chips and clears the tray at send; render the same list with PasteChipGroup in the sent message.

Examples

States

ProTwo pastes in the composer, the same chip in a sent message, four language guesses and a 4 line threshold to paste into.

Props

PropTypeNotes
usePasteChips({ minLines?, minChars?, initial?, onChange? })Defaults 10 lines, 1,000 characters
returns pastes, onPaste, add, remove, take, isLong, setState and handlers
PasteChipTray pastes, onRemovePastedText[], (id) => voidInside a PromptInput
PasteChipGroup pastesPastedText[]Read only chips for a message
PasteChip paste, onRemove?, onExpand?, variant?PastedText, "composer" | "message"One chip, for custom rows
PastedText{ id, text, lines?, language?, at? }at is the caret position at paste
guessLanguage(text)stringThe guess on its own
labelsPartial<…Labels>Every string, for translation

Keyboard

KeyAction
Enter or SpaceOpen the preview
Backspace or DeleteRemove the focused chip
EscapeClose the preview

Accessibility

  • Each chip is a button named with its language and line count, as in Pasted Log, 11 lines. Open preview.
  • Removing a chip moves focus to the next chip, or back to the textarea.
  • The preview scroll area is focusable, so the paste can be read without a pointer.

Motion

A chip enters from scale 0.96 and 4 px of travel in 180 ms, as if the text folded into a file. Removing or inserting it exits in 140 ms; from the keyboard it goes at once. The preview grows from the chip. Reduced motion keeps the fades only.