KQ-1108 · DROP/PIN
Drop Pin
A location picker on an invented, procedurally drawn town with its own survey grid. Holding anywhere grows a shadow under the finger while an aiming ring closes on it; at the delay a pin falls from above the top edge on a gravity tween with a falling whistle, lands with a thock, squashes at its tip on snap and rebounds on a landing spring whose damping comes from bounce (the house recoil by default), reflected off the ground so it hops rather than sinks, and its grid reference fades up above it. The pin drags 1:1, lifting off its shadow on flick and landing where a flick would come to rest on glide; keyboard focus shows a crosshair the arrow keys move, Enter drops the pin there and Delete removes it.
Hold anywhere to drop a pin, or use the arrow keys to move the crosshair, Shift to move it further, Enter to drop the pin and Delete to remove it.
no pin · hold anywhere on the map
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/drop-pin
Props
- value / defaultValue
- { x: number; y: number } | null
- default null
- Where the pin is, in map units (0 to 1200 east, 0 to 200 down from the top edge), or null for no pin. A value set by the host glides, falls or leaves silently.
- onValueChange
- (point: { x: number; y: number } | null) => void
- default —
- Fires once per drop, once per drag on release (with where the throw comes to rest), and with null when the pin is removed.
- label
- string
- default "Map"
- The map's accessible name: what the pin marks.
- delay
- number
- default 450
- How long a press must be held before the pin drops, in ms.
- bounce
- number
- default 0.5
- How lively the landing is, 0 to 1: a thud with a small squash, the house recoil's two hops, or a rubber ball.
- colour
- "cobalt" | "red" | "green" | "amber"
- default "cobalt"
- The pin head, the aiming ring and the crosshair.
- map
- "paper" | "night"
- default "paper"
- A warm street map that follows the page theme, or a dark map with lit streets in both themes.
- sound
- boolean
- default false
- Play the falling whistle and the landing thocks. Nothing plays, and no audio context exists, unless this is on.
- disabled
- boolean
- default false
- Dims the map and takes it out of the tab order; holds, drags and keys do nothing.
- className
- string
- default —
- Merged onto the map box, which is 200px tall, full width up to 1200px.
| Prop | Type | Default | Description |
|---|---|---|---|
| value / defaultValue | { x: number; y: number } | null | null | Where the pin is, in map units (0 to 1200 east, 0 to 200 down from the top edge), or null for no pin. A value set by the host glides, falls or leaves silently. |
| onValueChange | (point: { x: number; y: number } | null) => void | — | Fires once per drop, once per drag on release (with where the throw comes to rest), and with null when the pin is removed. |
| label | string | "Map" | The map's accessible name: what the pin marks. |
| delay | number | 450 | How long a press must be held before the pin drops, in ms. |
| bounce | number | 0.5 | How lively the landing is, 0 to 1: a thud with a small squash, the house recoil's two hops, or a rubber ball. |
| colour | "cobalt" | "red" | "green" | "amber" | "cobalt" | The pin head, the aiming ring and the crosshair. |
| map | "paper" | "night" | "paper" | A warm street map that follows the page theme, or a dark map with lit streets in both themes. |
| sound | boolean | false | Play the falling whistle and the landing thocks. Nothing plays, and no audio context exists, unless this is on. |
| disabled | boolean | false | Dims the map and takes it out of the tab order; holds, drags and keys do nothing. |
| className | string | — | Merged onto the map box, which is 200px tall, full width up to 1200px. |