KQ-2065 · PASTE/FOLD

Paste Fold

A prompt composer that recognises a large paste — a log, a table, a long email, code — and instead of flooding the field spills it in as a sheet of its first lines, then folds it on springs.glide into a labelled block showing its kind, line count and first line, with the caret already after it so you keep typing. Peeking flips the composer to the block's numbered lines with the height gliding, and Trim keeps only the lines you mark (Errors only marks a log's errors in one press); over the character limit the meter turns danger and Send holds. The message is a flow of real textareas and block chips: Left at the start of a run or Backspace there selects the block before it, Space peeks inside, Backspace removes it, and on a phone blocks wrap as full-width chips.

KQ-2065 · PASTE/FOLD

Gaugeworks · import service · run 4412

35 / 4,000

type, or paste something long · gaugeworks import

Install

One command — the source lands in your repo. Or copy it from the Code tab.

$ pnpm dlx shadcn@latest add @kinetiq/paste-fold

Props

foldThreshold
number
default 8
Pastes with at least this many lines fold into a block; shorter ones land as text.
chipStyle
"tab" | "card" | "pill"
default "tab"
A tab with a kind strip and the first line, a two-line card, or a compact pill.
accent
string
default "var(--accent-bright)"
Chips, selection, meter and Send — any CSS colour.
value / defaultValue
PasteFoldPart[]
default — / defaultPasteFoldValue
The message as text runs and folded blocks in order, controlled or initial.
onValueChange
(parts: PasteFoldPart[]) => void
default —
Fires with the whole message after every edit, fold, trim or removal.
rules
PasteFoldRule[]
default defaultPasteRules
How pastes are recognised (log, table, email, code), tried in order, each with an optional one-press keep filter for the trim view; anything else folds as Text.
foldChars
number
default 1200
Pastes with at least this many characters fold too, whatever their line count.
limit
number
default 4000
The most characters a message may carry, blocks included; past it the meter turns danger and Send holds.
onPasteDetected
(block: PasteBlock) => void
default —
A paste was folded into a block.
onExpand
(block: PasteBlock) => void
default —
A block was opened to peek inside.
onTrim
(block: PasteBlock, kept: number[]) => void
default —
A block was trimmed to the marked lines (indexes into its previous lines).
onSubmit
(parts: PasteFoldPart[], text: string) => void
default —
Enter or Send: the parts, and the message as plain text with blocks fenced.
placeholder
string
default "Describe the problem, or paste the log…"
Placeholder for an empty message.
label
string
default "Message"
The message's accessible name.
busy
boolean
default false
An answer is being written: Send holds and spins.
disabled
boolean
default false
Nothing can be typed, pasted or sent.
ref
React.Ref<PasteFoldHandle>
default —
Imperative handle: paste(text) pastes as a real paste would; focus() puts the caret at the end.
className
string
default —
Classes for the outer surface.