KQ-1660 · FIRST/EVENT
First Event
An analytics panel with nothing in it yet, drawn honestly: the axes, the gridlines and a listening pulse at the origin, with the install steps beside it and the minutes counted from a now prop. When the first event arrives the pulse stops, the point drops onto the y-axis and lands on springs.recoil with a ripple along the baseline, and the line begins to draw from it — a clip sweeping right to each new reading — while the scale rises on springs.glide and the steps tick off on springs.flick in a cascade. The steps' Copy buttons are one tab stop that Up, Down, Home and End move through, and silence past the timeout lists what usually goes wrong.
Waylight events
Production · listening since 14:04
Send your first event
Add the tracker
Import it where your app starts.
import { track } from "waylight/track";Initialise with your key
Once, before any event is sent.
track.init("wl_pub_7c2e91");Send a test event
From anywhere a visitor acts.
track("signup", { plan: "trial" });Open your app
Click around like a visitor. Events land here within a minute.
Up and Down move between the copy buttons.
listening · 4 min · waiting for the first signup
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/first-event
Props
- project
- { name: string; environment?: string }
- default defaultFirstEventProject
- The project being wired up, named in the header.
- installSteps
- FirstEventStep[]
- default defaultFirstEventSteps
- What to do to send the first event, in order: { id, title, detail?, code? }; steps with code get a Copy button.
- events
- { at: number; count: number }[]
- default []
- Received buckets, oldest first. The first one to arrive plays the drop; later ones extend the line.
- listeningSince
- number
- default four minutes before now
- When listening began, in ms.
- now
- number
- default defaultFirstEventNow
- The moment the waiting minutes count to, in ms; never read from the clock during render.
- timeoutMinutes
- number
- default 15
- Minutes of silence before the pulse slows and the panel lists what usually goes wrong.
- troubleshooting
- { id: string; title: string; detail?: string }[]
- default defaultFirstEventTroubleshooting
- What usually goes wrong, shown once listening times out.
- windowMinutes
- number
- default 30
- Minutes the x-axis spans from the first event; later readings slide the window.
- metric
- string
- default "events"
- What is being counted, in the chart's words and announcements.
- onCopy
- (stepId: string, text: string) => void
- default —
- A step's snippet was copied (it is also written to the clipboard when one is available).
- onCheckNow
- () => void | Promise<unknown>
- default —
- Check now was pressed. Return a promise to show the check in flight.
- pulseStyle
- "rings" | "sweep" | "dot"
- default "rings"
- How the origin listens: rings leaving it, a scanning sweep between the axes, or a breathing dot.
- axisStyle
- "grid" | "ticks" | "bare"
- default "grid"
- Full gridlines, axis lines with tick marks, or just the baseline.
- accent
- string
- default "var(--accent-bright)"
- The pulse, the line, the points and the finished steps. Any CSS colour.
- maxHeight
- number
- default 540
- Tallest the surface grows before its body scrolls inside, px.
- disabled
- boolean
- default false
- Nothing can be copied or checked; the surface dims.
- className
- string
- default —
- Classes for the outer surface.
| Prop | Type | Default | Description |
|---|---|---|---|
| project | { name: string; environment?: string } | defaultFirstEventProject | The project being wired up, named in the header. |
| installSteps | FirstEventStep[] | defaultFirstEventSteps | What to do to send the first event, in order: { id, title, detail?, code? }; steps with code get a Copy button. |
| events | { at: number; count: number }[] | [] | Received buckets, oldest first. The first one to arrive plays the drop; later ones extend the line. |
| listeningSince | number | four minutes before now | When listening began, in ms. |
| now | number | defaultFirstEventNow | The moment the waiting minutes count to, in ms; never read from the clock during render. |
| timeoutMinutes | number | 15 | Minutes of silence before the pulse slows and the panel lists what usually goes wrong. |
| troubleshooting | { id: string; title: string; detail?: string }[] | defaultFirstEventTroubleshooting | What usually goes wrong, shown once listening times out. |
| windowMinutes | number | 30 | Minutes the x-axis spans from the first event; later readings slide the window. |
| metric | string | "events" | What is being counted, in the chart's words and announcements. |
| onCopy | (stepId: string, text: string) => void | — | A step's snippet was copied (it is also written to the clipboard when one is available). |
| onCheckNow | () => void | Promise<unknown> | — | Check now was pressed. Return a promise to show the check in flight. |
| pulseStyle | "rings" | "sweep" | "dot" | "rings" | How the origin listens: rings leaving it, a scanning sweep between the axes, or a breathing dot. |
| axisStyle | "grid" | "ticks" | "bare" | "grid" | Full gridlines, axis lines with tick marks, or just the baseline. |
| accent | string | "var(--accent-bright)" | The pulse, the line, the points and the finished steps. Any CSS colour. |
| maxHeight | number | 540 | Tallest the surface grows before its body scrolls inside, px. |
| disabled | boolean | false | Nothing can be copied or checked; the surface dims. |
| className | string | — | Classes for the outer surface. |