KQ-1111 · SLING/SEND
Sling Send
A composer whose send button is a slingshot: the draft rides as a bubble in the pouch of a rubber band, and pulling it back (and to one side to aim) stretches the band 1:1 with the finger, thinning and warming it as it goes, with a creak pitched by the stretch. Let go past a third of the way and the band fires as a real spring, the bubble leaves the pouch at that speed and flies out through the frame's own clipped edge while the band wobbles back on springs.recoil; a short pull snaps back on springs.snap carrying the release velocity, nothing sent. Enter in the text field sends with a full pull; on the bubble, Arrow keys pull and aim, Enter lets go and Escape lets the band down.
Fieldline: Your order FW-4410 shipped this morning.
You: Great. Is there a tracking number?
Fieldline: FL 88 2041 7763, arriving Thursday.
Enter or Space sends with a full pull. Arrow Down pulls back, Arrow Up eases off, Arrow Left and Right aim, then Enter lets go. Escape lets the band down.
reply loaded · pull back and let go
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/sling-send
Props
- value / defaultValue
- string
- default ""
- The draft. Controlled or uncontrolled.
- onValueChange
- (value: string) => void
- default —
- Fires as the draft is typed, and with "" the moment the band fires.
- onSend
- (message: string) => void
- default —
- Fires the moment the band fires, with the message.
- label
- string
- default "Message"
- The text field's accessible name.
- placeholder
- string
- default "Write a message"
- Shown in the empty field and on the empty bubble.
- stiffness
- number
- default 0.5
- The band's spring, 0 to 1: a slack band pushes slowly and lobs the bubble, a stiff one fires it fast. It also sets the snap-back and the band's thickness.
- maxStretch
- number
- default 100
- How far the band pulls before it resists, in px, 60 to 140. The launch frame grows with it.
- trajectory
- "straight" | "arc" | "guided"
- default "arc"
- How the bubble flies once it leaves the band: along the aim, under gravity so an angled shot curves, or turning upright so every shot leaves through the top.
- trail
- boolean
- default true
- A fading streak behind the bubble in flight.
- sound
- boolean
- default false
- Play the band's synthesised sounds: a creak pitched by the stretch while it moves, a twang when it fires, a whoosh as the bubble leaves, a slap when it snaps back. Nothing plays, and no audio context exists, unless this is on.
- disabled
- boolean
- default false
- Dims the composer and disables the field and the bubble.
- className
- string
- default —
- Merged onto the frame's classes.
| Prop | Type | Default | Description |
|---|---|---|---|
| value / defaultValue | string | "" | The draft. Controlled or uncontrolled. |
| onValueChange | (value: string) => void | — | Fires as the draft is typed, and with "" the moment the band fires. |
| onSend | (message: string) => void | — | Fires the moment the band fires, with the message. |
| label | string | "Message" | The text field's accessible name. |
| placeholder | string | "Write a message" | Shown in the empty field and on the empty bubble. |
| stiffness | number | 0.5 | The band's spring, 0 to 1: a slack band pushes slowly and lobs the bubble, a stiff one fires it fast. It also sets the snap-back and the band's thickness. |
| maxStretch | number | 100 | How far the band pulls before it resists, in px, 60 to 140. The launch frame grows with it. |
| trajectory | "straight" | "arc" | "guided" | "arc" | How the bubble flies once it leaves the band: along the aim, under gravity so an angled shot curves, or turning upright so every shot leaves through the top. |
| trail | boolean | true | A fading streak behind the bubble in flight. |
| sound | boolean | false | Play the band's synthesised sounds: a creak pitched by the stretch while it moves, a twang when it fires, a whoosh as the bubble leaves, a slap when it snaps back. Nothing plays, and no audio context exists, unless this is on. |
| disabled | boolean | false | Dims the composer and disables the field and the bubble. |
| className | string | — | Merged onto the frame's classes. |