KQ-1581 · DART/CURSOR

Dart Cursor

Inside its box the cursor is a folded paper dart seen from above, nose on the pointer: a small 3D model with dihedral wings and a keel, flat-shaded from an upper-left light, whose shadow falls further and softer the higher it flies. The nose points where it flies on springs.snap, it banks into each turn by the coordinated-turn angle on springs.snap, dips its nose as it slows on springs.glide and rides higher with speed on springs.drift; circle it fast and it loops the loop, and two hairlines from its wingtips trail behind and fade. A lifted finger or a pointer that leaves throws it on to glide, bank away from the edges and land; keyboard focus on a child flies it there along a banked curve, and Enter or Space on that child salutes with a loop.

KQ-1581 · DART/CURSOR

Waylight · Travel journal

Every trip, folded into one page.

landed · point inside, or press Tab

Install

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

$ pnpm dlx shadcn@latest add @kinetiq/dart-cursor

Props

children
React.ReactNode
default —
The area the dart flies in. Its buttons and links keep every click, focus and key.
size
number
default 26
The dart's length, px.
bank
number
default 0.7
How far it rolls into a turn, 0 (flat turns) to 1 (steep, knife-edge rolls).
trail
number
default 1.2
How long its wingtip trails last, seconds; 0 draws none.
color
"paper" | "kraft" | "cobalt" | "ink" | string
default "paper"
The paper: a named tone from the theme, or any CSS colour.
loop
boolean
default true
Circle fast and it loops the loop.
glide
boolean
default true
A lifted finger or a pointer that leaves throws the dart on, to glide and land.
drag
number
default 0.5
How quickly a glide bleeds its speed, 0 (floaty) to 1 (heavy).
lift
number
default 0.5
How high speed carries it, 0 to 1: its shadow falls further below a fast dart.
restAt
[number, number]
default [0.86, 0.72]
Where it sits landed before anyone points, as fractions of the box.
restHeading
number
default -150
Which way it points while landed, degrees (0 is right, -90 up).
targets
string
default "a[href], button, input, select, textarea, [role='button'], [tabindex]:not([tabindex='-1'])"
Children it flies to when they take keyboard focus, as a CSS selector.
followFocus
boolean
default true
Keyboard focus on a child flies the dart to it; Enter or Space there loops.
hideCursor
boolean
default true
Hide the system cursor while the dart leads (never over text fields, never after a key).
interactive
boolean
default true
The pointer and touch fly the dart.
onLoop
() => void
default —
It looped the loop.
onLand
() => void
default —
It touched down after a glide or a flight.
className
string
default —
Classes for the box.