KQ-758 · DRAFT/PARK

Draft Park

A composer with a parking rail beneath it. Park takes the field's draft and puts it aside: a ghost of the text drops out of the field on the exit ease while a chip with its first words lands on the rail from sixteen pixels on glide — a layout move, no bounce. Pressing the chip slides it back, the chip leaving upward on the exit ease as the text arrives in the field on glide with the caret at its end; a draft already in the field is parked in the same motion, so a restore is a swap and nothing is lost. The rail is measured, so its height glides to the chip rows, and drafts persist across runs: Send clears the field while the rail keeps every chip.

KQ-758 · DRAFT/PARK
Enter sendsEnter sends, Shift+Enter breaks the line, Park puts the draft aside

No parked drafts

No drafts · type, then park

Install

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

$ pnpm dlx shadcn@latest add @kinetiq/draft-park

Props

value / defaultValue
string
default ""
Controlled or initial field text.
onValueChange
(value: string) => void
default
Fires from every edit, a park and a restore.
drafts / defaultDrafts
ParkedDraft[]
default []
Controlled or initial parked drafts, { id, text }, newest last.
onDraftsChange
(drafts: ParkedDraft[]) => void
default
Fires from a park, a restore and a discard with the whole rail.
onPark
(draft: ParkedDraft) => void
default
Fires from the Park button, and from a restore that swapped the field's draft out, with the draft it made.
onRestore
(draft: ParkedDraft) => void
default
Fires from a chip press with the draft it returned.
onDiscard
(draft: ParkedDraft) => void
default
Fires from a chip's discard button.
onSend
(value: string) => void
default
Fires from Enter or the Send button with the trimmed draft; the field clears.
live
boolean
default false
A run is in flight: Send is held, Park and the rail still work.
placeholder
string
default "Ask anything"
Placeholder while the field is empty.
label
string
default
Names the field.