KQ-1102 · COPY/SLIP

Copy Slip

A copy field whose Copy button is a clipboard with its clip standing open. Pressed, a paper slip carrying the text lifts off the value and flies in a true throw — x linear, y a measured arc that never leaves the component — into the clipboard, where the clip clamps shut on snap and the glyph takes the landing on recoil; the button says Copied until the clip reopens. The slip only goes in if the clipboard took the text: a refusal bounces it back out on recoil, selects the text and says why in words, and Enter and Space copy through the same press.

KQ-1102 · COPY/SLIP
Payment link
pay.waylight.test/r/4F9A-C21E

ready · nothing copied yet

Install

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

$ pnpm dlx shadcn@latest add @kinetiq/copy-slip

Props

value
string
default —
What is copied, and shown in the field.
label
string
default —
Names the field. The button is named by its word plus this: "Copy Payment link".
arc
number
default 0.8
How high the slip is lobbed, 0 to 1: 0 slides it straight along the row, 1 uses all the room above it. The swish rises with it.
slip
number
default 0.5
How light the paper is, 0 to 1: a stiff card thrown straight and fast, or a slip that hangs, leans along its path, flutters and takes its time.
hold
number
default 2
Seconds the clip stays shut and the button says Copied. The clock pauses while the page is hidden.
showText
boolean
default true
Print the copied text on the slip; off draws ruled lines, for values that should not fly past a shared screen.
onCopy
(value: string) => void
default —
Fires once the clipboard has taken the value.
onCopyError
(reason: "insecure" | "blocked" | "unavailable") => void
default —
Fires when the clipboard refused: an insecure page, a denied permission, or a writer that failed or did not answer.
writer
(text: string) => Promise<void>
default —
Writes the text. Defaults to the system clipboard's writeText; swap in rich copy or a test double.
sound
boolean
default false
Play the paper and the clip. Nothing plays, and no audio context exists, unless this is on.
disabled
boolean
default false
Disables the button and dims the field.
className
string
default —
Merged onto the root element's classes.