KQ-1586 · GEL/CLING

Gel Cling

A thick gel window cling on any surface, drawn as a 72-node soft body: press it and it squishes away from the finger and rings back; grab it and peel, and the part in your fingers comes away 1:1 while the rest clings, the peel front running across it as the pull grows and strings of tack stretching between the glass and the lifted gel until each snaps into a bead. Pull far enough and it lets go — the last strings snap in a run — and hangs from your finger, its far side catching up on its springs; let go and it falls on springs.snap, spreads as it meets the surface and pulls back with two small bounces, and clings. The decal is a real button: Enter peels it from the edge with the most room, the arrow keys carry it on springs.snap, Enter or Space sticks it down and Escape puts it back.

KQ-1586 · GEL/CLING

Starfish cling

Reusable gel, sticks to any glass.

Press to squish it. Drag a corner to peel it off and drop it anywhere. Enter lifts it, the arrow keys move it, Enter or Space sticks it down, Escape puts it back.

Coldbrook Aquarium · window clings

stuck · 50% across, 50% down

Install

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

$ pnpm dlx shadcn@latest add @kinetiq/gel-cling

Props

children
React.ReactNode
default —
The surface the decal clings to (a window, a card, a photo), drawn under the gel.
shape
"star" | "heart" | "flower" | "drop"
default "star"
The decal's outline.
size
number
default 112
The decal's width, px; held to 60% of the box's smaller side.
thickness
number
default 0.5
How thick the gel is, 0 to 1: a deeper rim and side wall, a longer shadow, a softer, slower wobble.
tack
number
default 0.5
How hard it clings, 0 to 1: how far you pull before it lets go, and how many strings of tack hold on and how long they stretch.
tint
"cherry" | "lime" | "sky" | "honey" | string
default "cherry"
The gel's colour: a named pigment (the same in both themes) or any CSS colour.
gloss
number
default 0.7
Strength of the glossy highlight, 0 to 1.
wobble
number
default 0.5
How long the gel jiggles after a press or a landing, 0 (dead) to 1 (ringing).
position / defaultPosition
[number, number]
default [0.5, 0.5]
Where the decal's centre sits, as [x, y] fractions of the box. A controlled change lifts it, glides it there and lays it down; a refused move glides it back.
onPositionChange
(position: [number, number]) => void
default —
Fires when the decal is stuck down somewhere new, with its centre as fractions (3 dp).
onPeel
(amount: number) => void
default —
Fires while a corner is peeled, with how far it is toward letting go, 0 to 1 in steps of 0.05.
onLift
() => void
default —
Fires when the decal lets go of the surface.
onStick
(position: [number, number]) => void
default —
Fires when it lands and clings again, with where.
label
string
default "Gel decal"
The decal's accessible name.
sound
boolean
default false
A gloop when it lets go and when it lands, a plip as each string of tack snaps, a blup when squished.
disabled
boolean
default false
The decal stays stuck: no press, peel or keys.
dpr
number
default 2
Cap on the canvas's device pixel ratio, at most 2.
className
string
default "h-56 w-full"
Sizes and shapes the surface; the decal never leaves it.